def post_payout(post): """Get current vote/payout data and recalculate trend/hot score.""" # total payout (completed and/or pending) payout = sum([ sbd_amount(post['total_payout_value']), sbd_amount(post['curator_payout_value']), sbd_amount(post['pending_payout_value']), ]) # `active_votes` was temporarily missing in dev -- ensure this condition # is caught ASAP. if no active_votes then rshares MUST be 0. ref: steem#2568 assert post['active_votes'] or int(post['net_rshares']) == 0 # get total rshares, and create comma-separated vote data blob rshares = sum(int(v['rshares']) for v in post['active_votes']) csvotes = "\n".join(map(_vote_csv_row, post['active_votes'])) # trending scores _timestamp = utc_timestamp(parse_time(post['created'])) sc_trend = _score(rshares, _timestamp, 480000) sc_hot = _score(rshares, _timestamp, 10000) return { 'payout': payout, 'rshares': rshares, 'csvotes': csvotes, 'sc_trend': sc_trend, 'sc_hot': sc_hot }
def post_payout(post): """Get current vote/payout data and recalculate trend/hot score.""" # total payout (completed and/or pending) payout = sum([ sbd_amount(post['total_payout_value']), sbd_amount(post['curator_payout_value']), sbd_amount(post['pending_payout_value']), ]) # get total rshares, and create comma-separated vote data blob rshares = sum(int(v['rshares']) for v in post['active_votes']) csvotes = "\n".join(map(_vote_csv_row, post['active_votes'])) # trending scores _timestamp = parse_time(post['created']).timestamp() sc_trend = score(rshares, _timestamp, 480000) sc_hot = score(rshares, _timestamp, 10000) return { 'payout': payout, 'rshares': rshares, 'csvotes': csvotes, 'sc_trend': sc_trend, 'sc_hot': sc_hot }
def post_stats(post): """Get post statistics and derived properties. Source: contentStats - https://github.com/steemit/condenser/blob/master/src/app/utils/StateFunctions.js#L109 """ neg_rshares = 0 total_votes = 0 up_votes = 0 for vote in post['active_votes']: rshares = int(vote['rshares']) if rshares == 0: continue total_votes += 1 if rshares > 0: up_votes += 1 if rshares < 0: neg_rshares += rshares # take negative rshares, divide by 2, truncate 10 digits (plus neg sign), # and count digits. creates a cheap log10, stake-based flag weight. # result: 1 = approx $400 of downvoting stake; 2 = $4,000; etc flag_weight = max((len(str(int(neg_rshares / 2))) - 11, 0)) author_rep = rep_log10(post['author_reputation']) has_pending_payout = sbd_amount(post['pending_payout_value']) >= 0.02 return { 'hide': author_rep < 0 and not has_pending_payout, 'gray': author_rep < 1, 'author_rep': author_rep, 'flag_weight': flag_weight, 'total_votes': total_votes, 'up_votes': up_votes }
def database_post_object(row, truncate_body=0): """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] post = {} post['author_rewards'] = row['author_rewards'] post['id'] = row['id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row['category'] if 'category' in row else 'undefined' post['title'] = row['title'] post['body'] = row['body'][0:truncate_body] if truncate_body else row['body'] post['json_metadata'] = row['json'] post['created'] = json_date(row['created_at']) post['last_update'] = json_date(row['updated_at']) post['depth'] = row['depth'] post['children'] = row['children'] post['last_payout'] = json_date(row['last_payout_at']) post['cashout_time'] = json_date(row['cashout_time']) post['max_cashout_time'] = json_date(None) # ABW: only relevant up to HF17, timestamp::max for all posts later (and also all paid) curator_payout = sbd_amount(row['curator_payout_value']) post['curator_payout_value'] = to_nai(_amount(curator_payout)) post['total_payout_value'] = to_nai(_amount(row['payout'] - curator_payout)) post['reward_weight'] = 10000 # ABW: only relevant between HF12 and HF17 and we don't have access to correct value post['root_author'] = row['root_author'] post['root_permlink'] = row['root_permlink'] post['allow_replies'] = row['allow_replies'] post['allow_votes'] = row['allow_votes'] post['allow_curation_rewards'] = row['allow_curation_rewards'] post['parent_author'] = row['parent_author'] post['parent_permlink'] = row['parent_permlink_or_category'] post['beneficiaries'] = row['beneficiaries'] post['max_accepted_payout'] = to_nai(row['max_accepted_payout']) post['percent_hbd'] = row['percent_hbd'] post['net_votes'] = row['net_votes'] if paid: post['total_vote_weight'] = 0 post['vote_rshares'] = 0 post['net_rshares'] = 0 # if row['rshares'] > 0 else row['rshares'] ABW: used to be like this but after HF19 cashouts disappear and all give 0 post['abs_rshares'] = 0 post['children_abs_rshares'] = 0 else: post['total_vote_weight'] = row['total_vote_weight'] post['vote_rshares'] = ( row['rshares'] + row['abs_rshares'] ) // 2 # effectively sum of all positive rshares post['net_rshares'] = row['rshares'] post['abs_rshares'] = row['abs_rshares'] post['children_abs_rshares'] = 0 # TODO - ABW: I'm not sure about that, it is costly and useless (used to be part of mechanism to determine cashout time) return post
def post_stats(post): """Get post statistics and derived properties. Source: contentStats - https://github.com/steemit/condenser/blob/master/src/app/utils/StateFunctions.js#L109 """ net_rshares_adj = 0 neg_rshares = 0 total_votes = 0 up_votes = 0 for vote in post['active_votes']: if vote['percent'] == 0: continue total_votes += 1 rshares = int(vote['rshares']) sign = 1 if vote['percent'] > 0 else -1 if sign > 0: up_votes += 1 if sign < 0: neg_rshares += rshares # For graying: sum rshares, but ignore neg rep users and dust downvotes neg_rep = str(vote['reputation'])[0] == '-' if not (neg_rep and sign < 0 and len(str(rshares)) < 11): net_rshares_adj += rshares # take negative rshares, divide by 2, truncate 10 digits (plus neg sign), # and count digits. creates a cheap log10, stake-based flag weight. # result: 1 = approx $400 of downvoting stake; 2 = $4,000; etc flag_weight = max((len(str(neg_rshares / 2)) - 11, 0)) author_rep = rep_log10(post['author_reputation']) is_low_value = net_rshares_adj < -9999999999 has_pending_payout = sbd_amount(post['pending_payout_value']) >= 0.02 return { 'hide': not has_pending_payout and (author_rep < 0), 'gray': not has_pending_payout and (author_rep < 1 or is_low_value), 'author_rep': author_rep, 'flag_weight': flag_weight, 'total_votes': total_votes, 'up_votes': up_votes }
def _bridge_post_object(row, truncate_body=0): """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] post = {} post['post_id'] = row['id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row.get('category', 'undefined') post['title'] = row['title'] post['body'] = row['body'][0:truncate_body] if truncate_body else row[ 'body'] try: post['json_metadata'] = json.loads(row['json']) except Exception: post['json_metadata'] = {} post['created'] = json_date(row['created_at']) post['updated'] = json_date(row['updated_at']) post['depth'] = row['depth'] post['children'] = row['children'] post['net_rshares'] = row['rshares'] post['is_paidout'] = row['is_paidout'] post['payout_at'] = json_date(row['payout_at']) post['payout'] = float(row['payout'] + row['pending_payout']) post['pending_payout_value'] = _amount(0 if paid else post['payout']) post['author_payout_value'] = _amount(0) # supplemented below post['curator_payout_value'] = _amount(0) # supplemented below post['promoted'] = _amount(row['promoted']) post['replies'] = [] post['author_reputation'] = rep_log10(row['author_rep']) neg_rshares = (row['rshares'] - row['abs_rshares'] ) // 2 # effectively sum of all negative rshares # take negative rshares, divide by 2, truncate 10 digits (plus neg sign), # and count digits. creates a cheap log10, stake-based flag weight. # result: 1 = approx $400 of downvoting stake; 2 = $4,000; etc flag_weight = max((len(str(int(neg_rshares / 2))) - 11, 0)) post['stats'] = { 'hide': row['is_hidden'], 'gray': row['is_grayed'], 'total_votes': row['total_votes'], 'flag_weight': float(flag_weight) } # TODO: down_weight #post['author_reputation'] = rep_to_raw(row['author_rep']) post['url'] = row['url'] post['beneficiaries'] = row['beneficiaries'] post['max_accepted_payout'] = row['max_accepted_payout'] post['percent_hbd'] = row['percent_hbd'] if paid: curator_payout = sbd_amount(row['curator_payout_value']) post['author_payout_value'] = _amount(row['payout'] - curator_payout) post['curator_payout_value'] = _amount(curator_payout) # TODO: re-evaluate if row['depth'] > 0: post['parent_author'] = row['parent_author'] post['parent_permlink'] = row['parent_permlink_or_category'] post['title'] = 'RE: ' + row[ 'root_title'] # PostSummary & comment context return post
def test_sbd_amount(): assert sbd_amount('1.001 SBD') == Decimal('1.001')
def post_basic(post): """Basic post normalization: json-md, tags, and flags.""" md = {} try: md = json.loads(post['json_metadata']) if not isinstance(md, dict): md = {} except Exception: pass thumb_url = '' if md and 'image' in md and md['image']: thumb_url = safe_img_url(first(md['image'])) or '' if thumb_url: md['image'] = [thumb_url] else: del md['image'] # clean up tags, check if nsfw tags = [post['category']] if md and 'tags' in md and isinstance(md['tags'], list): tags = tags + md['tags'] tags = set( list(map(lambda tag: (str(tag) or '').strip('# ').lower()[:32], tags))[0:5]) tags.discard('') is_nsfw = 'nsfw' in tags body = post['body'] if body.find('\x00') > -1: #url = post['author'] + '/' + post['permlink'] body = body.replace('\x00', '[NUL]') # payout date is last_payout if paid, and cashout_time if pending. is_paidout = (post['cashout_time'][0:4] == '1969') payout_at = post['last_payout'] if is_paidout else post['cashout_time'] # payout is declined if max_payout = 0, or if 100% is burned is_payout_declined = False if sbd_amount(post['max_accepted_payout']) == 0: is_payout_declined = True elif len(post['beneficiaries']) == 1: benny = first(post['beneficiaries']) if benny['account'] == 'null' and int(benny['weight']) == 10000: is_payout_declined = True # payout entirely in SP is_full_power = int(post['percent_steem_dollars']) == 0 return { 'json_metadata': md, 'image': thumb_url, 'tags': tags, 'is_nsfw': is_nsfw, 'body': body, 'preview': body[0:1024], 'payout_at': payout_at, 'is_paidout': is_paidout, 'is_payout_declined': is_payout_declined, 'is_full_power': is_full_power, }
def _condenser_post_object(row, truncate_body=0): """Given a hive_posts_cache row, create a legacy-style post object.""" paid = row['is_paidout'] # condenser#3424 mitigation if not row['category']: row['category'] = 'undefined' post = {} post['post_id'] = row['post_id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row['category'] post['title'] = row['title'] post['body'] = row['body'][0:truncate_body] if truncate_body else row[ 'body'] post['json_metadata'] = json.loads(row['json']) post['created'] = json_date(row['created_at']) post['updated'] = json_date(row['updated_at']) post['depth'] = row['depth'] post['children'] = row['children'] post['net_rshares'] = row['rshares'] post['is_paidout'] = row['is_paidout'] post['payout_at'] = json_date(row['payout_at']) post['payout'] = float(row['payout']) post['pending_payout_value'] = _amount(0 if paid else row['payout']) post['author_payout_value'] = _amount(row['payout'] if paid else 0) post['curator_payout_value'] = _amount(0) post['promoted'] = _amount(row['promoted']) post['replies'] = [] post['active_votes'] = _hydrate_active_votes(row['votes']) post['author_reputation'] = row['author_rep'] post['stats'] = { 'hide': row['is_hidden'], 'gray': row['is_grayed'], 'total_votes': row['total_votes'], 'flag_weight': row['flag_weight'] } # import fields from legacy object assert row['raw_json'] assert len(row['raw_json']) > 32 raw_json = json.loads(row['raw_json']) # TODO: move to core, or payout_details post['beneficiaries'] = raw_json['beneficiaries'] post['max_accepted_payout'] = raw_json['max_accepted_payout'] post['percent_steem_dollars'] = raw_json[ 'percent_steem_dollars'] # TODO: systag? if paid: curator_payout = sbd_amount(raw_json['curator_payout_value']) post['author_payout_value'] = _amount(row['payout'] - curator_payout) post['curator_payout_value'] = _amount(curator_payout) # TODO: re-evaluate if row['depth'] > 0: post['parent_author'] = raw_json['parent_author'] post['parent_permlink'] = raw_json['parent_permlink'] post['title'] = 'RE: ' + raw_json[ 'root_title'] # PostSummary & comment context #else: # post['parent_author'] = '' # post['parent_permlink'] = '' post['url'] = raw_json['url'] return post
def post_basic(post): """Basic post normalization: json-md, tags, and flags.""" md = {} # At least one case where jsonMetadata was double-encoded: condenser#895 # jsonMetadata = JSON.parse(jsonMetadata); try: md = json.loads(post['json_metadata']) if not isinstance(md, dict): md = {} except Exception: pass thumb_url = '' if md and 'image' in md: if md['image']: if not isinstance(md['image'], list): md['image'] = [md['image']] md['image'] = list(filter(None, map(safe_img_url, md['image']))) if md['image']: thumb_url = md['image'][0] else: del md['image'] # clean up tags, check if nsfw tags = [post['category']] # if (typeof tags == 'string') tags = tags.split(' '); # legacy condenser compat if md and 'tags' in md and isinstance(md['tags'], list): tags = tags + md['tags'] tags = map(lambda tag: (str(tag) or '').strip('# ').lower()[:32], tags) tags = filter(None, tags) tags = list(distinct(tags))[:5] is_nsfw = 'nsfw' in tags body = post['body'] if body.find('\x00') > -1: #url = post['author'] + '/' + post['permlink'] body = body.replace('\x00', '[NUL]') # payout date is last_payout if paid, and cashout_time if pending. is_paidout = (post['cashout_time'][0:4] == '1969') payout_at = post['last_payout'] if is_paidout else post['cashout_time'] # payout is declined if max_payout = 0, or if 100% is burned is_payout_declined = False if sbd_amount(post['max_accepted_payout']) == 0: is_payout_declined = True elif len(post['beneficiaries']) == 1: benny = first(post['beneficiaries']) if benny['account'] == 'null' and int(benny['weight']) == 10000: is_payout_declined = True # payout entirely in SP is_full_power = int(post['percent_steem_dollars']) == 0 return { 'json_metadata': md, 'image': thumb_url, 'tags': tags, 'is_nsfw': is_nsfw, 'body': body, 'preview': body[0:1024], 'payout_at': payout_at, 'is_paidout': is_paidout, 'is_payout_declined': is_payout_declined, 'is_full_power': is_full_power, }
def _condenser_post_object(row, truncate_body=0): """Given a hive_posts_cache row, create a legacy-style post object.""" paid = row['is_paidout'] post = {} post['post_id'] = row['post_id'] post['author'] = row['author'] post['permlink'] = row['permlink'] post['category'] = row['category'] post['title'] = row['title'] post['body'] = row['body'][0:truncate_body] if truncate_body else row[ 'body'] post['json_metadata'] = row['json'] post['created'] = _json_date(row['created_at']) post['last_update'] = _json_date(row['updated_at']) post['depth'] = row['depth'] post['children'] = row['children'] post['net_rshares'] = row['rshares'] post['last_payout'] = _json_date(row['payout_at'] if paid else None) post['cashout_time'] = _json_date(None if paid else row['payout_at']) post['total_payout_value'] = _amount(row['payout'] if paid else 0) post['curator_payout_value'] = _amount(0) post['pending_payout_value'] = _amount(0 if paid else row['payout']) post['promoted'] = "%.3f SBD" % row['promoted'] post['replies'] = [] post['body_length'] = len(row['body']) post['active_votes'] = _hydrate_active_votes(row['votes']) post['author_reputation'] = rep_to_raw(row['author_rep']) # import fields from legacy object assert row['raw_json'] assert len(row['raw_json']) > 32 raw_json = json.loads(row['raw_json']) if row['depth'] > 0: post['parent_author'] = raw_json['parent_author'] post['parent_permlink'] = raw_json['parent_permlink'] else: post['parent_author'] = '' post['parent_permlink'] = row['category'] post['url'] = raw_json['url'] post['root_title'] = raw_json['root_title'] post['beneficiaries'] = raw_json['beneficiaries'] post['max_accepted_payout'] = raw_json['max_accepted_payout'] post['percent_steem_dollars'] = raw_json['percent_steem_dollars'] if paid: curator_payout = sbd_amount(raw_json['curator_payout_value']) post['curator_payout_value'] = _amount(curator_payout) post['total_payout_value'] = _amount(row['payout'] - curator_payout) # not used by condenser, but may be useful #post['net_votes'] = post['total_votes'] - row['up_votes'] #post['allow_replies'] = raw_json['allow_replies'] #post['allow_votes'] = raw_json['allow_votes'] #post['allow_curation_rewards'] = raw_json['allow_curation_rewards'] return post
def _condenser_post_object(row, truncate_body=0, get_content_additions=False): """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] full_payout = row['pending_payout'] + row['payout'] post = {} post['author'] = row['author'] post['permlink'] = row['permlink'] if not row['category']: post['category'] = 'undefined' # condenser#3424 mitigation else: post['category'] = row['category'] post['title'] = row['title'] post['body'] = row['body'][0:truncate_body] if truncate_body else row[ 'body'] post['json_metadata'] = row['json'] post['created'] = json_date(row['created_at']) post['last_update'] = json_date(row['updated_at']) post['depth'] = row['depth'] post['children'] = row['children'] post['last_payout'] = json_date(row['payout_at'] if paid else None) post['cashout_time'] = json_date(None if paid else row['payout_at']) post['total_payout_value'] = _amount(row['payout'] if paid else 0) post['curator_payout_value'] = _amount(0) post['pending_payout_value'] = _amount(0 if paid else full_payout) post['promoted'] = _amount(row['promoted']) post['replies'] = [] post['body_length'] = len(row['body']) post['author_reputation'] = row['author_rep'] post['parent_author'] = row['parent_author'] post['parent_permlink'] = row['parent_permlink_or_category'] post['url'] = row['url'] post['root_title'] = row['root_title'] post['beneficiaries'] = row['beneficiaries'] post['max_accepted_payout'] = row['max_accepted_payout'] post['percent_hbd'] = row['percent_hbd'] if get_content_additions: post['id'] = row[ 'id'] # let's be compatible with old code until this API is supported. post['author_rewards'] = row['author_rewards'] post['max_cashout_time'] = json_date( None ) # ABW: only relevant up to HF17, timestamp::max for all posts later (and also all paid) curator_payout = sbd_amount(row['curator_payout_value']) post['curator_payout_value'] = _amount(curator_payout) post['total_payout_value'] = _amount(row['payout'] - curator_payout) post['reward_weight'] = 10000 post['root_author'] = row['root_author'] post['root_permlink'] = row['root_permlink'] post['allow_replies'] = row['allow_replies'] post['allow_votes'] = row['allow_votes'] post['allow_curation_rewards'] = row['allow_curation_rewards'] post['reblogged_by'] = [] post['net_votes'] = row['net_votes'] post[ 'children_abs_rshares'] = 0 # see: hive/server/database_api/objects.py:68 post['total_pending_payout_value'] = '0.000 HBD' # no data if paid: post['total_vote_weight'] = 0 post['vote_rshares'] = 0 post['net_rshares'] = 0 post['abs_rshares'] = 0 else: post['total_vote_weight'] = row['total_vote_weight'] post['vote_rshares'] = (row['rshares'] + row['abs_rshares']) // 2 post['net_rshares'] = row['rshares'] post['abs_rshares'] = row['abs_rshares'] else: post['post_id'] = row['id'] post['net_rshares'] = row['rshares'] if paid: curator_payout = sbd_amount(row['curator_payout_value']) post['curator_payout_value'] = _amount(curator_payout) post['total_payout_value'] = _amount(row['payout'] - curator_payout) return post
def comment_payout_op(cls): values_limit = 1000 """ Process comment payment operations """ for k, v in cls.comment_payout_ops.items(): author = None permlink = None # author payouts author_rewards = 0 author_rewards_hive = None author_rewards_hbd = None author_rewards_vests = None # total payout for comment #comment_author_reward = None #curators_vesting_payout = None total_payout_value = None curator_payout_value = None #beneficiary_payout_value = None; payout = None pending_payout = None payout_at = None last_payout_at = None cashout_time = None is_paidout = None total_vote_weight = None # [final] payout indicator - by default all rewards are zero, but might be overwritten by other operations # ABW: prior to some early HF that was not necessarily final payout since those were discussion driven so new comment/vote could trigger new cashout window, see f.e. # soulsistashakti/re-emily-cook-let-me-introduce-myself-my-name-is-emily-cook-and-i-m-the-producer-and-presenter-of-a-monthly-film-show-film-focus-20160701t012330329z # it emits that "final" operation at blocks: 2889020, 3053237, 3172559 and 4028469 if v[VirtualOperationType.CommentPayoutUpdate] is not None: value, date = v[VirtualOperationType.CommentPayoutUpdate] if author is None: author = value['author'] permlink = value['permlink'] is_paidout = True payout_at = date last_payout_at = date cashout_time = "infinity" pending_payout = 0 total_vote_weight = 0 # author rewards in current (final or nonfinal) payout (always comes with comment_reward_operation) if v[VirtualOperationType.AuthorReward] is not None: value, date = v[VirtualOperationType.AuthorReward] if author is None: author = value['author'] permlink = value['permlink'] author_rewards_hive = value['hive_payout']['amount'] author_rewards_hbd = value['hbd_payout']['amount'] author_rewards_vests = value['vesting_payout']['amount'] #curators_vesting_payout = value['curators_vesting_payout']['amount'] # summary of comment rewards in current (final or nonfinal) payout (always comes with author_reward_operation) if v[VirtualOperationType.CommentReward] is not None: value, date = v[VirtualOperationType.CommentReward] if author is None: author = value['author'] permlink = value['permlink'] #comment_author_reward = value['payout'] author_rewards = value['author_rewards'] total_payout_value = value['total_payout_value'] curator_payout_value = value['curator_payout_value'] #beneficiary_payout_value = value['beneficiary_payout_value'] payout = sum([ sbd_amount(total_payout_value), sbd_amount(curator_payout_value) ]) pending_payout = 0 last_payout_at = date # estimated pending_payout from vote (if exists with actual payout the value comes from vote cast after payout) if v[VirtualOperationType.EffectiveCommentVote] is not None: value, date = v[VirtualOperationType.EffectiveCommentVote] if author is None: author = value['author'] permlink = value['permlink'] pending_payout = sbd_amount(value['pending_payout']) total_vote_weight = value['total_vote_weight'] cls._comment_payout_ops.append( "('{}', {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {})" .format( author, escape_characters(permlink), "NULL" if (total_payout_value is None) else ("'{}'".format(legacy_amount(total_payout_value))), "NULL" if (curator_payout_value is None) else ("'{}'".format(legacy_amount(curator_payout_value))), author_rewards, "NULL" if (author_rewards_hive is None) else author_rewards_hive, "NULL" if (author_rewards_hbd is None) else author_rewards_hbd, "NULL" if (author_rewards_vests is None) else author_rewards_vests, "NULL" if (payout is None) else payout, "NULL" if (pending_payout is None) else pending_payout, "NULL" if (payout_at is None) else ("'{}'::timestamp".format(payout_at)), "NULL" if (last_payout_at is None) else ("'{}'::timestamp".format(last_payout_at)), "NULL" if (cashout_time is None) else ("'{}'::timestamp".format(cashout_time)), "NULL" if (is_paidout is None) else is_paidout, "NULL" if (total_vote_weight is None) else total_vote_weight)) n = len(cls.comment_payout_ops) cls.comment_payout_ops.clear() return n
async def normalize_post(context, post): """Takes a steemd post object and outputs bridge-api normalized version.""" db = context['db'] # load core md sql = """SELECT id, category, community_id, is_muted, is_valid FROM hive_posts WHERE author = :author AND permlink = :permlink""" core = await db.query_row(sql, author=post['author'], permlink=post['permlink']) if not core: core = dict(id=None, category=post['category'], community_id=None, is_muted=False, is_valid=True) # load author sql = """SELECT id, reputation FROM hive_accounts WHERE name = :name""" author = await db.query_row(sql, name=post['author']) # append core md post['category'] = core['category'] post['community_id'] = core['community_id'] post['gray'] = core['is_muted'] post['hide'] = not core['is_valid'] promoted = sbd_amount( post['promoted']) if post['promoted'] != '0.000 STEEM' else None # convert to internal object row = None try: row = post_to_internal(post, core['id'], 'insert', promoted=promoted) row = dict(row) except Exception as e: log.error("post_to_internal: %s %s", repr(e), traceback.format_exc()) raise e # normalized response ret = None try: if 'promoted' not in row: row['promoted'] = 0 row['author_rep'] = author['reputation'] ret = _condenser_post_object(row) except Exception as e: log.error("post_to_internal: %s %s", repr(e), traceback.format_exc()) raise e # decorate if core['community_id']: sql = """SELECT title FROM hive_communities WHERE id = :id""" title = await db.query_one(sql, id=core['community_id']) sql = """SELECT role_id, title FROM hive_roles WHERE community_id = :cid AND account_id = :aid""" role = await db.query_row(sql, cid=core['community_id'], aid=author['id']) ret['community_title'] = title ret['author_role'] = ROLES[role[0] if role else 0] ret['author_title'] = role[1] if role else '' return ret