PK‘<5á'{ÿ++WikiNotification/__init__.py# -*- coding: utf-8 -*- # vim: sw=4 ts=4 fenc=utf-8 # ============================================================================= # $Id: __init__.py 2 2006-09-28 22:08:17Z s0undt3ch $ # ============================================================================= # $URL: http://wikinotification.ufsoft.org/svn/trunk/WikiNotification/__init__.py $ # $LastChangedDate: 2006-09-29 00:08:17 +0200 (Fr, 29 Sep 2006) $ # $Rev: 2 $ # $LastChangedBy: s0undt3ch $ # ============================================================================= # Copyright (C) 2006 UfSoft.org - Pedro Algarvio # # Please view LICENSE for additional licensing information. # ============================================================================= import web_ui, listener, notification PK†68€N+~ââWikiNotification/web_ui.pyc;ò ÑGEc@sŠdkZdkTdklZlZdklZlZdkl Z l Z dk l Z dk lZdklZdefd „ƒYZdS( N(s*(shtmlsMarkup(sINavigationContributorsITemplateProvider(s HTTPNotFoundsIRequestHandler(sOption(s ICtxtnavAdder(sresource_filenamesWikiNotificationWebModulecBs“tZeeeeeƒeddddƒZd„Z d„Z d„Z d„Z d „Z d „Zd „Zd „Zd „Zd„Zd„ZRS(Nswiki-notifications redirect_timesdefaulticCsgSdS(N((sself((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pysget_htdocs_dirs"scCsttdƒ}|gSdS(Ns templates(sresource_filenames__name__s resource_dir(sselfs resource_dir((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pysget_templates_dirs%scCsdSdS(Ns notification((sselfsreq((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pysget_active_navigation_item*sccs6dkl}ddtidd|iiƒƒfVdS(N(s add_scriptsmetanavs notificationsMy Notificationsshref(strac.web.chromes add_scriptshtmlsAsreqshrefs notification(sselfsreqs add_script((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pysget_navigation_items-s cCs:t|iƒdjp |idjp|iidƒSdS(Nis/s/wiki(slensreqs path_infos startswith(sselfsreq((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pysmatch_ctxtnav_add3sccsd|idpd}|i|ƒ}||jo|ii|ƒdfVn|ii|ƒdfVdS(Nis WikiStarts Un-Watch Pages Watch Page(sreqs path_infospagesselfs_get_watched_pagesswatchedshrefs notification(sselfsreqswatchedspage((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pysget_ctxtnav_adds7s  cCsntid|iƒ}|oN|idƒo6|idƒ|id<|iid|idƒƒnt SndS(Ns^/notification(?:/(.*))?isnotification.wikipagesNOTIFICATION PAGE: %s( sresmatchsreqs path_infosgroupsargssselfslogsdebugsTrue(sselfsreqsmatch((s;build/bdist.darwin-8.0.1-x86/egg/WikiNotification/web_ui.pys match_requestAs  cCs¯d|ijo1t|id<|iiƒ|id|i|ƒ}|i|ƒddi|ƒd|id|i|ƒ}|i|ƒddi|ƒd|id # # Please view LICENSE for additional licensing information. # ============================================================================= import md5 from trac.core import * from trac.wiki.model import WikiPage from trac.versioncontrol.diff import unified_diff from trac.notification import NotifyEmail from trac.config import Option, BoolOption diff_header = """Index: %(name)s =================================================================== --- %(name)s (version: %(oldversion)s) +++ %(name)s (version: %(version)s) """ class WikiNotificationSystem(Component): smtp_from = Option( 'wiki-notification', 'smtp_from', 'trac+wiki@localhost', """Sender address to use in notification emails.""") smtp_always_cc = Option( 'wiki-notification', 'smtp_always_cc', '', """Email address(es) to always send notifications to, addresses can be see by all recipients (Cc:).""") smtp_always_bcc = Option( 'wiki-notification', 'smtp_always_bcc', '', """Email address(es) to always send notifications to, addresses do not appear publicly (Bcc:).""") use_public_cc = BoolOption( 'wiki-notification', 'use_public_cc', 'false', """Recipients can see email addresses of other CC'ed recipients. If this option is disabled(the default), recipients are put on BCC.""") redirect_time = Option( 'wiki-notification', 'redirect_time', 5, """The default secconds a redirect should take when watching/un-watching a wiki page""") class WikiNotifyEmail(NotifyEmail): template_name = "notification_email.cs" from_email = 'trac+wiki@localhost' COLS = 75 newwiki = False def __init__(self, env): NotifyEmail.__init__(self, env) def notify(self, action, page, version=None, time=None, comment=None, author=None, ipnr=None): self.page = page self.change_author = author if action == "added": self.newwiki = True self.hdf.set_unescaped('name', page.name) self.hdf.set_unescaped('text', page.text) self.hdf.set_unescaped('version', version) self.hdf.set_unescaped('author', author) self.hdf.set_unescaped('comment', comment) self.hdf.set_unescaped('ip', ipnr) self.hdf.set_unescaped('action', action) self.hdf.set_unescaped('link', self.env.abs_href.wiki(page.name)) self.hdf.set_unescaped('linkdiff', "%s?action=diff&version=%i" % \ (self.env.abs_href.wiki(page.name), page.version)) if page.version > 0 and action == 'modified': diff = diff_header % {'name': self.page.name, 'version': self.page.version, 'oldversion': self.page.version -1 } oldpage = WikiPage(self.env, page.name, page.version - 1) self.hdf.set_unescaped("oldversion", oldpage.version) self.hdf.set_unescaped("oldtext", oldpage.text) for line in unified_diff(oldpage.text.splitlines(), page.text.splitlines(), context=3): diff += "%s\n" % line self.wikidiff = diff projname = self.config.get('project', 'name') subject = '[%s] Notification: %s %s' % (projname, page.name, action.replace('_', ' ')) NotifyEmail.notify(self, page.name, subject) def get_message_id(self, rcpt): """Generate a predictable, but sufficiently unique message ID.""" s = '%s.%s.%d.%s' % (self.config.get('project', 'url'), self.page.name, self.page.time, rcpt.encode('ascii', 'ignore')) dig = md5.new(s).hexdigest() host = self.from_email[self.from_email.find('@') + 1:] msgid = '<%03d.%s@%s>' % (len(s), dig, host) return msgid def get_recipients(self, pagename): if not self.db: self.db = self.env.get_db_cnx() cursor = self.db.cursor() QUERY_SIDS = """SELECT sid from session_attribute WHERE name=%s AND value LIKE %s""" tos = [] cursor.execute(QUERY_SIDS, ('watched_pages', '%,'+pagename+',%')) sids = cursor.fetchall() self.env.log.debug('SIDS TO NOTIFY: %s', sids) QUERY_EMAILS = """SELECT value FROM session_attribute WHERE name=%s AND sid=%s""" for sid in sids: if sid[0] != self.change_author: self.env.log.debug('SID: %s', sid[0]) cursor.execute(QUERY_EMAILS, ('email', sid[0])) tos.append(cursor.fetchone()[0]) self.env.log.debug('TO\'s TO NOTIFY: %s', tos) return (tos, []) def send(self, torcpts, ccrcpts, mime_headers={}): import re from email.MIMEText import MIMEText from email.MIMEMultipart import MIMEMultipart from email.Utils import formatdate, formataddr from trac import __version__ body = self.hdf.render(self.template_name) projname = self.config.get('project', 'name') public_cc = self.config['wiki-notification'].get('smtp_public_cc') headers = {} headers['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__ headers['X-Trac-Version'] = __version__ headers['X-Trac-Project'] = projname headers['X-URL'] = self.config.get('project', 'url') headers['Subject'] = self.subject headers['From'] = (projname, self.from_email) headers['Sender'] = self.from_email headers['Reply-To'] = self.replyto_email always_cc = self.config['wiki-notification'].get('smtp_always_cc') always_bcc = self.config['wiki-notification'].get('smtp_always_bcc') hdrs = {} dest = filter(None, torcpts) or filter(None, ccrcpts) or \ filter(None, [always_cc]) or filter(None, [always_bcc]) self.env.log.debug('DEST: %s', dest) if not dest: self.env.log.info('no recipient for a wiki notification') return headers['Message-ID'] = self.get_message_id(dest[0]) headers['X-Trac-Wiki-URL'] = self.env.abs_href.wiki(self.page.name) if not self.newwiki: headers['In-Reply-To'] = self.get_message_id(dest[0]) headers['References'] = self.get_message_id(dest[0]) def build_addresses(rcpts): """Format and remove invalid addresses""" return filter(lambda x: x, \ [self.get_smtp_address(addr) for addr in rcpts]) def remove_dup(rcpts, all): """Remove duplicates""" tmp = [] for rcpt in rcpts: if not rcpt in all: tmp.append(rcpt) all.append(rcpt) return (tmp, all) toaddrs = build_addresses(torcpts) ccaddrs = build_addresses(ccrcpts) accparam = self.config['wiki-notification'].get('smtp_always_cc') accaddrs = accparam and \ build_addresses(accparam.replace(',', ' ').split()) or [] bccparam = self.config['wiki-notification'].get('smtp_always_bcc') bccaddrs = bccparam and \ build_addresses(bccparam.replace(',', ' ').split()) or [] recipients = [] (toaddrs, recipients) = remove_dup(toaddrs, recipients) (ccaddrs, recipients) = remove_dup(ccaddrs, recipients) (accaddrs, recipients) = remove_dup(accaddrs, recipients) (bccaddrs, recipients) = remove_dup(bccaddrs, recipients) # if there is not valid recipient, leave immediately if len(recipients) < 1: return pcc = accaddrs if public_cc: pcc += ccaddrs if toaddrs: headers['To'] = ', '.join(toaddrs) if pcc: headers['Cc'] = ', '.join(pcc) headers['Date'] = formatdate() # sanity check if not self._charset.body_encoding: try: dummy = body.encode('ascii') except UnicodeDecodeError: raise TracError, "Ticket contains non-Ascii chars. " \ "Please change encoding setting" mail = MIMEMultipart() # With MIMEMultipart the charset has to be set before any parts # are added. del mail['Content-Transfer-Encoding'] mail.set_charset(self._charset) mail.preamble = 'This is a multi-part message in MIME format.' # The text Message msg = MIMEText(body, 'plain') msg.add_header('Content-Disposition', 'inline', filename="message") del msg['Content-Transfer-Encoding'] msg.set_charset(self._charset) mail.attach(msg) try: # The Diff Attachment attach = MIMEText(self.wikidiff, 'x-patch') attach.add_header('Content-Disposition', 'inline', filename=self.page.name + '.diff') del attach['Content-Transfer-Encoding'] attach.set_charset(self._charset) mail.attach(attach) except AttributeError: # We don't have a wikidiff to attach pass self.add_headers(mail, headers); self.add_headers(mail, mime_headers); self.env.log.debug("Sending SMTP notification to %s on port %d to %s" % (self.smtp_server, self.smtp_port, recipients)) msgtext = mail.as_string() # Ensure the message complies with RFC2822: use CRLF line endings recrlf = re.compile("\r?\n") msgtext = "\r\n".join(recrlf.split(msgtext)) self.server.sendmail(mail['From'], recipients, msgtext) PK5>5ªì3ñ( ( WikiNotification/listener.py# -*- coding: utf-8 -*- # vim: sw=4 ts=4 fenc=utf-8 # ============================================================================= # $Id: listener.py 10 2006-09-30 06:09:43Z s0undt3ch $ # ============================================================================= # $URL: http://wikinotification.ufsoft.org/svn/trunk/WikiNotification/listener.py $ # $LastChangedDate: 2006-09-30 08:09:43 +0200 (Sa, 30 Sep 2006) $ # $Rev: 10 $ # $LastChangedBy: s0undt3ch $ # ============================================================================= # Copyright (C) 2006 UfSoft.org - Pedro Algarvio # # Please view LICENSE for additional licensing information. # ============================================================================= import inspect from trac.core import * from trac.wiki.api import IWikiChangeListener from WikiNotification.notification import WikiNotifyEmail class WikiChangeListener(Component): """Class that listens for wiki changes.""" implements(IWikiChangeListener) # Internal Methods def _get_req(self): """Grab req from inspect.stack()""" for x in inspect.stack(): if 'req' in x[0].f_locals: self.env.log.debug(x[0].f_locals['req']) return x[0].f_locals['req'] # IWikiChangeListener methods def wiki_page_added(self, page): version, time, author, comment, ipnr = page.get_history().next() wne = WikiNotifyEmail(page.env) wne.notify("added", page, version, time, comment, author, ipnr) def wiki_page_changed(self, page, version, t, comment, author, ipnr): time = t wne = WikiNotifyEmail(page.env) wne.notify("modified", page, version, time, comment, author, ipnr) def wiki_page_deleted(self, page): req = self._get_req() ipnr = req.remote_addr author = req.authname wne = WikiNotifyEmail(page.env) wne.notify("deleted", page, ipnr=ipnr, author=author) def wiki_page_version_deleted(self, page): req = self._get_req() ipnr = req.remote_addr author = req.authname version, time, author, comment, ipnr = page.get_history().next() wne = WikiNotifyEmail(page.env) wne.notify("deleted_version", page, version=version+1, author=author, ipnr=ipnr) PK†68†@úúWikiNotification/__init__.pyc;ò ÑGEc@sdkZdkZdkZdS(N(sweb_uislisteners notification(slisteners notificationsweb_ui((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/__init__.pys?sPK†68¢j’"þ þ WikiNotification/listener.pyc;ò ' Ec@sDdkZdkTdklZdklZdefd„ƒYZdS(N(s*(sIWikiChangeListener(sWikiNotifyEmailsWikiChangeListenercBsEtZdZeeƒd„Zd„Zd„Zd„Zd„Z RS(s$Class that listens for wiki changes.cCs`xYtiƒD]K}d|dijo1|iii|didƒ|didSq q WdS(sGrab req from inspect.stack()sreqiN(sinspectsstacksxsf_localssselfsenvslogsdebug(sselfsx((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pys_get_reqs  cCsS|iƒiƒ\}}}}}t|i ƒ}|i d||||||ƒdS(Nsadded( spages get_historysnextsversionstimesauthorscommentsipnrsWikiNotifyEmailsenvswnesnotify(sselfspagescommentsauthorswnesversionstimesipnr((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pyswiki_page_added#s!c Cs8|}t|iƒ}|id||||||ƒdS(Nsmodified( ststimesWikiNotifyEmailspagesenvswnesnotifysversionscommentsauthorsipnr( sselfspagesversionstscommentsauthorsipnrswnestime((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pyswiki_page_changed(scCsM|iƒ}|i}|i}t|i ƒ}|i d|d|d|ƒdS(Nsdeletedsipnrsauthor( sselfs_get_reqsreqs remote_addrsipnrsauthnamesauthorsWikiNotifyEmailspagesenvswnesnotify(sselfspagesauthorswnesreqsipnr((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pyswiki_page_deleted-s    c Csx|iƒ}|i}|i}|iƒi ƒ\}}}}}t |iƒ}|id|d|dd|d|ƒdS(Nsdeleted_versionsversionisauthorsipnr(sselfs_get_reqsreqs remote_addrsipnrsauthnamesauthorspages get_historysnextsversionstimescommentsWikiNotifyEmailsenvswnesnotify( sselfspagescommentsauthorsreqswnesversionstimesipnr((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pyswiki_page_version_deleted4s    !( s__name__s __module__s__doc__s implementssIWikiChangeListeners_get_reqswiki_page_addedswiki_page_changedswiki_page_deletedswiki_page_version_deleted(((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pysWikiChangeListeners      (sinspects trac.cores trac.wiki.apisIWikiChangeListenersWikiNotification.notificationsWikiNotifyEmails ComponentsWikiChangeListener(sIWikiChangeListenersinspectsWikiNotifyEmailsWikiChangeListener((s=build/bdist.darwin-8.0.1-x86/egg/WikiNotification/listener.pys?s   PK‘<5ž\DXŠŠWikiNotification/web_ui.py# -*- coding: utf-8 -*- # vim: sw=4 ts=4 fenc=utf-8 # ============================================================================= # $Id: web_ui.py 2 2006-09-28 22:08:17Z s0undt3ch $ # ============================================================================= # $URL: http://wikinotification.ufsoft.org/svn/trunk/WikiNotification/web_ui.py $ # $LastChangedDate: 2006-09-29 00:08:17 +0200 (Fr, 29 Sep 2006) $ # $Rev: 2 $ # $LastChangedBy: s0undt3ch $ # ============================================================================= # Copyright (C) 2006 UfSoft.org - Pedro Algarvio # # Please view LICENSE for additional licensing information. # ============================================================================= import re from trac.core import * from trac.util.html import html, Markup from trac.web.chrome import INavigationContributor, ITemplateProvider from trac.web import HTTPNotFound, IRequestHandler from trac.config import Option from ctxtnavadd.api import ICtxtnavAdder from pkg_resources import resource_filename class WikiNotificationWebModule(Component): implements(INavigationContributor, IRequestHandler, ITemplateProvider, ICtxtnavAdder) redirect_time = Option('wiki-notification', 'redirect_time', default=5) # ITemplateProvider methods def get_htdocs_dirs(self): return [] def get_templates_dirs(self): resource_dir = resource_filename(__name__, 'templates') return [resource_dir] # INavigationContributor methods def get_active_navigation_item(self, req): return 'notification' def get_navigation_items(self, req): from trac.web.chrome import add_script yield('metanav', 'notification', html.A('My Notifications', href=req.href.notification())) # ICtxtnavAdder methods def match_ctxtnav_add(self, req): return len(req.path_info) <= 1 or req.path_info == '/' or \ req.path_info.startswith('/wiki') def get_ctxtnav_adds(self, req): page = req.path_info[6:] or 'WikiStart' watched = self._get_watched_pages(req) if page in watched: yield (req.href.notification(page), 'Un-Watch Page') else: yield (req.href.notification(page), 'Watch Page') # IRequestHandler methods def match_request(self, req): match = re.match(r'^/notification(?:/(.*))?', req.path_info) if match: if match.group(1): req.args['notification.wikipage'] = match.group(1) self.log.debug('NOTIFICATION PAGE: %s', match.group(1)) return True def process_request(self, req): if 'email' not in req.session: req.hdf['notification.error'] = True req.hdf['settings.url'] = req.href.settings() return 'notification.cs', None try: req.hdf['notification.redirect_time'] = \ req.session['watched_pages.redirect_time'] except KeyError: req.hdf['notification.redirect_time'] = self.redirect_time wikipage = req.args.get('notification.wikipage', False) watched = self._get_watched_pages(req) if watched == ['']: watched = [] self.log.debug('WATCHED PAGES: %s', watched) req.hdf['notification.wikiurl'] = req.href.wiki() req.hdf['notification.my_not_url'] = req.href.notification() if wikipage: if wikipage in watched: req.hdf['notification.action'] = 'unwatch' self._unwatch_page(req, wikipage) else: self._watch_page(req, wikipage) req.hdf['notification.action'] = 'watch' req.hdf['notification.wikipage'] = wikipage req.hdf['notification.redir'] = req.abs_href.wiki(wikipage) req.hdf['notification.showlist'] = False else: if req.method == 'POST' and req.args.get('remove'): sel = req.args.get('sel') sel = isinstance(sel, list) and sel or [sel] for wikipage in sel: self._unwatch_page(req, wikipage) req.hdf['notification.redir'] = req.abs_href.notification() req.hdf['notification.removelist'] = sel elif req.method == 'POST' and req.args.get('update'): req.hdf['notification.redirect_time'] = \ req.session['watched_pages.redirect_time'] = \ req.args.get('redirect_time') req.hdf['notification.showlist'] = True req.hdf['notification.list'] = watched else: req.hdf['notification.showlist'] = True req.hdf['notification.list'] = watched return 'notification.cs', None # Internal methods def _get_watched_pages(self, req): try: watched = req.session['watched_pages'].strip(',').split(',') self.log.debug('WATCHED PAGES: %s', watched) return watched except KeyError: return [] def _watch_page(self, req, page): watched = self._get_watched_pages(req) watched.append(page) req.session['watched_pages'] = ','+','.join(watched)+',' def _unwatch_page(self, req, page): watched = self._get_watched_pages(req) watched.remove(page) req.session['watched_pages'] = ','+','.join(watched)+',' PK†68Ìú„**!WikiNotification/notification.pyc;ò  ¢!Ec@s€dkZdkTdklZdklZdklZdkl Z l Z dZ de fd„ƒYZ d efd „ƒYZdS( N(s*(sWikiPage(s unified_diff(s NotifyEmail(sOptions BoolOptionsŸIndex: %(name)s =================================================================== --- %(name)s (version: %(oldversion)s) +++ %(name)s (version: %(version)s) sWikiNotificationSystemcBsqtZeddddƒZeddddƒZedddd ƒZedd d d ƒZedd ddƒZRS(Nswiki-notifications smtp_fromstrac+wiki@localhosts-Sender address to use in notification emails.ssmtp_always_ccsshEmail address(es) to always send notifications to, addresses can be see by all recipients (Cc:).ssmtp_always_bccscEmail address(es) to always send notifications to, addresses do not appear publicly (Bcc:).s use_public_ccsfalses’Recipients can see email addresses of other CC'ed recipients. If this option is disabled(the default), recipients are put on BCC.s redirect_timeisYThe default secconds a redirect should take when watching/un-watching a wiki page( s__name__s __module__sOptions smtp_fromssmtp_always_ccssmtp_always_bccs BoolOptions use_public_ccs redirect_time(((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pysWikiNotificationSystems         sWikiNotifyEmailcBs_tZdZdZdZeZd„Zeeeeed„Z d„Z d„Z hd„Z RS( Nsnotification_email.csstrac+wiki@localhostiKcCsti||ƒdS(N(s NotifyEmails__init__sselfsenv(sselfsenv((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pys__init__@sc CsO||_||_|djo t|_n|iid|i ƒ|iid|i ƒ|iid|ƒ|iid|ƒ|iid|ƒ|iid|ƒ|iid|ƒ|iid |iii|i ƒƒ|iid d |iii|i ƒ|i fƒ|i d jo |d joÓthd|ii <d|ii <d|ii d<} t|i|i |i dƒ} |iid| i ƒ|iid| i ƒxJt| i iƒ|i iƒddƒD]} | d| 7} | |_qÙWn|iiddƒ}d||i |iddƒf} ti||i | ƒdS(Nsaddedsnamestextsversionsauthorscommentsipsactionslinkslinkdiffs%s?action=diff&version=%iismodifieds oldversionisoldtextscontextis%s sprojects[%s] Notification: %s %ss_s ( spagesselfsauthors change_authorsactionsTruesnewwikishdfs set_unescapedsnamestextsversionscommentsipnrsenvsabs_hrefswikis diff_headersdiffsWikiPagesoldpages unified_diffs splitlinesslineswikidiffsconfigsgetsprojnamesreplacessubjects NotifyEmailsnotify( sselfsactionspagesversionstimescommentsauthorsipnrsprojnamesoldpagessubjectsdiffsline((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pysnotifyCs4    %2;"cCsd|iiddƒ|ii|ii|iddƒf}t i |ƒi ƒ}|i |i idƒd}dt|ƒ||f}|Sd S( s;Generate a predictable, but sufficiently unique message ID.s %s.%s.%d.%ssprojectsurlsasciisignores@is <%03d.%s@%s>N(sselfsconfigsgetspagesnamestimesrcptsencodesssmd5snews hexdigestsdigs from_emailsfindshostslensmsgid(sselfsrcptsmsgidsdigssshost((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pysget_message_idls =cCs|i o|iiƒ|_n|iiƒ}d}g}|i|dd|dfƒ|i ƒ}|ii i d|ƒd}xq|D]i}|d|ijoO|ii i d|dƒ|i|d |dfƒ|i|iƒdƒq‰q‰W|ii i d |ƒ|gfSdS( NsYSELECT sid from session_attribute WHERE name=%s AND value LIKE %ss watched_pagess%,s,%sSIDS TO NOTIFY: %ssVSELECT value FROM session_attribute WHERE name=%s AND sid=%sisSID: %ssemailsTO's TO NOTIFY: %s(sselfsdbsenvs get_db_cnxscursors QUERY_SIDSstossexecutespagenamesfetchallssidsslogsdebugs QUERY_EMAILSssids change_authorsappendsfetchone(sselfspagenamestosssidsscursors QUERY_SIDSssids QUERY_EMAILS((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pysget_recipientsvs"  c"shdk}dkl}!dkl}dkl}l} dkl }ˆi i ˆi ƒ}ˆiiddƒ} ˆididƒ}h}d ||d <||d <| |d <ˆiidd ƒ|d<ˆi|d<| ˆif|d<ˆi|d<ˆi|d<ˆididƒ}ˆididƒ}h} tt|ƒp3tt|ƒp#tt|gƒptt|gƒ}ˆii i!d|ƒ| oˆii i"dƒdSnˆi#|dƒ|d<ˆii$i%ˆi&i'ƒ|d<ˆi( o2ˆi#|dƒ|d<ˆi#|dƒ|dˆi7ƒd(|_?|!|d)ƒ}|iAd*d+d,d-ƒ|d'=|i>ˆi7ƒ|iB|ƒyZ|!ˆiCd.ƒ} | iAd*d+d,ˆi&i'd/ƒ| d'=| i>ˆi7ƒ|iB| ƒWntDj onXˆiE||ƒˆiE||ƒˆii i!d0ˆiGˆiH|fƒ|iIƒ}|iKd1ƒ}d2i6|i/|ƒƒ}ˆiMiN|d||ƒdS(3N(sMIMEText(s MIMEMultipart(s formatdates formataddr(s __version__sprojectsnameswiki-notificationssmtp_public_ccsTrac %s, by Edgewall SoftwaresX-MailersX-Trac-VersionsX-Trac-ProjectsurlsX-URLsSubjectsFromsSendersReply-Tossmtp_always_ccssmtp_always_bccsDEST: %ss$no recipient for a wiki notificationis Message-IDsX-Trac-Wiki-URLs In-Reply-Tos Referencescs>td„gi}|D]}|ˆi|ƒƒq~ƒSdS(s#Format and remove invalid addressescCs|S(N(sx(sx((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pys±sN(sfiltersappends_[1]srcptssaddrsselfsget_smtp_address(srcptss_[1]saddr(sself(sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pysbuild_addresses¯s cCsQg}x:|D]2}||j o|i|ƒ|i|ƒq q W||fSdS(sRemove duplicatesN(stmpsrcptssrcptsallsappend(srcptssallstmpsrcpt((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pys remove_dup´s s,s is, sTosCcsDatesasciis?Ticket contains non-Ascii chars. Please change encoding settingsContent-Transfer-Encodings,This is a multi-part message in MIME format.splainsContent-Dispositionsinlinesfilenamesmessagesx-patchs.diffs0Sending SMTP notification to %s on port %d to %ss ? s (Osresemail.MIMETextsMIMETextsemail.MIMEMultiparts MIMEMultiparts email.Utilss formatdates formataddrstracs __version__sselfshdfsrenders template_namesbodysconfigsgetsprojnames public_ccsheadersssubjects from_emails replyto_emails always_ccs always_bccshdrssfiltersNonestorcptssccrcptssdestsenvslogsdebugsinfosget_message_idsabs_hrefswikispagesnamesnewwikisbuild_addressess remove_dupstoaddrssccaddrssaccparamsreplacessplitsaccaddrssbccparamsbccaddrss recipientsslenspccsjoins_charsets body_encodingsencodesdummysUnicodeDecodeErrors TracErrorsmails set_charsetspreamblesmsgs add_headersattachswikidiffsAttributeErrors add_headerss mime_headerss smtp_servers smtp_ports as_stringsmsgtextscompilesrecrlfsserverssendmail("sselfstorcptssccrcptss mime_headerssmailsrecrlfsccaddrss public_ccs always_ccs formataddrshdrssprojnamestoaddrssattachsbccparamsres always_bccsbuild_addressess formatdatesmsgspccs __version__saccaddrssbodys MIMEMultiparts recipientssmsgtextsdestsbccaddrssdummys remove_dupsheaderssaccparamsMIMEText((sselfsAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pyssend‹s¦         E    ,,      & ( s__name__s __module__s template_names from_emailsCOLSsFalsesnewwikis__init__sNonesnotifysget_message_idsget_recipientsssend(((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pysWikiNotifyEmail:s ) (smd5s trac.corestrac.wiki.modelsWikiPagestrac.versioncontrol.diffs unified_diffstrac.notifications NotifyEmails trac.configsOptions BoolOptions diff_headers ComponentsWikiNotificationSystemsWikiNotifyEmail( s NotifyEmails diff_headersOptionsWikiNotifyEmailsWikiNotificationSystems unified_diffs BoolOptionsmd5sWikiPage((sAbuild/bdist.darwin-8.0.1-x86/egg/WikiNotification/notification.pys?s    PK‘<5ÙŽ¢ V V *WikiNotification/templates/notification.cs

Notification Error

You must add your email address to Settings in order to be able to use wiki notifications

Notification Settings
= 1 ?>

 

List of Watched Pages

 Watched Wiki Pages

 

You are not watching any wiki pages

You will now recieve emails about changes made on .

No more emails about changes made on 1 ?> , will be sent to you.

Redirecting you back, if it fails, please click here

A list of the wiki pages you're watching can be found on My Notifications.

PKܘ>5Ù¥0¡¡0WikiNotification/templates/notification_email.cs Added page "" by from * Page URL: <> Comment: Content: Changed page "" by from * Page URL: <> Diff URL: <> Revision Comment: Changes on attached .diff file. Deleted page "" by from * Page URL: <> Deleted version "" of page "" by from * * The IP shown here might not mean anything if the user is behind a proxy. -- <> PK†68tò%ššEGG-INFO/SOURCES.txtREADME setup.cfg setup.py TracWikiNotification.egg-info/PKG-INFO TracWikiNotification.egg-info/SOURCES.txt TracWikiNotification.egg-info/dependency_links.txt TracWikiNotification.egg-info/entry_points.txt TracWikiNotification.egg-info/requires.txt TracWikiNotification.egg-info/top_level.txt WikiNotification/__init__.py WikiNotification/listener.py WikiNotification/notification.py WikiNotification/web_ui.py PK†68Cc©44EGG-INFO/entry_points.txt[trac.plugins] wikinotification = WikiNotification PK†68“×2EGG-INFO/dependency_links.txt PK†68QXzÉú ú EGG-INFO/PKG-INFOMetadata-Version: 1.0 Name: TracWikiNotification Version: 0.1.0rc4 Summary: Trac Plugin to allow email notification of changes on wiki pages Home-page: http://wikinotification.ufsoft.org Author: Pedro Algarvio Author-email: ufs@ufsoft.org License: BSD Download-URL: http://python.org/pypi/TracWikiNotification Description: ============================== Trac Wiki Notification Plugin ============================== Trac Wiki Notification is a pluggin that allows users(even anonymous, as long as email is set) to select the wiki pages that they wish to be notified(by email) when a change occurs on it. You can find more info on the `Trac WikiNotification `_ site where bugs and new feature requests should go to. Enabling the Plugin ------------------- It's as simple as:: [componentes] wikinotification.* = enabled Available Config Options ------------------------ These are the options available to include on your *trac.ini*. ===================== ==================== ================================ **Config Setting** **Default Value** **Explanation** --------------------- -------------------- -------------------------------- *redirect_time* 5 (in secconds) The default secconds a redirect should take when watching/un-watching a wiki page. This value is also definable per user, ie, user is able to configure this, of course for himself. --------------------- -------------------- -------------------------------- *smtp_always_bcc* *empty* Email address(es) to always send notifications to, addresses do not appear publicly (Bcc:). --------------------- -------------------- -------------------------------- *smtp_always_cc* *empty* Email address(es) to always send notifications to, addresses can be see by all recipients (Cc:). --------------------- -------------------- -------------------------------- *smtp_from* trac.wiki\@localhost Sender address to use in notification emails. --------------------- -------------------- -------------------------------- *use_public_cc* False Recipients can see email addresses of other CC'ed recipients. If this option is disabled(the default), recipients are put on BCC. ===================== ==================== ================================ Download and Installation ------------------------- Trac WikiNotification can be installed with `Easy Install `_ by typing:: > easy_install TracWikiNotification Platform: OS Independent - Anywhere Python and Trac >=0.10 is known to run. Classifier: Development Status :: 4 - Beta Classifier: Environment :: Web Environment Classifier: Intended Audience :: System Administrators Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Text Processing Classifier: Topic :: Utilities Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content PK†685WËEGG-INFO/requires.txtTracCtxtnavAddPK†68n EGG-INFO/top_level.txtWikiNotification PK†68“×2EGG-INFO/not-zip-safe PK‘<5á'{ÿ++¤WikiNotification/__init__.pyPK†68€N+~ââ¤eWikiNotification/web_ui.pycPK¢œB5Îÿ,‘‚)‚) ¤€WikiNotification/notification.pyPK5>5ªì3ñ( ( ¤@HWikiNotification/listener.pyPK†68†@úú¤¢QWikiNotification/__init__.pycPK†68¢j’"þ þ ¤×RWikiNotification/listener.pycPK‘<5ž\DXŠŠ¤`WikiNotification/web_ui.pyPK†68Ìú„**!¤ÒuWikiNotification/notification.pycPK‘<5ÙŽ¢ V V *¤® WikiNotification/templates/notification.csPKܘ>5Ù¥0¡¡0¤L®WikiNotification/templates/notification_email.csPK†68tò%šš¤;²EGG-INFO/SOURCES.txtPK†68Cc©44¤´EGG-INFO/entry_points.txtPK†68“×2¤r´EGG-INFO/dependency_links.txtPK†68QXzÉú ú ¤®´EGG-INFO/PKG-INFOPK†685Wˤ×ÂEGG-INFO/requires.txtPK†68n ¤ÃEGG-INFO/top_level.txtPK†68“×2¤]ÃEGG-INFO/not-zip-safePKë‘Ã