From 15c5869b54e9a770b9abbeab1e990b713cdb1b3b Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Thu, 9 May 2013 20:07:49 +0200 Subject: Update for django 1.4 --- aggregator/README.org | 5 - aggregator/__init__.py | 0 aggregator/feeds.py | 23 -- aggregator/management/__init__.py | 0 aggregator/management/commands/__init__.py | 0 aggregator/management/commands/loadfeeds.py | 101 -------- aggregator/migrations/0001_initial.py | 40 --- aggregator/migrations/__init__.py | 0 aggregator/models.py | 14 -- aggregator/templates/aggregator/base.html | 46 ---- aggregator/templates/aggregator/posts.html | 43 ---- aggregator/templatetags/__init__.py | 0 aggregator/templatetags/posts_extras.py | 20 -- aggregator/views.py | 22 -- local_settings.py.example | 42 ---- manage.py | 17 +- requirements.txt | 2 +- ryuslash/__init__.py | 0 ryuslash/aggregator/README.org | 5 + ryuslash/aggregator/__init__.py | 0 ryuslash/aggregator/feeds.py | 23 ++ ryuslash/aggregator/management/__init__.py | 0 .../aggregator/management/commands/__init__.py | 0 .../aggregator/management/commands/loadfeeds.py | 101 ++++++++ ryuslash/aggregator/migrations/0001_initial.py | 40 +++ ryuslash/aggregator/migrations/__init__.py | 0 ryuslash/aggregator/models.py | 14 ++ ryuslash/aggregator/templates/aggregator/base.html | 46 ++++ .../aggregator/templates/aggregator/posts.html | 43 ++++ ryuslash/aggregator/templatetags/__init__.py | 0 ryuslash/aggregator/templatetags/posts_extras.py | 20 ++ ryuslash/aggregator/views.py | 22 ++ ryuslash/local_settings.py.example | 42 ++++ ryuslash/settings.py | 106 ++++++++ ryuslash/static/favicon.png | Bin 0 -> 1128 bytes ryuslash/static/images/logos/.gitignore | 2 + ryuslash/static/logo.png | Bin 0 -> 15931 bytes ryuslash/static/main.css | 272 +++++++++++++++++++++ ryuslash/urls.py | 11 + settings.py | 105 -------- static/favicon.png | Bin 1128 -> 0 bytes static/images/logos/.gitignore | 2 - static/logo.png | Bin 15931 -> 0 bytes static/main.css | 272 --------------------- urls.py | 11 - 45 files changed, 754 insertions(+), 758 deletions(-) delete mode 100644 aggregator/README.org delete mode 100644 aggregator/__init__.py delete mode 100644 aggregator/feeds.py delete mode 100644 aggregator/management/__init__.py delete mode 100644 aggregator/management/commands/__init__.py delete mode 100644 aggregator/management/commands/loadfeeds.py delete mode 100644 aggregator/migrations/0001_initial.py delete mode 100644 aggregator/migrations/__init__.py delete mode 100644 aggregator/models.py delete mode 100644 aggregator/templates/aggregator/base.html delete mode 100644 aggregator/templates/aggregator/posts.html delete mode 100644 aggregator/templatetags/__init__.py delete mode 100644 aggregator/templatetags/posts_extras.py delete mode 100644 aggregator/views.py delete mode 100644 local_settings.py.example create mode 100644 ryuslash/__init__.py create mode 100644 ryuslash/aggregator/README.org create mode 100644 ryuslash/aggregator/__init__.py create mode 100644 ryuslash/aggregator/feeds.py create mode 100644 ryuslash/aggregator/management/__init__.py create mode 100644 ryuslash/aggregator/management/commands/__init__.py create mode 100644 ryuslash/aggregator/management/commands/loadfeeds.py create mode 100644 ryuslash/aggregator/migrations/0001_initial.py create mode 100644 ryuslash/aggregator/migrations/__init__.py create mode 100644 ryuslash/aggregator/models.py create mode 100644 ryuslash/aggregator/templates/aggregator/base.html create mode 100644 ryuslash/aggregator/templates/aggregator/posts.html create mode 100644 ryuslash/aggregator/templatetags/__init__.py create mode 100644 ryuslash/aggregator/templatetags/posts_extras.py create mode 100644 ryuslash/aggregator/views.py create mode 100644 ryuslash/local_settings.py.example create mode 100644 ryuslash/settings.py create mode 100644 ryuslash/static/favicon.png create mode 100644 ryuslash/static/images/logos/.gitignore create mode 100644 ryuslash/static/logo.png create mode 100644 ryuslash/static/main.css create mode 100644 ryuslash/urls.py delete mode 100644 settings.py delete mode 100644 static/favicon.png delete mode 100644 static/images/logos/.gitignore delete mode 100644 static/logo.png delete mode 100644 static/main.css delete mode 100644 urls.py diff --git a/aggregator/README.org b/aggregator/README.org deleted file mode 100644 index 1bca9e7..0000000 --- a/aggregator/README.org +++ /dev/null @@ -1,5 +0,0 @@ -* aggregator - - A simple django app that collects posts from specified feeds. It - keeps track of which was last updated when and copies the data to - its own tables. diff --git a/aggregator/__init__.py b/aggregator/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/aggregator/feeds.py b/aggregator/feeds.py deleted file mode 100644 index 75e5d4f..0000000 --- a/aggregator/feeds.py +++ /dev/null @@ -1,23 +0,0 @@ -from django.contrib.syndication.views import Feed - -from .models import Post - -class LatestPostsFeed(Feed): - title = "ryuslash's RSS feed" - link = "/" - description = "Updates by ryuslash" - - def items(self): - return Post.objects.all()[:20] - - def item_title(self, item): - return item.title - - def item_description(self, item): - return item.body - - def item_link(self, item): - return "/post/%d/" % item.pk - - def item_pubdate(self, item): - return item.updated diff --git a/aggregator/management/__init__.py b/aggregator/management/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/aggregator/management/commands/__init__.py b/aggregator/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/aggregator/management/commands/loadfeeds.py b/aggregator/management/commands/loadfeeds.py deleted file mode 100644 index f826312..0000000 --- a/aggregator/management/commands/loadfeeds.py +++ /dev/null @@ -1,101 +0,0 @@ -import feedparser -import datetime -import markdown -import re -import os -import urllib2 - -from django.core.management.base import BaseCommand - -from aggregator.models import Post -import settings - -class Command(BaseCommand): - help = "Load data from saved feeds." - - def prep_feedname(self, value): - value = re.sub('[^\w\s-]', '', value).strip().lower() - return re.sub('[-\s]+', '-', value) - - def get_ext(self, options): - if 'favicon_ext' in options.keys(): - return options['favicon_ext'] - else: - return 'ico' - - def get_logopath(self, feedname, options): - ext = self.get_ext(options) - filename = self.prep_feedname(feedname) + '.' + ext - basedir = os.path.dirname(os.path.abspath(settings.__file__)) - return os.path.join(basedir, 'static/images/logos', filename) - - def have_logo(self, feedname, options): - logopath = self.get_logopath(feedname, options) - return os.path.exists(logopath) - - def save_logo(self, feedname, options): - ext = self.get_ext(options) - url = options['base_url'] + '/favicon.' + ext - - try: - logo = urllib2.urlopen(url) - except: - return - - save = open(self.get_logopath(feedname, options), 'w') - - save.write(logo.read()) - save.close() - logo.close() - - def construct_feed_url(self, feed): - return feed['base_url'] + feed['feed_url'] - - def handle(self, *args, **kwargs): - for feedname, feedoptions in settings.FEEDS.iteritems(): - parsed = \ - feedparser.parse(self.construct_feed_url(feedoptions)) - icon = self.prep_feedname(feedname) + '.' \ - + self.get_ext(feedoptions) - newcount = 0 - - if not self.have_logo(feedname, feedoptions): - self.save_logo(feedname, feedoptions) - - for entry in parsed.entries: - if Post.objects.filter(post_id=entry.id).exists(): - continue - - dt = entry.updated_parsed \ - or entry.published_parsed - - if dt: - updated = datetime.datetime( - dt.tm_year, dt.tm_mon, dt.tm_mday, - dt.tm_hour, dt.tm_min, dt.tm_sec) - else: - updated = datetime.datetime.now() - - if 'content' in entry.keys(): - content = entry.content[0]['value'] - else: - content = entry.summary - - if feedoptions['markdown']: - content = markdown.markdown(content) - - if feedoptions.get('nl2br'): - content = re.sub('\n', '
\n', content) - - post = Post(post_id=entry.id, - title=entry.title, - category=feedoptions['category'], - link=entry.link, - updated=updated, - icon=icon, - content=content) - - post.save() - newcount += 1 - - print 'Grabbed %d new feeds from %s' % (newcount, feedname) diff --git a/aggregator/migrations/0001_initial.py b/aggregator/migrations/0001_initial.py deleted file mode 100644 index 550a389..0000000 --- a/aggregator/migrations/0001_initial.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- coding: 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 'Post' - db.create_table('aggregator_post', ( - ('post_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, primary_key=True)), - ('title', self.gf('django.db.models.fields.CharField')(max_length=500)), - ('category', self.gf('django.db.models.fields.CharField')(max_length=255)), - ('link', self.gf('django.db.models.fields.URLField')(max_length=255)), - ('updated', self.gf('django.db.models.fields.DateTimeField')()), - ('content', self.gf('django.db.models.fields.TextField')()), - ('icon', self.gf('django.db.models.fields.CharField')(max_length=255)), - )) - db.send_create_signal('aggregator', ['Post']) - - def backwards(self, orm): - # Deleting model 'Post' - db.delete_table('aggregator_post') - - models = { - 'aggregator.post': { - 'Meta': {'ordering': "['-updated']", 'object_name': 'Post'}, - 'category': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'content': ('django.db.models.fields.TextField', [], {}), - 'icon': ('django.db.models.fields.CharField', [], {'max_length': '255'}), - 'link': ('django.db.models.fields.URLField', [], {'max_length': '255'}), - 'post_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'primary_key': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'updated': ('django.db.models.fields.DateTimeField', [], {}) - } - } - - complete_apps = ['aggregator'] \ No newline at end of file diff --git a/aggregator/migrations/__init__.py b/aggregator/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/aggregator/models.py b/aggregator/models.py deleted file mode 100644 index 34fb5a3..0000000 --- a/aggregator/models.py +++ /dev/null @@ -1,14 +0,0 @@ -from django.db import models - -class Post(models.Model): - post_id = models.CharField(max_length=255, unique=True, - primary_key=True) - title = models.CharField(max_length=500) - category = models.CharField(max_length=255) - link = models.URLField(max_length=255) - updated = models.DateTimeField() - content = models.TextField() - icon = models.CharField(max_length=255) - - class Meta: - ordering = [ '-updated' ] diff --git a/aggregator/templates/aggregator/base.html b/aggregator/templates/aggregator/base.html deleted file mode 100644 index 215ec7e..0000000 --- a/aggregator/templates/aggregator/base.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - ryuslash - - - {% block head %}{% endblock %} - - - -
- ryuslash.org -

- - ryuslash - -

- - -
- -
- {% block content %}{% endblock %} - - - diff --git a/aggregator/templates/aggregator/posts.html b/aggregator/templates/aggregator/posts.html deleted file mode 100644 index b70cb0d..0000000 --- a/aggregator/templates/aggregator/posts.html +++ /dev/null @@ -1,43 +0,0 @@ -{% extends "aggregator/base.html" %} -{% load posts_extras %} - -{% block head %} - -{% endblock %} - -{% block content %} - {% for post in list.object_list %} -
- (defpost - {{ post.title|slugify|nameless|truncate:48 }} - () -
- {% autoescape off %}{{ post.content }}{% endautoescape %} -
- "{{ post.updated }}") -
- {% endfor %} - -
- {% if list.has_previous %} - - - - {% endif %} - - - {{ list.number }} / {{ list.paginator.num_pages }} - - - {% if list.has_next %} - - - - {% endif %} -
-{% endblock %} diff --git a/aggregator/templatetags/__init__.py b/aggregator/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/aggregator/templatetags/posts_extras.py b/aggregator/templatetags/posts_extras.py deleted file mode 100644 index 64718a2..0000000 --- a/aggregator/templatetags/posts_extras.py +++ /dev/null @@ -1,20 +0,0 @@ -import re - -from django import template -from django.template.defaultfilters import stringfilter - -register = template.Library() - -@stringfilter -def nameless(value): - return re.sub(r'(^|by[- ])(ryuslash|tom)[- ]?', '', value) - -@stringfilter -def truncate(value, length): - if len(value) > length: - value = value[:length-3] + '...' - - return value - -register.filter('nameless', nameless) -register.filter('truncate', truncate) diff --git a/aggregator/views.py b/aggregator/views.py deleted file mode 100644 index bb3c1b7..0000000 --- a/aggregator/views.py +++ /dev/null @@ -1,22 +0,0 @@ -from django.core.paginator import Paginator, InvalidPage, EmptyPage -from django.http import Http404 -from django.shortcuts import render - -from .models import Post - -def posts(request, cat, page=1): - category = cat or 'post' - queryset = Post.objects.filter(category=category) - paginator = Paginator(queryset, 20) - - if page == None: - page = 1 - - try: - object_list = paginator.page(page) - except (EmptyPage, InvalidPage): - raise Http404 - - return render(request, 'aggregator/posts.html', - { 'list': object_list, - 'category': category }) diff --git a/local_settings.py.example b/local_settings.py.example deleted file mode 100644 index 9247eba..0000000 --- a/local_settings.py.example +++ /dev/null @@ -1,42 +0,0 @@ -import os -import sys - -DEPLOY_PATH = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, DEPLOY_PATH) -sys.path.insert(0, "/home/ryuslash/.python/lib/python2.6/site-packages/South-0.7.3-py2.6.egg") - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - # ('Your Name', 'your_email@example.com'), -) - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': 'test.sqlite', # Or path to database file if using sqlite3. - 'USER': '', # Not used with sqlite3. - 'PASSWORD': '', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. - } -} - -# Local time zone for this installation. Choices can be found here: -# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name -# although not all choices may be available on all operating systems. -# On Unix systems, a value of None will cause Django to use the same -# timezone as the operating system. -# If running in a Windows environment this must be set to the same as your -# system time zone. -TIME_ZONE = 'Europe/Brussels' - -# Make this unique, and don't share it with anybody. -SECRET_KEY = '' - -FEEDS = {'Diaspora*': - { 'base_url': 'http://diasp.org/', - 'feed_url': 'public/someuser.atom', - 'markdown': True, - 'category': 'post' }} diff --git a/manage.py b/manage.py index 1473748..51881cf 100755 --- a/manage.py +++ b/manage.py @@ -1,14 +1,9 @@ #!/usr/bin/env python2 -from django.core.management import execute_manager -import imp -try: - imp.find_module('settings') # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__) - sys.exit(1) - -import settings +import os, sys if __name__ == "__main__": - execute_manager(settings) + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ryuslash.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/requirements.txt b/requirements.txt index a7f9cbf..fe887e2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -Django==1.3 +Django==1.4 South==0.7.4 Feedparser==5.1.1 Markdown==2.1.1 diff --git a/ryuslash/__init__.py b/ryuslash/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ryuslash/aggregator/README.org b/ryuslash/aggregator/README.org new file mode 100644 index 0000000..1bca9e7 --- /dev/null +++ b/ryuslash/aggregator/README.org @@ -0,0 +1,5 @@ +* aggregator + + A simple django app that collects posts from specified feeds. It + keeps track of which was last updated when and copies the data to + its own tables. diff --git a/ryuslash/aggregator/__init__.py b/ryuslash/aggregator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ryuslash/aggregator/feeds.py b/ryuslash/aggregator/feeds.py new file mode 100644 index 0000000..75e5d4f --- /dev/null +++ b/ryuslash/aggregator/feeds.py @@ -0,0 +1,23 @@ +from django.contrib.syndication.views import Feed + +from .models import Post + +class LatestPostsFeed(Feed): + title = "ryuslash's RSS feed" + link = "/" + description = "Updates by ryuslash" + + def items(self): + return Post.objects.all()[:20] + + def item_title(self, item): + return item.title + + def item_description(self, item): + return item.body + + def item_link(self, item): + return "/post/%d/" % item.pk + + def item_pubdate(self, item): + return item.updated diff --git a/ryuslash/aggregator/management/__init__.py b/ryuslash/aggregator/management/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ryuslash/aggregator/management/commands/__init__.py b/ryuslash/aggregator/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ryuslash/aggregator/management/commands/loadfeeds.py b/ryuslash/aggregator/management/commands/loadfeeds.py new file mode 100644 index 0000000..f826312 --- /dev/null +++ b/ryuslash/aggregator/management/commands/loadfeeds.py @@ -0,0 +1,101 @@ +import feedparser +import datetime +import markdown +import re +import os +import urllib2 + +from django.core.management.base import BaseCommand + +from aggregator.models import Post +import settings + +class Command(BaseCommand): + help = "Load data from saved feeds." + + def prep_feedname(self, value): + value = re.sub('[^\w\s-]', '', value).strip().lower() + return re.sub('[-\s]+', '-', value) + + def get_ext(self, options): + if 'favicon_ext' in options.keys(): + return options['favicon_ext'] + else: + return 'ico' + + def get_logopath(self, feedname, options): + ext = self.get_ext(options) + filename = self.prep_feedname(feedname) + '.' + ext + basedir = os.path.dirname(os.path.abspath(settings.__file__)) + return os.path.join(basedir, 'static/images/logos', filename) + + def have_logo(self, feedname, options): + logopath = self.get_logopath(feedname, options) + return os.path.exists(logopath) + + def save_logo(self, feedname, options): + ext = self.get_ext(options) + url = options['base_url'] + '/favicon.' + ext + + try: + logo = urllib2.urlopen(url) + except: + return + + save = open(self.get_logopath(feedname, options), 'w') + + save.write(logo.read()) + save.close() + logo.close() + + def construct_feed_url(self, feed): + return feed['base_url'] + feed['feed_url'] + + def handle(self, *args, **kwargs): + for feedname, feedoptions in settings.FEEDS.iteritems(): + parsed = \ + feedparser.parse(self.construct_feed_url(feedoptions)) + icon = self.prep_feedname(feedname) + '.' \ + + self.get_ext(feedoptions) + newcount = 0 + + if not self.have_logo(feedname, feedoptions): + self.save_logo(feedname, feedoptions) + + for entry in parsed.entries: + if Post.objects.filter(post_id=entry.id).exists(): + continue + + dt = entry.updated_parsed \ + or entry.published_parsed + + if dt: + updated = datetime.datetime( + dt.tm_year, dt.tm_mon, dt.tm_mday, + dt.tm_hour, dt.tm_min, dt.tm_sec) + else: + updated = datetime.datetime.now() + + if 'content' in entry.keys(): + content = entry.content[0]['value'] + else: + content = entry.summary + + if feedoptions['markdown']: + content = markdown.markdown(content) + + if feedoptions.get('nl2br'): + content = re.sub('\n', '
\n', content) + + post = Post(post_id=entry.id, + title=entry.title, + category=feedoptions['category'], + link=entry.link, + updated=updated, + icon=icon, + content=content) + + post.save() + newcount += 1 + + print 'Grabbed %d new feeds from %s' % (newcount, feedname) diff --git a/ryuslash/aggregator/migrations/0001_initial.py b/ryuslash/aggregator/migrations/0001_initial.py new file mode 100644 index 0000000..550a389 --- /dev/null +++ b/ryuslash/aggregator/migrations/0001_initial.py @@ -0,0 +1,40 @@ +# -*- coding: 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 'Post' + db.create_table('aggregator_post', ( + ('post_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, primary_key=True)), + ('title', self.gf('django.db.models.fields.CharField')(max_length=500)), + ('category', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('link', self.gf('django.db.models.fields.URLField')(max_length=255)), + ('updated', self.gf('django.db.models.fields.DateTimeField')()), + ('content', self.gf('django.db.models.fields.TextField')()), + ('icon', self.gf('django.db.models.fields.CharField')(max_length=255)), + )) + db.send_create_signal('aggregator', ['Post']) + + def backwards(self, orm): + # Deleting model 'Post' + db.delete_table('aggregator_post') + + models = { + 'aggregator.post': { + 'Meta': {'ordering': "['-updated']", 'object_name': 'Post'}, + 'category': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'icon': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'link': ('django.db.models.fields.URLField', [], {'max_length': '255'}), + 'post_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '500'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {}) + } + } + + complete_apps = ['aggregator'] \ No newline at end of file diff --git a/ryuslash/aggregator/migrations/__init__.py b/ryuslash/aggregator/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ryuslash/aggregator/models.py b/ryuslash/aggregator/models.py new file mode 100644 index 0000000..34fb5a3 --- /dev/null +++ b/ryuslash/aggregator/models.py @@ -0,0 +1,14 @@ +from django.db import models + +class Post(models.Model): + post_id = models.CharField(max_length=255, unique=True, + primary_key=True) + title = models.CharField(max_length=500) + category = models.CharField(max_length=255) + link = models.URLField(max_length=255) + updated = models.DateTimeField() + content = models.TextField() + icon = models.CharField(max_length=255) + + class Meta: + ordering = [ '-updated' ] diff --git a/ryuslash/aggregator/templates/aggregator/base.html b/ryuslash/aggregator/templates/aggregator/base.html new file mode 100644 index 0000000..215ec7e --- /dev/null +++ b/ryuslash/aggregator/templates/aggregator/base.html @@ -0,0 +1,46 @@ + + + + + + ryuslash + + + {% block head %}{% endblock %} + + + +
+ ryuslash.org +

+ + ryuslash + +

+ + +
+ +
+ {% block content %}{% endblock %} + + + diff --git a/ryuslash/aggregator/templates/aggregator/posts.html b/ryuslash/aggregator/templates/aggregator/posts.html new file mode 100644 index 0000000..b70cb0d --- /dev/null +++ b/ryuslash/aggregator/templates/aggregator/posts.html @@ -0,0 +1,43 @@ +{% extends "aggregator/base.html" %} +{% load posts_extras %} + +{% block head %} + +{% endblock %} + +{% block content %} + {% for post in list.object_list %} + + {% endfor %} + +
+ {% if list.has_previous %} + + + + {% endif %} + + + {{ list.number }} / {{ list.paginator.num_pages }} + + + {% if list.has_next %} + + + + {% endif %} +
+{% endblock %} diff --git a/ryuslash/aggregator/templatetags/__init__.py b/ryuslash/aggregator/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ryuslash/aggregator/templatetags/posts_extras.py b/ryuslash/aggregator/templatetags/posts_extras.py new file mode 100644 index 0000000..64718a2 --- /dev/null +++ b/ryuslash/aggregator/templatetags/posts_extras.py @@ -0,0 +1,20 @@ +import re + +from django import template +from django.template.defaultfilters import stringfilter + +register = template.Library() + +@stringfilter +def nameless(value): + return re.sub(r'(^|by[- ])(ryuslash|tom)[- ]?', '', value) + +@stringfilter +def truncate(value, length): + if len(value) > length: + value = value[:length-3] + '...' + + return value + +register.filter('nameless', nameless) +register.filter('truncate', truncate) diff --git a/ryuslash/aggregator/views.py b/ryuslash/aggregator/views.py new file mode 100644 index 0000000..bb3c1b7 --- /dev/null +++ b/ryuslash/aggregator/views.py @@ -0,0 +1,22 @@ +from django.core.paginator import Paginator, InvalidPage, EmptyPage +from django.http import Http404 +from django.shortcuts import render + +from .models import Post + +def posts(request, cat, page=1): + category = cat or 'post' + queryset = Post.objects.filter(category=category) + paginator = Paginator(queryset, 20) + + if page == None: + page = 1 + + try: + object_list = paginator.page(page) + except (EmptyPage, InvalidPage): + raise Http404 + + return render(request, 'aggregator/posts.html', + { 'list': object_list, + 'category': category }) diff --git a/ryuslash/local_settings.py.example b/ryuslash/local_settings.py.example new file mode 100644 index 0000000..9247eba --- /dev/null +++ b/ryuslash/local_settings.py.example @@ -0,0 +1,42 @@ +import os +import sys + +DEPLOY_PATH = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, DEPLOY_PATH) +sys.path.insert(0, "/home/ryuslash/.python/lib/python2.6/site-packages/South-0.7.3-py2.6.egg") + +DEBUG = True +TEMPLATE_DEBUG = DEBUG + +ADMINS = ( + # ('Your Name', 'your_email@example.com'), +) + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. + 'NAME': 'test.sqlite', # Or path to database file if using sqlite3. + 'USER': '', # Not used with sqlite3. + 'PASSWORD': '', # Not used with sqlite3. + 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. + 'PORT': '', # Set to empty string for default. Not used with sqlite3. + } +} + +# Local time zone for this installation. Choices can be found here: +# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name +# although not all choices may be available on all operating systems. +# On Unix systems, a value of None will cause Django to use the same +# timezone as the operating system. +# If running in a Windows environment this must be set to the same as your +# system time zone. +TIME_ZONE = 'Europe/Brussels' + +# Make this unique, and don't share it with anybody. +SECRET_KEY = '' + +FEEDS = {'Diaspora*': + { 'base_url': 'http://diasp.org/', + 'feed_url': 'public/someuser.atom', + 'markdown': True, + 'category': 'post' }} diff --git a/ryuslash/settings.py b/ryuslash/settings.py new file mode 100644 index 0000000..c5eecee --- /dev/null +++ b/ryuslash/settings.py @@ -0,0 +1,106 @@ +# Django settings for ryuslash_org project. +from local_settings import * + +MANAGERS = ADMINS + +# Language code for this installation. All choices can be found here: +# http://www.i18nguy.com/unicode/language-identifiers.html +LANGUAGE_CODE = 'en-us' + +SITE_ID = 1 + +# If you set this to False, Django will make some optimizations so as not +# to load the internationalization machinery. +USE_I18N = True + +# If you set this to False, Django will not format dates, numbers and +# calendars according to the current locale +USE_L10N = True + +# Absolute filesystem path to the directory that will hold user-uploaded files. +# Example: "/home/media/media.lawrence.com/media/" +MEDIA_ROOT = '' + +# URL that handles the media served from MEDIA_ROOT. Make sure to use a +# trailing slash. +# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" +MEDIA_URL = '' + +# Absolute path to the directory static files should be collected to. +# Don't put anything in this directory yourself; store your static files +# in apps' "static/" subdirectories and in STATICFILES_DIRS. +# Example: "/home/media/media.lawrence.com/static/" +STATIC_ROOT = '' + +# URL prefix for static files. +# Example: "http://media.lawrence.com/static/" +STATIC_URL = '/static/' + +# Additional locations of static files +STATICFILES_DIRS = [ '%s/static' % DEPLOY_PATH ] + +# List of finder classes that know how to find static files in +# various locations. +STATICFILES_FINDERS = ( + 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', +# 'django.contrib.staticfiles.finders.DefaultStorageFinder', +) + +# List of callables that know how to import templates from various sources. +TEMPLATE_LOADERS = ( + 'django.template.loaders.filesystem.Loader', + 'django.template.loaders.app_directories.Loader', +# 'django.template.loaders.eggs.Loader', +) + +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +) + +ROOT_URLCONF = 'ryuslash.urls' + +TEMPLATE_DIRS = ( + # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". + # Always use forward slashes, even on Windows. + # Don't forget to use absolute paths, not relative paths. +) + +INSTALLED_APPS = ('django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.staticfiles', + 'aggregator', + 'south') + +# A sample logging configuration. The only tangible logging +# performed by this configuration is to send an email to +# the site admins on every HTTP 500 error. +# See http://docs.djangoproject.com/en/dev/topics/logging for +# more details on how to customize your logging configuration. +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'handlers': { + 'mail_admins': { + 'level': 'ERROR', + 'filters': ['require_debug_false'], + 'class': 'django.utils.log.AdminEmailHandler' + } + }, + 'loggers': { + 'django.request': { + 'handlers': ['mail_admins'], + 'level': 'ERROR', + 'propagate': True, + }, + } +} diff --git a/ryuslash/static/favicon.png b/ryuslash/static/favicon.png new file mode 100644 index 0000000..66fc2e4 Binary files /dev/null and b/ryuslash/static/favicon.png differ diff --git a/ryuslash/static/images/logos/.gitignore b/ryuslash/static/images/logos/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/ryuslash/static/images/logos/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/ryuslash/static/logo.png b/ryuslash/static/logo.png new file mode 100644 index 0000000..a451578 Binary files /dev/null and b/ryuslash/static/logo.png differ diff --git a/ryuslash/static/main.css b/ryuslash/static/main.css new file mode 100644 index 0000000..4c8a460 --- /dev/null +++ b/ryuslash/static/main.css @@ -0,0 +1,272 @@ +* { + padding: 0; + margin: 0; + border: 0; +} + +a { + text-decoration: none; + color: orange; +} + +a:hover { + text-decoration: underline; +} + +body { + background-color: #252a2b; + color: #ffffff; + font-family: "DejaVu Sans", sans-serif; + padding-left: 10px; +} + +body > header { + float: left; + position: fixed; +} + +body > header > h1 { + font-size: 20px; +} + +body > header > h1 > a:hover { + text-decoration: none; +} + +body > header > nav > ul { + list-style-type: none; + margin-top: 5px; +} + +body > header > nav > ul > li { + margin: 0 3px; + font-weight: bold; + color: white; + border-width: 0 1px 0 1px; + border-style: solid; + border-color: #808080; +} + +body > header > nav > ul > li:hover { + background-color: #181818; + border-color: #404040; +} + +body > header > nav > ul > li.top { + border-top-width: 1px; + border-radius: 4px 4px 0 0; +} + +body > header > nav > ul > li.bottom { + border-bottom-width: 1px; + border-radius: 0 0 4px 4px; +} + +body > header > nav > ul > li > a { + padding: 3px 6px 3px 6px; + display: block; +} + +body > header > nav > ul > li > a:hover { + text-decoration: none; + color: orangered; +} + +pre { + margin: 20px 0 20px 40px; + font-family: "DejaVu Sans Mono", mono; + background-color: #181818; + border-radius: 10px; + padding: 5px; + color: #eeeeec; +} + +code { + font-family: "DejaVu Sans Mono", mono; + background-color: #181818; + padding: 1px 3px; + border-radius: 5px; + margin: 0 2px; + color: #eeeeec; +} + +article ul { + margin-left: 20px; +} + +article img { + vertical-align: middle; +} + +#logo-blue { + color: orangered; + position: relative; + top: -10px; +} + +p { + margin-bottom: 20px; +} + +#logo-orange { + color: orange; +} + +.keyword { + font-weight: bold; + color: #799fcf; +} + +.variable-name { + color: #ef2929; +} + +.string { + color: #ad7fa8; + margin-left: 25px; +} + +.post { + margin-bottom: 20px; +} + +.doc { + color: #babdb6; + margin-left: 25px; +} + +.doc a { + text-decoration: none; + color: #73d216; +} + +.doc a:hover { + text-decoration: underline; +} + +.doc p:last-child { + display: inline; +} + +.content { + width: 750px; + margin: 10px auto; +} + + +/* .category { */ +/* display: block; */ +/* float: right; */ +/* padding: 0 5px; */ +/* border-left: 1px #202020 solid; */ +/* margin-left: 5px; */ +/* } */ + +/* .category:hover { */ +/* border-left: 1px #ffffff solid; */ +/* background-color: #dddddd; */ +/* color: #404040; */ +/* text-decoration: none; */ +/* } */ + +/* .clear { */ +/* clear: both; */ +/* } */ + +/* .post { */ +/* margin-left: 20px; */ +/* } */ + +/* .post, */ +/* .post header, */ +/* .post header h1, */ +/* .post .postcontent { */ +/* display: inline */ +/* } */ + +/* .wordpress pre.src { */ +/* background-color: #002b36; */ +/* color: #839496; */ +/* font-family: "DejaVu Sans Mono", mono; */ +/* } */ + +/* #logo { */ +/* float: left; */ +/* } */ + +/* #sitetitle { */ +/* background-color: #000000; */ +/* color: #ffffff; */ +/* height: 70px; */ +/* line-height: 70px; */ +/* } */ + +/* #sitetitle #blue { */ +/* color: #4169E1; */ +/* position: relative; */ +/* top: -5px; */ +/* } */ + +/* #sitetitle #orange { */ +/* color: #ff9800; */ +/* position: relative; */ +/* top: 5px; */ +/* } */ + +/* #sitesubtitle { */ +/* background-color: #404040; */ +/* color: #dddddd; */ +/* text-align: right; */ +/* height: 30px; */ +/* line-height: 30px; */ +/* border-top: 1px #808080 solid; */ +/* font-size: 16px; */ +/* } */ + +/* #content { */ +/* width: 750px; */ +/* margin: 0 auto; */ +/* color: #ffffff; */ +/* margin-top: 2px; */ +/* } */ + +/* #content h2 { */ +/* margin-bottom: 5px; */ +/* } */ + +/* #feeds { */ +/* float: right; */ +/* background-color: #404040; */ +/* } */ + +/* #feeds a { */ +/* color: #dddddd; */ +/* display: block; */ +/* padding: 5px; */ +/* text-decoration: none; */ +/* } */ + +/* #feeds a:hover { */ +/* background-color: #dddddd; */ +/* color: #404040; */ +/* } */ + +/* #pager { */ +/* background-color: #808080; */ +/* color: #000000; */ +/* padding: 0 5px; */ +/* position: relative; */ +/* } */ + +/* #pager .nav-prev { */ +/* float: left; */ +/* } */ + +/* #pager .nav-next { */ +/* float: right; */ +/* text-align: right; */ +/* } */ + +/* #pager #current { */ +/* text-align: center; */ +/* } */ diff --git a/ryuslash/urls.py b/ryuslash/urls.py new file mode 100644 index 0000000..917f2e9 --- /dev/null +++ b/ryuslash/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls import patterns, url +from django.contrib.staticfiles.urls import staticfiles_urlpatterns + +from aggregator.feeds import LatestPostsFeed + +urlpatterns = patterns('', + url(r'^((?P[a-z_-]+)/)?((?P\d+)/)?$', + 'aggregator.views.posts'), + url(r'^feed/posts/$', LatestPostsFeed())) + +urlpatterns += staticfiles_urlpatterns() diff --git a/settings.py b/settings.py deleted file mode 100644 index 75de1a9..0000000 --- a/settings.py +++ /dev/null @@ -1,105 +0,0 @@ -# Django settings for ryuslash_org project. -from local_settings import * - -MANAGERS = ADMINS - -# Language code for this installation. All choices can be found here: -# http://www.i18nguy.com/unicode/language-identifiers.html -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# If you set this to False, Django will make some optimizations so as not -# to load the internationalization machinery. -USE_I18N = True - -# If you set this to False, Django will not format dates, numbers and -# calendars according to the current locale -USE_L10N = True - -# Absolute filesystem path to the directory that will hold user-uploaded files. -# Example: "/home/media/media.lawrence.com/media/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. Make sure to use a -# trailing slash. -# Examples: "http://media.lawrence.com/media/", "http://example.com/media/" -MEDIA_URL = '' - -# Absolute path to the directory static files should be collected to. -# Don't put anything in this directory yourself; store your static files -# in apps' "static/" subdirectories and in STATICFILES_DIRS. -# Example: "/home/media/media.lawrence.com/static/" -STATIC_ROOT = '' - -# URL prefix for static files. -# Example: "http://media.lawrence.com/static/" -STATIC_URL = '/static/' - -# URL prefix for admin static files -- CSS, JavaScript and images. -# Make sure to use a trailing slash. -# Examples: "http://foo.com/static/admin/", "/static/admin/". -ADMIN_MEDIA_PREFIX = '/static/admin/' - -# Additional locations of static files -STATICFILES_DIRS = [ '%s/static' % DEPLOY_PATH ] - -# List of finder classes that know how to find static files in -# various locations. -STATICFILES_FINDERS = ( - 'django.contrib.staticfiles.finders.FileSystemFinder', - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', -) - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader', -# 'django.template.loaders.eggs.Loader', -) - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', -) - -ROOT_URLCONF = 'ryuslash_org.urls' - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". - # Always use forward slashes, even on Windows. - # Don't forget to use absolute paths, not relative paths. -) - -INSTALLED_APPS = ('django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.staticfiles', - 'aggregator', - 'south') - -# A sample logging configuration. The only tangible logging -# performed by this configuration is to send an email to -# the site admins on every HTTP 500 error. -# See http://docs.djangoproject.com/en/dev/topics/logging for -# more details on how to customize your logging configuration. -LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, - 'handlers': { - 'mail_admins': { - 'level': 'ERROR', - 'class': 'django.utils.log.AdminEmailHandler' - } - }, - 'loggers': { - 'django.request': { - 'handlers': ['mail_admins'], - 'level': 'ERROR', - 'propagate': True, - }, - } -} diff --git a/static/favicon.png b/static/favicon.png deleted file mode 100644 index 66fc2e4..0000000 Binary files a/static/favicon.png and /dev/null differ diff --git a/static/images/logos/.gitignore b/static/images/logos/.gitignore deleted file mode 100644 index d6b7ef3..0000000 --- a/static/images/logos/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/static/logo.png b/static/logo.png deleted file mode 100644 index a451578..0000000 Binary files a/static/logo.png and /dev/null differ diff --git a/static/main.css b/static/main.css deleted file mode 100644 index 4c8a460..0000000 --- a/static/main.css +++ /dev/null @@ -1,272 +0,0 @@ -* { - padding: 0; - margin: 0; - border: 0; -} - -a { - text-decoration: none; - color: orange; -} - -a:hover { - text-decoration: underline; -} - -body { - background-color: #252a2b; - color: #ffffff; - font-family: "DejaVu Sans", sans-serif; - padding-left: 10px; -} - -body > header { - float: left; - position: fixed; -} - -body > header > h1 { - font-size: 20px; -} - -body > header > h1 > a:hover { - text-decoration: none; -} - -body > header > nav > ul { - list-style-type: none; - margin-top: 5px; -} - -body > header > nav > ul > li { - margin: 0 3px; - font-weight: bold; - color: white; - border-width: 0 1px 0 1px; - border-style: solid; - border-color: #808080; -} - -body > header > nav > ul > li:hover { - background-color: #181818; - border-color: #404040; -} - -body > header > nav > ul > li.top { - border-top-width: 1px; - border-radius: 4px 4px 0 0; -} - -body > header > nav > ul > li.bottom { - border-bottom-width: 1px; - border-radius: 0 0 4px 4px; -} - -body > header > nav > ul > li > a { - padding: 3px 6px 3px 6px; - display: block; -} - -body > header > nav > ul > li > a:hover { - text-decoration: none; - color: orangered; -} - -pre { - margin: 20px 0 20px 40px; - font-family: "DejaVu Sans Mono", mono; - background-color: #181818; - border-radius: 10px; - padding: 5px; - color: #eeeeec; -} - -code { - font-family: "DejaVu Sans Mono", mono; - background-color: #181818; - padding: 1px 3px; - border-radius: 5px; - margin: 0 2px; - color: #eeeeec; -} - -article ul { - margin-left: 20px; -} - -article img { - vertical-align: middle; -} - -#logo-blue { - color: orangered; - position: relative; - top: -10px; -} - -p { - margin-bottom: 20px; -} - -#logo-orange { - color: orange; -} - -.keyword { - font-weight: bold; - color: #799fcf; -} - -.variable-name { - color: #ef2929; -} - -.string { - color: #ad7fa8; - margin-left: 25px; -} - -.post { - margin-bottom: 20px; -} - -.doc { - color: #babdb6; - margin-left: 25px; -} - -.doc a { - text-decoration: none; - color: #73d216; -} - -.doc a:hover { - text-decoration: underline; -} - -.doc p:last-child { - display: inline; -} - -.content { - width: 750px; - margin: 10px auto; -} - - -/* .category { */ -/* display: block; */ -/* float: right; */ -/* padding: 0 5px; */ -/* border-left: 1px #202020 solid; */ -/* margin-left: 5px; */ -/* } */ - -/* .category:hover { */ -/* border-left: 1px #ffffff solid; */ -/* background-color: #dddddd; */ -/* color: #404040; */ -/* text-decoration: none; */ -/* } */ - -/* .clear { */ -/* clear: both; */ -/* } */ - -/* .post { */ -/* margin-left: 20px; */ -/* } */ - -/* .post, */ -/* .post header, */ -/* .post header h1, */ -/* .post .postcontent { */ -/* display: inline */ -/* } */ - -/* .wordpress pre.src { */ -/* background-color: #002b36; */ -/* color: #839496; */ -/* font-family: "DejaVu Sans Mono", mono; */ -/* } */ - -/* #logo { */ -/* float: left; */ -/* } */ - -/* #sitetitle { */ -/* background-color: #000000; */ -/* color: #ffffff; */ -/* height: 70px; */ -/* line-height: 70px; */ -/* } */ - -/* #sitetitle #blue { */ -/* color: #4169E1; */ -/* position: relative; */ -/* top: -5px; */ -/* } */ - -/* #sitetitle #orange { */ -/* color: #ff9800; */ -/* position: relative; */ -/* top: 5px; */ -/* } */ - -/* #sitesubtitle { */ -/* background-color: #404040; */ -/* color: #dddddd; */ -/* text-align: right; */ -/* height: 30px; */ -/* line-height: 30px; */ -/* border-top: 1px #808080 solid; */ -/* font-size: 16px; */ -/* } */ - -/* #content { */ -/* width: 750px; */ -/* margin: 0 auto; */ -/* color: #ffffff; */ -/* margin-top: 2px; */ -/* } */ - -/* #content h2 { */ -/* margin-bottom: 5px; */ -/* } */ - -/* #feeds { */ -/* float: right; */ -/* background-color: #404040; */ -/* } */ - -/* #feeds a { */ -/* color: #dddddd; */ -/* display: block; */ -/* padding: 5px; */ -/* text-decoration: none; */ -/* } */ - -/* #feeds a:hover { */ -/* background-color: #dddddd; */ -/* color: #404040; */ -/* } */ - -/* #pager { */ -/* background-color: #808080; */ -/* color: #000000; */ -/* padding: 0 5px; */ -/* position: relative; */ -/* } */ - -/* #pager .nav-prev { */ -/* float: left; */ -/* } */ - -/* #pager .nav-next { */ -/* float: right; */ -/* text-align: right; */ -/* } */ - -/* #pager #current { */ -/* text-align: center; */ -/* } */ diff --git a/urls.py b/urls.py deleted file mode 100644 index d23c303..0000000 --- a/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.conf.urls.defaults import patterns, url -from django.contrib.staticfiles.urls import staticfiles_urlpatterns - -from aggregator.feeds import LatestPostsFeed - -urlpatterns = patterns('', - url(r'^((?P[a-z_-]+)/)?((?P\d+)/)?$', - 'aggregator.views.posts'), - url(r'^feed/posts/$', LatestPostsFeed())) - -urlpatterns += staticfiles_urlpatterns() -- cgit v1.2.3-54-g00ecf