]>
git.gir.st - subscriptionfeed.git/blob - app/browse/lib.py
3 from datetime
import datetime
, timezone
5 from ..common
.innertube
import G
7 def fetch_ajax(endpoint
, **kwargs
):
9 fetch data using a continuation protobuf
11 # TODO: handle auto_generated!
12 today
= datetime
.now(timezone
.utc
).strftime("%Y%m%d")
14 # TODO: this is not cached any more! -> https://github.com/reclosedev/requests-cache/issues/154
15 # Note: this 'innertube' API key exists since at least 2015: https://stackoverflow.com/q/33511165
16 r
= requests
.post(f
"https://www.youtube.com/youtubei/v1/{endpoint}?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8", json
={
18 'context': {'client': {
22 'clientVersion': f
'2.{today}.01.01',
31 def canonicalize_channel(name
, typ
="c"):
32 if re
.fullmatch(r
"(UC[A-Za-z0-9_-]{22})", name
):
35 # get UCID of /c/ (vanity URLs):
36 today
= datetime
.now(timezone
.utc
).strftime("%Y%m%d")
37 typ
+= "/" if typ
!= "@" else ""
38 r
= requests
.get(f
'https://www.youtube.com/{typ}{name}/about?pbj=1&hl=en_US', headers
={
39 'x-youtube-client-name': '1',
40 'x-youtube-client-version': f
'2.{today}.01.01', # see fetch_searchresults()
43 return r
.json()[1]['response']['metadata']['channelMetadataRenderer']['rssUrl'].split("=")[1]
50 def find_and_parse_error(result
):
52 result|
G('responseContext')|
G('errors')|
G('error')|
G(0)
53 or result|
G('alerts')|
G(0)|
G('alertRenderer')
59 error_type
= error_obj|
G('code', 'type', 'status') or 'Error'
61 error_obj|
G('debugInfo', 'externalErrorMessage')
62 or error_obj|
G('text')|G
.text
63 or error_obj|
G('message')
66 return f
"{error_type}: {error.rstrip('.')}"