Commits

Dan Carroll committed bf1fd30

Remove internal activitysync app, switch to use the new external django-activitysync package

  • Participants
  • Parent commits 65a56b5

Comments (0)

Files changed (43)

File mysite/activitysync/__init__.py

Empty file removed.

File mysite/activitysync/admin.py

-# Activity admin page
-from activitysync.models import Provider, Activity
-from django.contrib import admin
-
-admin.site.register(Provider)
-
-class ActivityAdmin(admin.ModelAdmin):
-    list_display = ('title', 'provider', 'published', 'link', 'pub_date')
-    list_filter = ['pub_date', 'provider', 'username', 'published']
-    search_fields = ['title', 'comments']
-    date_hierarchy = 'pub_date'
-
-admin.site.register(Activity, ActivityAdmin)
-

File mysite/activitysync/management/__init__.py

Empty file removed.

File mysite/activitysync/management/commands/__init__.py

Empty file removed.

File mysite/activitysync/management/commands/updateactivities.py

-from django.conf import settings
-from django.core import exceptions
-from django.core.management.base import BaseCommand, CommandError
-from django.core.management.color import no_style
-from django.core.mail import mail_admins
-from optparse import make_option
-from activitysync.models import Provider, Activity
-from activitysync.providers import ActivityProvider, ActivityInfo
-
-import os
-import sys
-import time
-import datetime
-import feedparser
-import twitter
-
-class Command(BaseCommand):
-    option_list = BaseCommand.option_list + (
-        make_option('--send-result', '-s', default=False, action='store_true', dest='sendmail',
-            help='Send email with new activities to site admins'),
-        make_option('--dry-run', '-d', default=False, action='store_true', dest='dryrun',
-            help='Gather activities, but do not create items in database'),
-    )
-    help = "Update activities by depositing them into the blog database."
-
-    def handle(self, *args, **options): 
-        self.style = no_style()
-        if len(args) != 0:
-            raise CommandError("Command does not accept any arguments")
-
-        send_email = options.get('sendmail')
-        dry_run = options.get('dryrun')
-
-        email_status_info = []
-        items_added = False
-        try:
-            # Go through provider list
-            provider_list = getattr(settings, 'ACTIVITYSYNC_PROVIDERS', [])
-            for provider_path in provider_list:
-                try:
-                    dot = provider_path.rindex('.')
-                except ValueError:
-                    raise exceptions.ImproperlyConfigured('%s is not an activity provider' % provider_path)
-                provider_module, provider_classname = provider_path[:dot], provider_path[dot+1:]
-                try:
-                    mod = __import__(provider_module, {}, {}, [''])
-                except ImportError, e:
-                    raise exceptions.ImproperlyConfigured('Error importing provider %s: %s' % (provider_module, e))
-                try:
-                    provider_class = getattr(mod, provider_classname)
-                except AttributeError:
-                    raise exceptions.ImproperlyConfigured('Provider module "%s" does not define a "%s" class' % (provider_module, provider_classname))
-
-                provider_instance = provider_class()
-                email_status_info.append('\n\n%s\n\n' % provider_instance.name())
-
-                # Create Provider model object if it does not exist
-                try:
-                    providerModelObject = Provider.objects.get(sourceid=provider_instance.sourceid())
-                except Provider.DoesNotExist:
-                    print 'First time seeing provider with sourceid: %s' % provider_instance.sourceid()
-                    providerModelObject = Provider.objects.create(
-                        name=provider_instance.name(),
-                        prefix=provider_instance.prefix(),
-                        link=provider_instance.link(),
-                        sourceid=provider_instance.sourceid()
-                    )
-
-                for activity_item in provider_instance.get_activity():
-                    try:
-                        Activity.objects.get(guid=activity_item.guid)
-                    except Activity.DoesNotExist:
-                        print "Created item: %s (%s)" % (activity_item.title, activity_item.link)
-                        email_status_info.append("Created item: %s (%s)\n" % (activity_item.title, activity_item.link))
-                        items_added = True
-                        
-                        if dry_run:
-                            print 'Dry run, not creating item'
-                        else:
-                            Activity.objects.create(title=activity_item.title, link=activity_item.link, username=activity_item.username, author=activity_item.author, comments=activity_item.comments, pub_date=activity_item.pub_date, published=activity_item.published, guid=activity_item.guid, provider=providerModelObject)
-
-        except:
-            ### DEBUGGING CODE
-            raise
-            ### END DEBUGGING
-            items_added = True
-            print "Unexpected error:", sys.exc_info()[0]
-            email_status_info.append("Unexpected error: %s\n\n" % sys.exc_info()[0])    
-        finally:
-            if items_added:
-                mailBody = u""
-                for itemString in email_status_info:
-                    try:
-                        mailBody = mailBody.encode('utf-8') + itemString.encode('utf-8')
-                    except UnicodeDecodeError:
-                        mailBody = mailBody + "\n\nFAILED TO PARSE ACTIVITY\n\n"
-                if send_email:
-                    mail_admins('Update Activities command completed', mailBody, fail_silently=False)
-                    print 'Mail sent to admins'
-

File mysite/activitysync/managers.py

-from django.db.models import Manager
-import datetime
-
-class ActivityManager(Manager):
-    def get_query_set(self):
-        return super(ActivityManager, self).get_query_set().select_related('provider')
-   
-    def published(self):
-        """Returns published posts that are not in the future."""
-        return self.get_query_set().filter(published=True, pub_date__lte=datetime.datetime.now())
-

File mysite/activitysync/media/README

-Social network icons courtesy of Komodo Media
----------------------------------------------
-http://www.komodomedia.com/download/
-Social Network Icon Pack by Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License (http://creativecommons.org/licenses/by-nc-sa/3.0/)
-

File mysite/activitysync/media/networks/delicious.png

Removed
Old image

File mysite/activitysync/media/networks/digg.png

Removed
Old image

File mysite/activitysync/media/networks/email.png

Removed
Old image

File mysite/activitysync/media/networks/facebook.png

Removed
Old image

File mysite/activitysync/media/networks/flickr.png

Removed
Old image

File mysite/activitysync/media/networks/google.png

Removed
Old image

File mysite/activitysync/media/networks/googlereader.png

Removed
Old image

File mysite/activitysync/media/networks/hulu.png

Removed
Old image

File mysite/activitysync/media/networks/linkedin.png

Removed
Old image

File mysite/activitysync/media/networks/picasa.png

Removed
Old image

File mysite/activitysync/media/networks/posterous.png

Removed
Old image

File mysite/activitysync/media/networks/reddit.png

Removed
Old image

File mysite/activitysync/media/networks/rss.png

Removed
Old image

File mysite/activitysync/media/networks/tumblr.png

Removed
Old image

File mysite/activitysync/media/networks/twitter.png

Removed
Old image

File mysite/activitysync/media/networks/windowslive.png

Removed
Old image

File mysite/activitysync/media/networks/youtube.png

Removed
Old image

File mysite/activitysync/migrations/0001_initial.py

-# 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 'Activity'
-        db.create_table('activitysync_activity', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('title', self.gf('django.db.models.fields.CharField')(max_length=200)),
-            ('link', self.gf('django.db.models.fields.URLField')(max_length=500)),
-            ('source', self.gf('django.db.models.fields.CharField')(max_length=2)),
-            ('username', self.gf('django.db.models.fields.CharField')(max_length=20, blank=True)),
-            ('author', self.gf('django.db.models.fields.CharField')(max_length=20, blank=True)),
-            ('comments', self.gf('django.db.models.fields.TextField')(blank=True)),
-            ('pub_date', self.gf('django.db.models.fields.DateTimeField')()),
-            ('published', self.gf('django.db.models.fields.BooleanField')(default=True)),
-            ('guid', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255, db_index=True)),
-        ))
-        db.send_create_signal('activitysync', ['Activity'])
-
-
-    def backwards(self, orm):
-        
-        # Deleting model 'Activity'
-        db.delete_table('activitysync_activity')
-
-
-    models = {
-        'activitysync.activity': {
-            'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Activity'},
-            'author': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
-            'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'guid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'published': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'source': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'username': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['activitysync']

File mysite/activitysync/migrations/0002_auto__add_provider__add_field_activity_provider.py

-# 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 'Provider'
-        db.create_table('activitysync_provider', (
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('prefix', self.gf('django.db.models.fields.CharField')(max_length=50)),
-            ('link', self.gf('django.db.models.fields.URLField')(max_length=500)),
-            ('sourceid', self.gf('django.db.models.fields.CharField')(unique=True, max_length=20, primary_key=True, db_index=True)),
-        ))
-        db.send_create_signal('activitysync', ['Provider'])
-
-        # Adding field 'Activity.provider'
-        db.add_column('activitysync_activity', 'provider', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['activitysync.Provider'], null=True), keep_default=False)
-
-
-    def backwards(self, orm):
-        
-        # Deleting model 'Provider'
-        db.delete_table('activitysync_provider')
-
-        # Deleting field 'Activity.provider'
-        db.delete_column('activitysync_activity', 'provider_id')
-
-
-    models = {
-        'activitysync.activity': {
-            'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Activity'},
-            'author': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
-            'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'guid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'provider': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['activitysync.Provider']", 'null': 'True'}),
-            'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'published': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'source': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'username': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
-        },
-        'activitysync.provider': {
-            'Meta': {'ordering': "('name',)", 'object_name': 'Provider'},
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'prefix': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'sourceid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'primary_key': 'True', 'db_index': 'True'})
-        }
-    }
-
-    complete_apps = ['activitysync']

File mysite/activitysync/migrations/0003_convert_to_provider_objects.py

-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        for activity in orm.Activity.objects.all():
-            print "Activity: %s" % activity.title
-            provider = self.get_or_create_provider(orm, activity)
-            print "   - Has provider: %s" % provider.name
-            activity.provider = provider
-            activity.save()
-
-    def backwards(self, orm):
-        for activity in orm.Activity.objects.all():
-            provider = activity.provider
-            print 'Activity: %s' % activity.title
-            print '   - Has source: %s' % self.sourceid_to_sourcechoice(provider)
-            activity.source = self.sourceid_to_sourcechoice(provider)
-            activity.save()   
-
-    def get_or_create_provider(self, orm, activity):
-        sourceid = self.get_provider_sourceid(activity)
-
-        try:
-            provider = orm.Provider.objects.get(sourceid=sourceid)
-            return provider
-        except orm.Provider.DoesNotExist:
-            name = self.get_provider_name(activity)
-            prefix = self.get_activity_prefix(activity)
-            link = self.get_network_link(activity)
-
-            provider = orm.Provider.objects.create(name=name, prefix=prefix, link=link, sourceid=sourceid)
-            return provider
-
-    def get_provider_sourceid(self, activity):
-        if activity.source == 'T':
-            return u"twitter"
-        elif activity.source == 'DL':
-            return u"delicious"
-        elif activity.source == 'DG':
-            return u"digg"
-        elif activity.source == 'FB':
-            return u"facebook"
-        elif activity.source == 'HU':
-            return u"hulu"
-        elif activity.source == 'RD':
-            return u"reddit"
-        elif activity.source == 'GR':
-            return u"googlereader"
-
-    def get_provider_name(self, activity):
-        if activity.source == 'T':
-            return u"Twitter"
-        elif activity.source == 'DL':
-            return u"Delicious"
-        elif activity.source == 'DG':
-            return u"Digg"
-        elif activity.source == 'FB':
-            return u"Facebook"
-        elif activity.source == 'HU':
-            return u"Hulu"
-        elif activity.source == 'RD':
-            return u"Reddit"
-        elif activity.source == 'GR':
-            return u"Google Reader"
- 
-    def get_activity_prefix(self, activity):
-        if activity.source == 'DL':
-            return u'Bookmarked '
-        elif activity.source == 'DG':
-            return u'Dugg '
-        elif activity.source == 'HU':
-            return u'Watched '
-        elif activity.source == 'RD':
-            return u'Liked '
-        elif activity.source == 'GR':
-            return u'Shared '
-        else:
-            return u''
-    
-    def get_network_link(self, activity):
-        if activity.source == 'T':
-            return u"http://twitter.com/"
-        elif activity.source == 'DL':
-            return u"http://delicious.com/"
-        elif activity.source == 'DG':
-            return u"http://www.digg.com"
-        elif activity.source == 'FB':
-            return u"http://www.facebook.com/"
-        elif activity.source == 'HU':
-            return u"http://www.hulu.com/"
-        elif activity.source == 'RD':
-            return u"http://www.reddit.com/"
-        elif activity.source == 'GR':
-            return u"http://www.google.com/reader/"
-
-# HELPER METHODS FOR BACKWARDS MIGRATION
-    def sourceid_to_sourcechoice(self, provider):
-        if provider.sourceid == 'twitter':
-            return u"T"
-        elif provider.sourceid == 'delicious':
-            return u"DL"
-        elif provider.sourceid == 'digg':
-            return u"DG"
-        elif provider.sourceid == 'facebook':
-            return u"FB"
-        elif provider.sourceid == 'hulu':
-            return u"HU"
-        elif provider.sourceid == 'reddit':
-            return u"RD"
-        elif provider.sourceid == 'googlereader':
-            return u"GR"
-
-
-    models = {
-        'activitysync.activity': {
-            'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Activity'},
-            'author': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
-            'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'guid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'provider': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['activitysync.Provider']", 'null': 'True'}),
-            'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'published': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'source': ('django.db.models.fields.CharField', [], {'max_length': '2'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'username': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
-        },
-        'activitysync.provider': {
-            'Meta': {'ordering': "('name',)", 'object_name': 'Provider'},
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'prefix': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'sourceid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'primary_key': 'True', 'db_index': 'True'})
-        }
-    }
-
-    complete_apps = ['activitysync']

File mysite/activitysync/migrations/0004_auto__del_field_activity_source.py

-# 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):
-        
-        # Deleting field 'Activity.source'
-        db.delete_column('activitysync_activity', 'source')
-
-
-    def backwards(self, orm):
-        
-        # Adding field 'Activity.source'
-        db.add_column('activitysync_activity', 'source', self.gf('django.db.models.fields.CharField')(default='?', max_length=2), keep_default=False)
-
-
-    models = {
-        'activitysync.activity': {
-            'Meta': {'ordering': "('-pub_date',)", 'object_name': 'Activity'},
-            'author': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'}),
-            'comments': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'guid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255', 'db_index': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'provider': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['activitysync.Provider']", 'null': 'True'}),
-            'pub_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'published': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'username': ('django.db.models.fields.CharField', [], {'max_length': '20', 'blank': 'True'})
-        },
-        'activitysync.provider': {
-            'Meta': {'ordering': "('name',)", 'object_name': 'Provider'},
-            'link': ('django.db.models.fields.URLField', [], {'max_length': '500'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
-            'prefix': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
-            'sourceid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20', 'primary_key': 'True', 'db_index': 'True'})
-        }
-    }
-
-    complete_apps = ['activitysync']

File mysite/activitysync/migrations/__init__.py

Empty file removed.

File mysite/activitysync/models.py

-from django.db import models
-from activitysync.managers import ActivityManager
-
-class Provider(models.Model):
-    """Provider represents a particular social network"""
-    name = models.CharField(max_length=50)
-    prefix = models.CharField(max_length=50, blank=True)
-    link = models.URLField(max_length=500)
-    sourceid = models.CharField(max_length=20, primary_key=True, unique=True, db_index=True)
-
-    class Meta:
-        verbose_name = 'provider'
-        verbose_name_plural = 'providers'
-        ordering = ('name',)
-    
-    def __unicode__(self):
-        return u'%s' % self.name
-
-
-class Activity(models.Model):
-    """Activity from social network (Twitter, Flickr, etc)."""
-    
-    title = models.CharField('title', max_length=200)
-    link = models.URLField(max_length=500)
-    username = models.CharField(max_length=20, blank=True)
-    author = models.CharField(max_length=20, blank=True)
-    comments = models.TextField(blank=True)
-    pub_date = models.DateTimeField('Date published')
-    published = models.BooleanField(default=True)
-    guid = models.CharField(max_length=255, unique=True, db_index=True)
-
-    provider = models.ForeignKey(Provider, null=True)
-
-    objects = ActivityManager()
-    
-    class Meta:
-        verbose_name = 'activity'
-        verbose_name_plural = 'activities'
-        ordering = ('-pub_date',)
-        get_latest_by = 'pub_date'
-    
-    def __unicode__(self):
-        return u'%s' % self.title
-       

File mysite/activitysync/paginator.py

-from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage
-from django.core.urlresolvers import reverse
-
-# Code borrowed from django-pagination.  I ripped it out since I didn't want the
-# rest of the functionality it provided (auto-pagination).
-class InfinitePaginator(Paginator):
-    """
-    Paginator designed for cases when it's not important to know how many total
-    pages.  This is useful for any object_list that has no count() method or can
-    be used to improve performance for MySQL by removing counts.
-
-    The orphans parameter has been removed for simplicity and there's a link
-    template string for creating the links to the next and previous pages.
-    """
-
-    def __init__(self, object_list, per_page, allow_empty_first_page=True):
-        orphans = 0 # no orphans
-        super(InfinitePaginator, self).__init__(object_list, per_page, orphans,
-            allow_empty_first_page)
-        # no count or num pages
-        del self._num_pages, self._count
-
-    def validate_number(self, number):
-        """
-        Validates the given 1-based page number.
-        """
-        try:
-            number = int(number)
-        except ValueError:
-            raise PageNotAnInteger('That page number is not an integer')
-        if number < 1:
-            raise EmptyPage('That page number is less than 1')
-        return number
-
-    def page(self, number):
-        """
-        Returns a Page object for the given 1-based page number.
-        """
-        number = self.validate_number(number)
-        bottom = (number - 1) * self.per_page
-        top = bottom + self.per_page
-        page_items = self.object_list[bottom:top]
-        # check moved from validate_number
-        if not page_items:
-            if number == 1 and self.allow_empty_first_page:
-                pass
-            else:
-                raise EmptyPage('That page contains no results')
-        return InfinitePage(page_items, number, self)
-
-    def _get_count(self):
-        """
-        Returns the total number of objects, across all pages.
-        """
-        raise NotImplementedError
-    count = property(_get_count)
-
-    def _get_num_pages(self):
-        """
-        Returns the total number of pages.
-        """
-        raise NotImplementedError
-    num_pages = property(_get_num_pages)
-
-    def _get_page_range(self):
-        """
-        Returns a 1-based range of pages for iterating through within
-        a template for loop.
-        """
-        raise NotImplementedError
-    page_range = property(_get_page_range)
-
-
-class InfinitePage(Page):
-    def __init__(self, object_list, number, paginator):
-        self.object_list = object_list
-        self.number = number
-        self.paginator = paginator
-        self.cached_has_next = None
-
-    def __repr__(self):
-        return '<Page %s>' % self.number
-
-    def has_next(self):
-        """
-        Checks for one more item than last on this page.
-        """
-        if self.cached_has_next != None:
-            return self.cached_has_next
-
-        try:
-            next_item = self.paginator.object_list[
-                self.number * self.paginator.per_page]
-        except IndexError:
-            self.cached_has_next = False
-            return False
-
-        self.cached_has_next = True
-        return True
-
-    def end_index(self):
-        """
-        Returns the 1-based index of the last object on this page,
-        relative to total objects found (hits).
-        """
-        return ((self.number - 1) * self.paginator.per_page +
-            len(self.object_list))
-
-    #Bonus methods for creating links
-
-    def next_link(self):
-        if self.has_next():
-            return reverse('activity_paged', args=[self.number + 1])
-        return None
-
-    def previous_link(self):
-        if self.has_previous():
-            if self.number == 2:
-                return reverse('main_activity')
-            else:
-                return reverse('activity_paged', args=[self.number - 1])
-        return None
-
-    def page_title(self):
-        if self.number > 1:
-            return 'Page %s' % self.number
-        return None
-
-    def create_template_context(self):
-        return {
-            'object_list': self.object_list,
-            'page_title': self.page_title(),
-            'has_next': self.has_next(),
-            'has_previous': self.has_previous(),
-            'next': self.next_link(),
-            'previous': self.previous_link(),
-        }

File mysite/activitysync/providers/__init__.py

-"""Base ActivityProvider class"""
-
-class ActivityProvider(object):
-    """
-    Base class for activity providers (networks that provide social activity)
-    """
-
-    def get_activity(self):
-        """Returns a list of ActivityInfo objects representing the provider's activity"""
-        raise NotImplementedError
-
-    def name(self):
-        """Name of the network the provider connects to"""
-        raise NotImplementedError
-
-    def prefix(self):
-        """Prefix to put before activity item representing the action of the activity (i.e. "shared", "liked", etc)"""
-        raise NotImplementedError
-
-    def link(self):
-        """Link to the network or user profile page on the network"""
-        raise NotImplementedError
-
-    def sourceid(self):
-        """String representing the name or identification for the network. Used to associate items with the provider."""
-        raise NotImplementedError
-
-class ActivityInfo(object):
-    def __init__(self, title, link, pub_date, guid, username=None, author=None, comments='', published=True):
-        self.title = title
-        self.link = link
-        self.username = username
-        self.author = author
-        self.comments = comments
-        self.pub_date = pub_date
-        self.published = published
-        self.guid = guid
-

File mysite/activitysync/providers/googlereader.py

-from django.conf import settings
-from activitysync.providers import ActivityProvider, ActivityInfo
-
-import time
-import datetime
-import feedparser
-
-class GoogleReaderProvider(ActivityProvider):
-    """
-    Provider for accessing shared Google Reader items for one user.
-    """
-#class ActivityInfo(object):
-#    def __init__(self, title=None, link=None, username=None, author=None, comments=None, pub_data=None, published=True, guid=None)
-
-    def get_activity(self):
-        item_list = []
-
-        print 'Attempting to parse Google Reader feed'
-        parsed_feed = feedparser.parse(settings.GOOGLEREADER_SHARED_RSS)
-    
-        for entry in parsed_feed.entries:
-            title = entry.title.encode(parsed_feed.encoding, "xmlcharrefreplace")
-            guid = entry.get("id", entry.link).encode(parsed_feed.encoding, "xmlcharrefreplace")
-            link = entry.link.encode(parsed_feed.encoding, "xmlcharrefreplace")
-
-            shared_by = u"Dan Carroll"
-            comments =u""
-                
-            if not guid:
-                guid = link
-                    
-            try:
-                if entry.has_key('published_parsed'):
-                    date_published = datetime.datetime.fromtimestamp(time.mktime(entry.published_parsed) - time.timezone)
-                elif entry.has_key('updated_parsed'):
-                    date_published = datetime.datetime.fromtimestamp(time.mktime(entry.updated_parsed) - time.timezone)
-                elif entry.has_key('modified_parsed'):
-                    date_published = datetime.datetime.fromtimestamp(time.mktime(entry.modified_parsed) - time.timezone)
-                else:
-                    date_published = datetime.datetime.now()
-            except TypeError:
-                date_published = datetime.datetime.now()
-                        
-            if entry.has_key('content'):        
-                if len(entry.content) == 2:
-                    comments = entry.content[1].value.encode(parsed_feed.encoding, "xmlcharrefreplace")
-            
-            activity_info = ActivityInfo(title=title, link=link, pub_date=date_published, guid=guid, username=shared_by, author=shared_by, comments=comments)
-            item_list.append(activity_info)
-
-        return item_list
-
-
-    def name(self):
-        return 'Google Reader'
-
-    def prefix(self):
-        return 'Shared'
-
-    def link(self):
-        return settings.GOOGLEREADER_PUBLIC_URL
-
-    def sourceid(self):
-        return 'googlereader'
-

File mysite/activitysync/providers/redditprovider.py

-from django.conf import settings
-from activitysync.providers import ActivityProvider, ActivityInfo
-
-import time
-import datetime
-import feedparser
-
-class RedditProvider(ActivityProvider):
-    """
-    Provider for accessing liked Reddit items for one user.
-    """
-    
-    def get_activity(self):
-        item_list = []
-
-        print 'Attempting to parse Reddit feed'
-        username = settings.REDDIT_USERNAME
-        parsed_feed = feedparser.parse("http://www.reddit.com/user/%s/liked/.rss" % username)
-
-        for entry in parsed_feed.entries:
-            title = entry.title.encode(parsed_feed.encoding, "xmlcharrefreplace")
-            guid = entry.get("id", entry.link).encode(parsed_feed.encoding, "xmlcharrefreplace")
-            link = entry.link.encode(parsed_feed.encoding, "xmlcharrefreplace")
-
-            if not guid:
-                guid = link
-
-            if entry.has_key('author'):
-                author = entry.author.encode(parsed_feed.encoding, "xmlcharrefreplace")
-            else:
-                author = u''
-
-            try:
-                if entry.has_key('published_parsed'):
-                    date_published = datetime.datetime.fromtimestamp(time.mktime(entry.published_parsed) - time.timezone)
-                elif entry.has_key('updated_parsed'):
-                    date_published = datetime.datetime.fromtimestamp(time.mktime(entry.updated_parsed) - time.timezone)
-                elif entry.has_key('modified_parsed'):
-                    date_published = datetime.datetime.fromtimestamp(time.mktime(entry.modified_parsed) - time.timezone)
-                else:
-                    date_published = datetime.datetime.now()
-            except TypeError:
-                date_published = datetime.datetime.now()
-                    
-            activity_info = ActivityInfo(title=title, link=link, pub_date=date_published, guid=guid, username=username, author=author)
-            item_list.append(activity_info)
-
-        return item_list
-
-
-    def name(self):
-        return 'Reddit'
-
-    def prefix(self):
-        return 'Liked'
-
-    def link(self):
-        return 'http://www.reddit.com/user/%s/' % settings.REDDIT_USERNAME
-
-    def sourceid(self):
-        return 'reddit'
-

File mysite/activitysync/providers/twitterprovider.py

-from django.conf import settings
-from activitysync.providers import ActivityProvider, ActivityInfo
-
-import time
-import datetime
-import twitter as TwitterLibrary
-
-class TwitterProvider(ActivityProvider):
-    """
-    Provider for accessing Twitter status updates for one user.
-    """
-    
-    def get_activity(self):
-        item_list = []
-
-        print 'Attempting to obtain Twitter items'
-        api = TwitterLibrary.Api()
-        username = settings.TWITTER_USERNAME
-        statuses = api.GetUserTimeline(username, count=50)
-
-        for status in statuses:
-            title = status.text
-            guid = "twitter:%s" % status.id
-            link = "http://twitter.com/%s/statuses/%s" % (status.user.screen_name, status.id)
-            author = status.user.name
-                
-            date_published = datetime.datetime.fromtimestamp(status.created_at_in_seconds)
-                 
-            # Don't show @replies
-            if not status.in_reply_to_user_id:
-                activity_info = ActivityInfo(title=title, link=link, pub_date=date_published, guid=guid, username=username, author=author)
-                item_list.append(activity_info)
-
-        return item_list
-
-
-    def name(self):
-        return 'Twitter'
-
-    def prefix(self):
-        return ''
-
-    def link(self):
-        return 'http://twitter.com/%s' % settings.TWITTER_USERNAME
-
-    def sourceid(self):
-        return 'twitter'
-

File mysite/activitysync/templates/activitysync/activities_tag.html

-{% if not use_date_headers %}<div id="activity-list"><ul>{% endif %}
-{% for activity in activities %}
-{% if use_date_headers %}    
-    {% ifchanged activity.pub_date.date %}
-        {% if not forloop.first %}</ul></div>{% endif %}
-        <h2 class="section-title">{{ activity.pub_date|date:"F j" }}</h2>
-        <div id="activity-list"><ul>
-    {% endifchanged %}
-{% endif %}
-    <li><a href="{{ activity.provider.link }}"><img src="{{ MEDIA_URL }}networks/{{ activity.provider.sourceid }}.png" alt="{{ activity.provider.name }}" /></a>{{ activity.provider.prefix }} <a href="{{ activity.link }}">{{ activity.title }}</a> <span class="time">{{ activity.pub_date|timesince|upper }} AGO</span></li>
-    
-{% endfor %}
-</ul></div>

File mysite/activitysync/templatetags/__init__.py

Empty file removed.

File mysite/activitysync/templatetags/activitysync_extras.py

-from django import template
-from django.conf import settings
-from activitysync.models import Activity
-
-register = template.Library()
-
-@register.inclusion_tag('activitysync/activities_tag.html')
-def render_activities(activities):
-    return {
-        'activities': activities,
-        'use_date_headers': False,
-        'MEDIA_URL': settings.MEDIA_URL,
-    }
-
-@register.inclusion_tag('activitysync/activities_tag.html')
-def render_activities_with_date_headers(activities):
-    return {
-        'activities': activities,
-        'use_date_headers': True,
-        'MEDIA_URL': settings.MEDIA_URL,
-    }
-

File mysite/activitysync/tests.py

-"""
-This file demonstrates two different styles of tests (one doctest and one
-unittest). These will both pass when you run "manage.py test".
-
-Replace these with more appropriate tests for your application.
-"""
-
-from django.test import TestCase
-
-class SimpleTest(TestCase):
-    def test_basic_addition(self):
-        """
-        Tests that 1 + 1 always equals 2.
-        """
-        self.failUnlessEqual(1 + 1, 2)
-
-__test__ = {"doctest": """
-Another way to test that 1 + 1 is equal to 2.
-
->>> 1 + 1 == 2
-True
-"""}
-

File mysite/activitysync/views.py

-from django.http import Http404
-from django.shortcuts import redirect, render_to_response
-from django.template import RequestContext
-
-from activitysync.models import Activity
-from activitysync.paginator import InfinitePaginator
-
-def activity(request, page="1", explicit_page_request=False):
-    # Make sure page parameter is an integer
-    try:
-        page = int(page)
-    except:
-        raise Http404
-
-    # Make sure we only have one canonical first page
-    if explicit_page_request and page == 1:
-        return redirect('main_activity')
-
-    # Previous URL uses GET parameter 'page', so let's check
-    # for that and redirect to new view if necessary
-    if not explicit_page_request:
-        try:
-            requestNum = request.GET['page']
-            if requestNum != None and requestNum.isdigit():
-                return redirect('activity_paged', page=requestNum)
-        except KeyError:
-            pass
-    
-    activity_list = Activity.objects.published().defer("username", "author", "comments", "guid")
-    paginator = InfinitePaginator(activity_list, 25)
-    
-    try:
-        activities = paginator.page(page)
-    except:
-        raise Http404
-        
-    return render_to_response('activity.html',
-                activities.create_template_context(),
-                context_instance=RequestContext(request))

File mysite/deploy.py.template

 
 GOOGLE_ANALYTICS_CODE = ''
 
-TWITTER_USERNAME = ''
-REDDIT_USERNAME = ''
-GOOGLEREADER_SHARED_RSS = ''
-GOOGLEREADER_PUBLIC_URL = ''
+ACTIVITYSYNC_SETTINGS = {
+    'TWITTER_USERNAME': '',
+    'REDDIT_USERNAME': '',
+    'GOOGLEREADER_SHARED_RSS': '',
+    'GOOGLEREADER_PUBLIC_URL': '',
+}
 

File mysite/settings.py

 # Activity sync settings
 ACTIVITYSYNC_PROVIDERS = (
     'activitysync.providers.googlereader.GoogleReaderProvider',
-    'activitysync.providers.twitterprovider.TwitterProvider',
+    'activitysync.providers.twitterprovider.TwitterUserProvider',
     'activitysync.providers.redditprovider.RedditProvider',
 )
 
-TWITTER_USERNAME = deploy.TWITTER_USERNAME
-REDDIT_USERNAME = deploy.REDDIT_USERNAME
-GOOGLEREADER_SHARED_RSS = deploy.GOOGLEREADER_SHARED_RSS
-GOOGLEREADER_PUBLIC_URL = deploy.GOOGLEREADER_PUBLIC_URL
+ACTIVITYSYNC_SETTINGS = deploy.ACTIVITYSYNC_SETTINGS
 
 
 # Some special settings to aid development in debug mode

File requirements.txt

 Django==1.2.4
 MySQL-python==1.2.3c1
 South==0.7.3
+django-activitysync==0.2.1
 django-debug-toolbar==0.8.4
 django-disqus==0.3.4
 django-memcache-status==1.0.1