diff --git a/hive/db/sql_scripts/upgrade_view_schema.sql b/hive/db/sql_scripts/upgrade_view_schema.sql index ac5dbc0f0faffc98107acc843023db4262837a9d..041b7bb203a0f6f8c196b1fb4a42a561fe302688 100644 --- a/hive/db/sql_scripts/upgrade_view_schema.sql +++ b/hive/db/sql_scripts/upgrade_view_schema.sql @@ -197,7 +197,7 @@ SELECT hp.id, JOIN hive_permlink_data hpd_pp ON hpd_pp.id = pp.permlink_id JOIN hive_accounts ha_rp ON ha_rp.id = rp.author_id JOIN hive_permlink_data hpd_rp ON hpd_rp.id = rp.permlink_id - JOIN hive_post_data rpd ON rpd.id = rp.id + LEFT JOIN hive_post_data rpd ON rpd.id = rp.id JOIN hive_category_data hcd ON hcd.id = hp.category_id JOIN hive_category_data rcd ON rcd.id = rp.category_id LEFT JOIN hive_communities hc ON hp.community_id = hc.id diff --git a/hive/server/condenser_api/methods.py b/hive/server/condenser_api/methods.py index 98532149c8457bcbea6304bce2aba9eb7b819f3d..e24bd278a0701e42a7b33cc2f309816a32bb33d3 100644 --- a/hive/server/condenser_api/methods.py +++ b/hive/server/condenser_api/methods.py @@ -19,7 +19,94 @@ from hive.server.database_api.methods import find_votes_impl, VotesPresentation from hive.utils.normalize import time_string_with_t # pylint: disable=too-many-arguments,line-too-long,too-many-lines - +SQL_CONTENT = """ + SELECT + hp.id, + hp.counter_deleted, + ha_a.name AS author, + hp.active, + hp.author_rewards, + hpd_p.permlink, + hpd.title, + hpd.body, + hcd.category, + hp.depth, + hp.promoted, + hp.payout, + hp.pending_payout, + hp.payout_at, + hp.last_payout_at, + hp.cashout_time, + hp.is_paidout, + hp.children, + 0 AS active_votes, + hp.created_at, + hp.updated_at, + COALESCE(( SELECT sum(v.rshares) AS sum + FROM hive_votes v + WHERE (v.post_id = hp.id) + GROUP BY v.post_id), (0)::numeric) AS rshares, + COALESCE(( SELECT sum( + CASE (v.rshares >= 0) + WHEN true THEN v.rshares + ELSE (- v.rshares) + END) AS sum + FROM hive_votes v + WHERE ((v.post_id = hp.id) AND (NOT (v.rshares = 0))) + GROUP BY v.post_id), (0)::numeric) AS abs_rshares, + COALESCE(( SELECT count(1) AS count + FROM hive_votes v + WHERE ((v.post_id = hp.id) AND v.is_effective) + GROUP BY v.post_id), (0)::bigint) AS total_votes, + COALESCE(( SELECT sum( + CASE (v.rshares > 0) + WHEN true THEN 1 + ELSE '-1'::integer + END) AS sum + FROM hive_votes v + WHERE ((v.post_id = hp.id) AND (NOT (v.rshares = 0))) + GROUP BY v.post_id), (0)::bigint) AS net_votes, + hpd.json, + ha_a.reputation AS author_rep, + hp.total_vote_weight, + ha_pp.name AS parent_author, + ha_pp.id AS parent_author_id, + CASE (hp.depth > 0) + WHEN true THEN hpd_pp.permlink + ELSE hcd.category + END AS parent_permlink_or_category, + hp.curator_payout_value, + ha_rp.name AS root_author, + hpd_rp.permlink AS root_permlink, + hp.max_accepted_payout, + hp.percent_hbd, + true AS allow_replies, + hp.allow_votes, + hp.allow_curation_rewards, + hp.beneficiaries, + concat('/', rcd.category, '/@', ha_rp.name, '/', hpd_rp.permlink, + CASE rp.id + WHEN hp.id THEN ''::text + ELSE concat('#@', ha_a.name, '/', hpd_p.permlink) + END) AS url, + rpd.title AS root_title + FROM + hive_posts hp + JOIN hive_accounts_view ha_a ON ha_a.id = hp.author_id + JOIN hive_permlink_data hpd_p ON hpd_p.id = hp.permlink_id + JOIN hive_post_data hpd ON hpd.id = hp.id + JOIN hive_category_data hcd ON hcd.id = hp.category_id + JOIN hive_posts pp ON pp.id = hp.parent_id + JOIN hive_accounts ha_pp ON ha_pp.id = pp.author_id + JOIN hive_permlink_data hpd_pp ON hpd_pp.id = pp.permlink_id + JOIN hive_posts rp ON rp.id = hp.root_id + JOIN hive_accounts ha_rp ON ha_rp.id = rp.author_id + JOIN hive_permlink_data hpd_rp ON hpd_rp.id = rp.permlink_id + JOIN hive_category_data rcd ON rcd.id = rp.category_id + LEFT JOIN hive_post_data rpd ON rpd.id = rp.id + WHERE + ha_a.name = :author AND hpd_p.permlink = :permlink +""" SQL_TEMPLATE = """ SELECT hp.id, @@ -151,23 +238,23 @@ async def get_content(context, author: str, permlink: str, observer=None): valid_account(author) valid_permlink(permlink) #force copy - sql = str(SQL_TEMPLATE) - sql += """ - WHERE - hp.author = :author AND hp.permlink = :permlink - """ + sql = str(SQL_CONTENT) post = None result = await db.query_all(sql, author=author, permlink=permlink) if result: result = dict(result[0]) - post = _condenser_post_object(result, 0, True) - post['active_votes'] = await find_votes_impl(db, author, permlink, VotesPresentation.ActiveVotes) - if not observer: - post['active_votes'] = _mute_votes(post['active_votes'], Mutes.all()) + deleted = result['counter_deleted'] + post = _condenser_post_object(result, 0, True, deleted) + if deleted: + post['active_votes'] = [] else: - blacklists_for_user = await Mutes.get_blacklists_for_observer(observer, context) - post['active_votes'] = _mute_votes(post['active_votes'], blacklists_for_user.keys()) + post['active_votes'] = await find_votes_impl(db, author, permlink, VotesPresentation.ActiveVotes) + if not observer: + post['active_votes'] = _mute_votes(post['active_votes'], Mutes.all()) + else: + blacklists_for_user = await Mutes.get_blacklists_for_observer(observer, context) + post['active_votes'] = _mute_votes(post['active_votes'], blacklists_for_user.keys()) assert post, 'post was not found in cache' return post diff --git a/hive/server/condenser_api/objects.py b/hive/server/condenser_api/objects.py index 991693acc50dc96c91b4db1d990398672ac05682..090e771628742887fcb921fb70aa0c27d39c9e34 100644 --- a/hive/server/condenser_api/objects.py +++ b/hive/server/condenser_api/objects.py @@ -175,9 +175,10 @@ def _condenser_account_object(row): 'profile_image': profile['profile_image'], }})} -def _condenser_post_object(row, truncate_body=0, get_content_additions=False): +def _condenser_post_object(row, truncate_body=0, get_content_additions=False, deleted=False): """Given a hive_posts row, create a legacy-style post object.""" paid = row['is_paidout'] + date_default = '1970-01-01 00:00:00' # condenser#3424 mitigation if not row['category']: @@ -185,67 +186,67 @@ def _condenser_post_object(row, truncate_body=0, get_content_additions=False): full_payout = row['pending_payout'] + row['payout']; post = {} - post['post_id'] = row['id'] - post['author'] = row['author'] - post['permlink'] = row['permlink'] - post['category'] = row['category'] + post['post_id'] = row['id'] if not deleted else 0 + post['author'] = row['author'] if not deleted else '' + post['permlink'] = row['permlink'] if not deleted else '' + post['category'] = row['category'] if not deleted else '' - post['title'] = row['title'] - post['body'] = row['body'][0:truncate_body] if truncate_body else row['body'] - post['json_metadata'] = row['json'] + post['title'] = row['title'] if not deleted else '' + post['body'] = (row['body'][0:truncate_body] if truncate_body else row['body']) if not deleted else '' + post['json_metadata'] = row['json'] if not deleted else '' - 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['created'] = json_date(row['created_at'] if not deleted else date_default) + post['last_update'] = json_date(row['updated_at'] if not deleted else date_default) + post['depth'] = row['depth'] if not deleted else 0 + post['children'] = row['children'] if not deleted else 0 + post['net_rshares'] = row['rshares'] if not deleted else 0 - 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['last_payout'] = json_date(row['payout_at'] if paid and not deleted else date_default) + post['cashout_time'] = json_date(None if paid or deleted 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['pending_payout_value'] = _amount(0 if paid or deleted else full_payout) + post['promoted'] = _amount(row['promoted'] if not deleted else 0) post['replies'] = [] - post['body_length'] = len(row['body']) - post['author_reputation'] = row['author_rep'] + post['body_length'] = len(row['body']) if not deleted else 0 + post['author_reputation'] = row['author_rep'] if not deleted else 0 - post['parent_author'] = row['parent_author'] - post['parent_permlink'] = row['parent_permlink_or_category'] + post['parent_author'] = row['parent_author'] if not deleted else '' + post['parent_permlink'] = row['parent_permlink_or_category'] if not deleted else '' - 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'] + post['url'] = row['url'] if not deleted else '' + post['root_title'] = row['root_title'] if not deleted else '' + post['beneficiaries'] = row['beneficiaries'] if not deleted else [] + post['max_accepted_payout'] = row['max_accepted_payout'] if not deleted else '0.000 HBD' + post['percent_hbd'] = row['percent_hbd'] if not deleted else 0 if get_content_additions: - post['id'] = row['id'] # let's be compatible with old code until this API is supported. - post['active'] = json_date(row['active']) - 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) + post['id'] = row['id'] if not deleted else 0 # let's be compatible with old code until this API is supported. + post['active'] = json_date(row['active'] if not deleted else date_default) + post['author_rewards'] = row['author_rewards'] if not deleted else 0 + post['max_cashout_time'] = json_date(None) if not deleted else date_default # 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['curator_payout_value'] = _amount(curator_payout if not deleted else 0) + post['total_payout_value'] = _amount(row['payout'] - curator_payout if not deleted else 0) - post['reward_weight'] = 10000 + post['reward_weight'] = 10000 if not deleted else 0 - post['root_author'] = row['root_author'] - post['root_permlink'] = row['root_permlink'] + post['root_author'] = row['root_author'] if not deleted else '' + post['root_permlink'] = row['root_permlink'] if not deleted else '' - post['allow_replies'] = row['allow_replies'] - post['allow_votes'] = row['allow_votes'] - post['allow_curation_rewards'] = row['allow_curation_rewards'] + post['allow_replies'] = row['allow_replies'] if not deleted else False + post['allow_votes'] = row['allow_votes'] if not deleted else False + post['allow_curation_rewards'] = row['allow_curation_rewards'] if not deleted else False post['reblogged_by'] = [] - post['net_votes'] = row['net_votes'] + post['net_votes'] = row['net_votes'] if not deleted else 0 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: + if paid or deleted: post['total_vote_weight'] = 0 post['vote_rshares'] = 0 post['abs_rshares'] = 0 @@ -255,9 +256,9 @@ def _condenser_post_object(row, truncate_body=0, get_content_additions=False): post['abs_rshares'] = row['abs_rshares'] else: 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) + curator_payout = sbd_amount(row['curator_payout_value'] if not deleted else 0) + post['curator_payout_value'] = _amount(curator_payout if not deleted else 0) + post['total_payout_value'] = _amount(row['payout'] - curator_payout if not deleted else 0) return post