source: watchlistplugin/0.12/tracwatchlist/wiki.py

Last change on this file was 15264, checked in by Ryan J Ollos, 8 years ago

Remove unnecessary svn:mime-type on py files

svn:mime-type was set to "plain" for many files.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Id Date Author Rev URL
File size: 11.1 KB
Line 
1# -*- coding: utf-8 -*-
2"""
3= Watchlist Plugin for Trac =
4Plugin Website:  http://trac-hacks.org/wiki/WatchlistPlugin
5Trac website:    http://trac.edgewall.org/
6
7Copyright (c) 2008-2010 by Martin Scharrer <martin@scharrer-online.de>
8All rights reserved.
9
10The i18n support was added by Steffen Hoffmann <hoff.st@web.de>.
11
12This program is free software: you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation, either version 3 of the License, or
15(at your option) any later version.
16
17This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20GNU General Public License for more details.
21
22For a copy of the GNU General Public License see
23<http://www.gnu.org/licenses/>.
24
25$Id: wiki.py 15264 2016-02-11 04:22:34Z rjollos $
26"""
27
28__url__      = ur"$URL: //trac-hacks.org/svn/watchlistplugin/0.12/tracwatchlist/wiki.py $"[6:-2]
29__author__   = ur"$Author: rjollos $"[9:-2]
30__revision__ = int("0" + ur"$Rev: 15264 $"[6:-2].strip('M'))
31__date__     = ur"$Date: 2016-02-11 04:22:34 +0000 (Thu, 11 Feb 2016) $"[7:-2]
32
33from  trac.core              import  *
34from  genshi.builder         import  tag
35from  trac.wiki.model        import  WikiPage
36from  trac.wiki.formatter    import  format_to_oneliner
37from  trac.util.datefmt      import  pretty_timedelta, \
38                                     datetime, utc, to_timestamp
39from  trac.util.text         import  obfuscate_email_address
40
41from  trac.util.datefmt      import  format_datetime as trac_format_datetime
42from  trac.web.chrome        import  Chrome
43from  trac.mimeview.api      import  Context
44from  trac.resource          import  Resource
45from  trac.attachment        import  Attachment
46
47from  tracwatchlist.api      import  BasicWatchlist
48from  tracwatchlist.translation import  _, N_, T_, t_, tag_, ngettext
49from  tracwatchlist.util     import  moreless, format_datetime, LC_TIME,\
50                                     convert_to_sql_wildcards
51
52
53class WikiWatchlist(BasicWatchlist):
54    """Watchlist entry for wiki pages."""
55    realms = ['wiki']
56    fields = {'wiki':{
57        'changetime': T_("Modified"),
58        'author'    : T_("Author"),
59        'version'   : T_("Version"),
60        'diff'      : T_("Diff"),
61        'history'   : T_("History"),
62        # TRANSLATOR: Abbreviated label for 'unwatch' column header.
63        # Should be a single character to not widen the column.
64        'unwatch'   : N_("U"),
65        # TRANSLATOR: Label for 'notify' column header.
66        # Should tell the user that notifications can be switched on or off
67        # with the check-boxes in this column.
68        'notify'    : N_("Notify"),
69        'comment'   : T_("Comment"),
70
71        'readonly'  : N_("read-only"),
72        # T#RANSLATOR: IP = Internet Protocol (address)
73        #'ipnr'      : N_("IP"), # Note: not supported by Trac 0.12 WikiPage class
74    }}
75    default_fields = {'wiki':[
76        'name', 'changetime', 'author', 'version', 'diff',
77        'history', 'unwatch', 'notify', 'comment',
78    ]}
79    tagsystem = None
80
81
82    def __init__(self):
83        self.fields['wiki']['name'] = self.get_realm_label('wiki')
84        try: # Try to support the Tags Plugin
85            from tractags.api import TagSystem
86            self.tagsystem = self.env[TagSystem]
87        except ImportError, e:
88            pass
89        else:
90            if self.tagsystem:
91                self.fields['wiki']['tags'] = _("Tags")
92
93
94    def get_realm_label(self, realm, n_plural=1, astitle=False):
95        if astitle:
96            # TRANSLATOR: 'wiki page(s)' as title
97            return ngettext("Wiki Page", "Wiki Pages", n_plural)
98        else:
99            # TRANSLATOR: 'wiki page(s)' inside a sentence
100            return ngettext("wiki page", "wiki pages", n_plural)
101
102
103    def _get_sql(self, resids, fuzzy, var='name'):
104        if isinstance(resids,basestring):
105            if fuzzy:
106                resids += '*'
107            args = convert_to_sql_wildcards(resids).replace(',',' ').split()
108            sql = ' OR '.join((' ' + var + " LIKE %s ESCAPE '|' ",) * len(args))
109        else:
110            args = list(resids)
111            if (len(args) == 1):
112                sql = ' ' + var + '=%s '
113            else:
114                sql = ' ' + var + ' IN (' + ','.join(('%s',) * len(args)) + ') '
115        return sql, args
116
117
118    def resources_exists(self, realm, resids, fuzzy=0):
119        if not resids:
120            return []
121        sql, args = self._get_sql(resids, fuzzy)
122        if not sql:
123            return []
124        db = self.env.get_db_cnx()
125        cursor = db.cursor()
126        cursor.execute("""
127            SELECT DISTINCT name
128            FROM wiki
129            WHERE
130        """ + sql, args)
131        return [ unicode(v[0]) for v in cursor.fetchall() ]
132
133
134    def watched_resources(self, realm, resids, user, wl, fuzzy=0):
135        if not resids:
136            return []
137        sql, args = self._get_sql(resids, fuzzy, 'resid')
138        if not sql:
139            return []
140        db = self.env.get_db_cnx()
141        cursor = db.cursor()
142        cursor.log = self.log
143        cursor.execute("""
144            SELECT resid
145            FROM watchlist
146            WHERE wluser=%s AND realm='wiki' AND (
147        """ + sql + " )", [user] + args)
148        return [ unicode(v[0]) for v in cursor.fetchall() ]
149
150
151    def unwatched_resources(self, realm, resids, user, wl, fuzzy=0):
152        if not resids:
153            return []
154        sql, args = self._get_sql(resids, fuzzy)
155        if not sql:
156            return []
157        db = self.env.get_db_cnx()
158        cursor = db.cursor()
159        cursor.execute("""
160            SELECT DISTINCT name
161            FROM wiki
162            WHERE name NOT in (
163                SELECT resid
164                FROM watchlist
165                WHERE wluser=%s AND realm='wiki'
166            ) AND (
167        """ + sql + " )", [user] + args)
168        return [ unicode(v[0]) for v in cursor.fetchall() ]
169
170
171    def get_list(self, realm, wl, req, fields=None):
172        db = self.env.get_db_cnx()
173        cursor = db.cursor()
174        user = req.authname
175        locale = getattr(req, 'locale', None) or LC_TIME
176        context = Context.from_request(req)
177        wikilist = []
178        extradict = {}
179        if not fields:
180            fields = set(self.default_fields['wiki'])
181        else:
182            fields = set(fields)
183
184        if 'changetime' in fields:
185            max_changetime = datetime(1970,1,1,tzinfo=utc)
186            min_changetime = datetime.now(utc)
187
188        for name, last_visit in wl.get_watched_resources( 'wiki', req.authname ):
189            wikipage = WikiPage(self.env, name, db=db)
190            wikidict = {}
191
192            if not wikipage.exists:
193                wikidict['deleted'] = True
194                if 'name' in fields:
195                    wikidict['name'] = name
196                if 'author' in fields:
197                    wikidict['author'] = '?'
198                if 'changetime' in fields:
199                    wikidict['changedsincelastvisit'] = 1
200                    wikidict['changetime'] = '?'
201                    wikidict['ichangetime'] = 0
202                if 'comment' in fields:
203                    wikidict['comment'] = tag.strong(t_("deleted"), class_='deleted')
204                if 'notify' in fields:
205                    wikidict['notify'] =  wl.is_notify(req, 'wiki', name)
206                wikilist.append(wikidict)
207                continue
208
209            comment = wikipage.comment
210            changetime = wikipage.time
211            author = wikipage.author
212            if wl.options['attachment_changes']:
213                latest_attachment = None
214                for attachment in Attachment.select(self.env, 'wiki', name, db):
215                    if attachment.date > changetime:
216                        latest_attachment = attachment
217                if latest_attachment:
218                    changetime = latest_attachment.date
219                    author = latest_attachment.author
220                    if 'comment' in fields:
221                        wikitext = '[attachment:"' + ':'.join([latest_attachment.filename,'wiki',name]) + \
222                                   '" ' + latest_attachment.filename  + ']'
223                        desc = latest_attachment.description
224                        comment = tag(tag_("Attachment %(attachment)s added",\
225                                attachment=format_to_oneliner(self.env, context, wikitext, shorten=False)),
226                                desc and ': ' or '.', moreless(desc,10))
227            if 'attachment' in fields:
228                attachments = []
229                for attachment in Attachment.select(self.env, 'wiki', name, db):
230                    wikitext = '[attachment:"' + ':'.join([attachment.filename,'wiki',name]) + '" ' + attachment.filename  + ']'
231                    attachments.extend([tag(', '), format_to_oneliner(self.env, context, wikitext, shorten=False)])
232                if attachments:
233                    attachments.reverse()
234                    attachments.pop()
235                ticketdict['attachment'] = moreless(attachments, 5)
236            if 'name' in fields:
237                wikidict['name'] = name
238            if 'author' in fields:
239                if not (Chrome(self.env).show_email_addresses or
240                        'EMAIL_VIEW' in req.perm(wikipage.resource)):
241                    wikidict['author'] = obfuscate_email_address(author)
242                else:
243                    wikidict['author'] = author
244            if 'version' in fields:
245                wikidict['version'] = unicode(wikipage.version)
246            if 'changetime' in fields:
247                wikidict['changetime'] = format_datetime( changetime, locale=locale, tzinfo=req.tz )
248                wikidict['ichangetime'] = to_timestamp( changetime )
249                wikidict['changedsincelastvisit'] = last_visit < wikidict['ichangetime'] and 1 or 0
250                wikidict['timedelta'] = pretty_timedelta( changetime )
251                wikidict['timeline_link'] = req.href.timeline(precision='seconds',
252                    from_=trac_format_datetime ( changetime, 'iso8601', tzinfo=req.tz))
253                if changetime > max_changetime:
254                    max_changetime = changetime
255                if changetime < min_changetime:
256                    min_changetime = changetime
257            if 'comment' in fields:
258                comment = moreless(comment or "", 200)
259                wikidict['comment'] = comment
260            if 'notify' in fields:
261                wikidict['notify']   = wl.is_notify(req, 'wiki', name)
262            if 'readonly' in fields:
263                wikidict['readonly'] = wikipage.readonly and t_("yes") or t_("no")
264            if 'tags' in fields and self.tagsystem:
265                tags = []
266                for t in self.tagsystem.get_tags(req, Resource('wiki', name)):
267                    tags.extend([tag.a(t,href=req.href('tags',q=t)), tag(', ')])
268                if tags:
269                    tags.pop()
270                wikidict['tags'] = moreless(tags, 10)
271            #if 'ipnr' in fields:
272            #    wikidict['ipnr'] = wikipage.ipnr,  # Note: Not supported by Trac 0.12
273            wikilist.append(wikidict)
274
275        if 'changetime' in fields:
276            extradict['max_changetime'] = format_datetime( max_changetime, locale=locale, tzinfo=req.tz )
277            extradict['min_changetime'] = format_datetime( min_changetime, locale=locale, tzinfo=req.tz )
278
279        return wikilist, extradict
280
281# EOF
Note: See TracBrowser for help on using the repository browser.