diff --git a/apps/reader/views.py b/apps/reader/views.py index 1e6d04a82..a449e0c46 100644 --- a/apps/reader/views.py +++ b/apps/reader/views.py @@ -17,6 +17,7 @@ from django.core.mail import mail_admins from collections import defaultdict from operator import itemgetter from mongoengine.queryset import OperationError +from apps.recommendations.models import RecommendedFeed, RecommendedFeedUserFeedback from apps.analyzer.models import MClassifierTitle, MClassifierAuthor, MClassifierFeed, MClassifierTag from apps.analyzer.models import apply_classifier_titles, apply_classifier_feeds, apply_classifier_authors, apply_classifier_tags from apps.analyzer.models import get_classifiers_for_user @@ -65,6 +66,9 @@ def index(request): feed_count = UserSubscription.objects.filter(user=request.user).count() active_count = UserSubscription.objects.filter(user=request.user, active=True).count() train_count = UserSubscription.objects.filter(user=request.user, active=True, is_trained=False, feed__stories_last_month__gte=1).count() + + recommended_feed = RecommendedFeed.objects.filter(is_public=True)[0] + recommended_feed_feedback = RecommendedFeedUserFeedback.objects.filter(recommendation=recommended_feed) howitworks_page = random.randint(0, 5) return render_to_response('reader/feeds.xhtml', { @@ -79,6 +83,8 @@ def index(request): 'active_count': active_count, 'train_count': active_count - train_count, 'account_images': range(1, 4), + 'recommended_feed': recommended_feed, + 'recommended_feed_feedback': recommended_feed_feedback, }, context_instance=RequestContext(request)) @never_cache diff --git a/apps/recommendations/__init__.py b/apps/recommendations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/recommendations/migrations/0001_initial.py b/apps/recommendations/migrations/0001_initial.py new file mode 100644 index 000000000..5d1e8f02a --- /dev/null +++ b/apps/recommendations/migrations/0001_initial.py @@ -0,0 +1,105 @@ +# 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 'RecommendedFeed' + db.create_table('recommendations_recommendedfeed', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('feed', self.gf('django.db.models.fields.related.ForeignKey')(related_name='recommendations', to=orm['rss_feeds.Feed'])), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='recommendations', to=orm['auth.User'])), + ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + ('is_public', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('created_date', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)), + ('approved_date', self.gf('django.db.models.fields.DateField')(null=True)), + )) + db.send_create_signal('recommendations', ['RecommendedFeed']) + + + def backwards(self, orm): + + # Deleting model 'RecommendedFeed' + db.delete_table('recommendations_recommendedfeed') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'recommendations.recommendedfeed': { + 'Meta': {'object_name': 'RecommendedFeed'}, + 'approved_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'created_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'feed': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recommendations'", 'to': "orm['rss_feeds.Feed']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recommendations'", 'to': "orm['auth.User']"}) + }, + 'rss_feeds.feed': { + 'Meta': {'ordering': "['feed_title']", 'object_name': 'Feed', 'db_table': "'feeds'"}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'active_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1', 'db_index': 'True'}), + 'average_stories_per_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'creation': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'days_to_trim': ('django.db.models.fields.IntegerField', [], {'default': '90'}), + 'etag': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'exception_code': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'feed_address': ('django.db.models.fields.URLField', [], {'unique': 'True', 'max_length': '255'}), + 'feed_link': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'feed_title': ('django.db.models.fields.CharField', [], {'default': "'[Untitled]'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'fetched_once': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'has_feed_exception': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'has_page_exception': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_load_time': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'min_to_decay': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'next_scheduled_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'num_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'premium_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'queued_date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'stories_last_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['recommendations'] diff --git a/apps/recommendations/migrations/0002_feed_feedback.py b/apps/recommendations/migrations/0002_feed_feedback.py new file mode 100644 index 000000000..1fbf96ade --- /dev/null +++ b/apps/recommendations/migrations/0002_feed_feedback.py @@ -0,0 +1,111 @@ +# 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 'RecommendedFeedUserFeedback' + db.create_table('recommendations_recommendedfeeduserfeedback', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('recommendation', self.gf('django.db.models.fields.related.ForeignKey')(related_name='feedback', to=orm['recommendations.RecommendedFeed'])), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='feed_feedback', to=orm['auth.User'])), + ('score', self.gf('django.db.models.fields.IntegerField')(default=0)), + ('created_date', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)), + )) + db.send_create_signal('recommendations', ['RecommendedFeedUserFeedback']) + + + def backwards(self, orm): + + # Deleting model 'RecommendedFeedUserFeedback' + db.delete_table('recommendations_recommendedfeeduserfeedback') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'recommendations.recommendedfeed': { + 'Meta': {'object_name': 'RecommendedFeed'}, + 'approved_date': ('django.db.models.fields.DateField', [], {'null': 'True'}), + 'created_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'feed': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recommendations'", 'to': "orm['rss_feeds.Feed']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'recommendations'", 'to': "orm['auth.User']"}) + }, + 'recommendations.recommendedfeeduserfeedback': { + 'Meta': {'object_name': 'RecommendedFeedUserFeedback'}, + 'created_date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'recommendation': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'feedback'", 'to': "orm['recommendations.RecommendedFeed']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'feed_feedback'", 'to': "orm['auth.User']"}) + }, + 'rss_feeds.feed': { + 'Meta': {'ordering': "['feed_title']", 'object_name': 'Feed', 'db_table': "'feeds'"}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'active_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1', 'db_index': 'True'}), + 'average_stories_per_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'creation': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'days_to_trim': ('django.db.models.fields.IntegerField', [], {'default': '90'}), + 'etag': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'exception_code': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'feed_address': ('django.db.models.fields.URLField', [], {'unique': 'True', 'max_length': '255'}), + 'feed_link': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'feed_title': ('django.db.models.fields.CharField', [], {'default': "'[Untitled]'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'fetched_once': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'has_feed_exception': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'has_page_exception': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_load_time': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'min_to_decay': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'next_scheduled_update': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'num_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'premium_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), + 'queued_date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}), + 'stories_last_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + } + } + + complete_apps = ['recommendations'] diff --git a/apps/recommendations/migrations/__init__.py b/apps/recommendations/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/recommendations/models.py b/apps/recommendations/models.py new file mode 100644 index 000000000..3bbc757bb --- /dev/null +++ b/apps/recommendations/models.py @@ -0,0 +1,24 @@ +from django.db import models +from django.contrib.auth.models import User +from apps.rss_feeds.models import Feed + +class RecommendedFeed(models.Model): + feed = models.ForeignKey(Feed, related_name='recommendations') + user = models.ForeignKey(User, related_name='recommendations') + description = models.TextField(null=True, blank=True) + is_public = models.BooleanField(default=False) + created_date = models.DateField(auto_now_add=True) + approved_date = models.DateField(null=True) + + def __unicode__(self): + return "%s (%s)" % (self.feed, self.approved_date or self.created_date) + + class Meta: + ordering = ['-approved_date'] + + +class RecommendedFeedUserFeedback(models.Model): + recommendation = models.ForeignKey(RecommendedFeed, related_name='feedback') + user = models.ForeignKey(User, related_name='feed_feedback') + score = models.IntegerField(default=0) + created_date = models.DateField(auto_now_add=True) \ No newline at end of file diff --git a/apps/recommendations/templatetags/__init__.py b/apps/recommendations/templatetags/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/apps/recommendations/templatetags/recommendations_tags.py b/apps/recommendations/templatetags/recommendations_tags.py new file mode 100644 index 000000000..0bdc2cb28 --- /dev/null +++ b/apps/recommendations/templatetags/recommendations_tags.py @@ -0,0 +1,10 @@ +from django import template + +register = template.Library() + +@register.inclusion_tag('recommendations/render_recommended_feed.xhtml', takes_context=True) +def render_recommended_feed(context, recommended_feed): + return { + 'recommended_feed': recommended_feed, + 'user': context['user'], + } \ No newline at end of file diff --git a/apps/recommendations/tests.py b/apps/recommendations/tests.py new file mode 100644 index 000000000..2247054b3 --- /dev/null +++ b/apps/recommendations/tests.py @@ -0,0 +1,23 @@ +""" +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 +"""} + diff --git a/apps/recommendations/views.py b/apps/recommendations/views.py new file mode 100644 index 000000000..60f00ef0e --- /dev/null +++ b/apps/recommendations/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/media/NewsBlur Helper Safari.pkg b/media/NewsBlur Helper Safari.pkg new file mode 100644 index 000000000..44b5114ba Binary files /dev/null and b/media/NewsBlur Helper Safari.pkg differ diff --git a/media/css/modals.css b/media/css/modals.css index 8c448c3ba..454493878 100644 --- a/media/css/modals.css +++ b/media/css/modals.css @@ -60,9 +60,23 @@ .NB-module h5 { margin: 0; padding: 8px 8px 6px; - background-color: #D9DDF9; - text-shadow: 0 1px 0 #F6F6F6; - border-bottom: 1px solid #A0A0A0; + background-color: #D1E1FA; + background-image: -webkit-gradient( + linear, + left bottom, + left top, + color-stop(0.16, #C5D7FB), + color-stop(0.84, #D8E1FF) + ); + background-image: -moz-linear-gradient( + center bottom, + #C5D7FB 16%, + #D8E1FF 84% + ); + + text-shadow: 1px 1px 0 #E9E9E9; + border-top: 1px solid #D1DAF7; + border-bottom: 1px solid #A1A9CF; color:#505050; font-size: 14px; font-family: "Gill Sans", inherit; diff --git a/media/css/reader.css b/media/css/reader.css index c46660e44..0e5baef2e 100644 --- a/media/css/reader.css +++ b/media/css/reader.css @@ -3114,7 +3114,7 @@ background: transparent; width: 16px; height: 16px; float: left; - padding: 2px 3px 0px; + padding: 0 3px 0px; } .NB-module .NB-module-direction.NB-disabled { @@ -3170,6 +3170,39 @@ background: transparent; /* = Main Page = */ /* ============= */ +.NB-module a { + text-decoration: none; +/* color: #3E4773;*/ +} + +.NB-module a:hover { +/* color: #0E1763;*/ +} + +#NB-splash .NB-module h5 { + margin: 0 0 12px; + padding: 8px 12px 6px; +} + +.NB-module .NB-module-header-left { + float: left; +} +.NB-module .NB-module-header-center { + text-align: center; + margin: 0 auto; + width: 132px; +} +.NB-module .NB-module-header-right { + font-size: 13px; + line-height: 16px; + font-weight: normal; + float: right; +} + +/* =========================== */ +/* = Right Modules - Account = */ +/* =========================== */ + .NB-account .NB-module { margin: 24px 0 0; padding: 0; @@ -3178,35 +3211,6 @@ background: transparent; overflow: hidden; } -.NB-account .NB-module a { - text-decoration: none; -/* color: #3E4773;*/ -} - -.NB-account .NB-module a:hover { -/* color: #0E1763;*/ -} - -.NB-account .NB-module h5 { - margin: 0 0 12px; - padding: 8px 12px 6px; -} - -.NB-account .NB-module .NB-module-header-left { - float: left; -} -.NB-account .NB-module .NB-module-header-center { - text-align: center; - margin: 0 auto; - width: 132px; -} -.NB-account .NB-module .NB-module-header-right { - font-size: 13px; - line-height: 16px; - font-weight: normal; - float: right; -} - .NB-account .NB-module .NB-module-account { position: relative; min-height: 77px; @@ -3406,6 +3410,37 @@ background: transparent; text-align: center; } +/* ================== */ +/* = Center Modules = */ +/* ================== */ + +.NB-modules-center { + margin-left: 284px; + margin-right: 478px; + padding: 24px; +} + +/* ============================ */ +/* = Module: Recommended Feed = */ +/* ============================ */ + +.NB-module-recommended { + +} + .NB-module-recommended .NB-module-recommended-date { + line-height: 14px; + float: left; + color: #8493CD; + margin: 1px 2px 0 0; + text-shadow: 0 1px 0 #E9E9E9; + } + .NB-module-recommended .NB-module-recommended-date span { + vertical-align: text-top; + margin: 0 0 0 -3px; + font-size: 8px; + color: #8487C4; + } + /* ========= */ /* = Menus = */ /* ========= */ diff --git a/settings.py b/settings.py index 89242467b..129d1f6c1 100644 --- a/settings.py +++ b/settings.py @@ -246,6 +246,7 @@ INSTALLED_APPS = ( 'apps.analyzer', 'apps.feed_import', 'apps.profile', + 'apps.recommendations', 'south', 'utils', 'utils.typogrify', diff --git a/templates/reader/feeds.xhtml b/templates/reader/feeds.xhtml index 8e3c11c61..bca5e3d5c 100644 --- a/templates/reader/feeds.xhtml +++ b/templates/reader/feeds.xhtml @@ -1,6 +1,6 @@ {% extends 'base.html' %} -{% load typogrify_tags %} +{% load typogrify_tags recommendations_tags %} {% block content %} @@ -17,6 +17,10 @@ $(document).ready(function() {
+
+ {# {% render_recommended_feed recommended_feed %} #} +
+
{% if not user.is_authenticated %} diff --git a/templates/recommendations/render_recommended_feed.xhtml b/templates/recommendations/render_recommended_feed.xhtml new file mode 100644 index 000000000..1e4574273 --- /dev/null +++ b/templates/recommendations/render_recommended_feed.xhtml @@ -0,0 +1,30 @@ + \ No newline at end of file