Paging from 1 and not 0. Moving the JS assetmodel to use new paging and API endpoints.

This commit is contained in:
Samuel Clay 2011-04-21 10:44:50 -04:00
parent 42d6abe247
commit a2e082b0d8
10 changed files with 48 additions and 41 deletions

View file

@ -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:

View file

@ -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')

View file

@ -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<feed_id>\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'),

View file

@ -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,

View file

@ -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));

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -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,

View file

@ -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);

View file

@ -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',

View file

@ -55,13 +55,20 @@
<th>Example</th>
</tr>
<tr>
<td>include_favicons</td> <td><span class="optional">Optional</span> Include
<td>include_favicons</td>
<td><span class="optional">Optional</span> Include
favicons inline. Since they can be time consuming to download, you can optionally
turn them off. Use <tt>/api/v1/feeds/favicons/</tt> to retrieve the favicons in a
separate request.</td>
<td><code>true</code></td>
<td><code>true/false</code></td>
</tr>
<tr>
<td>flat</td>
<td><span class="optional">Optional</span> Returns a flat folder structure instead of nested folders. Useful when displaying all folders in a single depth without recursive descent.</td>
<td><code>false</code></td>
<td><code>true/false</code></td>
</tr>
</table>
<h4>Example Response</h4>
@ -75,19 +82,19 @@
<h4>Tips</h4>
<ul>
<li>Use <code>/api/v1/reader/refresh_feeds</code> to get updated unread counts.</li>
<li>Use <code>/reader/refresh_feeds</code> to get updated unread counts.</li>
<li>Turn off <code>include_favicons</code> if you can either cache favicons or can
wait to fetch them.</li>
</ul>
<h3><tt>GET /api/v1/feeds/favicons</tt></h3>
<h3><tt>GET /reader/favicons</tt></h3>
<ul>
<li>Retrieve a list of favicons for a list of feeds. Used when combined with
<tt>/api/v1/reader/feed_list</tt> and <tt>include_favicons=false</tt>, so the
feed_list request contains far less data. Useful for mobile devices, but requires a
<tt>/reader/feeds</tt> and <tt>include_favicons=false</tt>, so the
feeds request contains far less data. Useful for mobile devices, but requires a
second request.</li>
</ul>
@ -100,7 +107,7 @@
</tr>
<tr>
<td>feeds</td>
<td><span class="required">REQUIRED</span> Array of feed ids</td>
<td><span class="optional">OPTIONAL</span> Array of feed ids. Leave empty to retrieve all active (enabled) feeds.</td>
<td></td>
<td><code>[1, 2, 3]</code></td>
</tr>