added comments to v1 api, introduced failsafe for videos without related video feed (e.g. age restricted videos)
This commit is contained in:
@@ -31,22 +31,34 @@ def stats():
|
|||||||
|
|
||||||
def hot(data):
|
def hot(data):
|
||||||
#print(data)
|
#print(data)
|
||||||
|
# if we are given not enough data to work with, return bad request.
|
||||||
|
# example:
|
||||||
|
# hot related videoId
|
||||||
|
# 0. 1. 2. [No. of argument]
|
||||||
if len(data) <= 2:
|
if len(data) <= 2:
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: bad request. supply required arguments.', []
|
return 400, f'error: bad request. supply required arguments.', []
|
||||||
|
|
||||||
|
# check our first argument
|
||||||
match data[1]:
|
match data[1]:
|
||||||
|
|
||||||
|
# if it can be handled by yt_dlp, use yt_dlp
|
||||||
case "video" | "channel" | "handle" | "playlist":
|
case "video" | "channel" | "handle" | "playlist":
|
||||||
url_lookup = {'video': 'https://www.youtube.com/watch?v=', 'channel': 'https://www.youtube.com/channel/', 'handle': 'https://www.youtube.com/@', 'playlist': 'https://www.youtube.com/playlist?list='}
|
url_lookup = {'video': 'https://www.youtube.com/watch?v=', 'channel': 'https://www.youtube.com/channel/', 'handle': 'https://www.youtube.com/@', 'playlist': 'https://www.youtube.com/playlist?list='}
|
||||||
comment_count = ""
|
comment_count = ""
|
||||||
|
# require 3 arguments (if using "c" or "nc")
|
||||||
if len(data) <= 3:
|
if len(data) <= 3:
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: bad request. supply required arguments.', []
|
return 400, f'error: bad request. supply required arguments.', []
|
||||||
|
# comment settings should be either Comments, No Comments, or Limited Comments
|
||||||
if data[2] not in ("c", "nc", "lc"):
|
if data[2] not in ("c", "nc", "lc"):
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return notImplemented(data)
|
return notImplemented(data)
|
||||||
|
# require 4 arguments (when using "lc" we need to know the number of comments to retrieve)
|
||||||
if data[2] == "lc" and len(data) <= 4:
|
if data[2] == "lc" and len(data) <= 4:
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: bad request. limited comments (lc) requires an extra argument specifying amount of comments.', []
|
return 400, f'error: bad request. limited comments (lc) requires an extra argument specifying amount of comments.', []
|
||||||
|
# check if the additional "lc" argument is a number
|
||||||
elif data[2] == "lc":
|
elif data[2] == "lc":
|
||||||
try:
|
try:
|
||||||
comment_count = str(int(data[3]))
|
comment_count = str(int(data[3]))
|
||||||
@@ -54,6 +66,7 @@ def hot(data):
|
|||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: bad request. {data[3]} is not a number.', []
|
return 400, f'error: bad request. {data[3]} is not a number.', []
|
||||||
videoId = data[4]
|
videoId = data[4]
|
||||||
|
# if the user didn't choose Limited Comments, then the videoId must be the fourth (zero included) argument
|
||||||
else:
|
else:
|
||||||
videoId = data[3]
|
videoId = data[3]
|
||||||
|
|
||||||
@@ -61,19 +74,29 @@ def hot(data):
|
|||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: bad request. wrong videoId: {videoId} is {len(videoId)} characters long, but should be 11.', []
|
return 400, f'error: bad request. wrong videoId: {videoId} is {len(videoId)} characters long, but should be 11.', []
|
||||||
|
|
||||||
|
# assume we want to get the comments
|
||||||
getcomments = True
|
getcomments = True
|
||||||
|
# unless we're given "nc"
|
||||||
if data[2] == "nc":
|
if data[2] == "nc":
|
||||||
getcomments = False
|
getcomments = False
|
||||||
|
|
||||||
|
# try to get the data
|
||||||
try:
|
try:
|
||||||
started = time.time()
|
started = time.time()
|
||||||
extracted_dict = ythdd_extractor.extract(url_lookup[data[1]] + videoId, getcomments=getcomments, maxcomments=comment_count)
|
extracted_dict = ythdd_extractor.extract(url_lookup[data[1]] + videoId, getcomments=getcomments, maxcomments=comment_count)
|
||||||
extracted_dict["took"] = time.time() - started
|
extracted_dict["took"] = time.time() - started
|
||||||
return 200, "OK", extracted_dict
|
return 200, "OK", extracted_dict
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# shrink yt_dlp's unnecessarily long error message
|
||||||
|
# example: \u001b[0;31mERROR:\u001b[0m [youtube] videoIdABCD: Sign in to confirm your age. This video may be inappropriate for some users.
|
||||||
|
# TODO: perhaps implement proper error handling? so that we don't need this hacky solution
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: failed to get "{videoId}" ({data[2]})', {'error_msg': str(e)}
|
error_msg = str(e).replace("\u001b[0;31mERROR:\u001b[0m [youtube] " + videoId + ": ", "") # yt_dlp error message with color codes
|
||||||
|
return 400, f'error: failed to get "{videoId}" ({data[2]})', {'error_msg': error_msg}
|
||||||
|
|
||||||
|
# if some functionality is not supported or buried deep within yt_dlp, as is the case with "related videos" feed, use our own (naive) approach
|
||||||
case "related":
|
case "related":
|
||||||
|
# no logic needed for additional arguments here
|
||||||
videoId = data[2]
|
videoId = data[2]
|
||||||
if len(videoId) != 11: # videoId sanity check
|
if len(videoId) != 11: # videoId sanity check
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
@@ -81,10 +104,16 @@ def hot(data):
|
|||||||
|
|
||||||
started = time.time()
|
started = time.time()
|
||||||
try:
|
try:
|
||||||
|
# try to actually get the data
|
||||||
extracted_related = ythdd_extractor.related('https://www.youtube.com/watch?v=' + videoId)
|
extracted_related = ythdd_extractor.related('https://www.youtube.com/watch?v=' + videoId)
|
||||||
extracted_related['took'] = time.time() - started
|
extracted_related['took'] = time.time() - started
|
||||||
return 200, "OK", extracted_related
|
return 200, "OK", extracted_related
|
||||||
|
except KeyError:
|
||||||
|
# instead of throwing error at age restricted videos for not having "related videos" feed,
|
||||||
|
# return an empty feed
|
||||||
|
return 200, "OK", {'secondaryResults': {'results': []}, 'took': time.time() - started}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# general exception handler
|
||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return 400, f'error: unknown error while parsing {videoId}: {e}', []
|
return 400, f'error: unknown error while parsing {videoId}: {e}', []
|
||||||
|
|
||||||
@@ -92,41 +121,6 @@ def hot(data):
|
|||||||
incrementBadRequests()
|
incrementBadRequests()
|
||||||
return notImplemented(data)
|
return notImplemented(data)
|
||||||
|
|
||||||
|
|
||||||
'''
|
|
||||||
if data[1] not in ("video", "channel", "handle", "playlist", "related"):
|
|
||||||
incrementBadRequests()
|
|
||||||
return notImplemented(data)
|
|
||||||
if data[2] not in ("c", "nc", "lc"): # comments, no comments, limited comments
|
|
||||||
incrementBadRequests()
|
|
||||||
return notImplemented(data)
|
|
||||||
if data[2] == "lc":
|
|
||||||
if len(data) <= 4:
|
|
||||||
incrementBadRequests()
|
|
||||||
return 400, f'error: bad request. limited comments (lc) requires an extra argument specifying amount of comments.', []
|
|
||||||
try:
|
|
||||||
comment_count = str(int(data[3]))
|
|
||||||
except:
|
|
||||||
incrementBadRequests()
|
|
||||||
return 400, f'error: bad request. {data[3]} is not a number.', []
|
|
||||||
videoId = data[4]
|
|
||||||
else:
|
|
||||||
videoId = data[3]
|
|
||||||
try:
|
|
||||||
url_lookup = {'video': 'https://www.youtube.com/watch?v=', 'channel': 'https://www.youtube.com/channel/', 'handle': 'https://www.youtube.com/@', 'playlist': 'https://www.youtube.com/playlist?list='}
|
|
||||||
if data[2] == "nc":
|
|
||||||
getcomments = False
|
|
||||||
else:
|
|
||||||
getcomments = True
|
|
||||||
started = int(time.time())
|
|
||||||
extracted_dict = ythdd_extractor.extract(url_lookup[data[1]] + videoId, getcomments=getcomments, maxcomments=comment_count)
|
|
||||||
extracted_dict["took"] = int(time.time()) - started
|
|
||||||
return 200, "OK", extracted_dict
|
|
||||||
except Exception as e:
|
|
||||||
incrementBadRequests()
|
|
||||||
return 400, f'error: failed to get "{videoId}" ({data[2]}). {e}', []
|
|
||||||
'''
|
|
||||||
|
|
||||||
def lookup(data):
|
def lookup(data):
|
||||||
match data[0]:
|
match data[0]:
|
||||||
case 'stats':
|
case 'stats':
|
||||||
|
|||||||
Reference in New Issue
Block a user