From 6b51c2e47ac114503b1c870967ed88b3c65dc7b8 Mon Sep 17 00:00:00 2001 From: Dylan Date: Thu, 15 Sep 2022 20:16:54 +0100 Subject: [PATCH 1/9] Updated readme.md --- readme.md | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/readme.md b/readme.md index b8ab747..e427b76 100644 --- a/readme.md +++ b/readme.md @@ -41,15 +41,9 @@ vxTwitter generates a config.json in its root directory the first time you run i - **db**: Caches all links to a mongoDB database. This should be used it you are using uWSGI and are not just running the script on its own as one worker - **json**: This saves cached links to a local **links.json** file +- **dynamodb**: Saves cached links to a DynamoDB database - set `table` to the table name to cache links to. - **none**: Does not cache requests. Not reccomended as you can easily use up your Twitter API credits with this. Intended for use with another cache system (i.e NGINX uwsgi_cache) -**method** - ( Options: **youtube-dl**, **api**, **hybrid** ) - -- **youtube-dl**: the original method for grabbing twitter video links, this uses a guest token provided via youtube-dl and should work well for individual instances, but may not scale up to a very large amount of usage - -- **api**: this directly uses the twitter API to grab tweet info, limited to 900 calls per 15m -- **hybrid**: This will start off by using the twitter API to grab tweet info, but if the rate limit is reached or the api fails for any other reason it will switch over to youtube-dl to avoid downtime - **color** - Accepts a hex formatted color code, can change the embed color **appname** - Can change the app name easily wherever it's shown @@ -63,10 +57,8 @@ vxTwitter generates a config.json in its root directory the first time you run i **apiMirrors** - During an influx of traffic (i.e when Twitter embeds break!) it's very likely that Twitter will begin to block you for sending too many requests. This is an array of replacement Twitter API URLs which can be called upon when requesting tweet info locally fails. An example of an implementation of an API Mirror is in the twExtract directory, and is intended to be hosted on AWS Lambda. If multiple mirror URLs are specified, one will be selected at random. -This project is licensed under the **Do What The Fuck You Want Public License** - - - ## Other stuff We check for t.co links in non video tweets, and if one is found, we direct the discord useragent to embed that link directly, this means that twitter links containing youtube / vimeo links will automatically embed those as if you had just directly linked to that content + +This project is licensed under the **Do What The Fuck You Want Public License** \ No newline at end of file From 5841ea73d82884b55d11dbfcf975ee2f1fd13d6f Mon Sep 17 00:00:00 2001 From: Dylan Date: Sun, 18 Sep 2022 17:04:03 +0100 Subject: [PATCH 2/9] Improved MP4 Redirect --- twitfix.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/twitfix.py b/twitfix.py index a11a2c7..8b946f9 100644 --- a/twitfix.py +++ b/twitfix.py @@ -68,8 +68,9 @@ def twitfix(sub_path): clean = twitter_url[:-4] else: clean = twitter_url - vid = requests.get(direct_video_link(clean)) - return Response(vid.content,mimetype="video/mp4") + #vid = requests.get(direct_video_link(clean)) + #return Response(vid.content,mimetype="video/mp4") keeping this here in case Discord changes their mind & blocks 307's + return redirect(direct_video_link(clean),code=307) # Discord, why do you fail to play 301/302 redirected URLS with .mp4 at the end??? else: return message("To use a direct MP4 link in discord, remove anything past '?' and put '.mp4' at the end") else: From 6489bb22d3116948ea5c18a4c9f7ce8171afbdcc Mon Sep 17 00:00:00 2001 From: Dylan Date: Sun, 18 Sep 2022 17:16:24 +0100 Subject: [PATCH 3/9] Fixed upgradeVNF using wrong variable --- twitfix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twitfix.py b/twitfix.py index 8b946f9..6ae076c 100644 --- a/twitfix.py +++ b/twitfix.py @@ -227,7 +227,7 @@ def embed_video(video_link, image=0): # Return Embed from any tweet link print(e) return message(msgs.failedToScan) else: - vnf = upgradeVNF(vnf) + cached_vnf = upgradeVNF(cached_vnf) return embed(video_link, cached_vnf, image) def tweetInfo(url, tweet="", desc="", thumb="", uploader="", screen_name="", pfp="", tweetType="", images="", hits=0, likes=0, rts=0, time="", qrt={}, nsfw=False,ttl=None,verified=False): # Return a dict of video info with default values From 6add65d37bdddcb1227bfd1435569cfe8e5b029a Mon Sep 17 00:00:00 2001 From: Dylan Date: Mon, 19 Sep 2022 01:35:02 +0100 Subject: [PATCH 4/9] Small code cleanup --- twitfix.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/twitfix.py b/twitfix.py index 6ae076c..523ab0c 100644 --- a/twitfix.py +++ b/twitfix.py @@ -55,7 +55,6 @@ def oembedend(): def twitfix(sub_path): user_agent = request.headers.get('user-agent') match = pathregex.search(sub_path) - print(request.url) if request.url.startswith("https://d.vx"): # Matches d.fx? Try to give the user a direct link if match.start() == 0: @@ -63,7 +62,7 @@ def twitfix(sub_path): if user_agent in generate_embed_user_agents: print( " ➤ [ D ] d.vx link shown to discord user-agent!") if request.url.endswith(".mp4") and "?" not in request.url: - # TODO: Cache this, but not for too long as disk space can fill up + if "?" not in request.url: clean = twitter_url[:-4] else: From 5f56e2248fab7e328da1cc7df0704e9334d42d66 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 20 Sep 2022 01:12:21 +0100 Subject: [PATCH 5/9] Send correct video size in embed --- templates/video.html | 8 ++++---- twitfix.py | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/templates/video.html b/templates/video.html index 736c71e..3436a52 100644 --- a/templates/video.html +++ b/templates/video.html @@ -6,8 +6,8 @@ - - + + @@ -15,8 +15,8 @@ - - + + diff --git a/twitfix.py b/twitfix.py index 523ab0c..b02a8e2 100644 --- a/twitfix.py +++ b/twitfix.py @@ -178,6 +178,11 @@ def upgradeVNF(vnf): # Makes sure any VNF object passed through this has proper fields if they're added in later versions if 'verified' not in vnf: vnf['verified']=False + if 'size' not in vnf: + if vnf['type'] == 'Video': + vnf['size']={'width':720,'height':480} + else: + vnf['size']={} return vnf def getDefaultTTL(): # TTL for deleting items from the database @@ -229,7 +234,7 @@ def embed_video(video_link, image=0): # Return Embed from any tweet link cached_vnf = upgradeVNF(cached_vnf) return embed(video_link, cached_vnf, image) -def tweetInfo(url, tweet="", desc="", thumb="", uploader="", screen_name="", pfp="", tweetType="", images="", hits=0, likes=0, rts=0, time="", qrt={}, nsfw=False,ttl=None,verified=False): # Return a dict of video info with default values +def tweetInfo(url, tweet="", desc="", thumb="", uploader="", screen_name="", pfp="", tweetType="", images="", hits=0, likes=0, rts=0, time="", qrt={}, nsfw=False,ttl=None,verified=False,size={}): # Return a dict of video info with default values if (ttl==None): ttl = getDefaultTTL() vnf = { @@ -249,7 +254,8 @@ def tweetInfo(url, tweet="", desc="", thumb="", uploader="", screen_name="", pfp "qrt" : qrt, "nsfw" : nsfw, "ttl" : ttl, - "verified" : verified + "verified" : verified, + "size" : size } return vnf @@ -268,6 +274,7 @@ def link_to_vnf_from_tweet_data(tweet,video_link): if tweet['extended_entities']['media'][0]['video_info']['variants']: best_bitrate = -1 thumb = tweet['extended_entities']['media'][0]['media_url'] + size=tweet['extended_entities']['media'][0]["original_info"] for video in tweet['extended_entities']['media'][0]['video_info']['variants']: if video['content_type'] == "video/mp4" and video['bitrate'] > best_bitrate: url = video['url'] @@ -321,7 +328,8 @@ def link_to_vnf_from_tweet_data(tweet,video_link): qrt=qrt, images=imgs, nsfw=nsfw, - verified=tweet['user']['verified'] + verified=tweet['user']['verified'], + size=size ) return vnf @@ -382,7 +390,8 @@ def getTemplate(template,vnf,desc,image,video_link,color,urlDesc,urlUser,urlLink urlDesc = urlDesc, urlUser = urlUser, urlLink = urlLink, - tweetLink = vnf['tweet'] ) + tweetLink = vnf['tweet'], + videoSize = vnf['size'] ) def embed(video_link, vnf, image): print(" ➤ [ E ] Embedding " + vnf['type'] + ": " + vnf['url']) From 7e7530b90c90d91fee3d3fb20901f6b901d5b1b8 Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 20 Sep 2022 01:30:45 +0100 Subject: [PATCH 6/9] Cleaned up/unified link->VNF code --- twitfix.py | 64 ++++++++++++++++++++---------------------------------- 1 file changed, 23 insertions(+), 41 deletions(-) diff --git a/twitfix.py b/twitfix.py index b02a8e2..42c1d8f 100644 --- a/twitfix.py +++ b/twitfix.py @@ -188,51 +188,40 @@ def upgradeVNF(vnf): def getDefaultTTL(): # TTL for deleting items from the database return datetime.today().replace(microsecond=0) + timedelta(days=1) -def direct_video(video_link): # Just get a redirect to a MP4 link from any tweet link +def vnfFromCacheOrDL(video_link): cached_vnf = getVnfFromLinkCache(video_link) if cached_vnf == None: try: vnf = link_to_vnf(video_link) addVnfToLinkCache(video_link, vnf) - return redirect(vnf['url'], 301) - print(" ➤ [ D ] Redirecting to direct URL: " + vnf['url']) + return vnf except Exception as e: print(e) - return message(msgs.failedToScan) + return None else: - return redirect(cached_vnf['url'], 301) - print(" ➤ [ D ] Redirecting to direct URL: " + vnf['url']) + return upgradeVNF(cached_vnf) + +def direct_video(video_link): # Just get a redirect to a MP4 link from any tweet link + vnf = vnfFromCacheOrDL(video_link) + if vnf != None: + return redirect(vnf['url'], 301) + else: + return message(msgs.failedToScan) def direct_video_link(video_link): # Just get a redirect to a MP4 link from any tweet link - cached_vnf = getVnfFromLinkCache(video_link) - if cached_vnf == None: - try: - vnf = link_to_vnf(video_link) - addVnfToLinkCache(video_link, vnf) - return vnf['url'] - print(" ➤ [ D ] Redirecting to direct URL: " + vnf['url']) - except Exception as e: - print(e) - return message(msgs.failedToScan) + vnf = vnfFromCacheOrDL(video_link) + if vnf != None: + return vnf['url'] else: - return cached_vnf['url'] - print(" ➤ [ D ] Redirecting to direct URL: " + vnf['url']) + return message(msgs.failedToScan) def embed_video(video_link, image=0): # Return Embed from any tweet link - cached_vnf = getVnfFromLinkCache(video_link) + vnf = vnfFromCacheOrDL(video_link) - if cached_vnf == None: - try: - vnf = link_to_vnf(video_link) - addVnfToLinkCache(video_link, vnf) - return embed(video_link, vnf, image) - - except Exception as e: - print(e) - return message(msgs.failedToScan) + if vnf != None: + return embed(video_link, vnf, image) else: - cached_vnf = upgradeVNF(cached_vnf) - return embed(video_link, cached_vnf, image) + return message(msgs.failedToScan) def tweetInfo(url, tweet="", desc="", thumb="", uploader="", screen_name="", pfp="", tweetType="", images="", hits=0, likes=0, rts=0, time="", qrt={}, nsfw=False,ttl=None,verified=False,size={}): # Return a dict of video info with default values if (ttl==None): @@ -439,19 +428,12 @@ def embed(video_link, vnf, image): def embedCombined(video_link): - cached_vnf = getVnfFromLinkCache(video_link) + vnf = vnfFromCacheOrDL(video_link) - if cached_vnf == None: - try: - vnf = link_to_vnf(video_link) - addVnfToLinkCache(video_link, vnf) - return embedCombinedVnf(video_link, vnf) - - except Exception as e: - print(e) - return message(msgs.failedToScan) + if vnf != None: + return embedCombinedVnf(video_link, vnf) else: - return embedCombinedVnf(video_link, cached_vnf) + return message(msgs.failedToScan) def embedCombinedVnf(video_link,vnf): if vnf['type'] != "Image" or vnf['images'][4] == "1": From 9981a2deb0743b4cf398ac490da2334101747d7c Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 20 Sep 2022 01:39:21 +0100 Subject: [PATCH 7/9] Use template for direct MP4 link --- templates/rawvideo.html | 16 ++++++++++++++++ twitfix.py | 12 ++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 templates/rawvideo.html diff --git a/templates/rawvideo.html b/templates/rawvideo.html new file mode 100644 index 0000000..f50cbc3 --- /dev/null +++ b/templates/rawvideo.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} {% block head %} + + + + + + + + + + + + + + + {% endblock %} {% block body %} Redirecting you to the video in a moment. Or click here. {% endblock %} \ No newline at end of file diff --git a/twitfix.py b/twitfix.py index 42c1d8f..693f405 100644 --- a/twitfix.py +++ b/twitfix.py @@ -67,9 +67,9 @@ def twitfix(sub_path): clean = twitter_url[:-4] else: clean = twitter_url - #vid = requests.get(direct_video_link(clean)) - #return Response(vid.content,mimetype="video/mp4") keeping this here in case Discord changes their mind & blocks 307's - return redirect(direct_video_link(clean),code=307) # Discord, why do you fail to play 301/302 redirected URLS with .mp4 at the end??? + + vnf = vnfFromCacheOrDL(clean) + return getTemplate("rawvideo.html",vnf,"","",clean,"","","","") else: return message("To use a direct MP4 link in discord, remove anything past '?' and put '.mp4' at the end") else: @@ -93,9 +93,9 @@ def twitfix(sub_path): clean = twitter_url[:-4] else: clean = twitter_url - # TODO: Cache this, but not for too long as disk space can fill up - vid = requests.get(direct_video_link(clean)) - return Response(vid.content,mimetype="video/mp4") + + vnf = vnfFromCacheOrDL(clean) + return getTemplate("rawvideo.html",vnf,"","",clean,"","","","") elif request.url.endswith("/1") or request.url.endswith("/2") or request.url.endswith("/3") or request.url.endswith("/4") or request.url.endswith("%2F1") or request.url.endswith("%2F2") or request.url.endswith("%2F3") or request.url.endswith("%2F4"): twitter_url = "https://twitter.com/" + sub_path From bbcb3ceb052c66e0c60672e93fa70bf00cf35b4e Mon Sep 17 00:00:00 2001 From: Dylan Date: Tue, 20 Sep 2022 17:44:03 +0100 Subject: [PATCH 8/9] Misc. Bug fixes --- serverless.yml | 4 ++-- twitfix.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/serverless.yml b/serverless.yml index 06d2ec8..e0ac2b9 100644 --- a/serverless.yml +++ b/serverless.yml @@ -47,8 +47,8 @@ functions: vxTwitterApp: handler: wsgi_handler.handler url: true - timeout: 15 - MemorySize: 1024 + timeout: 5 + memorySize: 300 layers: - Ref: PythonRequirementsLambdaLayer diff --git a/twitfix.py b/twitfix.py index 693f405..4fe1f8c 100644 --- a/twitfix.py +++ b/twitfix.py @@ -271,6 +271,7 @@ def link_to_vnf_from_tweet_data(tweet,video_link): elif tweetType(tweet) == "Text": url = "" thumb = "" + size = {} else: imgs = ["","","","", ""] i = 0 @@ -283,6 +284,7 @@ def link_to_vnf_from_tweet_data(tweet,video_link): url = "" images= imgs thumb = tweet['extended_entities']['media'][0]['media_url_https'] + size = {} qrt = {} @@ -359,6 +361,9 @@ def message(text): url = config['config']['url'] ) def getTemplate(template,vnf,desc,image,video_link,color,urlDesc,urlUser,urlLink,appNameSuffix=""): + if ('width' in vnf['size'] and 'height' in vnf['size']): + vnf['size']['width'] = min(vnf['size']['width'],2000) + vnf['size']['height'] = min(vnf['size']['height'],2000) return render_template( template, likes = vnf['likes'], From 403b82d7fef41d1017c64c3582b085ab93e1b310 Mon Sep 17 00:00:00 2001 From: Dylan Date: Wed, 28 Sep 2022 19:22:41 +0100 Subject: [PATCH 9/9] Improved messages for errors, removed apiMirrors --- configHandler.py | 6 ++--- msgs.py | 4 ++-- readme.md | 3 --- serverless.yml | 2 +- twitfix.py | 61 +++++++++++++++++++++++++++++++----------------- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/configHandler.py b/configHandler.py index d19ea63..65f8c8b 100644 --- a/configHandler.py +++ b/configHandler.py @@ -11,8 +11,7 @@ if ('RUNNING_SERVERLESS' in os.environ and os.environ['RUNNING_SERVERLESS'] == ' "appname": os.environ["VXTWITTER_APP_NAME"], "repo": os.environ["VXTWITTER_REPO"], "url": os.environ["VXTWITTER_URL"], - "combination_method": os.environ["VXTWITTER_COMBINATION_METHOD"], # can either be 'local' or a URL to a server handling requests in the same format - "apiMirrors":[] + "combination_method": os.environ["VXTWITTER_COMBINATION_METHOD"] # can either be 'local' or a URL to a server handling requests in the same format } } else: @@ -28,8 +27,7 @@ else: "appname": "vxTwitter", "repo": "https://github.com/dylanpdx/BetterTwitFix", "url": "https://vxtwitter.com", - "combination_method": "local", # can either be 'local' or a URL to a server handling requests in the same format - "apiMirrors":[] + "combination_method": "local" # can either be 'local' or a URL to a server handling requests in the same format } } diff --git a/msgs.py b/msgs.py index 47f9ba4..d554d4d 100644 --- a/msgs.py +++ b/msgs.py @@ -1,5 +1,5 @@ -failedToScan="Failed to scan your link! This may be due to an incorrect link, private account, or the twitter API itself might be having issues (Check here: https://api.twitterstat.us/)\nIt's also possible that Twitter is API limiting me, in which case I can't do anything about it." - +failedToScan="Failed to scan your link! This may be due to an incorrect link, private/suspended account, deleted tweet, or Twitter itself might be having issues (Check here: https://api.twitterstat.us/)" +failedToScanExtra = "\n\nTwitter gave me this error: " def genLikesDisplay(vnf): return ("\n\n💖 " + str(vnf['likes']) + " 🔁 " + str(vnf['rts']) + "\n") diff --git a/readme.md b/readme.md index e427b76..a566fdf 100644 --- a/readme.md +++ b/readme.md @@ -54,9 +54,6 @@ vxTwitter generates a config.json in its root directory the first time you run i **combination_method** - using c.vxtwitter as the url causes vxTwitter to combine all images in the post into one. This is CPU intensive, so you might not want it running on the same machine that's serving requests. When `combination_method` is set to `local`, it will use the local machine to combine the images. This requires pillow to be installed. If you want to use another server, replace `local` with the URL to the endpoint which combines images. Both methods use the code in the `combineImg` module. Inside, there's also a `Dockerfile` intended to be deployed as a combination endpoint on an [AWS Lambda function](https://docs.aws.amazon.com/lambda/latest/dg/images-create.html). -**apiMirrors** - During an influx of traffic (i.e when Twitter embeds break!) it's very likely that Twitter will begin to block you for sending too many requests. -This is an array of replacement Twitter API URLs which can be called upon when requesting tweet info locally fails. An example of an implementation of an API Mirror is in the twExtract directory, and is intended to be hosted on AWS Lambda. If multiple mirror URLs are specified, one will be selected at random. - ## Other stuff We check for t.co links in non video tweets, and if one is found, we direct the discord useragent to embed that link directly, this means that twitter links containing youtube / vimeo links will automatically embed those as if you had just directly linked to that content diff --git a/serverless.yml b/serverless.yml index e0ac2b9..3ed9026 100644 --- a/serverless.yml +++ b/serverless.yml @@ -48,7 +48,7 @@ functions: handler: wsgi_handler.handler url: true timeout: 5 - memorySize: 300 + memorySize: 150 layers: - Ref: PythonRequirementsLambdaLayer diff --git a/twitfix.py b/twitfix.py index 4fe1f8c..b05f969 100644 --- a/twitfix.py +++ b/twitfix.py @@ -1,8 +1,10 @@ +from email import utils from random import Random, random from weakref import finalize from flask import Flask, render_template, request, redirect, abort, Response, send_from_directory, url_for, send_file, make_response, jsonify from flask_cors import CORS import textwrap +from pkg_resources import ExtractionError import requests import re import os @@ -16,6 +18,7 @@ import twExtract as twExtract from configHandler import config from cache import addVnfToLinkCache,getVnfFromLinkCache import random +from yt_dlp.utils import ExtractorError app = Flask(__name__) CORS(app) @@ -68,7 +71,11 @@ def twitfix(sub_path): else: clean = twitter_url - vnf = vnfFromCacheOrDL(clean) + vnf,e = vnfFromCacheOrDL(clean) + if vnf == None: + if e is not None: + return message(msgs.failedToScan+msgs.failedToScanExtra+e) + return message(msgs.failedToScan) return getTemplate("rawvideo.html",vnf,"","",clean,"","","","") else: return message("To use a direct MP4 link in discord, remove anything past '?' and put '.mp4' at the end") @@ -94,7 +101,11 @@ def twitfix(sub_path): else: clean = twitter_url - vnf = vnfFromCacheOrDL(clean) + vnf,e = vnfFromCacheOrDL(clean) + if vnf is None: + if e is not None: + return message(msgs.failedToScan+msgs.failedToScanExtra+e) + return message(msgs.failedToScan) return getTemplate("rawvideo.html",vnf,"","",clean,"","","","") elif request.url.endswith("/1") or request.url.endswith("/2") or request.url.endswith("/3") or request.url.endswith("/4") or request.url.endswith("%2F1") or request.url.endswith("%2F2") or request.url.endswith("%2F3") or request.url.endswith("%2F4"): @@ -194,33 +205,47 @@ def vnfFromCacheOrDL(video_link): try: vnf = link_to_vnf(video_link) addVnfToLinkCache(video_link, vnf) - return vnf + return vnf,None + except ExtractorError as exErr: + if 'HTTP Error 404' in exErr.msg: + exErr.msg="Tweet not found." + elif 'suspended' in exErr.msg: + exErr.msg="This Tweet is from a suspended account." + else: + exErr.msg=None + return None,exErr.msg except Exception as e: print(e) - return None + return None,None else: - return upgradeVNF(cached_vnf) + return upgradeVNF(cached_vnf),None def direct_video(video_link): # Just get a redirect to a MP4 link from any tweet link - vnf = vnfFromCacheOrDL(video_link) + vnf,e = vnfFromCacheOrDL(video_link) if vnf != None: return redirect(vnf['url'], 301) else: + if e is not None: + return message(msgs.failedToScan+msgs.failedToScanExtra+e) return message(msgs.failedToScan) def direct_video_link(video_link): # Just get a redirect to a MP4 link from any tweet link - vnf = vnfFromCacheOrDL(video_link) + vnf,e = vnfFromCacheOrDL(video_link) if vnf != None: return vnf['url'] else: + if e is not None: + return message(msgs.failedToScan+msgs.failedToScanExtra+e) return message(msgs.failedToScan) def embed_video(video_link, image=0): # Return Embed from any tweet link - vnf = vnfFromCacheOrDL(video_link) + vnf,e = vnfFromCacheOrDL(video_link) if vnf != None: return embed(video_link, vnf, image) else: + if e is not None: + return message(msgs.failedToScan+msgs.failedToScanExtra+e) return message(msgs.failedToScan) def tweetInfo(url, tweet="", desc="", thumb="", uploader="", screen_name="", pfp="", tweetType="", images="", hits=0, likes=0, rts=0, time="", qrt={}, nsfw=False,ttl=None,verified=False,size={}): # Return a dict of video info with default values @@ -327,15 +352,9 @@ def link_to_vnf_from_tweet_data(tweet,video_link): def link_to_vnf_from_unofficial_api(video_link): + tweet=None print(" ➤ [ + ] Attempting to download tweet info from UNOFFICIAL Twitter API") - try: - tweet = twExtract.extractStatus(video_link) - except Exception as e: - print(' ➤ [ !!! ] Local UNOFFICIAL API Failed') - if ('apiMirrors' in config['config'] and len(config['config']['apiMirrors']) > 0): - mirror = random.choice(config['config']['apiMirrors']) - print(" ➤ [ + ] Using API Mirror: "+mirror) - tweet = requests.get(mirror+"?url="+video_link).json() + tweet = twExtract.extractStatus(video_link) print (" ➤ [ ✔ ] Unofficial API Success") return link_to_vnf_from_tweet_data(tweet,video_link) @@ -345,11 +364,7 @@ def link_to_vnf_from_api(video_link): return link_to_vnf_from_tweet_data(tweet,video_link) def link_to_vnf(video_link): # Return a VideoInfo object or die trying - try: - return link_to_vnf_from_unofficial_api(video_link) - except Exception as e: - print(" ➤ [ !!! ] Unofficial Twitter API Failed") - print(e) + return link_to_vnf_from_unofficial_api(video_link) def message(text): return render_template( @@ -433,11 +448,13 @@ def embed(video_link, vnf, image): def embedCombined(video_link): - vnf = vnfFromCacheOrDL(video_link) + vnf,e = vnfFromCacheOrDL(video_link) if vnf != None: return embedCombinedVnf(video_link, vnf) else: + if e is not None: + return message(msgs.failedToScan+msgs.failedToScanExtra+e) return message(msgs.failedToScan) def embedCombinedVnf(video_link,vnf):