1# -*- coding: utf-8 -*-
2# Part of Odoo. See LICENSE file for full copyright and licensing details.
3from werkzeug import urls
4
5from odoo import api, fields, models
6from odoo.http import request
7from odoo.tools.json import scriptsafe as json_scriptsafe
8
9
10class ServerAction(models.Model):
11    """ Add website option in server actions. """
12
13    _name = 'ir.actions.server'
14    _inherit = 'ir.actions.server'
15
16    xml_id = fields.Char('External ID', compute='_compute_xml_id', help="ID of the action if defined in a XML file")
17    website_path = fields.Char('Website Path')
18    website_url = fields.Char('Website Url', compute='_get_website_url', help='The full URL to access the server action through the website.')
19    website_published = fields.Boolean('Available on the Website', copy=False,
20                                       help='A code server action can be executed from the website, using a dedicated '
21                                            'controller. The address is <base>/website/action/<website_path>. '
22                                            'Set this field as True to allow users to run this action. If it '
23                                            'is set to False the action cannot be run through the website.')
24
25    def _compute_xml_id(self):
26        res = self.get_external_id()
27        for action in self:
28            action.xml_id = res.get(action.id)
29
30    def _compute_website_url(self, website_path, xml_id):
31        base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
32        link = website_path or xml_id or (self.id and '%d' % self.id) or ''
33        if base_url and link:
34            path = '%s/%s' % ('/website/action', link)
35            return urls.url_join(base_url, path)
36        return ''
37
38    @api.depends('state', 'website_published', 'website_path', 'xml_id')
39    def _get_website_url(self):
40        for action in self:
41            if action.state == 'code' and action.website_published:
42                action.website_url = action._compute_website_url(action.website_path, action.xml_id)
43            else:
44                action.website_url = False
45
46    @api.model
47    def _get_eval_context(self, action):
48        """ Override to add the request object in eval_context. """
49        eval_context = super(ServerAction, self)._get_eval_context(action)
50        if action.state == 'code':
51            eval_context['request'] = request
52            eval_context['json'] = json_scriptsafe
53        return eval_context
54
55    @api.model
56    def _run_action_code_multi(self, eval_context=None):
57        """ Override to allow returning response the same way action is already
58            returned by the basic server action behavior. Note that response has
59            priority over action, avoid using both.
60        """
61        res = super(ServerAction, self)._run_action_code_multi(eval_context)
62        return eval_context.get('response', res)
63
64
65class IrActionsTodo(models.Model):
66    _name = 'ir.actions.todo'
67    _inherit = 'ir.actions.todo'
68
69    def action_launch(self):
70        res = super().action_launch()  # do ensure_one()
71
72        if self.id == self.env.ref('website.theme_install_todo').id:
73            # Pick a theme consume all ir.actions.todo by default (due to lower sequence).
74            # Once done, we re-enable the main ir.act.todo: open_menu
75            self.env.ref('base.open_menu').action_open()
76
77        return res
78