async def get_content(author: str, permlink: str): """Get a single post object.""" valid_account(author) valid_permlink(permlink) post_id = get_post_id(author, permlink) if not post_id: return {'id': 0, 'author': '', 'permlink': ''} return load_posts([post_id])[0]
async def get_content_replies(parent: str, parent_permlink: str): """Get a list of post objects based on parent.""" valid_account(parent) valid_permlink(parent_permlink) parent_id = get_post_id(parent, parent_permlink) if parent_id: child_ids = get_child_ids(parent_id) if child_ids: return load_posts(child_ids) return []
def _load_discussion(author, permlink): """Load a full discussion thread.""" post_id = get_post_id(author, permlink) if not post_id: return {} ret = [] queue = load_posts([post_id]) while queue: parent = queue.pop() children = load_posts(get_child_ids(parent['post_id'])) parent['replies'] = list(map(_ref, children)) queue.extend(children) ret.append(parent) return {_ref(post): post for post in ret}
async def get_state(path: str): """`get_state` reimplementation. See: https://github.com/steemit/steem/blob/06e67bd4aea73391123eca99e1a22a8612b0c47e/libraries/app/database_api.cpp#L1937 """ (path, part) = _normalize_path(path) state = { 'feed_price': _get_feed_price(), 'props': _get_props_lite(), '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[1] == 'blog', 'canonical blog route is `/@account`' assert not part[2], 'unexpected account path[2] %s' % path account = valid_account(part[0][1:]) state['accounts'][account] = _load_account(account) if part[1] not in ACCOUNT_TAB_IGNORE: assert part[1] in ACCOUNT_TAB_KEYS, "invalid acct path %s" % path key = ACCOUNT_TAB_KEYS[part[1]] posts = await _get_account_discussion_by_key(account, key) state['content'] = _keyed_posts(posts) state['accounts'][account][key] = list(state['content'].keys()) # discussion - `/category/@account/permlink` elif part[1] and part[1][0] == '@': author = valid_account(part[1][1:]) permlink = valid_permlink(part[2]) post_id = get_post_id(author, permlink) state['content'] = _load_posts_recursive([post_id]) if post_id else {} state['accounts'] = _load_content_accounts(state['content']) # ranked posts - `/sort/category` elif part[0] in ['trending', 'promoted', 'hot', 'created']: 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) posts = load_posts(cursor.pids_by_query(sort, '', '', 20, tag)) state['content'] = _keyed_posts(posts) state['discussion_idx'] = {tag: {sort: list(state['content'].keys())}} state['tag_idx'] = {'trending': await get_top_trending_tags_summary()} # 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(): state['tag_idx']['trending'].append(tag['name']) state['tags'][tag['name']] = tag elif part[0] == 'witnesses' or part[0] == '~witnesses': assert not part[1] and not part[2] raise Exception("not implemented: /%s" % path) elif part[0] in CONDENSER_NOOP_URLS: assert not part[1] and not part[2] else: print('unhandled path /%s' % path) return state