mirror of
https://github.com/viq/NewsBlur.git
synced 2025-08-05 16:49:45 +00:00
A bit risky but this commit fixes read status issues with stories found in both blurblogs and feeds. Adds a new redis set of read stories, specific to users and blurblog subscriptions, that won't get cleared out when the story is removed from mongo.
This commit is contained in:
parent
9ac6c399cf
commit
5af6e3835a
2 changed files with 53 additions and 36 deletions
|
@ -653,7 +653,7 @@ class UserSubscription(models.Model):
|
|||
class RUserStory:
|
||||
|
||||
@classmethod
|
||||
def mark_read(cls, user_id, story_feed_id, story_hash, r=None, r2=None):
|
||||
def mark_read(cls, user_id, story_feed_id, story_hash, social_user_ids=None, r=None, r2=None):
|
||||
if not r:
|
||||
r = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_POOL)
|
||||
if not r2:
|
||||
|
@ -663,34 +663,43 @@ class RUserStory:
|
|||
|
||||
if not story_hash: return
|
||||
|
||||
now = int(time.time())
|
||||
def redis_commands(key):
|
||||
r.sadd(key, story_hash)
|
||||
r2.sadd(key, story_hash)
|
||||
r.expire(key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
r2.expire(key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
|
||||
all_read_stories_key = 'RS:%s' % (user_id)
|
||||
r.sadd(all_read_stories_key, story_hash)
|
||||
r2.sadd(all_read_stories_key, story_hash)
|
||||
r2.zadd('z' + all_read_stories_key, story_hash, now)
|
||||
r.expire(all_read_stories_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
r2.expire(all_read_stories_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
r2.expire('z' + all_read_stories_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
redis_commands(all_read_stories_key)
|
||||
|
||||
read_story_key = 'RS:%s:%s' % (user_id, story_feed_id)
|
||||
r.sadd(read_story_key, story_hash)
|
||||
r2.sadd(read_story_key, story_hash)
|
||||
r2.zadd('z' + read_story_key, story_hash, now)
|
||||
r.expire(read_story_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
r2.expire(read_story_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
r2.expire('z' + read_story_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
redis_commands(read_story_key)
|
||||
|
||||
if social_user_ids:
|
||||
for social_user_id in social_user_ids:
|
||||
social_read_story_key = 'RS:%s:B:%s' % (user_id, social_user_id)
|
||||
redis_commands(social_read_story_key)
|
||||
|
||||
@staticmethod
|
||||
def mark_unread(user_id, story_feed_id, story_hash):
|
||||
r = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_POOL)
|
||||
r2 = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_POOL2)
|
||||
|
||||
r.srem('RS:%s' % user_id, story_hash)
|
||||
r2.srem('RS:%s' % user_id, story_hash)
|
||||
r2.zrem('zRS:%s' % user_id, story_hash)
|
||||
r.srem('RS:%s:%s' % (user_id, story_feed_id), story_hash)
|
||||
r2.srem('RS:%s:%s' % (user_id, story_feed_id), story_hash)
|
||||
r2.zrem('zRS:%s:%s' % (user_id, story_feed_id), story_hash)
|
||||
def mark_unread(user_id, story_feed_id, story_hash, social_user_ids=None):
|
||||
r = redis.Redis(connection_pool=settings.REDIS_POOL)
|
||||
h = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_POOL)
|
||||
h2 = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_POOL2)
|
||||
|
||||
h.srem('RS:%s' % user_id, story_hash)
|
||||
h2.srem('RS:%s' % user_id, story_hash)
|
||||
h.srem('RS:%s:%s' % (user_id, story_feed_id), story_hash)
|
||||
h2.srem('RS:%s:%s' % (user_id, story_feed_id), story_hash)
|
||||
|
||||
# Find other social feeds with this story to update their counts
|
||||
friend_key = "F:%s:F" % (user_id)
|
||||
share_key = "S:%s" % (story_hash)
|
||||
friends_with_shares = [int(f) for f in r.sinter(share_key, friend_key)]
|
||||
|
||||
if friends_with_shares:
|
||||
for social_user_id in friends_with_shares:
|
||||
h.srem('RS:%s:B:%s' % (user_id, social_user_id), story_hash)
|
||||
h2.srem('RS:%s:B:%s' % (user_id, social_user_id), story_hash)
|
||||
|
||||
@staticmethod
|
||||
def get_stories(user_id, feed_id, r=None):
|
||||
|
@ -706,7 +715,6 @@ class RUserStory:
|
|||
p = r.pipeline()
|
||||
p2 = r2.pipeline()
|
||||
story_hashes = cls.get_stories(user_id, old_feed_id, r=r)
|
||||
now = int(time.time())
|
||||
|
||||
for story_hash in story_hashes:
|
||||
_, hash_story = MStory.split_story_hash(story_hash)
|
||||
|
@ -714,18 +722,14 @@ class RUserStory:
|
|||
read_feed_key = "RS:%s:%s" % (user_id, new_feed_id)
|
||||
p.sadd(read_feed_key, new_story_hash)
|
||||
p2.sadd(read_feed_key, new_story_hash)
|
||||
p2.zadd('z' + read_feed_key, new_story_hash, now)
|
||||
p.expire(read_feed_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
p2.expire(read_feed_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
p2.expire('z' + read_feed_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
|
||||
read_user_key = "RS:%s" % (user_id)
|
||||
p.sadd(read_user_key, new_story_hash)
|
||||
p2.sadd(read_user_key, new_story_hash)
|
||||
p2.zadd('z' + read_user_key, new_story_hash, now)
|
||||
p.expire(read_user_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
p2.expire(read_user_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
p2.expire('z' + read_user_key, settings.DAYS_OF_UNREAD*24*60*60)
|
||||
|
||||
p.execute()
|
||||
p2.execute()
|
||||
|
|
|
@ -857,9 +857,10 @@ class MSocialSubscription(mongo.Document):
|
|||
r = redis.Redis(connection_pool=settings.REDIS_STORY_HASH_POOL)
|
||||
ignore_user_stories = False
|
||||
|
||||
stories_key = 'B:%s' % (self.subscription_user_id)
|
||||
read_stories_key = 'RS:%s' % (self.user_id)
|
||||
unread_stories_key = 'UB:%s:%s' % (self.user_id, self.subscription_user_id)
|
||||
stories_key = 'B:%s' % (self.subscription_user_id)
|
||||
read_stories_key = 'RS:%s' % (self.user_id)
|
||||
read_social_stories_key = 'RS:%s:B:%s' % (self.user_id, self.subscription_user_id)
|
||||
unread_stories_key = 'UB:%s:%s' % (self.user_id, self.subscription_user_id)
|
||||
|
||||
if not r.exists(stories_key):
|
||||
return []
|
||||
|
@ -868,6 +869,7 @@ class MSocialSubscription(mongo.Document):
|
|||
unread_stories_key = stories_key
|
||||
else:
|
||||
r.sdiffstore(unread_stories_key, stories_key, read_stories_key)
|
||||
r.sdiffstore(unread_stories_key, unread_stories_key, read_social_stories_key)
|
||||
|
||||
sorted_stories_key = 'zB:%s' % (self.subscription_user_id)
|
||||
unread_ranked_stories_key = 'z%sUB:%s:%s' % ('h' if hashes_only else '',
|
||||
|
@ -970,14 +972,18 @@ class MSocialSubscription(mongo.Document):
|
|||
logging.user(request, "~FYRead story in social subscription: %s" % (sub_username))
|
||||
|
||||
for story_hash in set(story_hashes):
|
||||
if feed_id:
|
||||
story_hash = MStory.ensure_story_hash(story_hash, story_feed_id=feed_id)
|
||||
if not feed_id:
|
||||
feed_id, _ = MStory.split_story_hash(story_hash)
|
||||
RUserStory.mark_read(self.user_id, feed_id, story_hash)
|
||||
|
||||
|
||||
# Find other social feeds with this story to update their counts
|
||||
friend_key = "F:%s:F" % (self.user_id)
|
||||
share_key = "S:%s" % (story_hash)
|
||||
friends_with_shares = [int(f) for f in r.sinter(share_key, friend_key)]
|
||||
|
||||
RUserStory.mark_read(self.user_id, feed_id, story_hash, social_user_ids=friends_with_shares)
|
||||
|
||||
if self.user_id in friends_with_shares:
|
||||
friends_with_shares.remove(self.user_id)
|
||||
if friends_with_shares:
|
||||
|
@ -1003,7 +1009,8 @@ class MSocialSubscription(mongo.Document):
|
|||
def mark_unsub_story_ids_as_read(cls, user_id, social_user_id, story_ids, feed_id=None,
|
||||
request=None):
|
||||
data = dict(code=0, payload=story_ids)
|
||||
|
||||
r = redis.Redis(connection_pool=settings.REDIS_POOL)
|
||||
|
||||
if not request:
|
||||
request = User.objects.get(pk=user_id)
|
||||
|
||||
|
@ -1019,7 +1026,13 @@ class MSocialSubscription(mongo.Document):
|
|||
except MSharedStory.DoesNotExist:
|
||||
continue
|
||||
|
||||
RUserStory.mark_read(user_id, story.story_feed_id, story.story_hash)
|
||||
# Find other social feeds with this story to update their counts
|
||||
friend_key = "F:%s:F" % (user_id)
|
||||
share_key = "S:%s" % (story.story_hash)
|
||||
friends_with_shares = [int(f) for f in r.sinter(share_key, friend_key)]
|
||||
|
||||
RUserStory.mark_read(user_id, story.story_feed_id, story.story_hash,
|
||||
social_user_ids=friends_with_shares)
|
||||
|
||||
# Also count on original subscription
|
||||
usersubs = UserSubscription.objects.filter(user=user_id, feed=story.story_feed_id)
|
||||
|
|
Loading…
Add table
Reference in a new issue