Example #1
0
def test_post_stats():
    ret = post_stats(POST_1)
    expect = {'hide': False,
              'gray': False,
              'author_rep': 49.03,
              'flag_weight': 0,
              'total_votes': 4,
              'up_votes': 4}
    assert ret == expect
Example #2
0
    def _sql(cls, pid, post, level=None):
        """Given a post and "update level", generate SQL edit statement.

        Valid levels are:
         - `insert`: post does not yet exist in cache
         - `update`: post was modified
         - `payout`: post was paidout
         - `upvote`: post payout/votes changed
        """

        #pylint: disable=bad-whitespace
        assert post['author'], "post {} is blank".format(pid)

        # last-minute sanity check to ensure `pid` is correct #78
        pid2 = cls._get_id(post['author'] + '/' + post['permlink'])
        assert pid == pid2, "hpc id %d maps to %d" % (pid, pid2)

        # inserts always sequential. if pid > last_id, this operation
        # *must* be an insert; so `level` must not be any form of update.
        if pid > cls.last_id() and level != 'insert':
            raise Exception("WARNING: new pid, but level=%s. #%d vs %d, %s" %
                            (level, pid, cls.last_id(), repr(post)))

        # start building the queries
        tag_sqls = []
        values = [('post_id', pid)]

        # immutable; write only once (*edge case: undeleted posts)
        if level == 'insert':
            values.extend([('author', post['author']),
                           ('permlink', post['permlink']),
                           ('category', post['category']),
                           ('depth', post['depth'])])

        # always write, unless simple vote update
        if level in ['insert', 'payout', 'update']:
            basic = post_basic(post)
            values.extend([
                ('created_at', post['created']),  # immutable*
                ('updated_at', post['last_update']),
                ('title', post['title']),
                ('payout_at', basic['payout_at']),  # immutable*
                ('preview', basic['preview']),
                ('body', basic['body']),
                ('img_url', basic['image']),
                ('is_nsfw', basic['is_nsfw']),
                ('is_declined', basic['is_payout_declined']),
                ('is_full_power', basic['is_full_power']),
                ('is_paidout', basic['is_paidout']),
                ('json', json.dumps(basic['json_metadata'])),
                ('raw_json', json.dumps(post_legacy(post))),
                ('children', min(post['children'], 32767))
            ])

        # update tags if action is insert/update and is root post
        if level in ['insert', 'update'] and not post['depth']:
            diff = level != 'insert'  # do not attempt tag diff on insert
            tag_sqls.extend(cls._tag_sqls(pid, basic['tags'], diff=diff))

        # if there's a pending promoted value to write, pull it out
        if pid in cls._pending_promoted:
            bal = cls._pending_promoted[pid]
            values.append(('promoted', bal))
            del cls._pending_promoted[pid]

        # update unconditionally
        payout = post_payout(post)
        stats = post_stats(post)
        values.extend([('payout', "%f" % payout['payout']),
                       ('rshares', "%d" % payout['rshares']),
                       ('votes', "%s" % payout['csvotes']),
                       ('sc_trend', "%f" % payout['sc_trend']),
                       ('sc_hot', "%f" % payout['sc_hot']),
                       ('flag_weight', "%f" % stats['flag_weight']),
                       ('total_votes', "%d" % stats['total_votes']),
                       ('up_votes', "%d" % stats['up_votes']),
                       ('is_hidden', "%d" % stats['hide']),
                       ('is_grayed', "%d" % stats['gray']),
                       ('author_rep', "%f" % stats['author_rep'])])

        # build the post insert/update SQL, add tag SQLs
        mode = 'insert' if level == 'insert' else 'update'
        return [cls._write_sql(values, mode)] + tag_sqls
Example #3
0
    def _sql(cls, pid, post, level=None):
        """Given a post and "update level", generate SQL edit statement.

        Valid levels are:
         - `insert`: post does not yet exist in cache
         - `payout`: post was paidout
         - `update`: post was modified
         - `upvote`: post payout/votes changed
         - `recount`: post child count changed
        """

        #pylint: disable=bad-whitespace
        assert post['author'], "post {} is blank".format(pid)

        # last-minute sanity check to ensure `pid` is correct #78
        pid2 = cls._get_id(post['author'] + '/' + post['permlink'])
        assert pid == pid2, "hpc id %d maps to %d" % (pid, pid2)

        # inserts always sequential. if pid > last_id, this operation
        # *must* be an insert; so `level` must not be any form of update.
        if pid > cls.last_id() and level != 'insert':
            raise Exception("WARNING: new pid, but level=%s. #%d vs %d, %s" %
                            (level, pid, cls.last_id(), repr(post)))

        # start building the queries
        acc_id = Accounts.get_id(post['author'])
        values = [('post_id', pid)]

        # immutable; write only once (*edge case: undeleted posts)
        if level == 'insert':
            values.extend([('author', post['author']),
                           ('permlink', post['permlink']),
                           ('category', post['category']),
                           ('depth', post['depth'])])

        # always write, unless simple vote update
        if level in ['insert', 'payout', 'update']:
            basic = post_basic(post)
            values.extend([
                ('community_id', post['community_id']),  # immutable*
                ('created_at', post['created']),  # immutable*
                ('updated_at', post['last_update']),
                ('title', post['title']),
                ('payout_at', basic['payout_at']),  # immutable*
                ('preview', basic['preview']),
                ('body', basic['body']),
                ('img_url', basic['image']),
                ('is_nsfw', basic['is_nsfw']),
                ('is_declined', basic['is_payout_declined']),
                ('is_full_power', basic['is_full_power']),
                ('is_paidout', basic['is_paidout']),
                ('json', json.dumps(basic['json_metadata'])),
                ('raw_json', json.dumps(post_legacy(post))),
            ])

        # if there's a pending promoted value to write, pull it out
        if pid in cls._pending_promoted:
            bal = cls._pending_promoted.pop(pid)
            values.append(('promoted', bal))

        # update unconditionally
        payout = post_payout(post)
        stats = post_stats(post)

        # //--
        # if community - override fields.
        # TODO: make conditional (date-based?)
        assert 'community_id' in post, 'comm_id not loaded'
        if post['community_id']:
            stats['hide'] = post['hide']
            stats['gray'] = post['gray']
        # //--

        values.extend([
            ('payout', payout['payout']),
            ('rshares', payout['rshares']),
            ('votes', payout['csvotes']),
            ('sc_trend', payout['sc_trend']),
            ('sc_hot', payout['sc_hot']),
            ('flag_weight', stats['flag_weight']),
            ('total_votes', stats['total_votes']),
            ('up_votes', stats['up_votes']),
            ('is_hidden', stats['hide']),
            ('is_grayed', stats['gray']),
            ('author_rep', stats['author_rep']),
            ('children', min(post['children'], 32767)),
        ])

        # update tags if action is insert/update and is root post
        tag_sqls = []
        if level in ['insert', 'update'] and not post['depth']:
            diff = level != 'insert'  # do not attempt tag diff on insert
            tag_sqls.extend(cls._tag_sqls(pid, basic['tags'], diff=diff))

        # if recounting, update the parent next pass.
        if level == 'recount' and post['depth']:
            cls.recount(post['parent_author'], post['parent_permlink'])

        # trigger any notifications
        cls._notifs(post, pid, level, payout['payout'])

        # build the post insert/update SQL, add tag SQLs
        if level == 'insert':
            sql = cls._insert(values)
            # process new native ad, if valid
            ad_sql = NativeAd.process_ad(values, acc_id)
        else:
            sql = cls._update(values)
            # update ad content, if draft(0) in all communities
            ad_sql = NativeAd.process_ad(values, acc_id, new=False)

        # return ad SQL only if it is present
        if ad_sql is not None:
            _final = [sql] + tag_sqls + [ad_sql]
        else:
            _final = [sql] + tag_sqls

        return _final