diff --git a/apps/analyzer/tests.py b/apps/analyzer/tests.py index 1049d0c79..22c7aa7f3 100644 --- a/apps/analyzer/tests.py +++ b/apps/analyzer/tests.py @@ -1,7 +1,7 @@ from utils import json_functions as json from django.test.client import Client from django.contrib.auth.models import User -from apps.rss_feeds.models import Feed, Story +from apps.rss_feeds.models import Feed, MStory from django.test import TestCase from django.core import management from pprint import pprint @@ -49,7 +49,7 @@ class ClassifierTest(TestCase): management.call_command('loaddata', 'brownstoner2.json', verbosity=0) management.call_command('refresh_feed', force=1, feed=1, single_threaded=True, daemonize=False) - stories = Story.objects.filter(story_feed=1)[:53] + stories = MStory.objects(story_feed_id=1)[:53] phrasefilter = PhraseFilter() for story in stories: diff --git a/apps/reader/tests.py b/apps/reader/tests.py index 776ad4c8c..5ddca556e 100644 --- a/apps/reader/tests.py +++ b/apps/reader/tests.py @@ -10,7 +10,13 @@ class ReaderTest(TestCase): def setUp(self): self.client = Client() - + + def test_api_feeds(self): + self.client.login(username='conesus', password='test') + + response = self.client.get(reverse('load-feeds')) + pprint(json.decode(response.content)) + def test_delete_feed(self): self.client.login(username='conesus', password='test') diff --git a/apps/reader/urls.py b/apps/reader/urls.py index 19370b9ca..5f7524d1c 100644 --- a/apps/reader/urls.py +++ b/apps/reader/urls.py @@ -8,7 +8,7 @@ urlpatterns = patterns('', url(r'^login', views.login, name='login'), url(r'^signup', views.signup, name='signup'), url(r'^feeds', views.load_feeds, name='load-feeds'), - url(r'^feed', views.load_single_feed, name='load-single-feed'), + url(r'^feed/(?P\d+)', views.load_single_feed, name='load-single-feed'), url(r'^page', views.load_feed_page, name='load-feed-page'), url(r'^favicons', views.load_feed_favicons, name='load-feed-favicons'), url(r'^river_stories', views.load_river_stories, name='load-river-stories'), diff --git a/apps/reader/views.py b/apps/reader/views.py index 5ac7543d4..e8874186a 100644 --- a/apps/reader/views.py +++ b/apps/reader/views.py @@ -181,9 +181,7 @@ def load_feeds(request): def load_feed_favicons(request): user = get_user(request) feed_ids = request.REQUEST.getlist('feed_ids') - user_subs = UserSubscription.objects.select_related('feed').filter(user=user) - if not request.REQUEST.get('load_all'): - user_subs = user_subs.filter(active=True) + user_subs = UserSubscription.objects.select_related('feed').filter(user=user, active=True) if feed_ids: user_subs = user_subs.filter(feed__in=feed_ids) @@ -293,20 +291,15 @@ def refresh_feeds(request): return {'feeds': feeds} @json.json_view -def load_single_feed(request): +def load_single_feed(request, feed_id): start = datetime.datetime.utcnow() user = get_user(request) offset = int(request.REQUEST.get('offset', 0)) limit = int(request.REQUEST.get('limit', 12)) - page = int(request.REQUEST.get('page', 0)) + page = int(request.REQUEST.get('page', 1)) if page: - offset = limit * page - feed_id = None - try: - feed_id = int(request.REQUEST.get('feed_id', 0)) - except ValueError: - feed_id_matches = re.search(r'(\d+)', request.REQUEST['feed_id']) - if feed_id_matches: feed_id = int(feed_id_matches.group(1)) + offset = limit * (page-1) + feed_id = int(feed_id) dupe_feed_id = None if not feed_id: raise Http404 @@ -384,7 +377,8 @@ def load_single_feed(request): diff = datetime.datetime.utcnow()-start timediff = float("%s.%.2s" % (diff.seconds, (diff.microseconds / 1000))) last_update = relative_timesince(feed.last_update) - logging.user(request.user, "~FYLoading feed: ~SB%s ~SN(%s seconds)" % (feed, timediff)) + logging.user(request.user, "~FYLoading feed: ~SB%s%s ~SN(%s seconds)" % ( + feed, ('~SN/p%s' % page) if page > 1 else '', timediff)) FeedLoadtime.objects.create(feed=feed, loadtime=timediff) data = dict(stories=stories, diff --git a/media/css/reader.css b/media/css/reader.css index 9d301f8e2..5af0661f9 100644 --- a/media/css/reader.css +++ b/media/css/reader.css @@ -3491,7 +3491,7 @@ background: transparent; display: none; overflow: hidden; left: 0; - margin: 12px 0; + margin: 12px 0 0; } .NB-module-howitworks .NB-howitworks-page.NB-active { @@ -3503,7 +3503,7 @@ background: transparent; height: 135px; padding: 2px; border: 1px solid #E0E0E0; - margin: 0 12px 24px; + margin: 0 12px 0; float: left; } @@ -5252,7 +5252,11 @@ background: transparent; margin: 0; } .NB-static-api table td { - border: 1px solid #F6F6f6; + border-right: 1px solid #F6F6f6; + border-bottom: 1px solid #F6F6f6; +} +.NB-static-api table td:last-child { + border-right: none; } .NB-static-api table th { background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#FCFCFC), to(#E0E0E0)); diff --git a/media/img/reader/intelligence_slider_all.png b/media/img/reader/intelligence_slider_all.png new file mode 100644 index 000000000..ae99703ca Binary files /dev/null and b/media/img/reader/intelligence_slider_all.png differ diff --git a/media/js/newsblur/assetmodel.js b/media/js/newsblur/assetmodel.js index 4714dbd12..3493c6ed4 100644 --- a/media/js/newsblur/assetmodel.js +++ b/media/js/newsblur/assetmodel.js @@ -255,15 +255,14 @@ NEWSBLUR.AssetModel.Reader.prototype = { // NEWSBLUR.log(['load_feed', feed_id, page, first_load, callback, pre_callback, this.feeds[feed_id].feed_address]); if (feed_id) { - this.make_request('/reader/feed', + this.make_request('/reader/feed/'+feed_id, { - feed_id: feed_id, page: page, feed_address: this.feeds[feed_id].feed_address }, pre_callback, $.noop, { - 'ajax_group': (page ? 'feed_page' : 'feed'), + 'ajax_group': (page > 1 ? 'feed_page' : 'feed'), 'request_type': 'GET' } ); @@ -447,7 +446,7 @@ NEWSBLUR.AssetModel.Reader.prototype = { callback(updated_feeds); }, - refresh_feed: function(feed_id, callback, limit) { + refresh_feed: function(feed_id, callback) { var self = this; var pre_callback = function(data) { @@ -457,11 +456,9 @@ NEWSBLUR.AssetModel.Reader.prototype = { // NEWSBLUR.log(['refresh_feed', feed_id, page, first_load, callback, pre_callback]); if (feed_id) { - this.make_request('/reader/feed', + this.make_request('/reader/feed/'+feed_id, { - feed_id: feed_id, page: 0, - limit: limit, feed_address: this.feeds[feed_id].feed_address }, pre_callback, null, diff --git a/media/js/newsblur/reader.js b/media/js/newsblur/reader.js index 177e5d945..fa38fa2aa 100644 --- a/media/js/newsblur/reader.js +++ b/media/js/newsblur/reader.js @@ -1452,7 +1452,7 @@ this.active_feed = null; this.active_story = null; - this.$s.$story_titles.data('page', 0); + this.$s.$story_titles.data('page', 1); this.$s.$story_titles.data('feed_id', null); this.$s.$feed_stories.scrollTop(0); this.$s.$feed_stories.empty(); @@ -1484,7 +1484,7 @@ this.next_feed = feed_id; this.show_stories_progress_bar(); - $story_titles.data('page', 0); + $story_titles.data('page', 1); $story_titles.data('feed_id', feed_id); this.iframe_scroll = null; this.set_correct_story_view_for_feed(feed_id); @@ -1496,7 +1496,7 @@ _.delay(_.bind(function() { if (!delay || feed_id == self.next_feed) { - this.model.load_feed(feed_id, 0, true, $.rescope(this.post_open_feed, this)); + this.model.load_feed(feed_id, 1, true, $.rescope(this.post_open_feed, this)); } }, this), delay || 0); @@ -1664,7 +1664,7 @@ this.hide_splash_page(); this.active_feed = 'starred'; - $story_titles.data('page', 0); + $story_titles.data('page', 1); $story_titles.data('feed_id', null); this.iframe_scroll = null; this.mark_feed_as_selected(null, null); @@ -1720,7 +1720,7 @@ $folder.addClass('NB-selected'); } - $story_titles.data('page', 0); + $story_titles.data('page', 1); $story_titles.data('feed_id', null); this.iframe_scroll = null; this.flags['opening_feed'] = true; @@ -4529,8 +4529,7 @@ if (feed_id == this.active_feed) { NEWSBLUR.log(['UPDATING INLINE', feed.feed_title, $feed, $feed_on_page, replace_active_feed]); if (!replace_active_feed) { - // var limit = $('.story', this.$s.$story_titles).length; - // this.model.refresh_feed(feed_id, $.rescope(this.post_refresh_active_feed, this), limit); + // this.model.refresh_feed(feed_id, $.rescope(this.post_refresh_active_feed, this)); // Set the unread counts to what the client thinks they are, so when // the counts can be updated, they will force a refresh of the feed. this.model.feeds[feed_id].ps = parseInt($('.unread_count_positive', $feed_on_page).text(), 10); diff --git a/media/js/newsblur/reader_classifier.js b/media/js/newsblur/reader_classifier.js index df8575e8a..ab85acbec 100644 --- a/media/js/newsblur/reader_classifier.js +++ b/media/js/newsblur/reader_classifier.js @@ -253,7 +253,7 @@ var classifier_prototype = { ' Click on what you like and don\'t like.' ]), $.make('li', [ - $.make('img', { src: NEWSBLUR.Globals.MEDIA_URL + '/img/reader/intelligence_slider_positive.png', style: 'float: right', width: 114, height: 29 }), + $.make('img', { src: NEWSBLUR.Globals.MEDIA_URL + '/img/reader/intelligence_slider_all.png', style: 'float: right', width: 127, height: 92 }), $.make('b', 'The intelligence slider filters stories.'), $.make('img', { className: 'NB-trainer-bullet', src: NEWSBLUR.Globals.MEDIA_URL + '/img/icons/silk/bullet_green.png'}), ' are stories you like', diff --git a/templates/static/api.xhtml b/templates/static/api.xhtml index 8681d720c..d3c5d0083 100644 --- a/templates/static/api.xhtml +++ b/templates/static/api.xhtml @@ -55,13 +55,20 @@ Example - include_favicons Optional Include + include_favicons + Optional Include favicons inline. Since they can be time consuming to download, you can optionally turn them off. Use /api/v1/feeds/favicons/ to retrieve the favicons in a separate request. true true/false + + flat + Optional Returns a flat folder structure instead of nested folders. Useful when displaying all folders in a single depth without recursive descent. + false + true/false +

Example Response

@@ -75,19 +82,19 @@

Tips

-

GET /api/v1/feeds/favicons

+

GET /reader/favicons

@@ -100,7 +107,7 @@ feeds - REQUIRED Array of feed ids + OPTIONAL Array of feed ids. Leave empty to retrieve all active (enabled) feeds. [1, 2, 3]