aboutsummaryrefslogtreecommitdiffstats
path: root/aggregator
diff options
context:
space:
mode:
Diffstat (limited to 'aggregator')
-rw-r--r--aggregator/__init__.py0
-rw-r--r--aggregator/fixtures/initial_data.json43
-rw-r--r--aggregator/management/__init__.py0
-rw-r--r--aggregator/management/commands/__init__.py0
-rw-r--r--aggregator/management/commands/load_feeds.py37
-rw-r--r--aggregator/migrations/0001_initial.py72
-rw-r--r--aggregator/migrations/__init__.py0
-rw-r--r--aggregator/models.py25
-rw-r--r--aggregator/views.py20
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 })