Esempio n. 1
0
async def get_post_discussions_by_payout(context,
                                         start_author: str = '',
                                         start_permlink: str = '',
                                         limit: int = 20,
                                         tag: str = None,
                                         truncate_body: int = 0):
    """Query top-level posts, sorted by payout."""
    ids = await cursor.pids_by_query(
        context['db'], 'payout', valid_account(start_author, allow_empty=True),
        valid_permlink(start_permlink, allow_empty=True),
        valid_limit(limit, 100), valid_tag(tag, allow_empty=True))
    return await load_posts(context['db'], ids, truncate_body=truncate_body)
Esempio n. 2
0
async def get_discussions_by_created(context, start_author: str = '', start_permlink: str = '',
                                     limit: int = 20, tag: str = None,
                                     truncate_body: int = 0, filter_tags: list = None):
    """Query posts, sorted by creation date."""
    assert not filter_tags, 'filter_tags not supported'
    ids = await cursor.pids_by_query(
        context['db'],
        'created',
        valid_account(start_author, allow_empty=True),
        valid_permlink(start_permlink, allow_empty=True),
        valid_limit(limit, 100),
        valid_tag(tag, allow_empty=True))
    return await load_posts(context['db'], ids, truncate_body=truncate_body)
Esempio n. 3
0
async def get_trending_tags(context, start_tag: str = '', limit: int = 250):
    """Get top 250 trending tags among pending posts, with stats."""

    limit = valid_limit(limit, 250, 250)
    start_tag = valid_tag(start_tag, allow_empty=True)

    sql = "SELECT * FROM condenser_get_trending_tags( (:tag)::VARCHAR, :limit )"

    out = []
    for row in await context['db'].query_all(sql, limit=limit, tag=start_tag):
        out.append({
            'name': row['category'],
            'comments': row['total_posts'] - row['top_posts'],
            'top_posts': row['top_posts'],
            'total_payouts': "%.3f HBD" % row['total_payouts']})

    return out
Esempio n. 4
0
async def get_trending_tags(context, start_tag: str = '', limit: int = 250):
    """Get top 250 trending tags among pending posts, with stats."""

    limit = valid_limit(limit, ubound=250)
    start_tag = valid_tag(start_tag or '', allow_empty=True)

    if start_tag:
        seek = """
          HAVING SUM(payout) <= (
            SELECT SUM(payout)
              FROM hive_posts_cache
             WHERE is_paidout = '0'
               AND category = :start_tag)
        """
    else:
        seek = ''

    sql = """
      SELECT category,
             COUNT(*) AS total_posts,
             SUM(CASE WHEN depth = 0 THEN 1 ELSE 0 END) AS top_posts,
             SUM(payout) AS total_payouts
        FROM hive_posts_cache
       WHERE is_paidout = '0'
    GROUP BY category %s
    ORDER BY SUM(payout) DESC
       LIMIT :limit
    """ % seek

    out = []
    for row in await context['db'].query_all(sql,
                                             limit=limit,
                                             start_tag=start_tag):
        out.append({
            'name': row['category'],
            'comments': row['total_posts'] - row['top_posts'],
            'top_posts': row['top_posts'],
            'total_payouts': "%.3f SBD" % row['total_payouts']
        })

    return out
Esempio n. 5
0
async def get_ranked_posts(context,
                           sort,
                           start_author='',
                           start_permlink='',
                           limit=20,
                           tag=None,
                           observer=None):
    """Query posts, sorted by given method."""

    db = context['db']
    observer_id = await get_account_id(db, observer) if observer else None

    assert sort in [
        'trending', 'hot', 'created', 'promoted', 'payout', 'payout_comments',
        'muted'
    ], 'invalid sort'
    ids = await cursor.pids_by_ranked(
        context['db'], sort, valid_account(start_author, allow_empty=True),
        valid_permlink(start_permlink, allow_empty=True),
        valid_limit(limit, 100), valid_tag(tag, allow_empty=True), observer_id)

    return await load_posts(context['db'], ids)
Esempio n. 6
0
async def get_ranked_posts(context, sort:str, start_author:str='', start_permlink:str='',
                           limit:int=20, tag:str='', observer:str=''):
    """Query posts, sorted by given method."""
    supported_sort_list = ['trending', 'hot', 'created', 'promoted', 'payout', 'payout_comments', 'muted']
    assert sort in supported_sort_list, "Unsupported sort, valid sorts: {}".format(", ".join(supported_sort_list))

    db = context['db']

    async def process_query_results( sql_result ):
        posts = []
        for row in sql_result:
            post = _bridge_post_object(row)
            post['active_votes'] = await find_votes_impl(db, row['author'], row['permlink'], VotesPresentation.BridgeApi)
            post = append_statistics_to_post(post, row, row['is_pinned'])
            posts.append(post)
        return posts

    start_author = valid_account(start_author, allow_empty=True)
    start_permlink = valid_permlink(start_permlink, allow_empty=True)
    limit = valid_limit(limit, 100, 20)
    tag = valid_tag(tag, allow_empty=True)
    observer = valid_account(observer, allow_empty=(tag != "my"))

    if tag == "my":
        result = await _get_ranked_posts_for_observer_communities(db, sort, start_author, start_permlink, limit, observer)
        return await process_query_results(result)

    if tag and check_community(tag):
        result = await _get_ranked_posts_for_communities(db, sort, tag, start_author, start_permlink, limit, observer)
        return await process_query_results(result)

    if ( tag and tag != "all" ):
        result = await _get_ranked_posts_for_tag(db, sort, tag, start_author, start_permlink, limit, observer)
        return await process_query_results(result)

    result = await _get_ranked_posts_for_all(db, sort, start_author, start_permlink, limit, observer)
    return await process_query_results(result)
Esempio n. 7
0
async def get_state(context, path: str):
    """`get_state` reimplementation.

    See: https://github.com/steemit/steem/blob/06e67bd4aea73391123eca99e1a22a8612b0c47e/libraries/app/database_api.cpp#L1937
    """
    (path, part) = _normalize_path(path)

    db = context['db']

    state = {
        'feed_price': await _get_feed_price(db),
        'props': await _get_props_lite(db),
        'tags': {},
        'accounts': {},
        'content': {},
        'tag_idx': {
            'trending': []
        },
        'discussion_idx': {
            "": {}
        }
    }

    # account - `/@account/tab` (feed, blog, comments, replies)
    if part[0] and part[0][0] == '@':
        assert not part[1] == 'transfers', 'transfers API not served here'
        assert not part[2], 'unexpected account path[2] %s' % path

        if part[1] == '':
            part[1] = 'blog'

        account = valid_account(part[0][1:])
        state['accounts'][account] = await _load_account(db, account)

        if part[1] in ACCOUNT_TAB_KEYS:
            key = ACCOUNT_TAB_KEYS[part[1]]
            posts = await _get_account_discussion_by_key(db, account, key)
            state['content'] = _keyed_posts(posts)
            state['accounts'][account][key] = list(state['content'].keys())
        elif part[1] in ACCOUNT_TAB_IGNORE:
            pass  # condenser no-op URLs
        else:
            # invalid/undefined case; probably requesting `@user/permlink`,
            # but condenser still relies on a valid response for redirect.
            state['error'] = 'invalid get_state account path %s' % path

    # discussion - `/category/@account/permlink`
    elif part[1] and part[1][0] == '@':
        author = valid_account(part[1][1:])
        permlink = valid_permlink(part[2])
        state['content'] = await _load_discussion(db, author, permlink)
        state['accounts'] = await _load_content_accounts(
            db, state['content'], True)

    # ranked posts - `/sort/category`
    elif part[0] in POST_LIST_SORTS:
        assert not part[2], "unexpected discussion path part[2] %s" % path
        sort = valid_sort(part[0])
        tag = valid_tag(part[1].lower(), allow_empty=True)
        pids = await get_posts_by_given_sort(context, sort, '', '', 20, tag)
        state['content'] = _keyed_posts(pids)
        state['discussion_idx'] = {tag: {sort: list(state['content'].keys())}}
        state['tag_idx'] = {
            'trending': await get_top_trending_tags_summary(context)
        }

    # tag "explorer" - `/tags`
    elif part[0] == "tags":
        assert not part[1] and not part[2], 'invalid /tags request'
        for tag in await get_trending_tags(context):
            state['tag_idx']['trending'].append(tag['name'])
            state['tags'][tag['name']] = tag

    elif part[0] in CONDENSER_NOOP_URLS:
        assert not part[1] and not part[2]

    else:
        raise ApiError('unhandled path: /%s' % path)

    return state
Esempio n. 8
0
async def get_posts_by_given_sort(context,
                                  sort: str,
                                  start_author: str = '',
                                  start_permlink: str = '',
                                  limit: int = 20,
                                  tag: str = None,
                                  truncate_body: int = 0,
                                  filter_tags: list = None,
                                  observer: str = None):
    """Query posts, sorted by creation date."""
    assert not filter_tags, 'filter_tags not supported'

    db = context['db']

    start_author = valid_account(start_author, allow_empty=True),
    start_permlink = valid_permlink(start_permlink, allow_empty=True),
    limit = valid_limit(limit, 100, 20),
    tag = valid_tag(tag, allow_empty=True)
    observer = valid_account(observer, allow_empty=True)
    truncate_body = valid_truncate(truncate_body)

    posts = []
    is_community = tag[:5] == 'hive-'

    if sort == 'created':
        if is_community:
            sql = "SELECT * FROM bridge_get_ranked_post_by_created_for_community( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, False, (:observer)::VARCHAR )"
        elif tag == '':
            sql = "SELECT * FROM bridge_get_ranked_post_by_created( (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        else:
            sql = "SELECT * FROM bridge_get_ranked_post_by_created_for_tag( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
    elif sort == 'trending':
        if is_community:
            sql = "SELECT * FROM bridge_get_ranked_post_by_trends_for_community( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, False, (:observer)::VARCHAR )"
        elif tag == '':
            sql = "SELECT * FROM bridge_get_ranked_post_by_trends( (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        else:
            sql = "SELECT * FROM bridge_get_ranked_post_by_trends_for_tag( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
    elif sort == 'hot':
        if is_community:
            sql = "SELECT * FROM bridge_get_ranked_post_by_hot_for_community( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        elif tag == '':
            sql = "SELECT * FROM bridge_get_ranked_post_by_hot( (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        else:
            sql = "SELECT * FROM bridge_get_ranked_post_by_hot_for_tag( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
    elif sort == 'promoted':
        if is_community:
            sql = "SELECT * FROM bridge_get_ranked_post_by_promoted_for_community( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        elif tag == '':
            sql = "SELECT * FROM bridge_get_ranked_post_by_promoted( (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        else:
            sql = "SELECT * FROM bridge_get_ranked_post_by_promoted_for_tag( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
    elif sort == 'post_by_payout':
        if tag == '':
            sql = "SELECT * FROM bridge_get_ranked_post_by_payout( (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, False, (:observer)::VARCHAR )"
        else:
            sql = "SELECT * FROM bridge_get_ranked_post_by_payout_for_category( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, False, (:observer)::VARCHAR )"
    elif sort == 'comment_by_payout':
        if tag == '':
            sql = "SELECT * FROM bridge_get_ranked_post_by_payout_comments( (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
        else:
            sql = "SELECT * FROM bridge_get_ranked_post_by_payout_comments_for_category( (:tag)::VARCHAR, (:author)::VARCHAR, (:permlink)::VARCHAR, (:limit)::SMALLINT, (:observer)::VARCHAR )"
    else:
        return posts

    sql_result = await db.query_all(sql,
                                    tag=tag,
                                    author=start_author,
                                    permlink=start_permlink,
                                    limit=limit,
                                    observer=observer)

    for row in sql_result:
        post = _condenser_post_object(row, truncate_body)
        post['active_votes'] = await find_votes_impl(
            db, row['author'], row['permlink'], VotesPresentation.CondenserApi)
        posts.append(post)
    return posts