diff src/browser/notification.py @ 449:981ed669d3b3

/!\ reorganize all the file hierarchy, move the code and launching script to src: - browser_side --> src/browser - public --> src/browser_side/public - libervia.py --> src/browser/libervia_main.py - libervia_server --> src/server - libervia_server/libervia.sh --> src/libervia.sh - twisted --> src/twisted - new module src/common - split constants.py in 3 files: - src/common/constants.py - src/browser/constants.py - src/server/constants.py - output --> html (generated by pyjsbuild during the installation) - new option/parameter "data_dir" (-d) to indicates the directory containing html and server_css - setup.py installs libervia to the following paths: - src/common --> <LIB>/libervia/common - src/server --> <LIB>/libervia/server - src/twisted --> <LIB>/twisted - html --> <SHARE>/libervia/html - server_side --> <SHARE>libervia/server_side - LIBERVIA_INSTALL environment variable takes 2 new options with prompt confirmation: - clean: remove previous installation directories - purge: remove building and previous installation directories You may need to update your sat.conf and/or launching script to update the following options/parameters: - ssl_certificate - data_dir
author souliane <souliane@mailoo.org>
date Tue, 20 May 2014 06:41:16 +0200
parents browser_side/notification.py@d52f529a6d42
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/browser/notification.py	Tue May 20 06:41:16 2014 +0200
@@ -0,0 +1,122 @@
+from __pyjamas__ import JS, wnd
+from sat.core.log import getLogger
+log = getLogger(__name__)
+from sat.core.i18n import _
+
+from pyjamas import Window
+from pyjamas.Timer import Timer
+
+import dialog
+
+TIMER_DELAY = 5000
+
+
+class Notification(object):
+    """
+    If the browser supports it, the user allowed it to and the tab is in the
+    background, send desktop notifications on messages.
+
+    Requires both Web Notifications and Page Visibility API.
+    """
+
+    def __init__(self):
+        self.enabled = False
+        user_agent = None
+        notif_permission = None
+        JS("""
+        if (!('hidden' in document))
+            document.hidden = false;
+
+        user_agent = navigator.userAgent
+
+        if (!('Notification' in window))
+            return;
+
+        notif_permission = Notification.permission
+
+        if (Notification.permission === 'granted')
+            this.enabled = true;
+
+        else if (Notification.permission === 'default') {
+            Notification.requestPermission(function(permission){
+                if (permission !== 'granted')
+                    return;
+
+                self.enabled = true; //need to use self instead of this
+            });
+        }
+        """)
+
+        if "Chrome" in user_agent and notif_permission not in ['granted', 'denied']:
+            self.user_agent = user_agent
+            self._installChromiumWorkaround()
+
+        wnd().onfocus = self.onFocus
+        # wnd().onblur = self.onBlur
+        self._notif_count = 0
+        self._orig_title = Window.getTitle()
+
+    def _installChromiumWorkaround(self):
+        # XXX: Workaround for Chromium behaviour, it's doens't manage requestPermission on onLoad event
+        # see https://code.google.com/p/chromium/issues/detail?id=274284
+        # FIXME: need to be removed if Chromium behaviour changes
+        try:
+            version_full = [s for s in self.user_agent.split() if "Chrome" in s][0].split('/')[1]
+            version = int(version_full.split('.')[0])
+        except (IndexError, ValueError):
+            log.warning("Can't find Chromium version")
+            version = 0
+        log.info("Chromium version: %d" % (version,))
+        if version < 22:
+            log.info("Notification use the old prefixed version or are unmanaged")
+            return
+        if version < 32:
+            dialog.InfoDialog(_("Notifications activation for Chromium"), _('You need to activate notifications manually for your Chromium version.<br/>To activate notifications, click on the favicon on the left of the address bar')).show()
+            return
+
+        log.info("==> Installing Chromium notifications request workaround <==")
+        self._old_click = wnd().onclick
+        wnd().onclick = self._chromiumWorkaround
+
+    def _chromiumWorkaround(self):
+        log.info("Activating workaround")
+        JS("""
+            Notification.requestPermission(function(permission){
+                if (permission !== 'granted')
+                    return;
+                self.enabled = true; //need to use self instead of this
+            });
+        """)
+        wnd().onclick = self._old_click
+
+    def onFocus(self):
+        Window.setTitle(self._orig_title)
+        self._notif_count = 0
+
+    # def onBlur(self):
+    #     pass
+
+    def isHidden(self):
+        JS("""return document.hidden;""")
+
+    def _notify(self, title, body, icon):
+        if not self.enabled:
+            return
+        notification = None
+        JS("""
+           notification = new Notification(title, {body: body, icon: icon});
+           // Probably won’t work, but it doesn’t hurt to try.
+           notification.addEventListener('click', function() {
+               window.focus();
+           });
+           """)
+        notification.onshow = lambda: Timer(TIMER_DELAY, lambda timer: notification.close())
+
+    def highlightTab(self):
+        self._notif_count += 1
+        Window.setTitle("%s (%d)" % (self._orig_title, self._notif_count))
+
+    def notify(self, title, body, icon='/media/icons/apps/48/sat.png'):
+        if self.isHidden():
+            self._notify(title, body, icon)
+            self.highlightTab()