def save_tweet_media(tweet_dict): logger.info(f"[tweet:{tweet_dict['id_str']}] Downloading media...") dir_pref = os.path.join( context.relativize(context.get_config()['media_dir']), tweet_dict['id_str']) media = tweet_dict['extended_entities']['media'] i = 1 for item in media: mtype = item['type'] if mtype == 'video' or mtype == 'animated_gif': variants = sorted(item['video_info']['variants'], key=lambda variant: variant.get('bitrate', 0), reverse=True) url = variants[0]['url'] ext = '.mp4' else: url = item['media_url_https'] ext = os.path.splitext(url)[1] media_path = os.path.join(dir_pref, f"{i}_{mtype}{ext}") logger.debug( f"[tweet:{tweet_dict['id_str']}][{mtype}:{i}] Downloading {url}..." ) os.makedirs(dir_pref, exist_ok=True) urllib.request.urlretrieve(url, media_path) i += 1
def make_config(): config = {} cfont = context.get_config().get('custom_font', None) if cfont is not None: path = context.relativize(os.path.join('assets', 'css', f'{cfont}.css')) normal_path = path.replace('\\', '/') url = f'file://{urllib.parse.quote(normal_path)}' config['custom_font'] = {'css_url': url, 'path': path} return config
def get_environment(): global _environment if not _environment: _environment = Environment( loader=FileSystemLoader(context.get_config()['template']['path']), autoescape=select_autoescape(['html', 'xml'])) _environment.filters['tweet_htmlize'] = tweet_htmlize _environment.filters['short_datetime'] = short_datetime _environment.filters['long_datetime'] = long_datetime _environment.filters['tweet_source_name'] = tweet_source_name return _environment
def post_tweet_media_as_followup(self, tweet_id, in_reply_id, status): dir_pref = os.path.join( context.relativize(context.get_config()['media_dir']), tweet_id) if os.path.exists(dir_pref): logger.info(f"[tweet:{tweet_id}] posting followup media") new_media_ids = [] for m in os.listdir(dir_pref): full_path = os.path.join(dir_pref, m) mime_type, _ = mimetypes.guess_type(full_path) with open(full_path, 'rb') as fp: # chunked media upload for every type = better? new_media_id = self.twython.upload_video( fp, mime_type, check_progress=True)['media_id'] new_media_ids.append(new_media_id) if new_media_ids: stat = self.twython.update_status( status=status, media_ids=new_media_ids, in_reply_to_status_id=in_reply_id, auto_populate_reply_metadata=True) db.insert_repost(stat['id_str'], self.credentials.account_id, tweet_id, 'media')
from twython import Twython from twython.exceptions import TwythonAuthError from deleted_tweets import context context.initialize(__file__) config = context.get_config() consumer_keys = config.get('consumer', None) if not consumer_keys: print('''\nPlease set the consumer keys in config.json as: { "consumer": { "key": "<your_consumer_key_here>", "secret": "<your_consumer_secret_here>" } ... }\n''') exit(1) ck = consumer_keys['key'] cs = consumer_keys['secret'] rest = Twython(ck, cs) try: auth = rest.get_authentication_tokens() except TwythonAuthError: print("Bad API keys") exit(1) print("\nGo to this URL and log in:\n" + auth['auth_url'] + "\n")
def render_tweet(tweet): return tweetcap(context.get_config()['template']['name'], tweet)