mirror of
https://github.com/viq/NewsBlur.git
synced 2025-04-13 09:38:09 +00:00
Adding categories. Still needs subscription to categories being added to a user's subscription folders.
This commit is contained in:
parent
8b0ecf5535
commit
8820b9a62c
9 changed files with 146 additions and 1 deletions
0
apps/categories/__init__.py
Normal file
0
apps/categories/__init__.py
Normal file
80
apps/categories/models.py
Normal file
80
apps/categories/models.py
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
import mongoengine as mongo
|
||||||
|
from apps.rss_feeds.models import Feed
|
||||||
|
from itertools import groupby
|
||||||
|
|
||||||
|
class MCategory(mongo.Document):
|
||||||
|
title = mongo.StringField()
|
||||||
|
description = mongo.StringField()
|
||||||
|
feed_ids = mongo.ListField(mongo.IntField())
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
'collection': 'category',
|
||||||
|
'indexes': ['title'],
|
||||||
|
'allow_inheritance': False,
|
||||||
|
'index_drop_dups': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return "%s: %s sites" % (self.title, len(self.feed_ids))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def serialize(cls, category=None):
|
||||||
|
categories = cls.objects.all()
|
||||||
|
if category:
|
||||||
|
categories = categories.filter(title=category)
|
||||||
|
|
||||||
|
data = dict(categories=[], feeds={})
|
||||||
|
feed_ids = set()
|
||||||
|
for category in categories:
|
||||||
|
category_output = {
|
||||||
|
'title': category.title,
|
||||||
|
'description': category.description,
|
||||||
|
'feed_ids': category.feed_ids,
|
||||||
|
}
|
||||||
|
data['categories'].append(category_output)
|
||||||
|
feed_ids.update(list(category.feed_ids))
|
||||||
|
|
||||||
|
feeds = Feed.objects.filter(pk__in=feed_ids)
|
||||||
|
for feed in feeds:
|
||||||
|
data['feeds'][feed.pk] = feed.canonical()
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def reload_sites(cls, category_title=None):
|
||||||
|
category_sites = MCategorySite.objects.all()
|
||||||
|
if category_title:
|
||||||
|
category_sites = category_sites.filter(category_title=category_title)
|
||||||
|
|
||||||
|
category_groups = groupby(sorted(category_sites, key=lambda c: c.category_title), key=lambda c: c.category_title)
|
||||||
|
for category_title, sites in category_groups:
|
||||||
|
category = cls.objects.get(title=category_title)
|
||||||
|
category.feed_ids = [site.feed_id for site in sites]
|
||||||
|
category.save()
|
||||||
|
print " ---> Reloaded category: %s" % category
|
||||||
|
|
||||||
|
|
||||||
|
class MCategorySite(mongo.Document):
|
||||||
|
feed_id = mongo.IntField()
|
||||||
|
category_title = mongo.StringField()
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
'collection': 'category_site',
|
||||||
|
'indexes': ['feed_id', 'category_title'],
|
||||||
|
'allow_inheritance': False,
|
||||||
|
'index_drop_dups': True,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
feed = Feed.objects.get(pk=self.feed_id)
|
||||||
|
return "%s: %s" % (self.category_title, feed)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add(cls, category_title, feed_id):
|
||||||
|
category_site, created = cls.objects.get_or_create(category_title=category_title,
|
||||||
|
feed_id=feed_id)
|
||||||
|
|
||||||
|
if not created:
|
||||||
|
print " ---> Site is already in category: %s" % category_site
|
||||||
|
else:
|
||||||
|
MCategory.reload_sites(category_title)
|
16
apps/categories/tests.py
Normal file
16
apps/categories/tests.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
"""
|
||||||
|
This file demonstrates writing tests using the unittest module. These will pass
|
||||||
|
when you run "manage.py test".
|
||||||
|
|
||||||
|
Replace this 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.assertEqual(1 + 1, 2)
|
7
apps/categories/urls.py
Normal file
7
apps/categories/urls.py
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
from django.conf.urls.defaults import url, patterns
|
||||||
|
from apps.categories import views
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^/?$', views.all_categories, name='all-categories'),
|
||||||
|
url(r'^subscribe/?$', views.subscribe, name='categories-subscribe'),
|
||||||
|
)
|
29
apps/categories/views.py
Normal file
29
apps/categories/views.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
from apps.categories.models import MCategory
|
||||||
|
from utils import json_functions as json
|
||||||
|
from utils.user_functions import ajax_login_required
|
||||||
|
|
||||||
|
@json.json_view
|
||||||
|
def all_categories(request):
|
||||||
|
categories = MCategory.serialize()
|
||||||
|
|
||||||
|
return categories
|
||||||
|
|
||||||
|
@ajax_login_required
|
||||||
|
@json.json_view
|
||||||
|
def subscribe(request):
|
||||||
|
user = request.user
|
||||||
|
categories = MCategory.serialize()
|
||||||
|
category_titles = [c['title'] for c in categories['categories']]
|
||||||
|
subscribe_category_titles = request.POST.getlist('category')
|
||||||
|
|
||||||
|
invalid_category_title = False
|
||||||
|
for category_title in subscribe_category_titles:
|
||||||
|
if category_title not in category_titles:
|
||||||
|
invalid_category_title = True
|
||||||
|
|
||||||
|
if not subscribe_category_titles or invalid_category_title:
|
||||||
|
message = "Choose one or more of these categories: %s" % ', '.join(category_titles)
|
||||||
|
return dict(code=-1, message=message)
|
||||||
|
|
||||||
|
for category_title in categories:
|
||||||
|
pass
|
|
@ -34,6 +34,7 @@ except:
|
||||||
pass
|
pass
|
||||||
from apps.social.models import MSharedStory, MSocialProfile, MSocialServices
|
from apps.social.models import MSharedStory, MSocialProfile, MSocialServices
|
||||||
from apps.social.models import MSocialSubscription, MActivity
|
from apps.social.models import MSocialSubscription, MActivity
|
||||||
|
from apps.categories.models import MCategory
|
||||||
from apps.social.views import load_social_page
|
from apps.social.views import load_social_page
|
||||||
from utils import json_functions as json
|
from utils import json_functions as json
|
||||||
from utils.user_functions import get_user, ajax_login_required
|
from utils.user_functions import get_user, ajax_login_required
|
||||||
|
@ -234,6 +235,10 @@ def load_feeds(request):
|
||||||
user.profile.dashboard_date = datetime.datetime.now()
|
user.profile.dashboard_date = datetime.datetime.now()
|
||||||
user.profile.save()
|
user.profile.save()
|
||||||
|
|
||||||
|
categories = None
|
||||||
|
if not user_subs:
|
||||||
|
categories = MCategory.serialize()
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'feeds': feeds.values() if version == 2 else feeds,
|
'feeds': feeds.values() if version == 2 else feeds,
|
||||||
'social_feeds': social_feeds,
|
'social_feeds': social_feeds,
|
||||||
|
@ -241,6 +246,7 @@ def load_feeds(request):
|
||||||
'social_services': social_services,
|
'social_services': social_services,
|
||||||
'folders': json.decode(folders.folders),
|
'folders': json.decode(folders.folders),
|
||||||
'starred_count': starred_count,
|
'starred_count': starred_count,
|
||||||
|
'categories': categories
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -317,6 +323,10 @@ def load_feeds_flat(request):
|
||||||
social_feeds = MSocialSubscription.feeds(**social_params)
|
social_feeds = MSocialSubscription.feeds(**social_params)
|
||||||
social_profile = MSocialProfile.profile(user.pk)
|
social_profile = MSocialProfile.profile(user.pk)
|
||||||
|
|
||||||
|
categories = None
|
||||||
|
if not user_subs:
|
||||||
|
categories = MCategory.serialize()
|
||||||
|
|
||||||
logging.user(request, "~FBLoading ~SB%s~SN/~SB%s~SN feeds/socials ~FMflat~FB. %s" % (
|
logging.user(request, "~FBLoading ~SB%s~SN/~SB%s~SN feeds/socials ~FMflat~FB. %s" % (
|
||||||
len(feeds.keys()), len(social_feeds), '~SBUpdating counts.' if update_counts else ''))
|
len(feeds.keys()), len(social_feeds), '~SBUpdating counts.' if update_counts else ''))
|
||||||
|
|
||||||
|
@ -328,6 +338,7 @@ def load_feeds_flat(request):
|
||||||
"user": user.username,
|
"user": user.username,
|
||||||
"user_profile": user.profile,
|
"user_profile": user.profile,
|
||||||
"iphone_version": iphone_version,
|
"iphone_version": iphone_version,
|
||||||
|
"categories": categories,
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
|
@ -672,7 +672,7 @@ _.extend(NEWSBLUR.ReaderIntro.prototype, {
|
||||||
self.handle_opml_upload();
|
self.handle_opml_upload();
|
||||||
});
|
});
|
||||||
$.targetIs(e, { tagSelector: '.NB-friends-autofollow-checkbox' }, function($t, $p) {
|
$.targetIs(e, { tagSelector: '.NB-friends-autofollow-checkbox' }, function($t, $p) {
|
||||||
self.model.preference('autofollow_friends', $t.is(':checked'));
|
NEWSBLUR.assets.preference('autofollow_friends', $t.is(':checked'));
|
||||||
});
|
});
|
||||||
$.targetIs(e, { tagSelector: '#NB-intro-uptodate-follow-newsblur' }, function($t, $p) {
|
$.targetIs(e, { tagSelector: '#NB-intro-uptodate-follow-newsblur' }, function($t, $p) {
|
||||||
self.follow_twitter_account('newsblur');
|
self.follow_twitter_account('newsblur');
|
||||||
|
|
|
@ -229,6 +229,7 @@ INSTALLED_APPS = (
|
||||||
'apps.push',
|
'apps.push',
|
||||||
'apps.social',
|
'apps.social',
|
||||||
'apps.oauth',
|
'apps.oauth',
|
||||||
|
'apps.categories',
|
||||||
'south',
|
'south',
|
||||||
'utils',
|
'utils',
|
||||||
'vendor',
|
'vendor',
|
||||||
|
|
1
urls.py
1
urls.py
|
@ -26,6 +26,7 @@ urlpatterns = patterns('',
|
||||||
(r'^mobile/', include('apps.mobile.urls')),
|
(r'^mobile/', include('apps.mobile.urls')),
|
||||||
(r'^m/', include('apps.mobile.urls')),
|
(r'^m/', include('apps.mobile.urls')),
|
||||||
(r'^push/', include('apps.push.urls')),
|
(r'^push/', include('apps.push.urls')),
|
||||||
|
(r'^categories/', include('apps.categories.urls')),
|
||||||
url(r'^about/?', static_views.about, name='about'),
|
url(r'^about/?', static_views.about, name='about'),
|
||||||
url(r'^faq/?', static_views.faq, name='faq'),
|
url(r'^faq/?', static_views.faq, name='faq'),
|
||||||
url(r'^api/?', static_views.api, name='api'),
|
url(r'^api/?', static_views.api, name='api'),
|
||||||
|
|
Loading…
Add table
Reference in a new issue