Skip to content
Snippets Groups Projects
xbus_emitter.py 3.52 KiB
Newer Older
##############################################################################
#
#    Xbus emitter for Odoo
#    Copyright (C) 2015 XCG Consulting <http://odoo.consulting>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

import json
oury.balde's avatar
oury.balde committed

from odoo import api, fields, models
from ..util.odoo_context import get_clean_context


class XbusEmitter(models.Model):
    """Configuration profile to emit Xbus messages from Odoo.
    """

Christophe de Vienne's avatar
Christophe de Vienne committed
    _name = "xbus.emitter"
    _description = "Xbus emitter profile"
Christophe de Vienne's avatar
Christophe de Vienne committed
    _order = "priority ASC"

    name = fields.Char(string="Name", help="A name for this emitter profile.")

    priority = fields.Integer(
Christophe de Vienne's avatar
Christophe de Vienne committed
        string="Priority",
        required=True,
        help=(
Christophe de Vienne's avatar
Christophe de Vienne committed
            "Priority to sort emitter configuration objects; the lowest "
            "priority is the most important."
        ),
        default=100,
    )

    @api.multi
    def send_items(self, event_type, items, chunking="legacy", record=None):
        """Send the data to Xbus, inside one event with the specified event
        type.

        :param event_type: Name of an Xbus event type.
        :type event_type: String.

        :type items: Iterable.

        :param chunking: a default chunking to use to split big items.
        :type chunking: String. Values ("auto", "legacy", "single").

        :param record: A record this message is for. Allows navigating between
        records and their Xbus messages. Optional.
        :type record: Odoo record set.

        :return: The new job.
        :rtype: Odoo "xbus.emitter.job" record set.
        """

        self.ensure_one()

        # Remove default value fillers from the context. This can be called
        # from various places so safer / easier right here than upstream.
        emitter_context = get_clean_context(self)

        job_values = {
            "emitter_id": self.id,
            "event_type": event_type,
            "items": json.dumps(items),
            "chunking": chunking,
        }
        if record:
            job_values.update(
                {"record_id": record.id, "record_model": record._name}
            )
        emitter_job = (
            self.env["xbus.emitter.job"]
            .with_context(emitter_context)
            .create(job_values)

        self._send_notification()

        return emitter_job

    def _send_notification(self):
        """Run a "NOTIFY" postgresql command.
        Since we only tell the external process there is new data in our table,
        the channel name is going to be the table name.
        The payload is the ID of this emitter.

        Ref: <https://www.postgresql.org/docs/current/static/sql-notify.html>.
        """

Christophe de Vienne's avatar
Christophe de Vienne committed
        self.env.cr.execute(
            "NOTIFY %s, '%s'"
            % (
                self.env["xbus.emitter.job"]._table,
                self.id,
            )  # channel  # payload