Index: trac/notification.py
===================================================================
--- trac/notification.py	(revision 5574)
+++ trac/notification.py	(working copy)
@@ -20,6 +20,7 @@
 from trac import __version__
 from trac.config import BoolOption, IntOption, Option
 from trac.core import *
+from trac.util.cia import CIA
 from trac.util.text import CRLF
 from trac.web.chrome import Chrome
 from trac.web.clearsilver import HDFWrapper
@@ -140,7 +141,53 @@
         """
 
 
-class NotifyEmail(Notify):
+class NotifyCIA(Notify):
+    """Baseclass for notification via CIA."""
+
+    def notify(self, resid):
+        """Send message to recipients."""
+
+        # stupid code logic...
+        if self.config.getbool('notification', 'smtp_enabled'):
+            Notify.notify(self, resid)
+
+        if not self.config.getbool('notification', 'cia_enabled'):
+            return
+
+        project = self.config['notification'].get('cia_project')
+        server = self.config['notification'].get('cia_server')
+
+        if not project or not server:
+            raise TracError(Markup('Unable to notify CIA server: '
+                    'neither cia project nor server specified.'),
+                    'CIA Notification error')
+
+        if self.newticket:
+            updater = self.hdf["ticket.reporter"]
+        else:
+            updater = self.hdf["ticket.change.author"]
+
+        if self.newticket:
+            action = "opened"
+        else:
+            oldvalue = self.hdf.get("ticket.change.status.oldvalue")
+            newvalue = self.hdf.get("ticket.change.status.newvalue")
+            if oldvalue == "closed":
+                action = "reopened"
+            elif newvalue == "closed":
+                action = "closed (%s)" % self.ticket["resolution"]
+            else:
+                return
+
+        cia = CIA(project=project, server=server, module="ticket " + action)
+        cia(resid, updater,
+                "[%s] %s %s" %
+                   (self.hdf["ticket.component"],
+                    self.hdf["ticket.summary"],
+                    self.hdf['ticket.link']))
+
+
+class NotifyEmail(NotifyCIA):
     """Baseclass for notification by email."""
 
     smtp_server = 'localhost'
@@ -195,25 +242,24 @@
     def notify(self, resid, subject):
         self.subject = subject
 
-        if not self.config.getbool('notification', 'smtp_enabled'):
-            return
-        self.smtp_server = self.config['notification'].get('smtp_server')
-        self.smtp_port = self.config['notification'].getint('smtp_port')
-        self.from_email = self.config['notification'].get('smtp_from')
-        self.replyto_email = self.config['notification'].get('smtp_replyto')
-        self.from_email = self.from_email or self.replyto_email
-        if not self.from_email and not self.replyto_email:
-            raise TracError(Markup('Unable to send email due to identity '
-                                   'crisis.<p>Neither <b>notification.from</b> '
-                                   'nor <b>notification.reply_to</b> are '
-                                   'specified in the configuration.</p>'),
-                            'SMTP Notification Error')
+        if self.config.getbool('notification', 'smtp_enabled'):
+            self.smtp_server = self.config['notification'].get('smtp_server')
+            self.smtp_port = self.config['notification'].getint('smtp_port')
+            self.from_email = self.config['notification'].get('smtp_from')
+            self.replyto_email = self.config['notification'].get('smtp_replyto')
+            self.from_email = self.from_email or self.replyto_email
+            if not self.from_email and not self.replyto_email:
+                raise TracError(Markup('Unable to send email due to identity '
+                                       'crisis.<p>Neither <b>notification.from</b> '
+                                       'nor <b>notification.reply_to</b> are '
+                                       'specified in the configuration.</p>'),
+                                'SMTP Notification Error')
 
-        # Authentication info (optional)
-        self.user_name = self.config['notification'].get('smtp_user')
-        self.password = self.config['notification'].get('smtp_password')
+            # Authentication info (optional)
+            self.user_name = self.config['notification'].get('smtp_user')
+            self.password = self.config['notification'].get('smtp_password')
 
-        Notify.notify(self, resid)
+        NotifyCIA.notify(self, resid)
 
     def format_header(self, key, name, email=None):
         from email.Header import Header

