def validated_id(cls, name): """Verify `name` as a candidate and check for record id.""" if name: if name in cls._ids: return cls._ids[name] if cls.validated_name(name): if Accounts.exists(name): return cls.get_id(name) return None
def _get_op_community(cls, comment): md = load_json_key(comment, 'json_metadata') if not md or not isinstance(md, dict) or 'community' not in md: return None community = md['community'] if not isinstance(community, str): return None if not Accounts.exists(community): return None return community
def _validated_op(cls, account, op, date): """Validate and normalize the operation.""" if (not 'what' in op or not isinstance(op['what'], list) or not 'follower' in op or not 'following' in op): return what = first(op['what']) or '' defs = {'': 0, 'blog': 1, 'ignore': 2} if what not in defs: return if (op['follower'] == op['following'] # can't follow self or op['follower'] != account # impersonation or not Accounts.exists(op['following']) # invalid account or not Accounts.exists(op['follower'])): # invalid account return return dict(flr=Accounts.get_id(op['follower']), flg=Accounts.get_id(op['following']), state=defs[what], at=date)
def _validated_op(cls, actor, op, block_date, block_num): if 'account' not in op or \ 'author' not in op or \ 'permlink' not in op: return None if op['account'] != actor: return None # impersonation if not Accounts.exists(op['account']): return None if not Accounts.exists(op['author']): return None _delete = True if ('delete' in op and op['delete'] == 'delete') else False return dict(author = op['author'], permlink = op['permlink'], account = op['account'], block_date = block_date, block_num = block_num, delete = _delete )
def _validated_op(cls, account, op, date): """Validate and normalize the operation.""" if (not 'what' in op or not isinstance(op['what'], list) or not 'follower' in op or not 'following' in op): log.info("follow_op %s ignored due to basic errors", op) return None what = first(op['what']) or '' # ABW: the empty 'what' is used to clear existing 'blog' or 'ignore' state, however it can also be used to # introduce new empty relation record in hive_follows adding unnecessary data (it might become a problem # only if we wanted to immediately remove empty records) # we could add aliases for '' - 'unfollow' and 'unignore'/'unmute' # we could add alias for 'ignore' - 'mute' defs = {'': Action.Nothing, 'blog': Action.Blog, 'follow': Action.Blog, 'ignore': Action.Ignore, 'blacklist': Action.Blacklist, 'follow_blacklist': Action.Follow_blacklist, 'unblacklist': Action.Unblacklist, 'unfollow_blacklist': Action.Unfollow_blacklist, 'follow_muted': Action.Follow_muted, 'unfollow_muted': Action.Unfollow_muted, 'reset_blacklist' : Action.Reset_blacklist, 'reset_following_list': Action.Reset_following_list, 'reset_muted_list': Action.Reset_muted_list, 'reset_follow_blacklist': Action.Reset_follow_blacklist, 'reset_follow_muted_list': Action.Reset_follow_muted_list, 'reset_all_lists': Action.Reset_all_lists} if not isinstance(what, str) or what not in defs: log.info("follow_op %s ignored due to unknown type of follow", op) return None # follower is empty or follower account does not exist, or it wasn't that account that authorized operation if not op['follower'] or not Accounts.exists(op['follower']) or op['follower'] != account: log.info("follow_op %s ignored due to invalid follower", op) return None # normalize following to list op['following'] = op['following'] if isinstance(op['following'], list) else [op['following']] # if following name does not exist do not process it: basically equal to drop op for single following entry op['following'] = [following for following in op['following'] if following and Accounts.exists(following) and following != op['follower']] # ABW: note that since you could make 'following' list empty anyway by supplying nonexisting account # there was no point in excluding follow_op with provided empty list/empty string - such call actually # makes sense for state > 8 when 'following' is ignored state = defs[what] if not op['following'] and state < Action.Reset_blacklist: log.info("follow_op %s is void due to effectively empty list of following", op) return None return dict(follower=escape_characters(op['follower']), following=[escape_characters(following) for following in op['following']], state=state, at=date)
def _get_op_community(cls, comment, date): """Given a comment op, safely read 'community' field from json. Ensures value is readable and referenced account exists. """ # short-circuit pre-launch if date < '2018-07-01': return None md = load_json_key(comment, 'json_metadata') if (not md or not isinstance(md, dict) or not 'community' in md or not isinstance(md['community'], str) or not Accounts.exists(md['community'])): return None return md['community']
def _read_account(self): _name = read_key_str(self.op, 'account', 16) assert _name, 'must name an account' assert Accounts.exists(_name), 'account `%s` not found' % _name self.account = _name self.account_id = Accounts.get_id(_name)
def register(cls, ops, block_date): from hive.indexer.community import is_community_post_valid for op in ops: sql = ("SELECT id, is_deleted FROM hive_posts " "WHERE author = :a AND permlink = :p") ret = query_row(sql, a=op['author'], p=op['permlink']) pid = None if not ret: # post does not exist, go ahead and process it pass elif not ret[1]: # post exists and is not deleted, thus it's an edit. ignore. continue else: # post exists but was deleted. time to reinstate. pid = ret[0] # set parent & inherited attributes if op['parent_author'] == '': parent_id = None depth = 0 category = op['parent_permlink'] community = cls._get_op_community(op) or op['author'] else: parent_data = query_row( "SELECT id, depth, category, community FROM hive_posts WHERE author = :a " "AND permlink = :p", a=op['parent_author'], p=op['parent_permlink']) parent_id, parent_depth, category, community = parent_data depth = parent_depth + 1 # community must be an existing account if not Accounts.exists(community): community = op['author'] # validated community; will return None if invalid & defaults to author. is_valid = is_community_post_valid(community, op) if not is_valid: print("Invalid post @{}/{} in @{}".format( op['author'], op['permlink'], community)) # if we're reusing a previously-deleted post (rare!), update it if pid: query( "UPDATE hive_posts SET is_valid = :is_valid, is_deleted = '0', parent_id = :parent_id, category = :category, community = :community, depth = :depth WHERE id = :id", is_valid=is_valid, parent_id=parent_id, category=category, community=community, depth=depth, id=pid) else: sql = """ INSERT INTO hive_posts (is_valid, parent_id, author, permlink, category, community, depth, created_at) VALUES (:is_valid, :parent_id, :author, :permlink, :category, :community, :depth, :date) """ query(sql, is_valid=is_valid, parent_id=parent_id, author=op['author'], permlink=op['permlink'], category=category, community=community, depth=depth, date=block_date) pid = query_one( "SELECT id FROM hive_posts WHERE author = :a AND " "permlink = :p", a=op['author'], p=op['permlink']) # add top-level posts to feed cache if not op['parent_permlink']: sql = "INSERT INTO hive_feed_cache (account_id, post_id, created_at) VALUES (:account_id, :id, :created_at)" query(sql, account_id=Accounts.get_id(op['author']), id=pid, created_at=block_date)