channel info support for youtube handler

This commit is contained in:
Matias Wilkman 2024-01-18 07:51:56 +02:00
parent 5d1ca4bf86
commit c13b7c1369

View File

@ -805,11 +805,53 @@ class SpiffyTitles(callbacks.Plugin):
"SpiffyTitles: error getting video id from %s (%s)" % (url, str(e)) "SpiffyTitles: error getting video id from %s (%s)" % (url, str(e))
) )
def get_channel_id_from_url(self, url, info, api_key):
"""
Get YouTube channel ID from URL
"""
try:
parsed_url = urlparse(url)
if 'youtube.com' in parsed_url.netloc:
path_parts = parsed_url.path.split('/')
# URL of the form https://www.youtube.com/user/username or https://www.youtube.com/@username:
if 'user' in path_parts:
username = path_parts[path_parts.index('user') + 1]
api_url = 'https://www.googleapis.com/youtube/v3/channels'
log.debug("SpiffyTitles: requesting %s" % (api_url))
try:
request = requests.get(
api_url, timeout=self.timeout, proxies=self.proxies,
params={
'part': 'id',
'forUsername': username,
'key': api_key
}
)
request.raise_for_status()
data = json.loads(request.content.decode())
if data['items']:
return data['items'][0]['id']
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: YouTube Error: {0}".format(e))
# URL of the form https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw:
elif 'channel' in path_parts:
return path_parts[path_parts.index('channel') + 1]
# TODO: figure out a way to handle https://www.youtube.com/@GoogleDevelopers style URLs
return None
except Exception as e:
log.error(
"SpiffyTitles: error getting channel id from %s (%s)" % (url, str(e))
)
def handler_youtube(self, url, domain, channel): def handler_youtube(self, url, domain, channel):
""" """
Uses the Youtube API to provide additional meta data about Uses the Youtube API to provide additional meta data about
Youtube Video links posted. Youtube Video links posted.
""" """
type = "video"
youtube_handler_enabled = self.registryValue("youtube.enabled", channel) youtube_handler_enabled = self.registryValue("youtube.enabled", channel)
if not youtube_handler_enabled: if not youtube_handler_enabled:
return self.handler_default(url, channel) return self.handler_default(url, channel)
@ -826,9 +868,16 @@ class SpiffyTitles(callbacks.Plugin):
log.debug( log.debug(
"SpiffyTitles: Failed to get YouTube video ID for URL: {0}".format(url) "SpiffyTitles: Failed to get YouTube video ID for URL: {0}".format(url)
) )
channel_id = self.get_channel_id_from_url(url, domain, developer_key)
if not channel_id:
return self.handler_default(url, channel) return self.handler_default(url, channel)
else:
type = "channel"
else:
type = "video"
yt_template = Template(self.registryValue("youtube.template", channel)) yt_template = Template(self.registryValue("youtube.template", channel))
title = "" title = ""
if type == "video":
options = { options = {
"part": "snippet,statistics,contentDetails", "part": "snippet,statistics,contentDetails",
"maxResults": 1, "maxResults": 1,
@ -846,7 +895,7 @@ class SpiffyTitles(callbacks.Plugin):
requests.exceptions.RequestException, requests.exceptions.RequestException,
requests.exceptions.HTTPError, requests.exceptions.HTTPError,
) as e: ) as e:
log.error("SpiffyTitiles: YouTube Error: {0}".format(e)) log.error("SpiffyTitles: YouTube Error: {0}".format(e))
return self.handler_default(url, channel) return self.handler_default(url, channel)
response = json.loads(request.content.decode()) response = json.loads(request.content.decode())
if not response or not response.get("items"): if not response or not response.get("items"):
@ -910,6 +959,51 @@ class SpiffyTitles(callbacks.Plugin):
log.error( log.error(
"SpiffyTitles: IndexError. Youtube API JSON response: %s" % (str(e)) "SpiffyTitles: IndexError. Youtube API JSON response: %s" % (str(e))
) )
elif type == "channel":
options = {
"part": "snippet,statistics,contentDetails",
"maxResults": 1,
"key": developer_key,
"id": channel_id,
}
api_url = "https://www.googleapis.com/youtube/v3/channels"
log.debug("SpiffyTitles: requesting %s" % (api_url))
try:
request = requests.get(
api_url, params=options, timeout=self.timeout, proxies=self.proxies
)
request.raise_for_status()
except (
requests.exceptions.RequestException,
requests.exceptions.HTTPError,
) as e:
log.error("SpiffyTitles: YouTube Error: {0}".format(e))
return self.handler_default(url, channel)
response = json.loads(request.content.decode())
if not response or not response.get("items"):
log.error("SpiffyTitles: Failed to parse YouTube JSON response")
return self.handler_default(url, channel)
try:
items = response["items"]
channel = items[0]
snippet = channel["snippet"]
title = snippet["title"]
statistics = channel["statistics"]
view_count = 0
subscriber_count = 0
video_count = 0
if "viewCount" in statistics:
view_count = "{:,}".format(int(statistics["viewCount"]))
if "subscriberCount" in statistics:
subscriber_count = "{:,}".format(int(statistics["subscriberCount"]))
if "videoCount" in statistics:
video_count = "{:,}".format(int(statistics["videoCount"]))
yt_logo = "YouTube" #self.get_youtube_logo(channel) #FIXME: why doesn't work here?
title = yt_logo + " :: " + "Channel: " + title + " :: Views: " + view_count + " :: Subscribers: " + subscriber_count + " :: Videos: " + video_count
except IndexError as e:
log.error(
"SpiffyTitles: IndexError. Youtube API JSON response: %s" % (str(e))
)
# If we found a title, return that. otherwise, use default handler # If we found a title, return that. otherwise, use default handler
if title: if title:
return title return title