Complete backend for folder rss. Just needs a premium message.

This commit is contained in:
Samuel Clay 2015-08-22 19:31:24 -07:00
parent 1ad02d4b11
commit a47c402145
6 changed files with 113 additions and 8 deletions

View file

@ -13,6 +13,7 @@ from django.db.models import Count
from django.conf import settings
from django.contrib.auth.models import User
from django.core.cache import cache
from django.template.defaultfilters import slugify
from mongoengine.queryset import OperationError
from mongoengine.queryset import NotUniqueError
from apps.reader.managers import UserSubscriptionManager
@ -260,7 +261,7 @@ class UserSubscription(models.Model):
@classmethod
def feed_stories(cls, user_id, feed_ids=None, offset=0, limit=6,
order='newest', read_filter='all', usersubs=None, cutoff_date=None,
all_feed_ids=None):
all_feed_ids=None, cache_prefix=""):
rt = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_TEMP_POOL)
across_all_feeds = False
@ -277,8 +278,8 @@ class UserSubscription(models.Model):
# feeds_string = ""
feeds_string = ','.join(str(f) for f in sorted(all_feed_ids))[:30]
ranked_stories_keys = 'zU:%s:feeds:%s' % (user_id, feeds_string)
unread_ranked_stories_keys = 'zhU:%s:feeds:%s' % (user_id, feeds_string)
ranked_stories_keys = '%szU:%s:feeds:%s' % (cache_prefix, user_id, feeds_string)
unread_ranked_stories_keys = '%szhU:%s:feeds:%s' % (cache_prefix, user_id, feeds_string)
stories_cached = rt.exists(ranked_stories_keys)
unreads_cached = True if read_filter == "unread" else rt.exists(unread_ranked_stories_keys)
if offset and stories_cached and unreads_cached:
@ -1479,7 +1480,32 @@ class UserSubscriptionFolders(models.Model):
return feeds
return _flat(folders)
def feed_ids_under_folder_slug(self, slug):
folders = json.decode(self.folders)
def _feeds(folder, found=False, folder_title=None):
feeds = []
local_found = False
for item in folder:
if isinstance(item, int) and item not in feeds and found:
feeds.append(item)
elif isinstance(item, dict):
for f_k, f_v in item.items():
if slugify(f_k) == slug:
print "Found slug: ", slug, f_k, folder_title
found = True
local_found = True
folder_title = f_k
found_feeds, folder_title = _feeds(f_v, found, folder_title)
feeds.extend(found_feeds)
if local_found:
found = False
local_found = False
return feeds, folder_title
return _feeds(folders)
@classmethod
def add_all_missing_feeds(cls):
usf = cls.objects.all().order_by('pk')

View file

@ -22,6 +22,7 @@ urlpatterns = patterns('',
url(r'^read_stories', views.load_read_stories, name='load-read-stories'),
url(r'^starred_story_hashes', views.starred_story_hashes, name='starred-story-hashes'),
url(r'^starred_rss/(?P<user_id>\d+)/(?P<secret_token>\w+)/(?P<tag_slug>[-\w]+)?/?$', views.starred_stories_rss_feed, name='starred-stories-rss-feed'),
url(r'^folder_rss/(?P<user_id>\d+)/(?P<secret_token>\w+)/(?P<unread_filter>\w+)/(?P<folder_slug>[-\w]+)?/?$', views.folder_rss_feed, name='folder-rss-feed'),
url(r'^unread_story_hashes', views.unread_story_hashes, name='unread-story-hashes'),
url(r'^mark_all_as_read', views.mark_all_as_read, name='mark-all-as-read'),
url(r'^mark_story_as_read', views.mark_story_as_read, name='mark-story-as-read'),

View file

@ -943,6 +943,83 @@ def starred_stories_rss_feed(request, user_id, secret_token, tag_slug):
))
return HttpResponse(rss.writeString('utf-8'), content_type='application/rss+xml')
def folder_rss_feed(request, user_id, secret_token, unread_filter, folder_slug):
try:
user = User.objects.get(pk=user_id)
except User.DoesNotExist:
raise Http404
user_sub_folders = get_object_or_404(UserSubscriptionFolders, user=user)
feed_ids, folder_title = user_sub_folders.feed_ids_under_folder_slug(folder_slug)
usersubs = UserSubscription.subs_for_feeds(user.pk, feed_ids=feed_ids)
print feed_ids, folder_title, usersubs
if feed_ids:
params = {
"user_id": user.pk,
"feed_ids": feed_ids,
"offset": 0,
"limit": 20,
"order": 'newest',
"read_filter": 'all',
"cache_prefix": "RSS:"
}
story_hashes, unread_feed_story_hashes = UserSubscription.feed_stories(**params)
else:
story_hashes = []
unread_feed_story_hashes = []
stories = MStory.objects(story_hash__in=story_hashes).order_by('-story_date')
data = {}
data['title'] = "%s from %s (%s sites)" % (folder_title, user.username, len(feed_ids))
data['link'] = "%s%s" % (
settings.NEWSBLUR_URL,
reverse('folder', kwargs=dict(folder_name=folder_title)))
data['description'] = "Unread stories in %s on NewsBlur. From %s's account and contains %s sites." % (
folder_title,
user.username,
len(feed_ids))
data['lastBuildDate'] = datetime.datetime.utcnow()
data['generator'] = 'NewsBlur - %s' % settings.NEWSBLUR_URL
data['docs'] = None
data['author_name'] = user.username
data['feed_url'] = "%s%s" % (
settings.NEWSBLUR_URL,
reverse('folder-rss-feed',
kwargs=dict(user_id=user_id, secret_token=secret_token, unread_filter=unread_filter, folder_slug=folder_slug)),
)
rss = feedgenerator.Atom1Feed(**data)
for story in stories:
feed = Feed.get_by_id(story.story_feed_id)
story_content = (story.story_content_z and
zlib.decompress(story.story_content_z))
story_content = """<img src="//%s/rss_feeds/icon/%s" style="vertical-align:middle"> %s <br><br> %s""" % (
Site.objects.get_current().domain,
story.story_feed_id,
feed.feed_title if feed else "",
story_content
)
story_data = {
'title': story.story_title,
'link': story.story_permalink,
'description': story_content,
'author_name': story.story_author_name,
'categories': story.story_tags,
'unique_id': story.story_guid,
'pubdate': localtime_for_timezone(story.story_date, user.profile.timezone),
}
rss.add_item(**story_data)
logging.user(request, "~FBGenerating ~SB%s~SN's folder RSS feed (%s, %s stories): ~FM%s" % (
user.username,
folder_title,
len(stories),
request.META.get('HTTP_USER_AGENT', "")[:24]
))
return HttpResponse(rss.writeString('utf-8'), content_type='application/rss+xml')
@json.json_view
def load_read_stories(request):
user = get_user(request)

View file

@ -327,8 +327,8 @@ NEWSBLUR.Collections.Folders = Backbone.Collection.extend({
var url = NEWSBLUR.URLs['folder_rss'];
url = url.replace('{user_id}', NEWSBLUR.Globals.user_id);
url = url.replace('{secret_token}', NEWSBLUR.Globals.secret_token);
url = url.replace('{folder_title}', encodeURIComponent(this.options.title));
url = url + "?filter=" + filter;
url = url.replace('{unread_filter}', filter);
url = url.replace('{folder_title}', Inflector.sluggify(this.options.title));
console.log(['rss_url', this]);
return "https://" + NEWSBLUR.URLs.domain + url;

View file

@ -100,7 +100,7 @@
'domain' : "{% current_domain %}",
'favicon' : "/rss_feeds/icon/{id}",
'delete-account' : "{% url "profile-delete-account" %}",
'folder_rss' : "/reader/folder_rss/{user_id}/{secret_token}/{folder_title}"
'folder_rss' : "/reader/folder_rss/{user_id}/{secret_token}/{unread_filter}/{folder_title}"
};
NEWSBLUR.Models = {};
NEWSBLUR.Collections = {};

View file

@ -14,7 +14,7 @@ urlpatterns = patterns('',
(r'^add/?', reader_views.index),
(r'^try/?', reader_views.index),
(r'^site/(?P<feed_id>\d+)?', reader_views.index),
(r'^folder/(?P<folder_name>\d+)?', reader_views.index),
url(r'^folder/(?P<folder_name>\d+)?', reader_views.index, name='folder'),
url(r'^saved/(?P<tag_name>\d+)?', reader_views.index, name='saved-stories-tag'),
(r'^saved/?', reader_views.index),
(r'^read/?', reader_views.index),
@ -26,6 +26,7 @@ urlpatterns = patterns('',
(r'^rss_feeds/', include('apps.rss_feeds.urls')),
(r'^classifier/', include('apps.analyzer.urls')),
(r'^profile/', include('apps.profile.urls')),
(r'^folder_rss/', include('apps.profile.urls')),
(r'^import/', include('apps.feed_import.urls')),
(r'^api/', include('apps.api.urls')),
(r'^recommendations/', include('apps.recommendations.urls')),