Skip to content

Commit 081a0db

Browse files
committed
Flush read time when switching feeds.
1 parent d3bbb36 commit 081a0db

File tree

5 files changed

+75
-46
lines changed

5 files changed

+75
-46
lines changed

apps/monitor/views/newsblur_trending.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,21 @@ def get(self, request):
6868
data["unique_feeds_read"] = unique_feeds
6969

7070
# Format aggregate metrics
71-
formatted_data["total_read_seconds"] = (
72-
f'{chart_name}{{metric="total_read_seconds"}} {data["total_read_seconds"]}'
73-
)
74-
formatted_data["total_story_reads"] = (
75-
f'{chart_name}{{metric="total_story_reads"}} {data["total_story_reads"]}'
76-
)
77-
formatted_data["total_feed_reads"] = (
78-
f'{chart_name}{{metric="total_feed_reads"}} {data["total_feed_reads"]}'
79-
)
80-
formatted_data["unique_stories_read"] = (
81-
f'{chart_name}{{metric="unique_stories_read"}} {data["unique_stories_read"]}'
82-
)
83-
formatted_data["unique_feeds_read"] = (
84-
f'{chart_name}{{metric="unique_feeds_read"}} {data["unique_feeds_read"]}'
85-
)
71+
formatted_data[
72+
"total_read_seconds"
73+
] = f'{chart_name}{{metric="total_read_seconds"}} {data["total_read_seconds"]}'
74+
formatted_data[
75+
"total_story_reads"
76+
] = f'{chart_name}{{metric="total_story_reads"}} {data["total_story_reads"]}'
77+
formatted_data[
78+
"total_feed_reads"
79+
] = f'{chart_name}{{metric="total_feed_reads"}} {data["total_feed_reads"]}'
80+
formatted_data[
81+
"unique_stories_read"
82+
] = f'{chart_name}{{metric="unique_stories_read"}} {data["unique_stories_read"]}'
83+
formatted_data[
84+
"unique_feeds_read"
85+
] = f'{chart_name}{{metric="unique_feeds_read"}} {data["unique_feeds_read"]}'
8686

8787
# Top stories for both 1-day and 7-day windows
8888
for days in [1, 7]:
@@ -212,9 +212,9 @@ def get(self, request):
212212
avg_seconds = 0
213213

214214
key = f"avg_seconds_per_reader_{days}d"
215-
formatted_data[key] = (
216-
f'{chart_name}{{metric="avg_seconds_per_reader",days="{days}"}} {avg_seconds:.1f}'
217-
)
215+
formatted_data[
216+
key
217+
] = f'{chart_name}{{metric="avg_seconds_per_reader",days="{days}"}} {avg_seconds:.1f}'
218218

219219
# Self-monitoring: track how long this endpoint takes to respond
220220
elapsed_ms = (time.time() - start_time) * 1000

apps/statistics/rtrending.py

Lines changed: 21 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,8 @@ def get_trending_stories_detailed(cls, days=7, limit=50):
301301
return []
302302

303303
# Get the story hashes we care about
304-
story_hashes = [
305-
(sh.decode() if isinstance(sh, bytes) else sh)
306-
for sh, _ in time_result
307-
]
308-
time_map = {
309-
(sh.decode() if isinstance(sh, bytes) else sh): int(score)
310-
for sh, score in time_result
311-
}
304+
story_hashes = [(sh.decode() if isinstance(sh, bytes) else sh) for sh, _ in time_result]
305+
time_map = {(sh.decode() if isinstance(sh, bytes) else sh): int(score) for sh, score in time_result}
312306

313307
# Aggregate counts across days for these stories
314308
if len(count_keys) > 1:
@@ -342,13 +336,15 @@ def get_trending_stories_detailed(cls, days=7, limit=50):
342336
except (ValueError, IndexError):
343337
feed_id = 0
344338

345-
results.append({
346-
"story_hash": story_hash,
347-
"feed_id": feed_id,
348-
"total_seconds": total_seconds,
349-
"reader_count": reader_count,
350-
"avg_seconds_per_reader": total_seconds / reader_count if reader_count > 0 else 0,
351-
})
339+
results.append(
340+
{
341+
"story_hash": story_hash,
342+
"feed_id": feed_id,
343+
"total_seconds": total_seconds,
344+
"reader_count": reader_count,
345+
"avg_seconds_per_reader": total_seconds / reader_count if reader_count > 0 else 0,
346+
}
347+
)
352348

353349
return results
354350

@@ -390,13 +386,9 @@ def get_trending_feeds_detailed(cls, days=7, limit=50):
390386
if not time_result:
391387
return []
392388

393-
feed_ids = [
394-
(fid.decode() if isinstance(fid, bytes) else fid)
395-
for fid, _ in time_result
396-
]
389+
feed_ids = [(fid.decode() if isinstance(fid, bytes) else fid) for fid, _ in time_result]
397390
time_map = {
398-
(fid.decode() if isinstance(fid, bytes) else fid): int(score)
399-
for fid, score in time_result
391+
(fid.decode() if isinstance(fid, bytes) else fid): int(score) for fid, score in time_result
400392
}
401393

402394
# Aggregate counts
@@ -429,12 +421,14 @@ def get_trending_feeds_detailed(cls, days=7, limit=50):
429421
total_seconds = time_map.get(feed_id_str, 0)
430422
reader_count = count_map.get(feed_id_str, 0)
431423

432-
results.append({
433-
"feed_id": feed_id,
434-
"total_seconds": total_seconds,
435-
"reader_count": reader_count,
436-
"avg_seconds_per_reader": total_seconds / reader_count if reader_count > 0 else 0,
437-
})
424+
results.append(
425+
{
426+
"feed_id": feed_id,
427+
"total_seconds": total_seconds,
428+
"reader_count": reader_count,
429+
"avg_seconds_per_reader": total_seconds / reader_count if reader_count > 0 else 0,
430+
}
431+
)
438432

439433
return results
440434

media/js/newsblur/common/assetmodel.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,30 @@ NEWSBLUR.AssetModel = Backbone.Router.extend({
208208
}
209209
},
210210

211+
flush_read_times: function () {
212+
// Send any queued read times to the server immediately (e.g., when switching feeds)
213+
var self = this;
214+
if (!NEWSBLUR.Globals.is_authenticated) return;
215+
if (!this.queued_read_stories['read_times'] ||
216+
_.isEmpty(this.queued_read_stories['read_times'])) return;
217+
218+
var data = {
219+
read_times: JSON.stringify(this.queued_read_stories['read_times'])
220+
};
221+
222+
// Clear read_times before sending to avoid duplicates
223+
var read_times_to_send = this.queued_read_stories['read_times'];
224+
this.queued_read_stories['read_times'] = {};
225+
226+
this.make_request('/reader/mark_story_hashes_as_read', data, null, function () {
227+
// On error, restore queued read times to retry later
228+
if (!self.queued_read_stories['read_times']) {
229+
self.queued_read_stories['read_times'] = {};
230+
}
231+
_.extend(self.queued_read_stories['read_times'], read_times_to_send);
232+
});
233+
},
234+
211235
mark_story_hash_as_read: function (story, callback, error_callback, data) {
212236
var self = this;
213237

media/js/newsblur/reader/reader.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,6 +1338,17 @@
13381338
}
13391339
});
13401340

1341+
// Flush read time for the current story before resetting (for trending feeds feature)
1342+
if (NEWSBLUR.ReadTimeTracker && this.active_story) {
1343+
var story_hash = this.active_story.get('story_hash');
1344+
var read_time = NEWSBLUR.ReadTimeTracker.get_and_reset_read_time(story_hash);
1345+
if (read_time > 0) {
1346+
NEWSBLUR.assets.queue_read_time(story_hash, read_time);
1347+
}
1348+
NEWSBLUR.ReadTimeTracker.stop_tracking();
1349+
NEWSBLUR.assets.flush_read_times();
1350+
}
1351+
13411352
$.extend(this.flags, {
13421353
'scrolling_by_selecting_story_title': false,
13431354
'page_view_showing_feed_view': false,

utils/tlnb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def main(hostnames=None, roles=None, command=None, path=None):
4545
if not command:
4646
command = "tail -f"
4747

48-
if hostnames in ["app", "task", "push", "work"]:
48+
if hostnames in ["app", "task", "push", "work", "staging"]:
4949
roles = hostnames
5050
hostnames = None
5151

0 commit comments

Comments
 (0)