Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 3 commits
  • 6 files changed
  • 0 commit comments
  • 1 contributor
View
4 molly/apps/feeds/events/views.py
@@ -1,4 +1,4 @@
-from datetime import timedelta
+from datetime import datetime, timedelta
from xml.sax.saxutils import escape
from django.core.paginator import Paginator, EmptyPage, InvalidPage
@@ -73,7 +73,7 @@ def breadcrumb(self, request, context, slug):
def handle_GET(self, request, context, slug):
feed = get_object_or_404(Feed.events, slug=slug)
context['feed'] = feed
- context['feed_items'] = feed.item_set.order_by('dt_start')
+ context['feed_items'] = feed.item_set.filter(dt_start__gte=datetime.today()).order_by('dt_start')
return self.render(request, context, 'feeds/events/item_list')
class ItemDetailView(BaseView):
View
4 molly/apps/feeds/providers/__init__.py
@@ -1,4 +1,6 @@
class BaseFeedsProvider(object):
pass
-from rss import RSSFeedsProvider
+from rss import RSSFeedsProvider
+from ical import ICalFeedsProvider
+from talks_cam import TalksCamFeedsProvider
View
87 molly/apps/feeds/providers/ical.py
@@ -0,0 +1,87 @@
+from datetime import datetime, timedelta
+import urllib2
+import re
+import email
+import time
+import random
+import traceback
+import logging
+from icalendar import Calendar, Event
+from icalendar.prop import vDatetime
+
+from molly.external_media import sanitise_html
+from molly.conf.settings import batch
+
+from molly.apps.feeds.providers import BaseFeedsProvider
+
+__all__ = ['ICalFeedsProvider']
+
+logger = logging.getLogger(__name__)
+
+
+class ICalFeedsProvider(BaseFeedsProvider):
+ """
+ This is a basic iCal feeds provider.
+ Tested with Google Calendar feeds.
+ Doesn't react well with non standard iCal feeds.
+ """
+ verbose_name = 'iCal'
+
+ @batch('%d * * * *' % random.randint(0, 59))
+ def import_data(self, metadata, output):
+ """
+ Pulls iCal feeds
+ """
+
+ from molly.apps.feeds.models import Feed
+ for feed in Feed.objects.filter(provider=self.class_path):
+ output.write("Importing %s\n" % feed.title)
+ try:
+ self.import_feed(feed)
+ except Exception, e:
+ output.write("Error importing %s\n" % feed.title)
+ traceback.print_exc(file=output)
+ output.write('\n')
+ logger.warn("Error importing feed %r" % feed.title,
+ exc_info=True, extra={'url': feed.rss_url})
+
+ return metadata
+
+ def import_feed(self, feed):
+ from molly.apps.feeds.models import Item, vCard
+
+ calendar = Calendar.from_string(urllib2.urlopen(feed.rss_url).read())
+
+ items = set()
+ for component in calendar.walk():
+
+ if component.name == 'VEVENT':
+ item, created = Item.objects.get_or_create(feed=feed, guid=str(component.get('UID')))
+ # Do not create the event if one the property is not correct,
+ # e.g. datetime...
+ try:
+ item.dt_start = vDatetime.from_ical(str(component.get('DTSTART')))
+ item.dt_end = vDatetime.from_ical(str(component.get('DTEND')))
+ item.title = str(component.get('SUMMARY')).strip()
+ item.link = str(component.get('URL'))
+ item.description = sanitise_html(str(component.get('DESCRIPTION')))
+ if str(component.get('LOCATION')) != '':
+ location, created = vCard.objects.get_or_create(name=str(component.get('LOCATION')).strip())
+ # in the future, we could imagine to (try to) geocode the location
+ # to get a point field...
+ location.save()
+ item.venue = location
+ try:
+ item.last_modified = vDatetime.from_ical(str(component.get('LAST-MODIFIED')))
+ except Exception, e:
+ item.last_modified = datetime.now()
+ item.save()
+ items.add(item)
+ except ValueError, v:
+ logger.error('Could not parse event %s' % v)
+
+ for item in Item.objects.filter(feed=feed):
+ if item not in items:
+ item.delete()
+
+ return items
View
81 molly/apps/feeds/providers/talks_cam.py
@@ -0,0 +1,81 @@
+from datetime import datetime, timedelta
+from lxml import etree
+import urllib2
+import re
+import email
+import time
+import random
+import traceback
+import logging
+
+from molly.external_media import sanitise_html
+from molly.conf.settings import batch
+
+from molly.apps.feeds.providers import BaseFeedsProvider
+
+__all__ = ['TalksCamFeedsProvider']
+
+logger = logging.getLogger(__name__)
+
+
+class TalksCamFeedsProvider(BaseFeedsProvider):
+ verbose_name = 'TalksCam'
+
+ @batch('%d * * * *' % random.randint(0, 59))
+ def import_data(self, metadata, output):
+ """
+ Pulls TalksCam feeds
+ """
+
+ from molly.apps.feeds.models import Feed
+ for feed in Feed.objects.filter(provider=self.class_path):
+ output.write("Importing %s\n" % feed.title)
+ try:
+ self.import_feed(feed)
+ except Exception, e:
+ output.write("Error importing %s\n" % feed.title)
+ traceback.print_exc(file=output)
+ output.write('\n')
+ logger.warn("Error importing feed %r" % feed.title,
+ exc_info=True, extra={'url': feed.rss_url})
+
+ return metadata
+
+ def import_feed(self, feed):
+ from molly.apps.feeds.models import Item, vCard
+
+ xml = etree.parse(urllib2.urlopen(feed.rss_url))
+
+ feed.last_modified = datetime.now()
+ feed.save()
+
+ items = set()
+ for talk in xml.findall('talk'):
+ item, created = Item.objects.get_or_create(feed=feed, guid=talk.find('id').text)
+
+ item.last_modified = self.parse_date(talk.find('updated_at').text)
+ item.title = talk.find('title').text.strip()
+ item.description = sanitise_html(talk.find('abstract').text.strip())
+ item.link = talk.find('url').text
+ item.dt_start = self.parse_date(talk.find('start_time').text)
+ item.dt_end = self.parse_date(talk.find('end_time').text)
+
+ location, created = vCard.objects.get_or_create(name=talk.find('venue').text.strip())
+ location.save()
+ item.venue = location
+
+ item.save()
+
+ items.add(item)
+
+ for item in Item.objects.filter(feed=feed):
+ if item not in items:
+ item.delete()
+
+ return items
+
+ def parse_date(self, date):
+ """
+ Parse date as Tue, 21 Feb 2012 23:49:34 +0000
+ """
+ return datetime.strptime(date[:-6], "%a, %d %b %Y %H:%M:%S")
View
3  molly/commands/site_template/settings.py
@@ -773,8 +773,9 @@
Application('molly.apps.feeds', 'feeds', 'Feeds',
# The providers specify the kind of feeds this feed importer supports
providers = [
- # Only RSS is supported right now - this has no options
Provider('molly.apps.feeds.providers.RSSFeedsProvider'),
+ Provider('molly.apps.feeds.providers.ICalFeedsProvider'),
+ Provider('molly.apps.feeds.providers.TalksCamFeedsProvider'),
],
display_to_user = False,
),
View
1  setup.py
@@ -102,6 +102,7 @@
"suds",
"django-slimmer",
'pyyaml',
+ 'icalendar',
'mockito'
],
scripts = [

No commit comments for this range

Something went wrong with that request. Please try again.