Browse Source

New module web_notify

This technical module allows you to send instant notification messages from the server to the user in live.
pull/1071/head
Laurent Mignon (ACSONE) 8 years ago
committed by Aitor Bouzas
parent
commit
f50f17a174
  1. 80
      web_notify/README.rst
  2. 1
      web_notify/__init__.py
  3. 22
      web_notify/__openerp__.py
  4. 1
      web_notify/models/__init__.py
  5. 46
      web_notify/models/res_users.py
  6. BIN
      web_notify/static/description/icon.png
  7. BIN
      web_notify/static/description/notifications_screenshot.png
  8. 53
      web_notify/static/src/js/web_client.js
  9. 1
      web_notify/tests/__init__.py
  10. 51
      web_notify/tests/test_res_users.py
  11. 10
      web_notify/views/web_notify.xml

80
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
<https://github.com/OCA/web/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 <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Contributors
------------
* Laurent Mignon <laurent.mignon@acsone.eu>
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.

1
web_notify/__init__.py

@ -0,0 +1 @@
from . import models

22
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': [
],
}

1
web_notify/models/__init__.py

@ -0,0 +1 @@
from . import res_users

46
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)

BIN
web_notify/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

BIN
web_notify/static/description/notifications_screenshot.png

After

Width: 1599  |  Height: 364  |  Size: 56 KiB

53
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);
}
}
});
});

1
web_notify/tests/__init__.py

@ -0,0 +1 @@
from . import test_res_users

51
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))

10
web_notify/views/web_notify.xml

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_backend" name="web_noify assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/web_notify/static/src/js/web_client.js"/>
</xpath>
</template>
</data>
</odoo>
Loading…
Cancel
Save