Back to index

moin  1.9.0~rc2
Functions
MoinMoin.action.rss_rc Namespace Reference

Functions

def full_url
def execute

Detailed Description

    RSS Handling

    If you do changes, please check if it still validates after your changes:

    http://feedvalidator.org/

    @copyright: 2006-2007 MoinMoin:ThomasWaldmann
    @license: GNU GPL, see COPYING for details.

Function Documentation

def MoinMoin.action.rss_rc.execute (   pagename,
  request 
)
Send recent changes as an RSS document

Definition at line 23 of file rss_rc.py.

00023 
00024 def execute(pagename, request):
00025     """ Send recent changes as an RSS document
00026     """
00027     if not wikixml.ok:
00028         request.mimetype = 'text/plain'
00029         request.write("rss_rc action is not supported because of missing pyxml module.")
00030         return
00031 
00032     cfg = request.cfg
00033 
00034     # get params
00035     items_limit = 100
00036     try:
00037         max_items = int(request.values['items'])
00038         max_items = min(max_items, items_limit) # not more than `items_limit`
00039     except (KeyError, ValueError):
00040         # not more than 15 items in a RSS file by default
00041         max_items = 15
00042     try:
00043         unique = int(request.values.get('unique', 0))
00044     except ValueError:
00045         unique = 0
00046     try:
00047         diffs = int(request.values.get('diffs', 0))
00048     except ValueError:
00049         diffs = 0
00050     ## ddiffs inserted by Ralf Zosel <ralf@zosel.com>, 04.12.2003
00051     try:
00052         ddiffs = int(request.values.get('ddiffs', 0))
00053     except ValueError:
00054         ddiffs = 0
00055 
00056     # get data
00057     log = editlog.EditLog(request)
00058     logdata = []
00059     counter = 0
00060     pages = {}
00061     lastmod = 0
00062     for line in log.reverse():
00063         if not request.user.may.read(line.pagename):
00064             continue
00065         if (not line.action.startswith('SAVE') or
00066             ((line.pagename in pages) and unique)): continue
00067         #if log.dayChanged() and log.daycount > _MAX_DAYS: break
00068         line.editor = line.getInterwikiEditorData(request)
00069         line.time = timefuncs.tmtuple(wikiutil.version2timestamp(line.ed_time_usecs)) # UTC
00070         logdata.append(line)
00071         pages[line.pagename] = None
00072 
00073         if not lastmod:
00074             lastmod = wikiutil.version2timestamp(line.ed_time_usecs)
00075 
00076         counter += 1
00077         if counter >= max_items:
00078             break
00079     del log
00080 
00081     timestamp = timefuncs.formathttpdate(lastmod)
00082     etag = "%d-%d-%d-%d-%d" % (lastmod, max_items, diffs, ddiffs, unique)
00083 
00084     # for 304, we look at if-modified-since and if-none-match headers,
00085     # one of them must match and the other is either not there or must match.
00086     if request.if_modified_since == timestamp:
00087         if request.if_none_match:
00088             if request.if_none_match == etag:
00089                 request.status_code = 304
00090         else:
00091             request.status_code = 304
00092     elif request.if_none_match == etag:
00093         if request.if_modified_since:
00094             if request.if_modified_since == timestamp:
00095                 request.status_code = 304
00096         else:
00097             request.status_code = 304
00098     else:
00099         # generate an Expires header, using whatever setting the admin
00100         # defined for suggested cache lifetime of the RecentChanges RSS doc
00101         expires = time.time() + cfg.rss_cache
00102 
00103         request.mime_type = 'text/xml'
00104         request.expires = expires
00105         request.last_modified = lastmod
00106         request.headers.add('Etag', etag)
00107 
00108         # send the generated XML document
00109         baseurl = request.url_root
00110 
00111         logo = re.search(r'src="([^"]*)"', cfg.logo_string)
00112         if logo:
00113             logo = request.getQualifiedURL(logo.group(1))
00114 
00115         # prepare output
00116         out = StringIO.StringIO()
00117         handler = RssGenerator(out)
00118 
00119         # start SAX stream
00120         handler.startDocument()
00121         handler._out.write(
00122             '<!--\n'
00123             '    Add an "items=nnn" URL parameter to get more than the default 15 items.\n'
00124             '    You cannot get more than %d items though.\n'
00125             '    \n'
00126             '    Add "unique=1" to get a list of changes where page names are unique,\n'
00127             '    i.e. where only the latest change of each page is reflected.\n'
00128             '    \n'
00129             '    Add "diffs=1" to add change diffs to the description of each items.\n'
00130             '    \n'
00131             '    Add "ddiffs=1" to link directly to the diff (good for FeedReader).\n'
00132             '    Current settings: items=%i, unique=%i, diffs=%i, ddiffs=%i'
00133             '-->\n' % (items_limit, max_items, unique, diffs, ddiffs)
00134             )
00135 
00136         # emit channel description
00137         handler.startNode('channel', {
00138             (handler.xmlns['rdf'], 'about'): request.url_root,
00139             })
00140         handler.simpleNode('title', cfg.sitename)
00141         page = Page(request, pagename)
00142         handler.simpleNode('link', full_url(request, page))
00143         handler.simpleNode('description', 'RecentChanges at %s' % cfg.sitename)
00144         if logo:
00145             handler.simpleNode('image', None, {
00146                 (handler.xmlns['rdf'], 'resource'): logo,
00147                 })
00148         if cfg.interwikiname:
00149             handler.simpleNode(('wiki', 'interwiki'), cfg.interwikiname)
00150 
00151         handler.startNode('items')
00152         handler.startNode(('rdf', 'Seq'))
00153         for item in logdata:
00154             anchor = "%04d%02d%02d%02d%02d%02d" % item.time[:6]
00155             page = Page(request, item.pagename)
00156             link = full_url(request, page, anchor=anchor)
00157             handler.simpleNode(('rdf', 'li'), None, attr={(handler.xmlns['rdf'], 'resource'): link, })
00158         handler.endNode(('rdf', 'Seq'))
00159         handler.endNode('items')
00160         handler.endNode('channel')
00161 
00162         # emit logo data
00163         if logo:
00164             handler.startNode('image', attr={
00165                 (handler.xmlns['rdf'], 'about'): logo,
00166                 })
00167             handler.simpleNode('title', cfg.sitename)
00168             handler.simpleNode('link', baseurl)
00169             handler.simpleNode('url', logo)
00170             handler.endNode('image')
00171 
00172         # emit items
00173         for item in logdata:
00174             page = Page(request, item.pagename)
00175             anchor = "%04d%02d%02d%02d%02d%02d" % item.time[:6]
00176             rdflink = full_url(request, page, anchor=anchor)
00177             handler.startNode('item', attr={(handler.xmlns['rdf'], 'about'): rdflink, })
00178 
00179             # general attributes
00180             handler.simpleNode('title', item.pagename)
00181             if ddiffs:
00182                 handler.simpleNode('link', full_url(request, page, querystr={'action': 'diff'}))
00183             else:
00184                 handler.simpleNode('link', full_url(request, page))
00185 
00186             handler.simpleNode(('dc', 'date'), timefuncs.W3CDate(item.time))
00187 
00188             # description
00189             desc_text = item.comment
00190             if diffs:
00191                 # TODO: rewrite / extend wikiutil.pagediff
00192                 # searching for the matching pages doesn't really belong here
00193                 revisions = page.getRevList()
00194 
00195                 rl = len(revisions)
00196                 for idx in range(rl):
00197                     rev = revisions[idx]
00198                     if rev <= item.rev:
00199                         if idx + 1 < rl:
00200                             lines = wikiutil.pagediff(request, item.pagename, revisions[idx+1], item.pagename, 0, ignorews=1)
00201                             if len(lines) > 20:
00202                                 lines = lines[:20] + ['...\n']
00203                             lines = '\n'.join(lines)
00204                             lines = wikiutil.escape(lines)
00205                             desc_text = '%s\n<pre>\n%s\n</pre>\n' % (desc_text, lines)
00206                         break
00207             if desc_text:
00208                 handler.simpleNode('description', desc_text)
00209 
00210             # contributor
00211             edattr = {}
00212             if cfg.show_hosts:
00213                 edattr[(handler.xmlns['wiki'], 'host')] = item.hostname
00214             if item.editor[0] == 'interwiki':
00215                 edname = "%s:%s" % item.editor[1]
00216                 ##edattr[(None, 'link')] = baseurl + wikiutil.quoteWikiname(edname)
00217             else: # 'ip'
00218                 edname = item.editor[1]
00219                 ##edattr[(None, 'link')] = link + "?action=info"
00220 
00221             # this edattr stuff, esp. None as first tuple element breaks things (tracebacks)
00222             # if you know how to do this right, please send us a patch
00223 
00224             handler.startNode(('dc', 'contributor'))
00225             handler.startNode(('rdf', 'Description'), attr=edattr)
00226             handler.simpleNode(('rdf', 'value'), edname)
00227             handler.endNode(('rdf', 'Description'))
00228             handler.endNode(('dc', 'contributor'))
00229 
00230             # wiki extensions
00231             handler.simpleNode(('wiki', 'version'), "%i" % (item.ed_time_usecs))
00232             handler.simpleNode(('wiki', 'status'), ('deleted', 'updated')[page.exists()])
00233             handler.simpleNode(('wiki', 'diff'), full_url(request, page, querystr={'action': 'diff'}))
00234             handler.simpleNode(('wiki', 'history'), full_url(request, page, querystr={'action': 'info'}))
00235             # handler.simpleNode(('wiki', 'importance'), ) # ( major | minor )
00236             # handler.simpleNode(('wiki', 'version'), ) # ( #PCDATA )
00237 
00238             handler.endNode('item')
00239 
00240         # end SAX stream
00241         handler.endDocument()
00242 
00243         request.write(out.getvalue())
00244 

Here is the call graph for this function:

def MoinMoin.action.rss_rc.full_url (   request,
  page,
  querystr = None,
  anchor = None 
)

Definition at line 18 of file rss_rc.py.

00018 
00019 def full_url(request, page, querystr=None, anchor=None):
00020     url = page.url(request, anchor=anchor, querystr=querystr)
00021     url = wikiutil.escape(url)
00022     return request.getQualifiedURL(url)

Here is the caller graph for this function: