import traceback import urllib.parse import re accent_color = 'darkgreen' def extend_text(text, urls_container): for url in urls_container['urls']: text = text.replace(url['url'], f"{url['expanded_url']}") text = re.sub(r'@([a-zA-Z0-9_]+)', r'@\1', text) return text def render_user(user): html = '' html += f"" html += f"" html += '
' html += f"

{user['name']}

" html += '@' + user['screen_name'] html += '
' html += '
' return html def render_tweet(tweet, user, graph_tweet=None, is_pinned=False): html = '
' if 'retweeted_status_result' in tweet: graph_retweeted = tweet['retweeted_status_result']['result'] if 'tweet' in graph_retweeted: graph_retweeted = graph_retweeted['tweet'] retweeted = graph_retweeted['legacy'] retweeted_user = graph_retweeted['core']['user_results']['result']['legacy'] tweet_link = f"/{retweeted_user['screen_name']}/status/{retweeted['id_str']}" else: retweeted = None tweet_link = f"/{user['screen_name']}/status/{tweet['id_str']}" html += f"" if is_pinned: html += '

Pinned Tweet

' html += f"

{tweet['created_at']}

" html += render_user(user) if retweeted is not None: html += render_tweet(retweeted, retweeted_user, graph_retweeted) html += '
' return html if graph_tweet is not None and 'note_tweet' in graph_tweet: text = graph_tweet['note_tweet']['note_tweet_results']['result']['text'] else: text = tweet.get('full_text', tweet.get('text')) text = extend_text(text, tweet['entities']) html += '

' + text + '

' try: for media in tweet['extended_entities']['media']: html = html.replace(media['url'], '') url = media['media_url_https'] if media['type'] in ('video', 'animated_gif'): html += f"' else: html += f'' except KeyError: pass if graph_tweet is not None and 'quoted_status_result' in graph_tweet: quoted_tweet_graph = graph_tweet['quoted_status_result']['result'] quoted_tweet = quoted_tweet_graph['legacy'] quoted_user = quoted_tweet_graph['core']['user_results']['result']['legacy'] html += render_tweet(quoted_tweet, quoted_user, quoted_tweet_graph) html += f'' try: html += f"{tweet['reply_count']}" except KeyError: pass html += '' html += f'' html += f"{tweet['quote_count']}" html += '' html += f'' html += f"{tweet['retweet_count']}" html += '' html += f'' html += f"{tweet['favorite_count']}" html += '' html += f'' try: if graph_tweet is not None: html += f"{graph_tweet['views']['count']}" except KeyError: pass html += '' html += '' return html def render_graph_tweet(content, is_pinned): graph_tweet = content['itemContent']['tweet_results']['result'] if 'tweet' in graph_tweet: graph_tweet = graph_tweet['tweet'] tweet = graph_tweet['legacy'] user = graph_tweet['core']['user_results']['result'] if 'tweet' in user: user = user['tweet'] user = user['legacy'] return render_tweet(tweet, user, graph_tweet, is_pinned) def render_load_more(content, params): params['cursor'] = content['value'] href = urllib.parse.urlencode(params) return f"load more" def render_instruction(entry, params, is_pinned=False): html = '' content = entry['content'] if 'itemContent' in content: itemContent = content['itemContent'] if 'tweet_results' in itemContent: html += render_graph_tweet(content, is_pinned) elif 'user_results' in itemContent: try: html += render_user_card(itemContent['user_results']['result']['legacy']) except KeyError: traceback.print_exc() else: try: html += render_load_more(itemContent, params) except KeyError: traceback.print_exc() if 'items' in content: html += '
' if len(content['items']) > 1: html += f"
" for item in content['items']: try: html += render_graph_tweet(item['item'], is_pinned) except KeyError: traceback.print_exc() html += '
' if 'value' in content: html += render_load_more(content, params) return html def render_instructions(timeline, params=None): if params is None: params = {} html = '' for instruction in timeline['instructions']: if 'entry' in instruction and instruction['type'] == 'TimelinePinEntry': html += render_instruction(instruction['entry'], params, True) for instruction in timeline['instructions']: if 'entries' in instruction: for entry in instruction['entries']: html += render_instruction(entry, params) if 'entry' in instruction and instruction['type'] != 'TimelinePinEntry': html += render_instruction(instruction['entry'], params) return html def render_user_card(user): username = user['screen_name'] html = '' html += '
' html += f"{user['name']} (@{username}) - yitter" html += render_user(user) description = extend_text(user['description'], user['entities']['description']) html += '

' + description + '

' html += '

' html += f'Following: {user["friends_count"]} ' html += f'Followers: {user["followers_count"]}' html += '

' html += f'Home Likes' html += '
' return html def render_user_header(user): user = user['data']['user']['result']['legacy'] username = user['screen_name'] html = '' if 'profile_banner_url' in user: html += f"" html += render_user_card(user) return html def render_top(): html = '' html += '' html += '
' html += '
' html += f"

yitter

" html += '
' html += '
' html += '' html += '
' html += '' html += '
' return html