mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Fetching all unread stories, ordered by recency.
This commit is contained in:
parent
3c66d7ece4
commit
3d8d1247b1
5 changed files with 83 additions and 56 deletions
|
@ -770,24 +770,29 @@ def load_river_stories__redis(request):
|
|||
start = time.time()
|
||||
user = get_user(request)
|
||||
feed_ids = [int(feed_id) for feed_id in request.REQUEST.getlist('feeds') if feed_id]
|
||||
story_hashes = request.REQUEST.getlist('h')[:100]
|
||||
original_feed_ids = list(feed_ids)
|
||||
page = int(request.REQUEST.get('page', 1))
|
||||
order = request.REQUEST.get('order', 'newest')
|
||||
read_filter = request.REQUEST.get('read_filter', 'unread')
|
||||
now = localtime_for_timezone(datetime.datetime.now(), user.profile.timezone)
|
||||
|
||||
if not feed_ids:
|
||||
if not feed_ids and not story_hashes:
|
||||
usersubs = UserSubscription.objects.filter(user=user, active=True).only('feed')
|
||||
feed_ids = [sub.feed_id for sub in usersubs]
|
||||
|
||||
offset = (page-1) * limit
|
||||
limit = page * limit - 1
|
||||
|
||||
story_hashes, unread_feed_story_hashes = UserSubscription.feed_stories(user.pk, feed_ids,
|
||||
offset=offset, limit=limit,
|
||||
order=order,
|
||||
read_filter=read_filter)
|
||||
story_date_order = "%sstory_date" % ('' if order == 'oldest' else '-')
|
||||
|
||||
if story_hashes:
|
||||
unread_feed_story_hashes = []
|
||||
read_filter = 'unread'
|
||||
else:
|
||||
story_hashes, unread_feed_story_hashes = UserSubscription.feed_stories(user.pk, feed_ids,
|
||||
offset=offset, limit=limit,
|
||||
order=order,
|
||||
read_filter=read_filter)
|
||||
mstories = MStory.objects(story_hash__in=story_hashes).order_by(story_date_order)
|
||||
stories = Feed.format_stories(mstories)
|
||||
found_feed_ids = list(set([story['story_feed_id'] for story in stories]))
|
||||
|
@ -853,7 +858,7 @@ def load_river_stories__redis(request):
|
|||
"stories, ~SN%s/%s/%s feeds, %s/%s)" %
|
||||
(page, len(stories), len(mstories), len(found_feed_ids),
|
||||
len(feed_ids), len(original_feed_ids), order, read_filter))
|
||||
if page == 1:
|
||||
if page == 1:
|
||||
import random
|
||||
time.sleep(random.randint(0, 6))
|
||||
|
||||
|
@ -922,7 +927,7 @@ def mark_all_as_read(request):
|
|||
def mark_story_as_read(request):
|
||||
story_ids = request.REQUEST.getlist('story_id')
|
||||
feed_id = int(get_argument_or_404(request, 'feed_id'))
|
||||
|
||||
raise Http404
|
||||
try:
|
||||
usersub = UserSubscription.objects.select_related('feed').get(user=request.user, feed=feed_id)
|
||||
except Feed.DoesNotExist:
|
||||
|
@ -964,7 +969,7 @@ def mark_feed_stories_as_read(request):
|
|||
feed_id = int(feed_id)
|
||||
try:
|
||||
usersub = UserSubscription.objects.select_related('feed').get(user=request.user, feed=feed_id)
|
||||
data = usersub.mark_story_ids_as_read(story_ids)
|
||||
data = usersub.mark_story_ids_as_read(story_ids, request=request)
|
||||
except UserSubscription.DoesNotExist:
|
||||
return dict(code=-1, error="You are not subscribed to this feed_id: %d" % feed_id)
|
||||
except Feed.DoesNotExist:
|
||||
|
@ -973,7 +978,7 @@ def mark_feed_stories_as_read(request):
|
|||
if not duplicate_feed: raise Feed.DoesNotExist
|
||||
usersub = UserSubscription.objects.get(user=request.user,
|
||||
feed=duplicate_feed[0].feed)
|
||||
data = usersub.mark_story_ids_as_read(story_ids)
|
||||
data = usersub.mark_story_ids_as_read(story_ids, request=request)
|
||||
except (UserSubscription.DoesNotExist, Feed.DoesNotExist):
|
||||
return dict(code=-1, error="No feed exists for feed_id: %d" % feed_id)
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
NSInteger selectedIntelligence;
|
||||
int visibleUnreadCount;
|
||||
int savedStoriesCount;
|
||||
int totalUnfetchedStoryCount;
|
||||
NSMutableArray * recentlyReadStories;
|
||||
NSMutableSet * recentlyReadFeeds;
|
||||
NSMutableArray * readStories;
|
||||
|
@ -200,6 +201,7 @@
|
|||
@property (readwrite) int originalStoryCount;
|
||||
@property (readwrite) int visibleUnreadCount;
|
||||
@property (readwrite) int savedStoriesCount;
|
||||
@property (readwrite) int totalUnfetchedStoryCount;
|
||||
@property (readwrite) NSInteger selectedIntelligence;
|
||||
@property (readwrite) NSMutableArray * recentlyReadStories;
|
||||
@property (readwrite) NSMutableSet * recentlyReadFeeds;
|
||||
|
@ -321,8 +323,8 @@
|
|||
- (void)fetchAllUnreadStories;
|
||||
- (void)fetchAllUnreadStories:(int)page;
|
||||
- (void)storeAllUnreadStories:(ASIHTTPRequest *)request;
|
||||
- (void)flushQueuedReadStories:(BOOL)forceCheck;
|
||||
- (void)syncQueuedReadStories:(FMDatabase *)db withStories:(NSDictionary *)hashes;
|
||||
- (void)flushQueuedReadStories:(BOOL)forceCheck withCallback:(void(^)())callback;
|
||||
- (void)syncQueuedReadStories:(FMDatabase *)db withStories:(NSDictionary *)hashes withCallback:(void(^)())callback;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
@synthesize storyLocationsCount;
|
||||
@synthesize visibleUnreadCount;
|
||||
@synthesize savedStoriesCount;
|
||||
@synthesize totalUnfetchedStoryCount;
|
||||
@synthesize originalStoryCount;
|
||||
@synthesize selectedIntelligence;
|
||||
@synthesize activeOriginalStoryURL;
|
||||
|
@ -244,6 +245,7 @@
|
|||
- (void)viewDidLoad {
|
||||
self.visibleUnreadCount = 0;
|
||||
self.savedStoriesCount = 0;
|
||||
self.totalUnfetchedStoryCount = 0;
|
||||
[self setRecentlyReadStories:[NSMutableArray array]];
|
||||
}
|
||||
|
||||
|
@ -520,7 +522,7 @@
|
|||
|
||||
[feedDetailViewController resetFeedDetail];
|
||||
[feedDetailViewController fetchFeedDetail:1 withCallback:nil];
|
||||
[self flushQueuedReadStories:NO];
|
||||
[self flushQueuedReadStories:NO withCallback:nil];
|
||||
}
|
||||
|
||||
- (void)loadTryFeedDetailView:(NSString *)feedId
|
||||
|
@ -2114,19 +2116,39 @@
|
|||
}
|
||||
}
|
||||
}];
|
||||
[self fetchAllUnreadStories];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)fetchAllUnreadStories {
|
||||
- (NSArray *)unfetchedStoryHashes {
|
||||
NSMutableArray *hashes = [NSMutableArray array];
|
||||
|
||||
[self fetchAllUnreadStories:1];
|
||||
[self.database inDatabase:^(FMDatabase *db) {
|
||||
if (self.totalUnfetchedStoryCount == 0) {
|
||||
FMResultSet *cursor = [db executeQuery:@"SELECT COUNT(1) FROM unread_hashes u LEFT OUTER JOIN stories s ON (s.story_hash = u.story_hash) WHERE s.story_hash IS NULL"];
|
||||
while ([cursor next]) {
|
||||
self.totalUnfetchedStoryCount = [cursor objectForColumnIndex:0];
|
||||
}
|
||||
}
|
||||
|
||||
FMResultSet *cursor = [db executeQuery:@"SELECT u.story_hash FROM unread_hashes u LEFT OUTER JOIN stories s ON (s.story_hash = u.story_hash) WHERE s.story_hash IS NULL ORDER BY s.story_timestamp LIMIT 100"];
|
||||
while ([cursor next]) {
|
||||
[hashes addObject:[cursor objectForColumnName:@"story_hash"]];
|
||||
}
|
||||
}];
|
||||
|
||||
return hashes;
|
||||
}
|
||||
|
||||
- (void)fetchAllUnreadStories:(int)page {
|
||||
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/reader/river_stories?read_filter=unread&order=newest&page=%d",
|
||||
NEWSBLUR_URL, page]];
|
||||
- (void)fetchAllUnreadStories {
|
||||
NSArray *hashes = [self unfetchedStoryHashes];
|
||||
if ([hashes count] == 0) {
|
||||
NSLog(@"Finished downloading unread stories. %d total", self.totalUnfetchedStoryCount);
|
||||
return;
|
||||
}
|
||||
|
||||
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://%@/reader/river_stories?page=0&h=%@",
|
||||
NEWSBLUR_URL, [hashes componentsJoinedByString:@"&h="]]];
|
||||
ASIHTTPRequest *_request = [ASIHTTPRequest requestWithURL:url];
|
||||
__weak ASIHTTPRequest *request = _request;
|
||||
[request setResponseEncoding:NSUTF8StringEncoding];
|
||||
|
@ -2149,14 +2171,28 @@
|
|||
JSONObjectWithData:responseData
|
||||
options:kNilOptions
|
||||
error:&error];
|
||||
|
||||
__block BOOL anySuccess = NO;
|
||||
|
||||
for (NSDictionary *story in [results objectForKey:@"stories"]) {
|
||||
|
||||
[self.database inTransaction:^(FMDatabase *db, BOOL *rollback) {
|
||||
for (NSDictionary *story in [results objectForKey:@"stories"]) {
|
||||
BOOL inserted = [db executeUpdate:@"INSERT into stories"
|
||||
"(story_feed_id, story_hash, story_timestamp, story_json) VALUES "
|
||||
"(?, ?, ?, ?)",
|
||||
[story objectForKey:@"story_feed_id"],
|
||||
[story objectForKey:@"story_hash"],
|
||||
[story objectForKey:@"story_timestamp"],
|
||||
[story JSONRepresentation]
|
||||
];
|
||||
if (inserted) anySuccess = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
if (anySuccess) {
|
||||
[self fetchAllUnreadStories];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)flushQueuedReadStories:(BOOL)forceCheck {
|
||||
- (void)flushQueuedReadStories:(BOOL)forceCheck withCallback:(void(^)())callback {
|
||||
if (hasQueuedReadStories || forceCheck) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
|
||||
(unsigned long)NULL), ^(void) {
|
||||
|
@ -2174,14 +2210,18 @@
|
|||
|
||||
if ([[hashes allKeys] count]) {
|
||||
hasQueuedReadStories = NO;
|
||||
[self syncQueuedReadStories:db withStories:hashes];
|
||||
[self syncQueuedReadStories:db withStories:hashes withCallback:callback];
|
||||
} else {
|
||||
if (callback) callback();
|
||||
}
|
||||
}];
|
||||
});
|
||||
} else {
|
||||
if (callback) callback();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)syncQueuedReadStories:(FMDatabase *)db withStories:(NSDictionary *)hashes {
|
||||
- (void)syncQueuedReadStories:(FMDatabase *)db withStories:(NSDictionary *)hashes withCallback:(void(^)())callback {
|
||||
NSString *urlString = [NSString stringWithFormat:@"http://%@/reader/mark_feed_stories_as_read",
|
||||
NEWSBLUR_URL];
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
|
@ -2197,10 +2237,12 @@
|
|||
NSLog(@"Completed clearing %@ hashes", completedHashesStr);
|
||||
[db executeUpdate:[NSString stringWithFormat:@"DELETE FROM queued_read_hashes WHERE story_hash in (\"%@\")", completedHashesStr]]
|
||||
;
|
||||
if (callback) callback();
|
||||
}];
|
||||
[request setFailedBlock:^{
|
||||
NSLog(@"Failed mark read queued.");
|
||||
hasQueuedReadStories = YES;
|
||||
if (callback) callback();
|
||||
}];
|
||||
[request startAsynchronous];
|
||||
}
|
||||
|
|
|
@ -679,10 +679,15 @@ static const CGFloat kFolderTitleHeight = 28;
|
|||
[upgradeConfirm setTag:2];
|
||||
}
|
||||
|
||||
if (!self.inPullToRefresh_) {
|
||||
[self refreshFeedList];
|
||||
} else {
|
||||
if (self.inPullToRefresh_) {
|
||||
self.inPullToRefresh_ = NO;
|
||||
[self.appDelegate flushQueuedReadStories:YES withCallback:^{
|
||||
[self.appDelegate fetchUnreadHashes];
|
||||
}];
|
||||
} else {
|
||||
[self.appDelegate flushQueuedReadStories:YES withCallback:^{
|
||||
[self refreshFeedList];
|
||||
}];
|
||||
}
|
||||
|
||||
// start up the first time user experience
|
||||
|
@ -1471,7 +1476,6 @@ heightForHeaderInSection:(NSInteger)section {
|
|||
[appDelegate.folderCountCache removeAllObjects];
|
||||
[self.feedTitlesTable reloadData];
|
||||
[self refreshHeaderCounts];
|
||||
[self.appDelegate flushQueuedReadStories:YES];
|
||||
[self.appDelegate fetchUnreadHashes];
|
||||
}
|
||||
|
||||
|
|
|
@ -16,19 +16,6 @@
|
|||
landmarkName = "-resizeScrollView"
|
||||
landmarkType = "5">
|
||||
</FileBreakpoint>
|
||||
<FileBreakpoint
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Classes/NewsBlurAppDelegate.m"
|
||||
timestampString = "393041779.344441"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "715"
|
||||
endingLineNumber = "715"
|
||||
landmarkName = "-recalculateIntelligenceScores:"
|
||||
landmarkType = "5">
|
||||
</FileBreakpoint>
|
||||
<FileBreakpoint
|
||||
shouldBeEnabled = "No"
|
||||
ignoreCount = "0"
|
||||
|
@ -42,19 +29,6 @@
|
|||
landmarkName = "-doNextUnreadStory"
|
||||
landmarkType = "5">
|
||||
</FileBreakpoint>
|
||||
<FileBreakpoint
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "Classes/NewsBlurViewController.m"
|
||||
timestampString = "393043837.427452"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "889"
|
||||
endingLineNumber = "889"
|
||||
landmarkName = "-tableView:didSelectRowAtIndexPath:"
|
||||
landmarkType = "5">
|
||||
</FileBreakpoint>
|
||||
</FileBreakpoints>
|
||||
<SymbolicBreakpoints>
|
||||
<SymbolicBreakpoint
|
||||
|
|
Loading…
Add table
Reference in a new issue