def test_post_basic(): ret = post_basic(POST_1) expect = { 'json_metadata': { 'tags': ['spam'], 'image': [ 'https://pbs.twimg.com/media/DBgNm3jXoAAioyE.jpg', 'https://example.com/image.jpg' ], 'app': 'steemit/0.1', 'format': 'markdown' }, 'image': 'https://pbs.twimg.com/media/DBgNm3jXoAAioyE.jpg', 'tags': ['spam'], 'is_nsfw': False, 'body': 'https://pbs.twimg.com/media/DBgNm3jXoAAioyE.jpg', 'preview': 'https://pbs.twimg.com/media/DBgNm3jXoAAioyE.jpg', 'payout_at': '2017-06-27T15:53:51', 'is_paidout': True, 'is_payout_declined': False, 'is_full_power': False } assert ret == expect
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
def test_post_basic_tags(): tags = post_basic(POST_2)['tags'] expected = ['steemit', 'steem', 'abc', 'bcd', 'cde'] assert tags == expected, "got %s" % tags
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