Exemple #1
0
    def _process_legacy(cls, account, op_json, block_date):
        """Handle legacy 'follow' plugin ops (follow/mute/clear, reblog)

        follow {follower: {type: 'account'},
                following: {type: 'account'},
                what: {type: 'list'}}
        reblog {account: {type: 'account'},
                author: {type: 'account'},
                permlink: {type: 'permlink'},
                delete: {type: 'str', optional: True}}
        """
        if not isinstance(op_json, list):
            return
        if len(op_json) != 2:
            return
        if first(op_json) not in ['follow', 'reblog']:
            return
        if not isinstance(second(op_json), dict):
            return

        cmd, op_json = op_json  # ['follow', {data...}]
        if cmd == 'follow':
            Follow.follow_op(account, op_json, block_date)
        elif cmd == 'reblog':
            cls.reblog(account, op_json, block_date)
Exemple #2
0
    def _process_legacy(cls, account, op_json, block_date):
        """Handle legacy 'follow' plugin ops (follow/mute/clear, reblog)"""
        if not isinstance(op_json, list):
            return
        if len(op_json) != 2:
            return
        if first(op_json) not in ['follow', 'reblog']:
            return
        if not isinstance(second(op_json), dict):
            return

        cmd, op_json = op_json  # ['follow', {data...}]
        if cmd == 'follow':
            Follow.follow_op(account, op_json, block_date)
        elif cmd == 'reblog':
            cls.reblog(account, op_json, block_date)
Exemple #3
0
def process_json_follow_op(account, op_json, block_date):
    """ Process legacy 'follow' plugin ops (follow/mute/clear, reblog) """
    if type(op_json) != list:
        return
    if len(op_json) != 2:
        return
    if first(op_json) not in ['follow', 'reblog']:
        return
    if not isinstance(second(op_json), dict):
        return

    cmd, op_json = op_json  # ['follow', {data...}]
    if cmd == 'follow':
        if type(op_json['what']) != list:
            return
        what = first(op_json['what']) or 'clear'
        if what not in ['blog', 'clear', 'ignore']:
            return
        if not all([key in op_json for key in ['follower', 'following']]):
            print("bad follow op: {} {}".format(block_date, op_json))
            return

        follower = op_json['follower']
        following = op_json['following']

        if follower != account:
            return  # impersonation
        if not all(filter(is_valid_account_name, [follower, following])):
            return  # invalid input

        sql = """
        INSERT IGNORE INTO hive_follows (follower, following, created_at, state)
        VALUES (:fr, :fg, :at, :state) ON DUPLICATE KEY UPDATE state = :state
        """
        state = {'clear': 0, 'blog': 1, 'ignore': 2}[what]
        query(sql, fr=follower, fg=following, at=block_date, state=state)

    elif cmd == 'reblog':
        blogger = op_json['account']
        author = op_json['author']
        permlink = op_json['permlink']

        if blogger != account:
            return  # impersonation
        if not all(filter(is_valid_account_name, [author, blogger])):
            return

        post_id, depth = get_post_id_and_depth(author, permlink)

        if depth > 0:
            return  # prevent comment reblogs

        if not post_id:
            print("reblog: post not found: {}/{}".format(author, permlink))
            return

        if 'delete' in op_json and op_json['delete'] == 'delete':
            query(
                "DELETE FROM hive_reblogs WHERE account = :a AND post_id = :pid LIMIT 1",
                a=blogger,
                pid=post_id)
            sql = "DELETE FROM hive_feed_cache WHERE account = :account AND post_id = :id"
            query(sql, account=blogger, id=post_id)
        else:
            query(
                "INSERT IGNORE INTO hive_reblogs (account, post_id, created_at) "
                "VALUES (:a, :pid, :date)",
                a=blogger,
                pid=post_id,
                date=block_date)
            sql = "INSERT IGNORE INTO hive_feed_cache (account, post_id, created_at) VALUES (:account, :id, :created_at)"
            query(sql, account=blogger, id=post_id, created_at=block_date)
Exemple #4
0
def parse_operation(op):
    """ Update all relevant collections that this op impacts. """
    op_type = op['type']

    update_accounts_light = set()
    update_accounts_full = set()
    update_comments = set()

    def construct_identifier():
        return '@%s/%s' % (
            op.get('author', op.get('comment_author')),
            op.get('permlink', op.get('comment_permlink')),
        )

    def account_from_auths():
        return first(op.get('required_auths',
                            op.get('required_posting_auths')))

    if op_type in ['account_create', 'account_create_with_delegation']:
        update_accounts_light.add(op['creator'])
        update_accounts_full.add(op['new_account_name'])

    elif op_type in [
            'account_update', 'withdraw_vesting', 'claim_reward_balance',
            'return_vesting_delegation', 'account_witness_vote'
    ]:
        update_accounts_light.add(op['account'])

    elif op_type == 'account_witness_proxy':
        update_accounts_light.add(op['account'])
        update_accounts_light.add(op['proxy'])

    elif op_type in ['author_reward', 'comment']:
        update_accounts_light.add(op['author'])
        update_comments.add(construct_identifier())

    elif op_type == 'cancel_transfer_from_savings':
        update_accounts_light.add(op['from'])

    elif op_type == 'change_recovery_account':
        update_accounts_light.add(op['account_to_recover'])

    elif op_type == 'comment_benefactor_reward':
        update_accounts_light.add(op['benefactor'])

    elif op_type == [
            'convert', 'fill_convert_request', 'interest',
            'limit_order_cancel', 'limit_order_create', 'shutdown_witness',
            'witness_update'
    ]:
        update_accounts_light.add(op['owner'])

    elif op_type == 'curation_reward':
        update_accounts_light.add(op['curator'])

    elif op_type in ['custom', 'custom_json']:
        update_accounts_light.add(account_from_auths())

    elif op_type == 'delegate_vesting_shares':
        update_accounts_light.add(op['delegator'])
        update_accounts_light.add(op['delegatee'])

    elif op_type == 'delete_comment':
        update_accounts_light.add(op['author'])

    elif op_type in [
            'escrow_approve', 'escrow_dispute', 'escrow_release',
            'escrow_transfer'
    ]:
        accs = keep_in_dict(
            op, ['agent', 'from', 'to', 'who', 'receiver']).values()
        update_accounts_light.update(accs)

    elif op_type == 'feed_publish':
        update_accounts_light.add(op['publisher'])

    elif op_type in ['fill_order']:
        update_accounts_light.add(op['open_owner'])
        update_accounts_light.add(op['current_owner'])

    elif op_type in ['fill_vesting_withdraw']:
        update_accounts_light.add(op['to_account'])
        update_accounts_light.add(op['from_account'])

    elif op_type == 'pow2':
        acc = op['work'][1]['input']['worker_account']
        update_accounts_light.add(acc)

    elif op_type in ['recover_account', 'request_account_recovery']:
        update_accounts_light.add(op['account_to_recover'])

    elif op_type == 'set_withdraw_vesting_route':
        update_accounts_light.add(op['from_account'])
        # update_accounts_light.add(op['to_account'])
    elif op_type in [
            'transfer', 'transfer_from_savings', 'transfer_to_savings',
            'transfer_to_vesting'
    ]:
        accs = keep_in_dict(
            op, ['agent', 'from', 'to', 'who', 'receiver']).values()
        update_accounts_light.update(accs)

    elif op_type == 'vote':
        update_accounts_light.add(op['voter'])
        update_comments.add(construct_identifier())

    # handle followers
    if op_type == 'custom_json':
        with suppress(ValueError):
            cmd, op_json = json.loads(op['json'])  # ['follow', {data...}]
            if cmd == 'follow':
                accs = keep_in_dict(op_json,
                                    ['follower', 'following']).values()
                update_accounts_light.discard(first(accs))
                update_accounts_light.discard(second(accs))
                update_accounts_full.update(accs)

    return {
        'accounts': list(update_accounts_full),
        'accounts_light': list(update_accounts_light),
        'comments': list(update_comments),
    }
Exemple #5
0
def process_json_follow_op(account, op_json, block_date):
    """ This method processes any legacy 'follow' plugin ops (follow/mute/clear, reblog) """
    if type(op_json) != list:
        return
    if first(op_json) not in ['follow', 'reblog']:
        return
    if not isinstance(second(op_json), dict):
        return

    cmd, op_json = op_json  # ['follow', {data...}]
    if cmd == 'follow':
        if type(op_json['what']) != list:
            return
        what = first(op_json['what']) or 'clear'
        if what not in ['blog', 'clear', 'ignore']:
            return

        follower = op_json['follower']
        following = op_json['following']

        if follower != account:
            return  # impersonation attempt
        if not all(filter(is_valid_account_name, [follower, following])):
            return

        if what == 'clear':
            query("DELETE FROM hive_follows WHERE follower = '%s' "
                  "AND following = '%s' LIMIT 1" % (follower, following))
        else:
            fields = {
                'follower': follower,
                'following': following,
                'created_at': block_date,
                'is_muted': int(what == 'ignore')
            }
            query(
                "INSERT IGNORE INTO hive_follows (follower, following, created_at, is_muted) "
                "VALUES (:follower, :following, :created_at, :is_muted) "
                "ON DUPLICATE KEY UPDATE is_muted = :is_muted", **fields)

    elif cmd == 'reblog':
        blogger = op_json['account']
        author = op_json['author']
        permlink = op_json['permlink']

        if blogger != account:
            return  # impersonation
        if not all(filter(is_valid_account_name, [author, blogger])):
            return

        post_id, depth = get_post_id_and_depth(author, permlink)

        if depth > 0:
            return  # prevent comment reblogs

        if 'delete' in op_json and op_json['delete'] == 'delete':
            query(
                "DELETE FROM hive_reblogs WHERE account = '%s' AND post_id = %d LIMIT 1"
                % (blogger, post_id))
        else:
            query(
                "INSERT IGNORE INTO hive_reblogs (account, post_id, created_at) "
                "VALUES ('%s', %d, '%s')" % (blogger, post_id, block_date))