You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.9 KiB

8 years ago
  1. # -*- coding: utf-8 -*-
  2. # © 2014-2016 Therp BV <http://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from odoo import _, api, models, fields
  5. from odoo.exceptions import UserError
  6. from odoo.addons.base.ir.ir_model import MODULE_UNINSTALL_FLAG
  7. class IrModel(models.Model):
  8. _inherit = 'ir.model'
  9. def _drop_table(self):
  10. """this function crashes for undefined models"""
  11. existing_model_ids = self.filtered(lambda x: x.model in self.env)
  12. return super(IrModel, existing_model_ids)._drop_table()
  13. @api.depends()
  14. def _inherited_models(self):
  15. """this function crashes for undefined models"""
  16. existing_model_ids = self.filtered(lambda x: x.model in self.env)
  17. super(IrModel, existing_model_ids)._inherited_models()
  18. class IrModelFields(models.Model):
  19. _inherit = 'ir.model.fields'
  20. @api.multi
  21. def _prepare_update(self):
  22. """this function crashes for undefined models"""
  23. existing = self.filtered(lambda x: x.model in self.env)
  24. return super(IrModelFields, existing)._prepare_update()
  25. class CleanupPurgeLineModel(models.TransientModel):
  26. _inherit = 'cleanup.purge.line'
  27. _name = 'cleanup.purge.line.model'
  28. _description = 'Purge models'
  29. wizard_id = fields.Many2one(
  30. 'cleanup.purge.wizard.model', 'Purge Wizard', readonly=True)
  31. @api.multi
  32. def purge(self):
  33. """
  34. Unlink models upon manual confirmation.
  35. """
  36. context_flags = {
  37. MODULE_UNINSTALL_FLAG: True,
  38. 'purge': True,
  39. }
  40. if self:
  41. objs = self
  42. else:
  43. objs = self.env['cleanup.purge.line.model']\
  44. .browse(self._context.get('active_ids'))
  45. for line in objs:
  46. self.env.cr.execute(
  47. "SELECT id, model from ir_model WHERE model = %s",
  48. (line.name,))
  49. row = self.env.cr.fetchone()
  50. if not row:
  51. continue
  52. self.logger.info('Purging model %s', row[1])
  53. attachments = self.env['ir.attachment'].search([
  54. ('res_model', '=', line.name)
  55. ])
  56. if attachments:
  57. self.env.cr.execute(
  58. "UPDATE ir_attachment SET res_model = NULL "
  59. "WHERE id in %s",
  60. (tuple(attachments.ids), ))
  61. self.env['ir.model.constraint'].search([
  62. ('model', '=', line.name),
  63. ]).unlink()
  64. relations = self.env['ir.model.fields'].search([
  65. ('relation', '=', row[1]),
  66. ]).with_context(**context_flags)
  67. for relation in relations:
  68. try:
  69. # Fails if the model on the target side
  70. # cannot be instantiated
  71. relation.unlink()
  72. except KeyError:
  73. pass
  74. except AttributeError:
  75. pass
  76. self.env['ir.model.relation'].search([
  77. ('model', '=', line.name)
  78. ]).with_context(**context_flags).unlink()
  79. self.env['ir.model'].browse([row[0]])\
  80. .with_context(**context_flags).unlink()
  81. line.write({'purged': True})
  82. return True
  83. class CleanupPurgeWizardModel(models.TransientModel):
  84. _inherit = 'cleanup.purge.wizard'
  85. _name = 'cleanup.purge.wizard.model'
  86. _description = 'Purge models'
  87. @api.model
  88. def find(self):
  89. """
  90. Search for models that cannot be instantiated.
  91. """
  92. res = []
  93. self.env.cr.execute("SELECT model from ir_model")
  94. for model, in self.env.cr.fetchall():
  95. if model not in self.env:
  96. res.append((0, 0, {'name': model}))
  97. if not res:
  98. raise UserError(_('No orphaned models found'))
  99. return res
  100. purge_line_ids = fields.One2many(
  101. 'cleanup.purge.line.model', 'wizard_id', 'Models to purge')