示例#1
0
 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
示例#2
0
 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
示例#3
0
    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)
示例#4
0
    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 )
示例#5
0
    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)
示例#6
0
    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']
示例#7
0
 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)
示例#8
0
文件: posts.py 项目: Dito24/hivemind
    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)