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
+
+
+ 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(