diff --git a/hive/db/schema.py b/hive/db/schema.py index 08718053185e5aa3c4db9912fca57d0a518fed8e..046aed727c3a4ae9394eca325b4306ad6fe0a05e 100644 --- a/hive/db/schema.py +++ b/hive/db/schema.py @@ -601,7 +601,7 @@ def setup(db): "condenser_get_by_replies_to_account.sql", "condenser_get_by_account_comments.sql", "condenser_get_by_blog_without_reblog.sql", - "condenser_get_by_feed_with_reblog.sql", + "bridge_get_by_feed_with_reblog.sql", "condenser_get_by_blog.sql", "bridge_get_account_posts_by_blog.sql", "condenser_get_names_by_reblogged.sql", diff --git a/hive/db/sql_scripts/condenser_get_by_feed_with_reblog.sql b/hive/db/sql_scripts/bridge_get_by_feed_with_reblog.sql similarity index 70% rename from hive/db/sql_scripts/condenser_get_by_feed_with_reblog.sql rename to hive/db/sql_scripts/bridge_get_by_feed_with_reblog.sql index 1189ad0e0854bc9d2696cdb91cff494c6b032fa9..b2a35a7917879770fe94ea4901640c187928229d 100644 --- a/hive/db/sql_scripts/condenser_get_by_feed_with_reblog.sql +++ b/hive/db/sql_scripts/bridge_get_by_feed_with_reblog.sql @@ -1,7 +1,7 @@ -DROP FUNCTION IF EXISTS condenser_get_by_feed_with_reblog; +DROP FUNCTION IF EXISTS bridge_get_by_feed_with_reblog; -CREATE OR REPLACE FUNCTION condenser_get_by_feed_with_reblog( IN _account VARCHAR, IN _author VARCHAR, IN _permlink VARCHAR, IN _limit INTEGER) - RETURNS SETOF bridge_api_post +CREATE OR REPLACE FUNCTION bridge_get_by_feed_with_reblog( IN _account VARCHAR, IN _author VARCHAR, IN _permlink VARCHAR, IN _limit INTEGER) + RETURNS SETOF bridge_api_post_reblogs LANGUAGE 'plpgsql' STABLE ROWS 1000 @@ -23,7 +23,7 @@ BEGIN __cutoff = block_before_head( '1 month' ); - RETURN QUERY SELECT + RETURN QUERY SELECT -- bridge_get_by_feed_with_reblog hp.id, hp.author, hp.parent_author, @@ -59,16 +59,18 @@ BEGIN hp.community_title, hp.role_id, hp.is_pinned, - hp.curator_payout_value + hp.curator_payout_value, + T.reblogged_by FROM hive_posts_view hp JOIN ( - SELECT hfc.post_id, MIN(hfc.created_at) as min_created + SELECT hfc.post_id, MIN(hfc.created_at) as min_created, array_agg(ha.name) AS reblogged_by FROM hive_feed_cache hfc JOIN hive_follows hf ON hfc.account_id = hf.following - WHERE (__post_id = 0 OR hfc.created_at <= __min_date) - AND hfc.block_num > __cutoff AND hf.state = 1 AND hf.follower = __account_id + JOIN hive_accounts ha ON ha.id = hf.following + WHERE hfc.block_num > __cutoff AND hf.state = 1 AND hf.follower = __account_id GROUP BY hfc.post_id + HAVING __post_id = 0 OR MIN(hfc.created_at) <= __min_date ORDER BY min_created DESC LIMIT _limit ) T ON hp.id = T.post_id diff --git a/hive/db/sql_scripts/bridge_get_ranked_post_type.sql b/hive/db/sql_scripts/bridge_get_ranked_post_type.sql index dff7f737477a203a906abfe0a1eb039baec25b3c..e486bf70cb059126b22ad84068a5bc082427a99f 100644 --- a/hive/db/sql_scripts/bridge_get_ranked_post_type.sql +++ b/hive/db/sql_scripts/bridge_get_ranked_post_type.sql @@ -37,3 +37,44 @@ CREATE TYPE bridge_api_post AS ( is_pinned BOOLEAN, curator_payout_value VARCHAR ); + +DROP TYPE IF EXISTS bridge_api_post_reblogs CASCADE; +CREATE TYPE bridge_api_post_reblogs AS ( + id INTEGER, + author VARCHAR, + parent_author VARCHAR, + author_rep BIGINT, + root_title VARCHAR, + beneficiaries JSON, + max_accepted_payout VARCHAR, + percent_hbd INTEGER, + url TEXT, + permlink VARCHAR, + parent_permlink_or_category VARCHAR, + title VARCHAR, + body TEXT, + category VARCHAR, + depth SMALLINT, + promoted DECIMAL(10,3), + payout DECIMAL(10,3), + pending_payout DECIMAL(10,3), + payout_at TIMESTAMP, + is_paidout BOOLEAN, + children INTEGER, + votes INTEGER, + created_at TIMESTAMP, + updated_at TIMESTAMP, + rshares NUMERIC, + abs_rshares NUMERIC, + json TEXT, + is_hidden BOOLEAN, + is_grayed BOOLEAN, + total_votes BIGINT, + sc_trend FLOAT4, + role_title VARCHAR, + community_title VARCHAR, + role_id SMALLINT, + is_pinned BOOLEAN, + curator_payout_value VARCHAR, + reblogged_by VARCHAR[] +); diff --git a/hive/db/sql_scripts/db_upgrade.sh b/hive/db/sql_scripts/db_upgrade.sh index f88a769c622f83d501424d99230b333955cb194a..7a70e0d068ffd13faac77bf6e6b14b25f11c7aef 100755 --- a/hive/db/sql_scripts/db_upgrade.sh +++ b/hive/db/sql_scripts/db_upgrade.sh @@ -54,7 +54,7 @@ for sql in postgres_handle_view_changes.sql \ condenser_get_by_replies_to_account.sql \ condenser_get_by_account_comments.sql \ condenser_get_by_blog_without_reblog.sql \ - condenser_get_by_feed_with_reblog.sql \ + bridge_get_by_feed_with_reblog.sql \ condenser_get_by_blog.sql \ bridge_get_account_posts_by_blog.sql \ condenser_get_names_by_reblogged.sql \ diff --git a/hive/server/bridge_api/methods.py b/hive/server/bridge_api/methods.py index ea8bd756708d6b6d6a48abfe0715b5cd078a170b..d4a670ed5ea2baae6efccdad7440c59e1495f934 100644 --- a/hive/server/bridge_api/methods.py +++ b/hive/server/bridge_api/methods.py @@ -12,7 +12,6 @@ from hive.server.hive_api.common import get_account_id from hive.server.hive_api.objects import _follow_contexts from hive.server.hive_api.community import list_top_communities from hive.server.common.mutes import Mutes -from hive.server.hive_api.public import get_by_feed_with_reblog_impl #pylint: disable=too-many-arguments, no-else-return @@ -263,9 +262,6 @@ async def get_ranked_posts(context, sort:str, start_author:str='', start_permlin result = await _get_ranked_posts_for_all(db, sort, start_author, start_permlink, limit) return await process_query_results(result) -async def _get_account_posts_by_feed(db, account : str, start_author : str, start_permlink : str, limit : int): - return await get_by_feed_with_reblog_impl(db, account, start_author, start_permlink, limit) - @return_error_info async def get_account_posts(context, sort:str, account:str, start_author:str='', start_permlink:str='', limit:int=20, observer:str=None): @@ -286,7 +282,7 @@ async def get_account_posts(context, sort:str, account:str, start_author:str='', if sort == 'blog': sql = "SELECT * FROM bridge_get_account_posts_by_blog( (:account)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::INTEGER )" elif sort == 'feed': - return await _get_account_posts_by_feed(db, account, start_author, start_permlink, limit) + sql = "SELECT * FROM bridge_get_by_feed_with_reblog((:account)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::INTEGER)" elif sort == 'posts': sql = "SELECT * FROM bridge_get_account_posts_by_posts( (:account)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT )" elif sort == 'comments': @@ -310,8 +306,16 @@ async def get_account_posts(context, sort:str, account:str, start_author:str='', post = _bridge_post_object(row) post['active_votes'] = await find_votes_impl(db, row['author'], row['permlink'], VotesPresentation.BridgeApi) if sort == 'blog': - if post['author'] != account: - post['reblogged_by'] = [account] + if post['author'] != account: + post['reblogged_by'] = [account] + elif sort == 'feed': + reblogged_by = set(row['reblogged_by']) + reblogged_by.discard(row['author']) # Eliminate original author of reblogged post + if reblogged_by: + reblogged_by_list = list(reblogged_by) + reblogged_by_list.sort() + post['reblogged_by'] = reblogged_by_list + post = append_statistics_to_post(post, row, False if account_posts else row['is_pinned'], blacklists_for_user, not account_posts) posts.append(post) return posts diff --git a/hive/server/condenser_api/get_state.py b/hive/server/condenser_api/get_state.py index 4b5dbb4cdc01a30ed625693c26e3f23798a70b90..663abb50dd23441c3cfe5b6206e96e78c05a50a0 100644 --- a/hive/server/condenser_api/get_state.py +++ b/hive/server/condenser_api/get_state.py @@ -26,9 +26,7 @@ from hive.server.condenser_api.tags import ( import hive.server.condenser_api.cursor as cursor -from hive.server.condenser_api.methods import get_posts_by_given_sort - -from hive.server.hive_api.public import get_by_feed_with_reblog_impl +from hive.server.condenser_api.methods import get_posts_by_given_sort, get_discussions_by_feed_impl from hive.server.database_api.methods import find_votes_impl, VotesPresentation log = logging.getLogger(__name__) @@ -170,7 +168,7 @@ async def _get_account_discussion_by_key(db, account, key): elif key == 'blog': posts = await cursor.get_by_blog(db, account, '', '', 20) elif key == 'feed': - posts = await get_by_feed_with_reblog_impl(db, account, '', '', 20) + posts = await get_discussions_by_feed_impl(db, account, '', '', 20) else: raise ApiError("unknown account discussion key %s" % key) diff --git a/hive/server/condenser_api/methods.py b/hive/server/condenser_api/methods.py index b79a8206603151bb017cdf6806ba4c120d9c8eb4..610dbf5bc86ba23f131e76c5007e3a382845fc61 100644 --- a/hive/server/condenser_api/methods.py +++ b/hive/server/condenser_api/methods.py @@ -16,8 +16,6 @@ from hive.server.common.helpers import ( from hive.server.common.mutes import Mutes from hive.server.database_api.methods import find_votes_impl, VotesPresentation -from hive.server.hive_api.public import get_by_feed_with_reblog_impl - # pylint: disable=too-many-arguments,line-too-long,too-many-lines @return_error_info @@ -321,6 +319,29 @@ async def get_discussions_by_blog(context, tag: str = None, start_author: str = return posts_by_id +async def get_discussions_by_feed_impl(db, account: str, start_author: str = '', + start_permlink: str = '', limit: int = 20, truncate_body: int = 0): + """Get a list of posts for an account's feed.""" + sql = "SELECT * FROM bridge_get_by_feed_with_reblog((:account)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::INTEGER)" + result = await db.query_all(sql, account=account, author=start_author, permlink=start_permlink, limit=limit) + + posts = [] + for row in result: + row = dict(row) + post = _condenser_post_object(row, truncate_body=truncate_body) + reblogged_by = set(row['reblogged_by']) + reblogged_by.discard(row['author']) # Eliminate original author of reblogged post + if reblogged_by: + reblogged_by_list = list(reblogged_by) + reblogged_by_list.sort() + post['reblogged_by'] = reblogged_by_list + + post['active_votes'] = await find_votes_impl(db, row['author'], row['permlink'], VotesPresentation.CondenserApi) + posts.append(post) + + return posts + + @return_error_info @nested_query_compat async def get_discussions_by_feed(context, tag: str = None, start_author: str = '', @@ -329,7 +350,7 @@ async def get_discussions_by_feed(context, tag: str = None, start_author: str = """Retrieve account's personalized feed.""" assert tag, '`tag` cannot be blank' assert not filter_tags, 'filter_tags not supported' - return await get_by_feed_with_reblog_impl( + return await get_discussions_by_feed_impl( context['db'], valid_account(tag), valid_account(start_author, allow_empty=True), diff --git a/hive/server/hive_api/public.py b/hive/server/hive_api/public.py index 8119a99c963ae61e60a08759aba28b635955b424..273607a56d1e9bb5c97c4bbdcda1afbd8ceb0ae8 100644 --- a/hive/server/hive_api/public.py +++ b/hive/server/hive_api/public.py @@ -10,9 +10,6 @@ from hive.server.condenser_api.cursor import get_followers, get_following from hive.db.schema import DB_VERSION as SCHEMA_DB_VERSION -from hive.server.condenser_api.objects import _condenser_post_object -from hive.server.database_api.methods import find_votes_impl, VotesPresentation - log = logging.getLogger(__name__) # Accounts @@ -82,19 +79,3 @@ async def get_info(context): } return ret - -async def get_by_feed_with_reblog_impl(db, account: str, start_author: str = '', - start_permlink: str = '', limit: int = 20, truncate_body: int = 0): - """Get a list of posts for an account's feed.""" - sql = " SELECT * FROM condenser_get_by_feed_with_reblog( '{}', '{}', '{}', {} ) ".format( account, start_author, start_permlink, limit ) - result = await db.query_all(sql) - - posts = [] - for row in result: - row = dict(row) - post = _condenser_post_object(row, truncate_body=truncate_body) - - post['active_votes'] = await find_votes_impl(db, row['author'], row['permlink'], VotesPresentation.CondenserApi) - posts.append(post) - - return posts