Browse Source

[IMP] use base_patch_models_mixin

pull/28/head
Holger Brunn 9 years ago
parent
commit
03126bfc76
  1. 1
      mail_follower_custom_notification/models/__init__.py
  2. 92
      mail_follower_custom_notification/models/base_patch_models_mixin.py
  3. 36
      mail_follower_custom_notification/models/mail_thread.py

1
mail_follower_custom_notification/models/__init__.py

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2015 Therp BV <http://therp.nl> # © 2015 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import base_patch_models_mixin
from . import mail_followers from . import mail_followers
from . import mail_thread from . import mail_thread
from . import mail_message from . import mail_message

92
mail_follower_custom_notification/models/base_patch_models_mixin.py

@ -0,0 +1,92 @@
# -*- coding: utf-8 -*-
# © 2016 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from openerp import SUPERUSER_ID, models
_logger = logging.getLogger(__file__)
# TODO: this should be a helper module to cetralize the point of failure
# in case this introduces tacit bugs
class BasePatchModelsMixin(models.AbstractModel):
"""
This is a mixin class meant to simplify working with patches
on BaseModel or on abstract models like mail.thread.
If you just change them, models created earlier will lack the
attributes you add. Just inherit from this mixin, it will check
which existing models need your changes and apply them.
In your module, do something like
class MailThread(models.AbstractModel):
_name = 'mail.thread'
_inherit = ['base.patch.models.mixin', 'mail.thread']
in case you need to patch BaseModel, say
class BaseModel(models.BaseModel):
_name = 'my.unique.model.name'
_inherit = 'base.patch.models.mixin'
Your code will behave as if it was an inherited class of the class you pass
in the second parameter to _base_patch_models.
"""
_name = 'base.patch.models.mixin'
def _base_patch_models(self, cr, our_class=None, parent_class=None):
"""iterate through existing models to apply our changes there if
necessary"""
if self._name == BasePatchModelsMixin._name:
return
my_bases = self.__class__.__bases__
for i in range(max(len(my_bases) - 1, 0)):
if my_bases[i]._name == BasePatchModelsMixin._name:
our_class = my_bases[i - 1]
parent_class = my_bases[i + 1]
inherit = [self._inherit]\
if isinstance(self._inherit, basestring) else self._inherit
for i in range(len(my_bases) - 1, 0, -1):
# this can be different from the above if our mixin is used
# multiple times on the same model
if my_bases[i]._name in inherit:
parent_class = my_bases[i]
break
if self.__class__.__bases__[-1] == BasePatchModelsMixin\
and not our_class or not parent_class:
our_class = self.__class__.__bases__[-2]
parent_class = models.BaseModel
if not our_class or not parent_class:
_logger.info(
'Failed to autodetect own class or parent class for %s, '
'ignoring', self._name)
return
for model_name, model_object in self.pool.models.iteritems():
if not isinstance(model_object, parent_class):
continue
if isinstance(model_object, our_class):
continue
if not isinstance(model_object, models.Model):
continue
bases = list(model_object.__class__.__bases__)
position = 1
if parent_class == models.BaseModel:
position = len(bases)
else:
for i in range(len(bases) - 1, position, -1):
if bases[i]._name in inherit:
position = i
break
bases.insert(position, our_class)
model_object.__class__.__bases__ = tuple(bases)
def _register_hook(self, cr):
self._base_patch_models(cr)
for base in self.__class__.__bases__:
if not hasattr(super(base, self), '_register_hook'):
return
if super(base, self)._register_hook != self._register_hook:
return super(base, self)._register_hook.__func__(
super(base, self), cr)

36
mail_follower_custom_notification/models/mail_thread.py

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2015 Therp BV <http://therp.nl> # © 2015 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import SUPERUSER_ID, api, models
from openerp.addons.mail.mail_thread import mail_thread
from openerp import api, models
class MailThread(models.Model):
_inherit = 'mail.thread'
class MailThread(models.AbstractModel):
_inherit = ['base.patch.models.mixin', 'mail.thread']
_name = 'mail.thread'
@api.multi @api.multi
def _get_subscription_data(self, name, args, user_pid=None): def _get_subscription_data(self, name, args, user_pid=None):
@ -78,31 +78,3 @@ class MailThread(models.Model):
'force_own_subtype_ids': [(6, 0, ids_with_value( 'force_own_subtype_ids': [(6, 0, ids_with_value(
data, 'force_own', '1'))] data, 'force_own', '1'))]
}), }),
def _register_hook(self, cr):
model_ids = self.pool['ir.model'].search(cr, SUPERUSER_ID, [])
rebuilt = []
for model in self.pool['ir.model'].browse(cr, SUPERUSER_ID, model_ids):
if model.model not in self.pool:
continue
model_object = self.pool[model.model]
if not isinstance(model_object, mail_thread):
continue
if isinstance(model_object, MailThread):
continue
bases = list(model_object.__class__.__bases__)
if MailThread not in bases:
bases.insert(1, MailThread)
class_dict = dict(model_object.__dict__)
class_dict['_inherit'] = model_object._name
new_model_class = type(model_object._name, tuple(bases),
class_dict)
new_model = new_model_class._build_model(self.pool, cr)
self.pool.models[model.model] = new_model
new_model._prepare_setup(cr, SUPERUSER_ID)
new_model._setup_base(cr, SUPERUSER_ID, False)
new_model._setup_fields(cr, SUPERUSER_ID)
rebuilt.append(new_model)
for model in rebuilt:
model._setup_complete(cr, SUPERUSER_ID)
return super(MailThread, self)._register_hook(cr)
Loading…
Cancel
Save