def _notifs(cls, post, pid, level, payout): # pylint: disable=too-many-locals,too-many-branches author = post['author'] author_id = Accounts.get_id(author) parent_author = post['parent_author'] date = post['last_update'] # reply notif if level == 'insert' and parent_author and parent_author != author: irredeemable = parent_author in Mutes.all() parent_author_id = Accounts.get_id(parent_author) if not irredeemable and not cls._muted(parent_author_id, author_id): ntype = 'reply' if post['depth'] == 1 else 'reply_comment' Notify(ntype, src_id=author_id, dst_id=parent_author_id, score=Accounts.default_score(author), post_id=pid, when=date).write() # mentions notif if level in ('insert', 'update'): accounts = set(filter(Accounts.exists, mentions(post['body']))) accounts -= {author, parent_author} score = Accounts.default_score(author) if score < 30: max_mentions = 5 elif score < 60: max_mentions = 10 else: max_mentions = 25 if len(accounts) <= max_mentions: penalty = min([score, 2 * (len(accounts) - 1)]) for mention in accounts: mention_id = Accounts.get_id(mention) if (not cls._mentioned(pid, mention_id) and not cls._muted(mention_id, author_id)): Notify('mention', src_id=author_id, dst_id=mention_id, post_id=pid, when=date, score=(score - penalty)).write() else: url = '@%s/%s' % (author, post['permlink']) log.info("skip %d mentions in %s", len(accounts), url) # votes notif url = post['author'] + '/' + post['permlink'] if url in cls._votes: voters = cls._votes[url] del cls._votes[url] net = float(post['net_rshares']) ratio = float(payout) / net if net else 0 for vote in post['active_votes']: rshares = int(vote['rshares']) if vote['voter'] not in voters or rshares < 10e9: continue contrib = int(1000 * ratio * rshares) if contrib < 20: continue # < $0.020 voter_id = Accounts.get_id(vote['voter']) if not cls._voted(pid, author_id, voter_id): score = min(100, (len(str(contrib)) - 1) * 25) # $1 = 75 payload = "$%.3f" % (contrib / 1000) Notify('vote', src_id=voter_id, dst_id=author_id, when=vote['time'], post_id=pid, score=score, payload=payload).write()
def follow_op(cls, account, op_json, date): """Process an incoming follow op.""" op = cls._validated_op(account, op_json, date) if not op: return # perform delta check new_state = op['state'] old_state = cls._get_follow_db_state(op['flr'], op['flg']) if new_state == (old_state or 0): return # insert or update state if old_state is None: sql = """INSERT INTO hive_follows (follower, following, created_at, state) VALUES (:flr, :flg, :at, :state)""" else: sql = """UPDATE hive_follows SET state = :state WHERE follower = :flr AND following = :flg""" DB.query(sql, **op) # track count deltas if not DbState.is_initial_sync(): if new_state == 1: Follow.follow(op['flr'], op['flg']) if old_state is None: score = Accounts.default_score(op_json['follower']) Notify('follow', src_id=op['flr'], dst_id=op['flg'], when=op['at'], score=score).write() if old_state == 1: Follow.unfollow(op['flr'], op['flg'])
def reblog(cls, account, op_json, block_date): """Handle legacy 'reblog' op""" if ('account' not in op_json or 'author' not in op_json or 'permlink' not in op_json): return blogger = op_json['account'] author = op_json['author'] permlink = op_json['permlink'] if blogger != account: return # impersonation if not all(map(Accounts.exists, [author, blogger])): return post_id, depth = Posts.get_id_and_depth(author, permlink) if depth > 0: return # prevent comment reblogs if not post_id: log.debug("reblog: post not found: %s/%s", author, permlink) return author_id = Accounts.get_id(author) blogger_id = Accounts.get_id(blogger) if 'delete' in op_json and op_json['delete'] == 'delete': DB.query( "DELETE FROM hive_reblogs WHERE account = :a AND " "post_id = :pid LIMIT 1", a=blogger, pid=post_id) if not DbState.is_initial_sync(): FeedCache.delete(post_id, blogger_id) else: sql = ( "INSERT INTO hive_reblogs (account, post_id, created_at) " "VALUES (:a, :pid, :date) ON CONFLICT (account, post_id) DO NOTHING" ) DB.query(sql, a=blogger, pid=post_id, date=block_date) if not DbState.is_initial_sync(): FeedCache.insert(post_id, blogger_id, block_date) Notify('reblog', src_id=blogger_id, dst_id=author_id, post_id=post_id, when=block_date, score=Accounts.default_score(blogger)).write()