Compare commits
12 Commits
01c79fcfff
...
19.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
880106128a | ||
|
|
1a39a5a68c | ||
|
|
fe6b724bb5 | ||
| 1983913340 | |||
| 833d5e0298 | |||
| bf4049382e | |||
| f2d4064c5e | |||
|
|
4f9b0e7907 | ||
|
|
71908a3a47 | ||
| 2706479d9f | |||
|
|
fe8680941a | ||
|
|
3da7ae2cb8 |
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/testserver.iml" filepath="$PROJECT_DIR$/.idea/testserver.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
12
.idea/testserver.iml
generated
Normal file
12
.idea/testserver.iml
generated
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="PyDocumentationSettings">
|
||||||
|
<option name="format" value="PLAIN" />
|
||||||
|
<option name="myDocStringFormat" value="Plain" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
68
.idea/workspace.xml
generated
Normal file
68
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="417d3a9a-dab7-4fec-b2a8-da7eae112104" name="Changes" comment="" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="EmbeddingIndexingInfo">
|
||||||
|
<option name="cachedIndexableFilesCount" value="36" />
|
||||||
|
<option name="fileBasedEmbeddingIndicesEnabled" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="McpProjectServerCommands">
|
||||||
|
<commands />
|
||||||
|
<urls />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectColorInfo"><![CDATA[{
|
||||||
|
"associatedIndex": 7,
|
||||||
|
"fromUser": false
|
||||||
|
}]]></component>
|
||||||
|
<component name="ProjectId" id="3GRtXrhb1Z1wz5HO20Plf2KjZjN" />
|
||||||
|
<component name="ProjectViewState">
|
||||||
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
|
<option name="showLibraryContents" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent"><![CDATA[{
|
||||||
|
"keyToString": {
|
||||||
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
|
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||||
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
|
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||||
|
"codeWithMe.voiceChat.enabledByDefault": "false",
|
||||||
|
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
||||||
|
"git-widget-placeholder": "19.0",
|
||||||
|
"junie.onboarding.icon.badge.shown": "true",
|
||||||
|
"last_opened_file_path": "/home/dochse/development/testserver",
|
||||||
|
"nodejs_package_manager_path": "npm",
|
||||||
|
"to.speed.mode.migration.done": "true",
|
||||||
|
"vue.rearranger.settings.migration": "true"
|
||||||
|
}
|
||||||
|
}]]></component>
|
||||||
|
<component name="SharedIndexes">
|
||||||
|
<attachedChunks>
|
||||||
|
<set>
|
||||||
|
<option value="bundled-python-sdk-50341a9f1f9c-c2ffad84badb-com.jetbrains.pycharm.pro.sharedIndexes.bundled-PY-261.26222.68" />
|
||||||
|
</set>
|
||||||
|
</attachedChunks>
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="417d3a9a-dab7-4fec-b2a8-da7eae112104" name="Changes" comment="" />
|
||||||
|
<created>1783946253712</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1783946253712</updated>
|
||||||
|
<workItem from="1783946254947" duration="22000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -2,3 +2,5 @@
|
|||||||
|
|
||||||
from . import controllers
|
from . import controllers
|
||||||
from . import models
|
from . import models
|
||||||
|
from . import wizard
|
||||||
|
from .hooks import post_init_hook
|
||||||
@@ -17,7 +17,10 @@
|
|||||||
'module_type': 'official',
|
'module_type': 'official',
|
||||||
'depends': ['mail','base',],
|
'depends': ['mail','base',],
|
||||||
'data': [
|
'data': [
|
||||||
|
'wizard/install_warning_wizard_view.xml',
|
||||||
'views/views.xml',
|
'views/views.xml',
|
||||||
'data/data.xml'
|
'data/data.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
],
|
],
|
||||||
|
'post_init_hook': 'post_init_hook',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,55 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# Copyright 2024 Open2Bizz <info@open2bizz.nl>
|
||||||
# from odoo import http
|
# License LGPL-3
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request, Response
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
MAILHOG_BASE = "http://localhost:8025"
|
||||||
|
|
||||||
|
|
||||||
# class TestserverO2b(http.Controller):
|
class MailcatcherProxy(http.Controller):
|
||||||
# @http.route('/testserver_o2b/testserver_o2b/', auth='public')
|
|
||||||
# def index(self, **kw):
|
|
||||||
# return "Hello, world"
|
|
||||||
|
|
||||||
# @http.route('/testserver_o2b/testserver_o2b/objects/', auth='public')
|
@http.route(['/mailcatcher', '/mailcatcher/<path:subpath>'],
|
||||||
# def list(self, **kw):
|
type='http', auth='user', website=False, csrf=False)
|
||||||
# return http.request.render('testserver_o2b.listing', {
|
def mailcatcher_proxy(self, subpath='', **kw):
|
||||||
# 'root': '/testserver_o2b/testserver_o2b',
|
"""Proxy requests to the local MailHog instance."""
|
||||||
# 'objects': http.request.env['testserver_o2b.testserver_o2b'].search([]),
|
target_url = f"{MAILHOG_BASE}/{subpath}"
|
||||||
# })
|
if request.httprequest.query_string:
|
||||||
|
target_url += '?' + request.httprequest.query_string.decode('utf-8')
|
||||||
|
|
||||||
# @http.route('/testserver_o2b/testserver_o2b/objects/<model("testserver_o2b.testserver_o2b"):obj>/', auth='public')
|
try:
|
||||||
# def object(self, obj, **kw):
|
headers = {
|
||||||
# return http.request.render('testserver_o2b.object', {
|
k: v for k, v in request.httprequest.headers
|
||||||
# 'object': obj
|
if k.lower() not in ('host', 'cookie', 'authorization')
|
||||||
# })
|
}
|
||||||
|
resp = requests.request(
|
||||||
|
method=request.httprequest.method,
|
||||||
|
url=target_url,
|
||||||
|
headers=headers,
|
||||||
|
data=request.httprequest.get_data(),
|
||||||
|
timeout=30,
|
||||||
|
allow_redirects=False,
|
||||||
|
)
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
_logger.warning("Could not connect to MailHog at %s", MAILHOG_BASE)
|
||||||
|
return Response("MailHog is not available", status=502)
|
||||||
|
|
||||||
|
excluded_headers = {
|
||||||
|
'content-encoding', 'content-length', 'transfer-encoding',
|
||||||
|
'connection',
|
||||||
|
}
|
||||||
|
response_headers = [
|
||||||
|
(k, v) for k, v in resp.headers.items()
|
||||||
|
if k.lower() not in excluded_headers
|
||||||
|
]
|
||||||
|
|
||||||
|
return Response(
|
||||||
|
resp.content,
|
||||||
|
status=resp.status_code,
|
||||||
|
headers=response_headers,
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<odoo>
|
<odoo>
|
||||||
<data>
|
<data>
|
||||||
<function model="ir.config_parameter" name="_mailcatcher_url"/>
|
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|||||||
40
mailcatcher_menu/hooks.py
Normal file
40
mailcatcher_menu/hooks.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2024 Open2Bizz <info@open2bizz.nl>
|
||||||
|
# License LGPL-3
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def post_init_hook(env):
|
||||||
|
"""Install MailHog as a systemd service when the module is installed."""
|
||||||
|
script_path = os.path.join(
|
||||||
|
os.path.dirname(os.path.abspath(__file__)),
|
||||||
|
'install_mailhog_as_service.sh',
|
||||||
|
)
|
||||||
|
|
||||||
|
if not os.path.isfile(script_path):
|
||||||
|
_logger.error("MailHog install script not found at %s", script_path)
|
||||||
|
return
|
||||||
|
|
||||||
|
_logger.info("Running MailHog install script: %s", script_path)
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
['bash', script_path],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=300,
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
_logger.info("MailHog installed successfully.\n%s", result.stdout)
|
||||||
|
else:
|
||||||
|
_logger.error(
|
||||||
|
"MailHog install script failed (exit %s):\n%s\n%s",
|
||||||
|
result.returncode, result.stdout, result.stderr,
|
||||||
|
)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
_logger.error("MailHog install script timed out after 300 seconds")
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error("Failed to run MailHog install script: %s", e)
|
||||||
86
mailcatcher_menu/install_mailhog_as_service.sh
Normal file
86
mailcatcher_menu/install_mailhog_as_service.sh
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e # stop bij fouten
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Update apt..."
|
||||||
|
echo "==================================="
|
||||||
|
apt update
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Install dependencies..."
|
||||||
|
echo "==================================="
|
||||||
|
apt-get -y install wget tar
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Install Go 1.24.3..."
|
||||||
|
echo "==================================="
|
||||||
|
GO_VERSION=1.24.3
|
||||||
|
wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz
|
||||||
|
|
||||||
|
sudo rm -rf /usr/local/go
|
||||||
|
sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz
|
||||||
|
|
||||||
|
# Go environment correct instellen
|
||||||
|
export GOROOT=/usr/local/go
|
||||||
|
export GOPATH=$HOME/go
|
||||||
|
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
|
||||||
|
|
||||||
|
echo "Go version:"
|
||||||
|
go version
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Installing MailHog..."
|
||||||
|
echo "==================================="
|
||||||
|
/usr/local/go/bin/go install github.com/mailhog/MailHog@latest
|
||||||
|
|
||||||
|
if [ -f "$HOME/go/bin/MailHog" ]; then
|
||||||
|
echo "MailHog installed successfully"
|
||||||
|
else
|
||||||
|
echo "ERROR: MailHog binary not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Copy MailHog to /usr/local/bin..."
|
||||||
|
echo "==================================="
|
||||||
|
sudo cp "$HOME/go/bin/MailHog" /usr/local/bin/MailHog
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Create MailHog service..."
|
||||||
|
echo "==================================="
|
||||||
|
sudo tee /etc/systemd/system/mailhog.service > /dev/null <<EOL
|
||||||
|
[Unit]
|
||||||
|
Description=MailHog
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
ExecStart=/usr/local/bin/MailHog
|
||||||
|
Restart=always
|
||||||
|
Environment="PATH=/usr/local/go/bin:/usr/bin:/bin"
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOL
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "Enable + start MailHog service..."
|
||||||
|
echo "==================================="
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable mailhog
|
||||||
|
systemctl start mailhog
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "==================================="
|
||||||
|
echo "MailHog is running!"
|
||||||
|
echo "Web UI: http://localhost:8025"
|
||||||
|
echo "SMTP: localhost:1025"
|
||||||
|
echo "==================================="
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
from . import mailcatcher_menu
|
# No models needed — MailHog is accessed via the proxy controller
|
||||||
|
|||||||
@@ -1,27 +1,7 @@
|
|||||||
# Copyright 2024 Open2Bizz <info@open2bizz.nl>
|
# Copyright 2024 Open2Bizz <info@open2bizz.nl>
|
||||||
# License LGPL-3
|
# License LGPL-3
|
||||||
|
|
||||||
from odoo import api, fields, models, _
|
# MailHog is now accessed via the internal proxy controller at /mailcatcher/
|
||||||
|
# so no dynamic URL computation is needed anymore.
|
||||||
import logging
|
|
||||||
_logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class IrActionUrl(models.Model):
|
|
||||||
_inherit = "ir.config_parameter"
|
|
||||||
|
|
||||||
@api.model
|
|
||||||
#def init(self):
|
|
||||||
def _mailcatcher_url(self):
|
|
||||||
parameters = self.env['ir.config_parameter'].search([('key','=', 'web.base.url')])
|
|
||||||
if parameters:
|
|
||||||
parameter = parameters[0]
|
|
||||||
cont_nr = parameter.value.split("//",1)[1] #Haal https:// van string
|
|
||||||
cont_nr = cont_nr[0:3] #De eerste 3 karakters is het containernummer
|
|
||||||
act_url = "https://" + cont_nr + "-mailcatcher.staging.open2bizz.com"
|
|
||||||
_logger.info('---------- ACT_URL ---------- %s', act_url)
|
|
||||||
action_id = self.env['ir.model.data']._xmlid_to_res_id('mailcatcher_menu.action_mailcatcher_url')
|
|
||||||
action = self.env['ir.actions.act_url'].browse(action_id)
|
|
||||||
if action:
|
|
||||||
action.write({'url':act_url})
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||||
"access_mailcatcher_menu_mailcatcher_menu","mailcatcher_menu.mailcatcher_menu","model_mailcatcher_menu_mailcatcher_menu","base.group_user",1,1,1,1
|
"access_mailcatcher_install_warning_wizard","mailcatcher.install.warning.wizard","model_mailcatcher_install_warning_wizard","base.group_user",1,1,1,1
|
||||||
|
|||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<record model="ir.actions.act_url" id="action_mailcatcher_url">
|
<record model="ir.actions.act_url" id="action_mailcatcher_url">
|
||||||
<field name="name">Open Mailcatcher</field>
|
<field name="name">Open Mailcatcher</field>
|
||||||
<field name="url">https://mailcatcher.staging.open2bizz.com</field>
|
<field name="url">/mailcatcher/</field>
|
||||||
<field name="target">new</field>
|
<field name="target">new</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
3
mailcatcher_menu/wizard/__init__.py
Normal file
3
mailcatcher_menu/wizard/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import install_warning_wizard
|
||||||
43
mailcatcher_menu/wizard/install_warning_wizard.py
Normal file
43
mailcatcher_menu/wizard/install_warning_wizard.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Copyright 2024 Open2Bizz <info@open2bizz.nl>
|
||||||
|
# License LGPL-3
|
||||||
|
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
|
||||||
|
|
||||||
|
class MailcatcherInstallWarningWizard(models.TransientModel):
|
||||||
|
_name = 'mailcatcher.install.warning.wizard'
|
||||||
|
_description = 'MailCatcher Install Warning'
|
||||||
|
|
||||||
|
module_id = fields.Many2one('ir.module.module', string='Module', readonly=True)
|
||||||
|
|
||||||
|
def action_confirm_install(self):
|
||||||
|
"""User confirmed — proceed with the actual module installation."""
|
||||||
|
self.ensure_one()
|
||||||
|
return self.module_id.with_context(
|
||||||
|
skip_mailcatcher_warning=True
|
||||||
|
).button_immediate_install()
|
||||||
|
|
||||||
|
|
||||||
|
class IrModuleModule(models.Model):
|
||||||
|
_inherit = 'ir.module.module'
|
||||||
|
|
||||||
|
def button_immediate_install(self):
|
||||||
|
"""Override to show a warning before installing mailcatcher_menu."""
|
||||||
|
if self.env.context.get('skip_mailcatcher_warning'):
|
||||||
|
return super().button_immediate_install()
|
||||||
|
|
||||||
|
mailcatcher_modules = self.filtered(lambda m: m.name == 'mailcatcher_menu')
|
||||||
|
if mailcatcher_modules:
|
||||||
|
wizard = self.env['mailcatcher.install.warning.wizard'].create({
|
||||||
|
'module_id': mailcatcher_modules[0].id,
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
'name': _('Install MailCatcher Module'),
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'res_model': 'mailcatcher.install.warning.wizard',
|
||||||
|
'res_id': wizard.id,
|
||||||
|
'view_mode': 'form',
|
||||||
|
'target': 'new',
|
||||||
|
}
|
||||||
|
|
||||||
|
return super().button_immediate_install()
|
||||||
28
mailcatcher_menu/wizard/install_warning_wizard_view.xml
Normal file
28
mailcatcher_menu/wizard/install_warning_wizard_view.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<odoo>
|
||||||
|
<record id="view_mailcatcher_install_warning_wizard" model="ir.ui.view">
|
||||||
|
<field name="name">mailcatcher.install.warning.wizard.form</field>
|
||||||
|
<field name="model">mailcatcher.install.warning.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Install MailCatcher">
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<h4 class="alert-heading">Warning</h4>
|
||||||
|
<p>
|
||||||
|
You are about to install the <strong>MailCatcher</strong> module.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This will also install <strong>MailHog</strong> as a systemd service on this server.
|
||||||
|
MailHog will listen on port <strong>8025</strong> (Web UI) and port <strong>1025</strong> (SMTP).
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Do you want to proceed with the installation?
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<button name="action_confirm_install" type="object"
|
||||||
|
string="Confirm Install" class="btn-primary"/>
|
||||||
|
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from .hooks import post_init_hook
|
||||||
from . import models
|
from . import models
|
||||||
@@ -11,9 +11,10 @@
|
|||||||
'category': 'Tools',
|
'category': 'Tools',
|
||||||
'license': "AGPL-3",
|
'license': "AGPL-3",
|
||||||
'version': '19.0.1.0.0',
|
'version': '19.0.1.0.0',
|
||||||
'depends': ['mail','base','mailcatcher_menu',],
|
'depends': ['mail', 'base', 'mailcatcher_menu'],
|
||||||
'data': [
|
'data': [
|
||||||
'views/templates.xml',
|
'views/templates.xml',
|
||||||
'data/ir_cron.xml',
|
'data/ir_cron.xml',
|
||||||
],
|
],
|
||||||
|
'post_init_hook': 'post_init_hook',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,29 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="ir_cron_set_db_parameter" model="ir.cron">
|
<data noupdate="1">
|
||||||
<field name="name">Testserver: Set Date (ONLY FOR TEST ENV.)</field>
|
<record id="ir_cron_set_db_parameter" model="ir.cron">
|
||||||
<field name="model_id" ref="base.model_ir_logging"/>
|
<field name="name">Testserver: Set Date (ONLY FOR TEST ENV.)</field>
|
||||||
<field name="state">code</field>
|
<field name="model_id" ref="base.model_ir_logging"/>
|
||||||
<field name="code">model.set_db_param()</field>
|
<field name="state">code</field>
|
||||||
<field name="interval_type">days</field>
|
<field name="code">model.set_db_param()</field>
|
||||||
</record>
|
<field name="interval_number">1</field>
|
||||||
|
<field name="interval_type">days</field>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="active">True</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="ir_cron_cleanup_filestore_attachments" model="ir.cron">
|
||||||
|
<field name="name">Testserver: Cleanup Unneeded Filestore</field>
|
||||||
|
<field name="model_id" ref="base.model_ir_logging"/>
|
||||||
|
<field name="state">code</field>
|
||||||
|
<field name="code">model.cleanup_unneeded_filestore_attachments(5000)</field>
|
||||||
|
<field name="interval_number">15</field>
|
||||||
|
<field name="interval_type">minutes</field>
|
||||||
|
<field name="user_id" ref="base.user_root"/>
|
||||||
|
<field name="active">True</field>
|
||||||
|
</record>
|
||||||
|
<record id="base.autovacuum_job" model="ir.cron">
|
||||||
|
<field name="active">True</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
7
testserver_o2b/hooks.py
Normal file
7
testserver_o2b/hooks.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from odoo import api
|
||||||
|
|
||||||
|
|
||||||
|
def post_init_hook(env):
|
||||||
|
env['ir.logging'].sudo().cleanup_unneeded_filestore_attachments(limit=50)
|
||||||
@@ -15,12 +15,13 @@ class IrLogging(models.Model):
|
|||||||
|
|
||||||
MAIL_SERVERS = (
|
MAIL_SERVERS = (
|
||||||
('127.0.0.1', '1025', 'Lokale mailcatcher', 'login', 'name', 't'),
|
('127.0.0.1', '1025', 'Lokale mailcatcher', 'login', 'name', 't'),
|
||||||
('192.168.78.199', '1025', 'Algemene mailcatcher', 'login', 'name', 't'),
|
('192.168.78.199', '1025', 'Algemene mailcatcher', 'login', 'name', 'f'),
|
||||||
('hnode6.openworx.nl', '1025', 'Algemene mailcatcher vanaf hnode4', 'login', 'name', 't'),
|
('hnode6.openworx.nl', '1025', 'Algemene mailcatcher vanaf hnode4', 'login', 'name', 'f'),
|
||||||
)
|
)
|
||||||
EXPECTED_IP_PREFIX = '192.168.78.'
|
EXPECTED_IP_PREFIX = '192.168.78.'
|
||||||
REPORT_URL = 'http://127.0.0.1:8069'
|
REPORT_URL = 'http://127.0.0.1:8069'
|
||||||
ENTERPRISE_CODE = 'M160129258730'
|
ENTERPRISE_CODE = 'M160129258730'
|
||||||
|
FILESTORE_CLEANUP_BATCH_LIMIT = 100
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
database_uuid = str(uuid.uuid1())
|
database_uuid = str(uuid.uuid1())
|
||||||
@@ -80,6 +81,7 @@ class IrLogging(models.Model):
|
|||||||
"INSERT INTO ir_config_parameter(key, value) VALUES (%s, %s);",
|
"INSERT INTO ir_config_parameter(key, value) VALUES (%s, %s);",
|
||||||
(key, value),
|
(key, value),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _disable_web_push_notifications(self):
|
def _disable_web_push_notifications(self):
|
||||||
parameter = self.env['ir.config_parameter'].sudo()
|
parameter = self.env['ir.config_parameter'].sudo()
|
||||||
parameter.set_param('web_push.notification.enabled', '0')
|
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'))])
|
('key', 'in', ('mail.web_push_vapid_private_key', 'mail.web_push_vapid_public_key', 'mail.sfu_server_key'))])
|
||||||
for parameter in parameters:
|
for parameter in parameters:
|
||||||
parameter.sudo().unlink()
|
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;""")
|
self.env.cr.execute("""DELETE FROM mail_partner_device;""")
|
||||||
|
|
||||||
def _model_has_field(self, model_name, field_name=None):
|
def _model_has_field(self, model_name, field_name=None):
|
||||||
@@ -163,6 +165,36 @@ class IrLogging(models.Model):
|
|||||||
if addon_path.endswith('testserver'):
|
if addon_path.endswith('testserver'):
|
||||||
_logger.error(os.system(f'./{addon_path}/testserver.sh'))
|
_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
|
||||||
|
AND res_model not in ('sign.document','sign.request')
|
||||||
|
AND public = 'f'
|
||||||
|
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):
|
def set_db_param(self):
|
||||||
## Script to set database expiration date, when enterprise and test env.
|
## Script to set database expiration date, when enterprise and test env.
|
||||||
parameter = self.env['ir.config_parameter'].search(
|
parameter = self.env['ir.config_parameter'].search(
|
||||||
|
|||||||
Reference in New Issue
Block a user