2020-11-03 17:28:26 +01:00
|
|
|
import re
|
2022-09-09 19:08:46 +02:00
|
|
|
from typing import cast, Optional
|
2020-11-03 17:28:26 +01:00
|
|
|
|
2022-11-28 23:29:22 +01:00
|
|
|
from googleapiclient.errors import Error as GoogleApiError # type: ignore
|
2020-11-03 17:28:26 +01:00
|
|
|
|
|
|
|
from edmond.plugin import Plugin
|
2022-09-09 19:08:46 +02:00
|
|
|
from edmond.plugins.playlist_of_the_day import PlaylistOfTheDayPlugin
|
|
|
|
from edmond.plugins.youtube import YoutubePlugin
|
2020-11-03 17:28:26 +01:00
|
|
|
|
|
|
|
|
|
|
|
class YoutubeParserPlugin(Plugin):
|
|
|
|
|
|
|
|
VIDEO_URL_RE = re.compile(
|
2022-03-06 17:26:48 +01:00
|
|
|
r"https?:\/\/(?:[^/]+/watch\?(?:.*&)?v=(?P<code1>[^&\s]+)"
|
2021-06-07 10:45:54 +02:00
|
|
|
r"|youtu\.be/(?P<code2>[^&\s]+))"
|
2020-11-03 17:28:26 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
def __init__(self, bot):
|
|
|
|
super().__init__(bot)
|
|
|
|
self.priority = -3
|
2022-09-09 19:08:46 +02:00
|
|
|
self._youtube_plugin: Optional[YoutubePlugin] = None
|
2022-11-29 12:56:56 +01:00
|
|
|
self._potd_plugin: Optional[PlaylistOfTheDayPlugin] = None
|
2020-11-03 17:28:26 +01:00
|
|
|
|
|
|
|
@property
|
2022-09-09 19:08:46 +02:00
|
|
|
def youtube_plugin(self) -> Optional[YoutubePlugin]:
|
2020-11-03 17:28:26 +01:00
|
|
|
if self._youtube_plugin is None:
|
2022-09-09 19:08:46 +02:00
|
|
|
self._youtube_plugin = cast(
|
|
|
|
YoutubePlugin,
|
|
|
|
self.bot.get_plugin("youtube"),
|
|
|
|
)
|
2020-11-03 17:28:26 +01:00
|
|
|
return self._youtube_plugin
|
|
|
|
|
2022-09-09 19:08:46 +02:00
|
|
|
@property
|
|
|
|
def playlist_of_the_day_plugin(self) -> Optional[PlaylistOfTheDayPlugin]:
|
2022-11-29 12:56:56 +01:00
|
|
|
if self._potd_plugin is None:
|
|
|
|
self._potd_plugin = cast(
|
2022-09-09 19:08:46 +02:00
|
|
|
PlaylistOfTheDayPlugin,
|
|
|
|
self.bot.get_plugin("playlistoftheday"),
|
|
|
|
)
|
2022-11-29 12:56:56 +01:00
|
|
|
return self._potd_plugin
|
2022-09-09 19:08:46 +02:00
|
|
|
|
2020-11-03 17:28:26 +01:00
|
|
|
def on_welcome(self, _):
|
|
|
|
if not (self.youtube_plugin and self.youtube_plugin.is_ready):
|
2021-06-06 19:02:19 +02:00
|
|
|
self.bot.log_w("Youtube plugin is not available.")
|
2020-11-03 17:28:26 +01:00
|
|
|
self.is_ready = False
|
|
|
|
|
|
|
|
def on_pubmsg(self, event):
|
2022-05-16 11:09:55 +02:00
|
|
|
if not self.respects_handling_conditions():
|
|
|
|
return False
|
2021-06-07 10:52:04 +02:00
|
|
|
words = event.arguments[0].split()
|
|
|
|
for word in words:
|
2022-06-08 17:12:33 +02:00
|
|
|
matched = self.VIDEO_URL_RE.match(word)
|
|
|
|
if matched:
|
2022-09-09 19:08:46 +02:00
|
|
|
title = self.get_video_title(matched)
|
|
|
|
if title:
|
|
|
|
self.bot.say(event.target, title)
|
|
|
|
self.add_to_playlist(word, title)
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
self.signal_failure(event.target)
|
2020-11-03 17:28:26 +01:00
|
|
|
return False
|
|
|
|
|
2022-09-09 19:08:46 +02:00
|
|
|
def get_video_title(self, matched) -> Optional[str]:
|
|
|
|
if self.youtube_plugin is None:
|
|
|
|
return None
|
2022-06-08 17:12:33 +02:00
|
|
|
groupdict = matched.groupdict()
|
2021-06-07 10:52:04 +02:00
|
|
|
code = groupdict.get("code1") or groupdict.get("code2")
|
|
|
|
if not code:
|
2022-09-09 19:08:46 +02:00
|
|
|
return None
|
2020-11-03 17:28:26 +01:00
|
|
|
try:
|
2021-06-07 10:52:04 +02:00
|
|
|
search_response = (
|
2022-08-09 23:47:28 +02:00
|
|
|
self.youtube_plugin.youtube.videos()
|
2021-06-07 10:52:04 +02:00
|
|
|
.list(id=code, part="snippet")
|
|
|
|
.execute()
|
|
|
|
)
|
2020-11-03 17:28:26 +01:00
|
|
|
except GoogleApiError:
|
2022-09-09 19:08:46 +02:00
|
|
|
return None
|
2020-11-03 17:28:26 +01:00
|
|
|
title = ""
|
|
|
|
for result in search_response.get("items", []):
|
|
|
|
if result["kind"] == "youtube#video":
|
|
|
|
title = result["snippet"]["title"]
|
|
|
|
break
|
|
|
|
else:
|
2022-09-09 19:08:46 +02:00
|
|
|
return None
|
|
|
|
return title
|
|
|
|
|
|
|
|
def add_to_playlist(self, url: str, title: str):
|
|
|
|
if self.playlist_of_the_day_plugin is None:
|
|
|
|
return
|
|
|
|
self.playlist_of_the_day_plugin.add_line(f"{url} {title}")
|