From f50f17a1746f99256d4886c88a72bac3e663669b Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Tue, 20 Sep 2016 17:56:56 +0200 Subject: [PATCH] New module web_notify This technical module allows you to send instant notification messages from the server to the user in live. --- web_notify/README.rst | 80 ++++++++++++++++++ web_notify/__init__.py | 1 + web_notify/__openerp__.py | 22 +++++ web_notify/models/__init__.py | 1 + web_notify/models/res_users.py | 46 ++++++++++ web_notify/static/description/icon.png | Bin 0 -> 9455 bytes .../description/notifications_screenshot.png | Bin 0 -> 56872 bytes web_notify/static/src/js/web_client.js | 53 ++++++++++++ web_notify/tests/__init__.py | 1 + web_notify/tests/test_res_users.py | 51 +++++++++++ web_notify/views/web_notify.xml | 10 +++ 11 files changed, 265 insertions(+) create mode 100644 web_notify/README.rst create mode 100644 web_notify/__init__.py create mode 100644 web_notify/__openerp__.py create mode 100644 web_notify/models/__init__.py create mode 100644 web_notify/models/res_users.py create mode 100644 web_notify/static/description/icon.png create mode 100644 web_notify/static/description/notifications_screenshot.png create mode 100644 web_notify/static/src/js/web_client.js create mode 100644 web_notify/tests/__init__.py create mode 100644 web_notify/tests/test_res_users.py create mode 100644 web_notify/views/web_notify.xml diff --git a/web_notify/README.rst b/web_notify/README.rst new file mode 100644 index 00000000..f24f58fe --- /dev/null +++ b/web_notify/README.rst @@ -0,0 +1,80 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +========== +Web Notify +========== + +Send instant notification messages to the user in live. + +This technical module allows you to send instant notification messages from the server to the user in live. +Two kinds of notification are supported. + +* Warning: Displayed in a red flying popup div +* Information: Displayed in a light yellow flying popup div + +To send a notification to the user you just need to call one of the new methods defined on res.users: + +.. code-block:: python + + self.env.user.notify_info('My information message') + +or + +.. code-block:: python + + self.env.user.notify_warning('My marning message') + +.. figure:: static/description/notifications_screenshot.png + :scale: 80 % + :alt: Sample notifications + +Installation +============ + +This module is based on the Instant Messaging Bus. To work properly, the server must be launched in gevent mode. + + +Usage +===== + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/162/9.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Laurent Mignon + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/web_notify/__init__.py b/web_notify/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/web_notify/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/web_notify/__openerp__.py b/web_notify/__openerp__.py new file mode 100644 index 00000000..a6e542eb --- /dev/null +++ b/web_notify/__openerp__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'Web Notify', + 'summary': """ + Send notification messages to user""", + 'version': '9.0.1.0.0', + 'license': 'AGPL-3', + 'author': 'ACSONE SA/NV,Odoo Community Association (OCA)', + 'website': 'https://acsone.eu/', + 'depends': [ + 'web', + 'bus', + ], + 'data': [ + 'views/web_notify.xml' + ], + 'demo': [ + ], +} diff --git a/web_notify/models/__init__.py b/web_notify/models/__init__.py new file mode 100644 index 00000000..88351653 --- /dev/null +++ b/web_notify/models/__init__.py @@ -0,0 +1 @@ +from . import res_users diff --git a/web_notify/models/res_users.py b/web_notify/models/res_users.py new file mode 100644 index 00000000..51147455 --- /dev/null +++ b/web_notify/models/res_users.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, fields, models, _ + + +class ResUsers(models.Model): + + _inherit = 'res.users' + + @api.multi + @api.depends('create_date') + def _compute_channel_names(self): + for record in self: + res_id = record.id + record.notify_info_channel_name = 'notify_info_%s' % res_id + record.notify_warning_channel_name = 'notify_warning_%s' % res_id + + notify_info_channel_name = fields.Char( + compute='_compute_channel_names') + notify_warning_channel_name = fields.Char( + compute='_compute_channel_names') + + @api.multi + def notify_info(self, message, title=None, sticky=False): + title = title or _('Information') + self._notify_channel( + 'notify_info_channel_name', message, title, sticky) + + @api.multi + def notify_warning(self, message, title=None, sticky=False): + title = title or _('Warning') + self._notify_channel( + 'notify_warning_channel_name', message, title, sticky) + + @api.multi + def _notify_channel(self, channel_name_field, message, title, sticky): + bus_message = { + 'message': message, + 'title': title, + 'sticky': sticky + } + notifications = [(getattr(record, channel_name_field), bus_message) + for record in self] + self.env['bus.bus'].sendmany(notifications) diff --git a/web_notify/static/description/icon.png b/web_notify/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/web_notify/static/description/notifications_screenshot.png b/web_notify/static/description/notifications_screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1062cdc5efe61c456eb7b629b6cc79695444ce GIT binary patch literal 56872 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 literal 0 HcmV?d00001 diff --git a/web_notify/static/src/js/web_client.js b/web_notify/static/src/js/web_client.js new file mode 100644 index 00000000..3c908a07 --- /dev/null +++ b/web_notify/static/src/js/web_client.js @@ -0,0 +1,53 @@ +odoo.define('web_notify.WebClient', function (require) { +"use strict"; + +var WebClient = require('web.WebClient'); +var base_bus = require('bus.bus'); +var _ = require('_'); + +WebClient.include({ + init: function(parent, client_options){ + this._super(parent, client_options); + }, + show_application: function() { + this._super(); + this.start_polling(); + }, + on_logout: function() { + var self = this; + base_bus.bus.off('notification', this, this.bus_notification); + this._super(); + }, + start_polling: function() { + this.channel_warning = 'notify_warning_' + this.session.uid; + this.channel_info = 'notify_info_' + this.session.uid; + base_bus.bus.add_channel(this.channel_warning); + base_bus.bus.add_channel(this.channel_info); + base_bus.bus.on('notification', this, this.bus_notification); + base_bus.bus.start_polling(); + }, + bus_notification: function(notifications) { + var self = this; + _.each(notifications, function (notification) { + var channel = notification[0]; + var message = notification[1]; + if (channel === self.channel_warning) { + self.on_message_warning(message); + } else if (channel == self.channel_info) { + self.on_message_info(message); + } + }); + }, + on_message_warning: function(message){ + if(this.notification_manager) { + this.notification_manager.do_warn(message.title, message.message, message.sticky); + } + }, + on_message_info: function(message){ + if(this.notification_manager) { + this.notification_manager.do_notify(message.title, message.message, message.sticky); + } + } +}); + +}); \ No newline at end of file diff --git a/web_notify/tests/__init__.py b/web_notify/tests/__init__.py new file mode 100644 index 00000000..03c963d7 --- /dev/null +++ b/web_notify/tests/__init__.py @@ -0,0 +1 @@ +from . import test_res_users diff --git a/web_notify/tests/test_res_users.py b/web_notify/tests/test_res_users.py new file mode 100644 index 00000000..f6751fed --- /dev/null +++ b/web_notify/tests/test_res_users.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 ACSONE SA/NV +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp.tests import common +from openerp.addons.bus.models.bus import json_dump +import mock + + +class TestResUsers(common.TransactionCase): + + def test_notify_info(self): + bus_bus = self.env['bus.bus'] + domain = [ + ('channel', '=', + json_dump(self.env.user.notify_info_channel_name)) + ] + existing = bus_bus.search(domain) + self.env.user.notify_info( + message='message', title='title', sticky=True) + news = bus_bus.search(domain) - existing + self.assertEqual(1, len(news)) + self.assertEqual( + '{"message":"message","sticky":true,"title":"title"}', + news.message) + + def test_notify_warning(self): + bus_bus = self.env['bus.bus'] + domain = [ + ('channel', '=', + json_dump(self.env.user.notify_warning_channel_name)) + ] + existing = bus_bus.search(domain) + self.env.user.notify_warning( + message='message', title='title', sticky=True) + news = bus_bus.search(domain) - existing + self.assertEqual(1, len(news)) + self.assertEqual( + '{"message":"message","sticky":true,"title":"title"}', + news.message) + + def test_notify_many(self): + # check that the notification of a list of users is done with + # a single call to the bus + with mock.patch('openerp.addons.bus.models.bus.ImBus.sendmany' + ) as mockedSendMany: + users = self.env.user.search([(1, "=", 1)]) + self.assertTrue(len(users) > 1) + users.notify_warning('message') + self.assertEqual(1, mockedSendMany.call_count) + self.assertEqual(len(users), len(mockedSendMany.call_args)) diff --git a/web_notify/views/web_notify.xml b/web_notify/views/web_notify.xml new file mode 100644 index 00000000..b85d2e6f --- /dev/null +++ b/web_notify/views/web_notify.xml @@ -0,0 +1,10 @@ + + + +