1.1 --- a/scripts/import/eventfeed.py Thu Mar 11 23:43:19 2010 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,220 +0,0 @@
1.4 -# -*- coding: iso-8859-1 -*-
1.5 -"""
1.6 - MoinMoin - Event feed importer, based on the FeedReader macro, the irclog
1.7 - script in MoinMoin, and the EventAggregatorNewEvent action
1.8 -
1.9 - @copyright: 2008, 2009, 2010 by Paul Boddie <paul@boddie.org.uk>
1.10 - 2005-2007 MoinMoin:AlexanderSchremmer
1.11 - 2006 MoinMoin:ThomasWaldmann
1.12 -
1.13 - @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.14 -"""
1.15 -
1.16 -from MoinMoin.PageEditor import PageEditor
1.17 -from MoinMoin.script import MoinScript
1.18 -import EventAggregatorSupport
1.19 -import urllib
1.20 -import xml.dom.pulldom
1.21 -
1.22 -# The script's class.
1.23 -
1.24 -class PluginScript(MoinScript):
1.25 -
1.26 - """\
1.27 -Purpose:
1.28 -========
1.29 -This tool imports events from an RSS feed into event pages.
1.30 -
1.31 -Detailed Instructions:
1.32 -======================
1.33 -General syntax: moin [options] import eventfeed [eventfeed-options]
1.34 -
1.35 -[options] usually should be:
1.36 - --config-dir=/path/to/my/cfg/ --wiki-url=wiki.example.org/
1.37 -
1.38 -[eventfeed-options] see below:
1.39 - 0. To import events from the FSFE event feed
1.40 - moin ... import eventfeed --url=http://www.fsfe.org/events/events.en.rss ...
1.41 -
1.42 - 1. To use a specific template such as 'EventTemplate'
1.43 - moin ... import eventfeed --template=EventTemplate ...
1.44 -
1.45 - 2. To assign pages to specific categories such as 'CategoryEvents CategoryMeetings'
1.46 - moin ... import eventfeed --categories='CategoryEvents CategoryMeetings' ...
1.47 -
1.48 - 3. To use a specific author such as 'EventImporter'
1.49 - moin ... import eventfeed --author=EventImporter ...
1.50 -
1.51 - 4. To add pages under a common parent page such as 'Events'
1.52 - moin ... import eventfeed --parent=Events ...
1.53 -
1.54 - 5. To overwrite existing event pages
1.55 - moin ... import eventfeed --overwrite ...
1.56 -
1.57 - 5. To delete any event pages associated with the feed
1.58 - moin ... import eventfeed --delete ...
1.59 -"""
1.60 -
1.61 - FIELDS = ("title", "link", "description")
1.62 -
1.63 - def __init__(self, argv, def_values):
1.64 - MoinScript.__init__(self, argv, def_values)
1.65 - self.parser.add_option(
1.66 - "--url", dest="url", default="",
1.67 - help="Specify the location of the events RSS feed"
1.68 - )
1.69 - self.parser.add_option(
1.70 - "--template", dest="template", default="EventTemplate",
1.71 - help="Specify the template used to make the event pages"
1.72 - )
1.73 - self.parser.add_option(
1.74 - "--categories", dest="categories", default="CategoryEvents",
1.75 - help="Specify the categories to which the event pages will belong"
1.76 - )
1.77 - self.parser.add_option(
1.78 - "--author", dest="author", default="EventImporter",
1.79 - help="Specify the author of the event pages"
1.80 - )
1.81 - self.parser.add_option(
1.82 - "--parent", dest="parent", default="",
1.83 - help="Specify the parent page of the event pages"
1.84 - )
1.85 - self.parser.add_option(
1.86 - "--overwrite", dest="overwrite", action="store_true",
1.87 - help="Request that existing pages be overwritten"
1.88 - )
1.89 - self.parser.add_option(
1.90 - "--delete", dest="delete", action="store_true",
1.91 - help="Request that event pages associated with the feed be deleted"
1.92 - )
1.93 -
1.94 - def mainloop(self):
1.95 - self.init_request()
1.96 - if not self.options.url:
1.97 - print "No URL specified. Not importing any events!"
1.98 - else:
1.99 - self.read_events(self.options.url)
1.100 -
1.101 - def read_events(self, url):
1.102 -
1.103 - """
1.104 - Read events from the given events RSS feed, specified by 'url', creating
1.105 - new Wiki pages where appropriate.
1.106 - """
1.107 -
1.108 - request = self.request
1.109 - category_pagenames = self.options.categories.split()
1.110 -
1.111 - # Locate the template for events.
1.112 -
1.113 - template_page = PageEditor(request, self.options.template)
1.114 -
1.115 - if not template_page.exists():
1.116 - print "Template %r cannot be found. Not importing any events!" % self.options.template
1.117 - return
1.118 -
1.119 - # Process the feed.
1.120 -
1.121 - feed = urllib.urlopen(url)
1.122 -
1.123 - try:
1.124 - nodes = xml.dom.pulldom.parse(feed)
1.125 - event_details = {}
1.126 -
1.127 - in_item = 0
1.128 -
1.129 - # Read the nodes from the feed.
1.130 -
1.131 - for node_type, value in nodes:
1.132 - if node_type == xml.dom.pulldom.START_ELEMENT:
1.133 - if value.nodeName == "item":
1.134 - in_item = 1
1.135 -
1.136 - # Get the value of the important fields.
1.137 -
1.138 - elif in_item and value.nodeName in self.FIELDS:
1.139 - nodes.expandNode(value)
1.140 - event_details[value.nodeName] = self.text(value)
1.141 -
1.142 - # Where all fields have been read, make a new page.
1.143 -
1.144 - if reduce(lambda x, y: x and event_details.has_key(y), self.FIELDS, 1):
1.145 -
1.146 - # Define the page.
1.147 -
1.148 - title = event_details["title"]
1.149 -
1.150 - # Use any parent page information.
1.151 -
1.152 - full_title = EventAggregatorSupport.getFullPageName(self.options.parent, title)
1.153 -
1.154 - # Find the start and end dates.
1.155 -
1.156 - dates = EventAggregatorSupport.getDateStrings(title)
1.157 -
1.158 - # Require one or two dates.
1.159 -
1.160 - if dates and 1 <= len(dates) <= 2:
1.161 -
1.162 - # Deduce the end date.
1.163 -
1.164 - if len(dates) == 2:
1.165 - start_date, end_date = dates
1.166 - elif len(dates) == 1:
1.167 - start_date = end_date = dates[0]
1.168 -
1.169 - # Load the new page and replace the event details in the body.
1.170 -
1.171 - new_page = PageEditor(request, full_title,
1.172 - uid_override=self.options.author)
1.173 -
1.174 - # Delete the page if requested.
1.175 -
1.176 - if new_page.exists() and self.options.delete:
1.177 -
1.178 - try:
1.179 - new_page.deletePage()
1.180 - except new_page.AccessDenied:
1.181 - print "Page %r has not been deleted." % full_title
1.182 -
1.183 - # Complete the new page.
1.184 -
1.185 - elif not new_page.exists() or self.options.overwrite:
1.186 - event_details["summary"] = title
1.187 - event_details["start"] = start_date
1.188 - event_details["end"] = end_date
1.189 -
1.190 - try:
1.191 - EventAggregatorSupport.fillEventPageFromTemplate(
1.192 - template_page, new_page, event_details,
1.193 - category_pagenames)
1.194 -
1.195 - except new_page.Unchanged:
1.196 - print "Page %r is not changed." % full_title
1.197 -
1.198 - else:
1.199 - print "Not overwriting page %r." % full_title
1.200 -
1.201 - else:
1.202 - print "Could not deduce dates from %r." % title
1.203 -
1.204 - event_details = {}
1.205 -
1.206 - elif node_type == xml.dom.pulldom.END_ELEMENT:
1.207 - if value.nodeName == "item":
1.208 - in_item = 0
1.209 -
1.210 - finally:
1.211 - feed.close()
1.212 -
1.213 - def text(self, element):
1.214 -
1.215 - "Return the text within the given 'element'."
1.216 -
1.217 - nodes = []
1.218 - for node in element.childNodes:
1.219 - if node.nodeType == node.TEXT_NODE:
1.220 - nodes.append(node.nodeValue)
1.221 - return "".join(nodes)
1.222 -
1.223 -# vim: tabstop=4 expandtab shiftwidth=4