diff options
Diffstat (limited to 'aggregator')
-rw-r--r-- | aggregator/__init__.py | 0 | ||||
-rw-r--r-- | aggregator/fixtures/initial_data.json | 43 | ||||
-rw-r--r-- | aggregator/management/__init__.py | 0 | ||||
-rw-r--r-- | aggregator/management/commands/__init__.py | 0 | ||||
-rw-r--r-- | aggregator/management/commands/load_feeds.py | 37 | ||||
-rw-r--r-- | aggregator/migrations/0001_initial.py | 72 | ||||
-rw-r--r-- | aggregator/migrations/__init__.py | 0 | ||||
-rw-r--r-- | aggregator/models.py | 25 | ||||
-rw-r--r-- | aggregator/views.py | 20 |
9 files changed, 197 insertions, 0 deletions
diff --git a/aggregator/__init__.py b/aggregator/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aggregator/__init__.py diff --git a/aggregator/fixtures/initial_data.json b/aggregator/fixtures/initial_data.json new file mode 100644 index 0000000..76c6471 --- /dev/null +++ b/aggregator/fixtures/initial_data.json @@ -0,0 +1,43 @@ +[ + { + "model": "aggregator.Feed", + "pk": 1, + "fields": { + "base_url": "http://www.advogato.org/", + "feed_url": "person/ryuslash/rss.xml", + "uses_title": false, + "favicon_ext": "ico" + } + }, + { + "model": "aggregator.Feed", + "pk": 2, + "fields": { + "base_url": "http://diasp.org/", + "feed_url": "public/ryuslash.atom", + "uses_title": false, + "favicon_ext": "png", + "br2nl": true + } + }, + { + "model": "aggregator.Feed", + "pk": 3, + "fields": { + "base_url": "http://identi.ca/", + "feed_url": "api/statuses/user_timeline/107950.rss", + "uses_title": false, + "favicon_ext": "ico" + } + }, + { + "model": "aggregator.Feed", + "pk": 4, + "fields": { + "base_url": "https://github.com/", + "feed_url": "ryuslash.atom", + "uses_title": true, + "favicon_ext": "png" + } + } +] diff --git a/aggregator/management/__init__.py b/aggregator/management/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aggregator/management/__init__.py diff --git a/aggregator/management/commands/__init__.py b/aggregator/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aggregator/management/commands/__init__.py diff --git a/aggregator/management/commands/load_feeds.py b/aggregator/management/commands/load_feeds.py new file mode 100644 index 0000000..c143052 --- /dev/null +++ b/aggregator/management/commands/load_feeds.py @@ -0,0 +1,37 @@ +import feedparser +import datetime + +from django.core.management.base import BaseCommand + +from aggregator.models import Feed, Post + +class Command(BaseCommand): + help = "hi" + + def handle(self, *args, **kwargs): + feeds = Feed.objects.all() + + for feed in feeds: + parsed = feedparser.parse(feed.get_feed_url()) + feed.title = parsed.feed.title + + for entry in parsed.entries: + if not Post.objects.filter(post_id=entry.id).exists(): + updated = datetime.datetime( + entry.updated_parsed.tm_year, + entry.updated_parsed.tm_mon, + entry.updated_parsed.tm_mday, + entry.updated_parsed.tm_hour, + entry.updated_parsed.tm_min, + entry.updated_parsed.tm_sec) + + post = Post(post_id=entry.id, + title=entry.title, + body=entry.summary, + remote_url=entry.link, + updated=updated, + feed=feed) + post.save() + feed.updated = datetime.datetime.now() + + feed.save() diff --git a/aggregator/migrations/0001_initial.py b/aggregator/migrations/0001_initial.py new file mode 100644 index 0000000..73ca455 --- /dev/null +++ b/aggregator/migrations/0001_initial.py @@ -0,0 +1,72 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding model 'Feed' + db.create_table('aggregator_feed', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('base_url', self.gf('django.db.models.fields.URLField')(max_length=255)), + ('feed_url', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('favicon_ext', self.gf('django.db.models.fields.CharField')(max_length=4)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=500, blank=True)), + ('updated', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('uses_title', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('br2nl', self.gf('django.db.models.fields.BooleanField')(default=False)), + )) + db.send_create_signal('aggregator', ['Feed']) + + # Adding model 'Post' + db.create_table('aggregator_post', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('post_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=500)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=500)), + ('body', self.gf('django.db.models.fields.TextField')()), + ('remote_url', self.gf('django.db.models.fields.URLField')(max_length=255)), + ('updated', self.gf('django.db.models.fields.DateTimeField')()), + ('added', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('feed', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['aggregator.Feed'])), + )) + db.send_create_signal('aggregator', ['Post']) + + + def backwards(self, orm): + + # Deleting model 'Feed' + db.delete_table('aggregator_feed') + + # Deleting model 'Post' + db.delete_table('aggregator_post') + + + models = { + 'aggregator.feed': { + 'Meta': {'object_name': 'Feed'}, + 'base_url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), + 'br2nl': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'favicon_ext': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'feed_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '500', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'uses_title': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'aggregator.post': { + 'Meta': {'object_name': 'Post'}, + 'added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'feed': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['aggregator.Feed']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'post_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '500'}), + 'remote_url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {}) + } + } + + complete_apps = ['aggregator'] diff --git a/aggregator/migrations/__init__.py b/aggregator/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/aggregator/migrations/__init__.py diff --git a/aggregator/models.py b/aggregator/models.py new file mode 100644 index 0000000..302f774 --- /dev/null +++ b/aggregator/models.py @@ -0,0 +1,25 @@ +from django.db import models + +class Feed(models.Model): + base_url = models.URLField(max_length=255) + feed_url = models.CharField(max_length=255) + favicon_ext = models.CharField(max_length=4) + title = models.CharField(max_length=500, blank=True) + updated = models.DateTimeField(null=True, blank=True) + uses_title = models.BooleanField(default=False) + br2nl = models.BooleanField(default=False) + + def get_feed_url(self): + return self.base_url + self.feed_url + + def get_favicon_url(self): + return self.base_url + 'favicon.' + self.favicon_ext + +class Post(models.Model): + post_id = models.CharField(max_length=500, unique=True) + title = models.CharField(max_length=500) + body = models.TextField() + remote_url = models.URLField(max_length=255) + updated = models.DateTimeField() + added = models.DateTimeField(auto_now_add=True) + feed = models.ForeignKey(Feed) diff --git a/aggregator/views.py b/aggregator/views.py new file mode 100644 index 0000000..c946c31 --- /dev/null +++ b/aggregator/views.py @@ -0,0 +1,20 @@ +from django.core.paginator import Paginator, InvalidPage, EmptyPage +from django.http import Http404 +from django.shortcuts import render_to_response + +from .models import Post + +def posts(request, page=1): + queryset = Post.objects.order_by('-updated') + paginator = Paginator(queryset, 20) + + if page == None: + page = 1 + + try: + object_list = paginator.page(page) + except (EmptyPage, InvalidPage): + raise Http404 + + return render_to_response('aggregator/posts.html', + { 'list': object_list }) |