From 18fb2621dca6e20bcd3b6a99ef35ddcc8457c40d Mon Sep 17 00:00:00 2001
From: Bartek Wrona <wrona@syncad.com>
Date: Fri, 6 Nov 2020 16:17:17 +0100
Subject: [PATCH] Fixed implementation of bridge_api.get_account_posts by feed
 to match old HM behavior

---
 .../bridge_get_ranked_post_type.sql           | 41 +++++++++++++++++++
 .../condenser_get_by_feed_with_reblog.sql     | 18 ++++----
 hive/server/bridge_api/methods.py             | 14 +++++--
 hive/server/hive_api/public.py                | 15 ++++---
 4 files changed, 72 insertions(+), 16 deletions(-)

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 dff7f7374..e486bf70c 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/condenser_get_by_feed_with_reblog.sql b/hive/db/sql_scripts/condenser_get_by_feed_with_reblog.sql
index 1189ad0e0..b2a35a791 100644
--- a/hive/db/sql_scripts/condenser_get_by_feed_with_reblog.sql
+++ b/hive/db/sql_scripts/condenser_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/server/bridge_api/methods.py b/hive/server/bridge_api/methods.py
index 839720f3c..15177ea32 100644
--- a/hive/server/bridge_api/methods.py
+++ b/hive/server/bridge_api/methods.py
@@ -286,7 +286,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 +310,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/hive_api/public.py b/hive/server/hive_api/public.py
index f6415604c..4d3177b39 100644
--- a/hive/server/hive_api/public.py
+++ b/hive/server/hive_api/public.py
@@ -10,7 +10,7 @@ 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.bridge_api.objects import _bridge_post_object
 from hive.server.database_api.methods import find_votes_impl, VotesPresentation
 
 log = logging.getLogger(__name__)
@@ -84,15 +84,20 @@ async def get_info(context):
 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 )
+    sql = " SELECT * FROM bridge_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)
+        post = _bridge_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:
+            post['reblogged_by'] = list(reblogged_by)
+        log.info("Reblogged_by: {}".format(reblogged_by))
+
+        post['active_votes'] = await find_votes_impl(db, row['author'], row['permlink'], VotesPresentation.BridgeApi)
         posts.append(post)
 
     return posts
-- 
GitLab