Commit 05f5c6d5 authored by Yuri D'Elia's avatar Yuri D'Elia

First 'official' release:

* change the name to gnus-desktop-notify
* provide the gnus-desktop-notify-mode global minor mode.
* do not generate popups when called interactively
* more customization options (sheesh!)
parent 82184217
;;; -*- emacs-lisp -*-
;;; gnus-notify.el: External mail notification for Gnus
;;; gnus-desktop-notify.el: Gnus Desktop Notification global minor mode
;; Author: Yuri D'Elia <wavexx AT users.sf.net>
;; Contributors: Philipp Haselwarter <philipp.haselwarter AT gmx.de>
;; URL: http://www.thregr.org/~wavexx/hacks/gnus-notify.el
;; Version: 1.0 (2010/12/26)
;; URL: http://www.thregr.org/~wavexx/hacks/gnus-desktop-notify/
;; GIT: git://src.thregr.org/gnus-desktop-notify/
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
......@@ -22,11 +24,14 @@
;;; Commentary:
;; gnus-notify.el provides a simple mechanism to notify external programs when
;; new messages are received. For basic usage, to be used in conjunction with
;; gnus-daemon, put the following:
;; Desktop notification integration in Gnus!? Ohh goody!
;;
;; (require 'gnus-notify)
;; gnus-desktop-notify.el provides a simple mechanism to notify external
;; programs when new messages are received. For basic usage, to be used in
;; conjunction with gnus-daemon, put the following:
;;
;; (require 'gnus-desktop-notify)
;; (gnus-desktop-notify-mode)
;; (gnus-demon-add-scanmail)
;;
;; into your .gnus file. You'll need the 'notify-send' program, which (in
......@@ -36,55 +41,102 @@
;; messages.
;;
;; By default, all groups are notified when new messages are received. You can
;; exclude a single group by setting the 'group-notify' group parameter to
;; exclude a single group by setting the `group-notify' group parameter to
;; t. You can also selectively monitor groups instead by changing the
;; 'gnus-notify-mode' variable to 'gnus-notify-explicit and then manually
;; selecting which groups to include. Press 'G c' in the group buffer to
;; customize group parameters interactively.
;; `gnus-desktop-notify-groups' variable to `gnus-desktop-notify-explicit' and
;; then manually selecting which groups to include. Press 'G c' in the group
;; buffer to customize group parameters interactively.
;;
;; You can actually call any program by changing the 'gnus-notify-exec-program'
;; variable, or change the behavior entirely by setting a different
;; 'gnus-notify-function' function.
;; You can actually call any program by changing the
;; `gnus-desktop-notify-exec-program' variable, or change the behavior entirely
;; by setting a different `gnus-desktop-notify-function' function, or change
;; the way the popup is generated with `gnus-desktop-notify-send-mode'.
;;
;; See the 'gnus-notify' customization group for more details.
;; See the `gnus-desktop-notify' customization group for more details.
;;
;; Feel free to send suggestions and patches to wavexx AT users.sf.net
;;; Code:
(require 'assoc)
(require 'gnus-group)
;; Custom variables
(defgroup gnus-notify nil
(defgroup gnus-desktop-notify nil
"Gnus external notification framework"
:group 'gnus)
(defcustom gnus-notify-function 'gnus-notify-exec
(define-minor-mode gnus-desktop-notify-mode
"Gnus Desktop Notification mode uses libnotify's 'notify-send'
program to generate popup messages or call external executables
whenever a group receives new messages through gnus-demon (see
`gnus-demon-add-handler').
You can actually call any program by changing the
`gnus-desktop-notify-exec-program' variable, or change the
behavior entirely by setting a different
`gnus-desktop-notify-function' function.
See the `gnus-desktop-notify' customization group for more
details."
:init-value nil
:group 'gnus-desktop-notify
:require 'gnus
:global t
(cond
(gnus-desktop-notify-mode
(add-hook 'gnus-after-getting-new-news-hook 'gnus-desktop-notify-check)
(add-hook 'gnus-started-hook 'gnus-desktop-notify-check))
(t
(remove-hook 'gnus-after-getting-new-news-hook 'gnus-desktop-notify-check)
(remove-hook 'gnus-started-hook 'gnus-desktop-notify-check))))
;; Custom variables
(defcustom gnus-desktop-notify-function 'gnus-desktop-notify-send
"Function called when a group has new messages. The first
argument will be an alist containing the groups and the number of
new messages. The default is to use the 'gnus-notify-exec'
function to call an executable."
:type 'function
:group 'gnus-notify)
(defcustom gnus-notify-exec-program "notify-send -i /usr/share/icons/gnome-colors-common/16x16/apps/email.png"
"Executable called by the 'gnus-notify-exec' function. The
first argument will be the notification text. The default is to
use the libnotify's 'notify-send' program."
:type 'file
:group 'gnus-notify)
(defcustom gnus-notify-mode 'gnus-notify-all-except
"Gnus group notification mode. Can be either
'gnus-notify-all-except (to monitor all groups by default except
excluded ones), or 'gnus-notify-explicit (to monitor only
requested groups).
new messages. The default is to use `gnus-desktop-notify-send'.
The following functions are already available (see the
documentation for each function):
`gnus-desktop-notify-send': use the 'notify-send' program.
`gnus-desktop-notify-exec': call a customizable program."
:type 'function)
(defcustom gnus-desktop-notify-exec-program "xmessage"
"Executable called by the `gnus-desktop-notify-exec'
function. Each argument will be of the form:
'number of new messages:mailbox name'"
:type 'file)
(defcustom gnus-desktop-notify-send-program
"notify-send -i /usr/share/icons/gnome/32x32/actions/mail_new.png"
"Path and default arguments to the 'notify-send' program (part
of libnotify's utilities)."
:type 'file)
(defcustom gnus-desktop-notify-send-mode 'gnus-desktop-notify-multi
"`gnus-desktop-notify-send' behavior. Can be either:
'gnus-desktop-notify-single: display a single notification for
each group,
'gnus-desktop-notify-multi: display a multi-line notification for
all groups at once."
:type 'symbol)
(defcustom gnus-desktop-notify-groups 'gnus-desktop-notify-all-except
"Gnus group notification mode. Can be either:
'gnus-desktop-notify-all-except: monitor all groups by
default except excluded ones,
'gnus-desktop-notify-explicit: monitor only requested groups.
Groups can be included or excluded by setting the
'group-notify' group parameter to 't'. This can be set either in
the 'gnus-parameters' variable, or interactively by pressing 'G c'
in the group buffer."
:type 'symbol
:group 'gnus-notify)
the `gnus-parameters' variable, or interactively by pressing 'G
c' in the group buffer."
:type 'symbol)
;; Group parameters
......@@ -93,50 +145,76 @@ in the group buffer."
:type bool
:parameter-type '(const :tag "Include/exclude this group from
the notification of new messages (depending on the value of
'gnus-notify-mode')." t))
'gnus-desktop-notify-groups')." t))
;; Functions
(defun gnus-notify-exec (groups)
"Call a program defined by gnus-notify-exec-program with the
first argument being the notification text. The default is to use
the libnotify's 'notify-send' program."
(dolist (g groups)
(call-process-shell-command gnus-notify-exec-program nil 0 nil
"--" (shell-quote-argument (format "New mail in %s:%d" (car g) (cdr g))))))
(defun gnus-desktop-notify-exec (groups)
"Call a program defined by `gnus-desktop-notify-exec-program' with
each argument being of the form 'number of new messages:mailbox name'."
(let ( (args "") )
(dolist (g groups)
(setq args
(concat args " "
(shell-quote-argument (format "%d:%s" (cdr g) (car g))))))
(call-process-shell-command
gnus-desktop-notify-exec-program nil 0 nil args)))
(defun gnus-desktop-notify-escape-html-entities (str)
(setq str (replace-regexp-in-string "&" "&amp;" str))
(setq str (replace-regexp-in-string "<" "&lt;" str))
(setq str (replace-regexp-in-string ">" "&gt;" str))
str)
(defun gnus-desktop-notify-send (groups)
"Call 'notify-send' (as defined by `gnus-desktop-notify-send-program'),
with the behavior defined by `gnus-desktop-notify-send-mode'."
(case gnus-desktop-notify-send-mode
('gnus-desktop-notify-multi
(let ( (text "New mail:") )
(dolist (g groups)
(setq text
(concat text
(format "<br/><tt> <b>%d</b>:<b>%s</b></tt>"
(cdr g) (gnus-desktop-notify-escape-html-entities (car g))))))
(call-process-shell-command gnus-desktop-notify-send-program nil 0 nil "--"
(shell-quote-argument text))))
('gnus-desktop-notify-single
(dolist (g groups)
(call-process-shell-command gnus-desktop-notify-send-program nil 0 nil "--"
(shell-quote-argument
(format "New mail: <tt><b>%d</b>:<b>%s</b></tt>"
(cdr g) (gnus-desktop-notify-escape-html-entities (car g)))))))))
;; Internals
(setq gnus-notify-counts '())
(setq gnus-desktop-notify-counts '())
(defun gnus-notify-check (&rest ignored)
(defun gnus-desktop-notify-check (&rest ignored)
(interactive)
(let ( (updated-groups '()) )
(dolist (g gnus-newsrc-alist)
(let ( (read (or
(and (listp (car (gnus-info-read g)))
(cdar (gnus-info-read g)))
(cdr (gnus-info-read g)))) )
(and (listp (car (gnus-info-read g)))
(cdar (gnus-info-read g)))
(cdr (gnus-info-read g)))) )
(when read
(let* ( (name (gnus-info-group g))
(unread (gnus-group-unread (car g)))
(count (+ read unread))
(old-count (cdr (assoc name gnus-notify-counts)))
(old-count (cdr (assoc name gnus-desktop-notify-counts)))
(notify (gnus-group-find-parameter name 'group-notify)) )
(when (or
(and (eq gnus-notify-mode 'gnus-notify-all-except) (not notify))
(and (eq gnus-notify-mode 'gnus-notify-explicit) notify))
(aput 'gnus-notify-counts name count)
(and (eq gnus-desktop-notify-groups 'gnus-desktop-notify-all-except) (not notify))
(and (eq gnus-desktop-notify-groups 'gnus-desktop-notify-explicit) notify))
(aput 'gnus-desktop-notify-counts name count)
(when (and
unread (> unread 0)
old-count (> count old-count))
(setq updated-groups
(cons (cons name (- count old-count))
updated-groups))))))))
(when updated-groups
(funcall gnus-notify-function updated-groups))))
(when (and updated-groups (not (called-interactively-p 'any)))
(funcall gnus-desktop-notify-function updated-groups))))
;; Hooks into gnus
(add-hook 'gnus-after-getting-new-news-hook 'gnus-notify-check)
(add-hook 'gnus-started-hook 'gnus-notify-check)
(provide 'gnus-notify)
(provide 'gnus-desktop-notify)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment