diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..b7d62bd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/testserver.iml b/.idea/testserver.iml new file mode 100644 index 0000000..8b8c395 --- /dev/null +++ b/.idea/testserver.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..55bb9c5 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1783946253712 + + + + + + \ No newline at end of file diff --git a/testserver_o2b/__init__.py b/testserver_o2b/__init__.py index 5305644..67494e6 100644 --- a/testserver_o2b/__init__.py +++ b/testserver_o2b/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- -from . import models \ No newline at end of file +from . import hooks +from . import models diff --git a/testserver_o2b/__manifest__.py b/testserver_o2b/__manifest__.py index fb7e60f..006cae3 100644 --- a/testserver_o2b/__manifest__.py +++ b/testserver_o2b/__manifest__.py @@ -11,9 +11,10 @@ 'category': 'Tools', 'license': "AGPL-3", 'version': '19.0.1.0.0', - 'depends': ['mail','base','mailcatcher_menu',], + 'depends': ['mail', 'base', 'mailcatcher_menu'], 'data': [ 'views/templates.xml', 'data/ir_cron.xml', ], + 'post_init_hook': 'post_init_hook', } diff --git a/testserver_o2b/data/ir_cron.xml b/testserver_o2b/data/ir_cron.xml index 824baa2..66c48b4 100644 --- a/testserver_o2b/data/ir_cron.xml +++ b/testserver_o2b/data/ir_cron.xml @@ -1,10 +1,28 @@ - - Testserver: Set Date (ONLY FOR TEST ENV.) - - code - model.set_db_param() - days - - \ No newline at end of file + + + Testserver: Set Date (ONLY FOR TEST ENV.) + + code + model.set_db_param() + 1 + days + -1 + + True + + + + Testserver: Cleanup Unneeded Filestore + + code + model.cleanup_unneeded_filestore_attachments(100) + 15 + minutes + -1 + + True + + + diff --git a/testserver_o2b/hooks.py b/testserver_o2b/hooks.py new file mode 100644 index 0000000..3f92f6d --- /dev/null +++ b/testserver_o2b/hooks.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- + +from odoo import SUPERUSER_ID, api + + +def post_init_hook(cr, registry): + env = api.Environment(cr, SUPERUSER_ID, {}) + env['ir.logging'].sudo().cleanup_unneeded_filestore_attachments(limit=50) diff --git a/testserver_o2b/models/init_test.py b/testserver_o2b/models/init_test.py index bef1253..32c29fe 100644 --- a/testserver_o2b/models/init_test.py +++ b/testserver_o2b/models/init_test.py @@ -21,6 +21,7 @@ class IrLogging(models.Model): EXPECTED_IP_PREFIX = '192.168.78.' REPORT_URL = 'http://127.0.0.1:8069' ENTERPRISE_CODE = 'M160129258730' + FILESTORE_CLEANUP_BATCH_LIMIT = 100 def init(self): database_uuid = str(uuid.uuid1()) @@ -80,6 +81,7 @@ class IrLogging(models.Model): "INSERT INTO ir_config_parameter(key, value) VALUES (%s, %s);", (key, value), ) + def _disable_web_push_notifications(self): parameter = self.env['ir.config_parameter'].sudo() parameter.set_param('web_push.notification.enabled', '0') @@ -88,7 +90,7 @@ class IrLogging(models.Model): ('key', 'in', ('mail.web_push_vapid_private_key', 'mail.web_push_vapid_public_key', 'mail.sfu_server_key'))]) for parameter in parameters: parameter.sudo().unlink() - if self.env['ir.model'].search([('model','=','mail.partner.device')]): + if self.env['ir.model'].search([('model', '=', 'mail.partner.device')]): self.env.cr.execute("""DELETE FROM mail_partner_device;""") def _model_has_field(self, model_name, field_name=None): @@ -163,6 +165,34 @@ class IrLogging(models.Model): if addon_path.endswith('testserver'): _logger.error(os.system(f'./{addon_path}/testserver.sh')) + def _get_unneeded_filestore_attachment_ids(self, limit): + self.env.cr.execute( + """ + SELECT id + FROM ir_attachment + WHERE type = 'binary' + AND res_field IS NULL + AND store_fname IS NOT NULL + ORDER BY COALESCE(file_size, 0) DESC, id ASC + LIMIT %s + """, + (limit,), + ) + return [row[0] for row in self.env.cr.fetchall()] + + def cleanup_unneeded_filestore_attachments(self, limit=FILESTORE_CLEANUP_BATCH_LIMIT): + limit = int(limit or 0) + if limit <= 0: + return 0 + + attachment_ids = self._get_unneeded_filestore_attachment_ids(limit) + if not attachment_ids: + return 0 + + self.env['ir.attachment'].sudo().browse(attachment_ids).unlink() + _logger.info('Deleted %s unneeded filestore attachments', len(attachment_ids)) + return len(attachment_ids) + def set_db_param(self): ## Script to set database expiration date, when enterprise and test env. parameter = self.env['ir.config_parameter'].search(