mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Paging from 1 and not 0. Moving the JS assetmodel to use new paging and API endpoints.
This commit is contained in:
parent
42d6abe247
commit
a2e082b0d8
10 changed files with 48 additions and 41 deletions
|
@ -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:
|
||||
|
|
|
@ -11,6 +11,12 @@ 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')
|
||||
|
||||
|
|
|
@ -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'),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
BIN
media/img/reader/intelligence_slider_all.png
Normal file
BIN
media/img/reader/intelligence_slider_all.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue