2016-03-30 18:31:23 +00:00
|
|
|
#--require-config google-api-key
|
|
|
|
|
2016-03-29 11:56:58 +00:00
|
|
|
import re
|
2019-02-09 10:57:05 +00:00
|
|
|
from src import EventManager, ModuleManager, utils
|
2016-03-29 11:56:58 +00:00
|
|
|
|
|
|
|
REGEX_YOUTUBE = re.compile(
|
2016-03-31 12:36:26 +00:00
|
|
|
"https?://(?:www.)?(?:youtu.be/|youtube.com/watch\?[\S]*v=)([\w\-]{11})",
|
2016-03-29 11:56:58 +00:00
|
|
|
re.I)
|
|
|
|
REGEX_ISO8601 = re.compile("PT(\d+H)?(\d+M)?(\d+S)?", re.I)
|
|
|
|
|
|
|
|
URL_YOUTUBESEARCH = "https://www.googleapis.com/youtube/v3/search"
|
|
|
|
URL_YOUTUBEVIDEO = "https://www.googleapis.com/youtube/v3/videos"
|
|
|
|
|
|
|
|
URL_YOUTUBESHORT = "https://youtu.be/%s"
|
|
|
|
|
2018-12-09 21:02:58 +00:00
|
|
|
ARROW_UP = "↑"
|
|
|
|
ARROW_DOWN = "↓"
|
2016-03-29 11:56:58 +00:00
|
|
|
|
2018-10-03 12:22:37 +00:00
|
|
|
@utils.export("channelset", {"setting": "auto-youtube",
|
2018-09-27 11:08:07 +00:00
|
|
|
"help": "Disable/Enable automatically getting info from youtube URLs",
|
2018-10-03 12:22:37 +00:00
|
|
|
"validate": utils.bool_or_none})
|
2019-01-11 11:30:29 +00:00
|
|
|
@utils.export("channelset", {"setting": "youtube-safesearch",
|
|
|
|
"help": "Turn safe search off/on",
|
|
|
|
"validate": utils.bool_or_none})
|
2018-09-27 11:08:07 +00:00
|
|
|
class Module(ModuleManager.BaseModule):
|
2019-02-09 13:14:45 +00:00
|
|
|
def on_load(self):
|
|
|
|
self.exports.add("search-youtube", self._search_youtube)
|
|
|
|
|
2016-03-29 11:56:58 +00:00
|
|
|
def get_video_page(self, video_id, part):
|
2018-12-11 22:26:38 +00:00
|
|
|
return utils.http.request(URL_YOUTUBEVIDEO, get_params={"part": part,
|
2016-03-29 11:56:58 +00:00
|
|
|
"id": video_id, "key": self.bot.config["google-api-key"]},
|
|
|
|
json=True)
|
|
|
|
def video_details(self, video_id):
|
|
|
|
snippet = self.get_video_page(video_id, "snippet")
|
2018-12-11 22:26:38 +00:00
|
|
|
if snippet.data["items"]:
|
|
|
|
snippet = snippet.data["items"][0]["snippet"]
|
2018-12-12 13:28:54 +00:00
|
|
|
statistics = self.get_video_page(video_id, "statistics").data[
|
2016-03-29 11:56:58 +00:00
|
|
|
"items"][0]["statistics"]
|
2018-12-12 13:28:54 +00:00
|
|
|
content = self.get_video_page(video_id, "contentDetails").data[
|
2016-03-29 11:56:58 +00:00
|
|
|
"items"][0]["contentDetails"]
|
|
|
|
video_uploader = snippet["channelTitle"]
|
|
|
|
video_title = snippet["title"]
|
|
|
|
video_views = statistics["viewCount"]
|
2016-04-04 17:40:39 +00:00
|
|
|
video_likes = statistics.get("likeCount")
|
|
|
|
video_dislikes = statistics.get("dislikeCount")
|
2016-03-29 11:56:58 +00:00
|
|
|
video_duration = content["duration"]
|
2016-04-04 17:40:39 +00:00
|
|
|
video_opinions = ""
|
|
|
|
if video_likes and video_dislikes:
|
|
|
|
video_opinions = " (%s%s%s%s)" % (video_likes, ARROW_UP,
|
|
|
|
ARROW_DOWN, video_dislikes)
|
2016-03-29 11:56:58 +00:00
|
|
|
|
|
|
|
match = re.match(REGEX_ISO8601, video_duration)
|
|
|
|
video_duration = ""
|
|
|
|
video_duration += "%s:" % match.group(1)[:-1].zfill(2
|
|
|
|
) if match.group(1) else ""
|
|
|
|
video_duration += "%s:" % match.group(2)[:-1].zfill(2
|
2016-04-03 12:20:05 +00:00
|
|
|
) if match.group(2) else "00:"
|
2016-03-29 11:56:58 +00:00
|
|
|
video_duration += "%s" % match.group(3)[:-1].zfill(2
|
2016-04-03 12:20:05 +00:00
|
|
|
) if match.group(3) else "00"
|
2016-04-04 17:40:39 +00:00
|
|
|
return "%s (%s) uploaded by %s, %s views%s %s" % (
|
2016-03-29 11:56:58 +00:00
|
|
|
video_title, video_duration, video_uploader, "{:,}".format(
|
2018-05-02 06:20:52 +00:00
|
|
|
int(video_views)), video_opinions, URL_YOUTUBESHORT % video_id)
|
2016-03-29 11:56:58 +00:00
|
|
|
|
2019-02-09 13:14:45 +00:00
|
|
|
def _search_youtube(self, query):
|
2018-09-22 23:55:36 +00:00
|
|
|
video_id = ""
|
|
|
|
|
2018-12-11 22:26:38 +00:00
|
|
|
search_page = utils.http.request(URL_YOUTUBESEARCH,
|
2019-02-09 13:14:45 +00:00
|
|
|
get_params={"q": query, "part": "snippet",
|
2018-09-22 23:55:36 +00:00
|
|
|
"maxResults": "1", "type": "video",
|
|
|
|
"key": self.bot.config["google-api-key"]},
|
|
|
|
json=True)
|
|
|
|
|
|
|
|
if search_page:
|
2018-12-11 22:26:38 +00:00
|
|
|
if search_page.data["pageInfo"]["totalResults"] > 0:
|
|
|
|
video_id = search_page.data["items"][0]["id"]["videoId"]
|
2018-09-22 23:55:36 +00:00
|
|
|
return "https://youtu.be/%s" % video_id
|
|
|
|
|
2018-10-10 09:42:41 +00:00
|
|
|
@utils.hook("received.command.yt", alias_of="youtube")
|
|
|
|
@utils.hook("received.command.youtube")
|
2016-03-29 11:56:58 +00:00
|
|
|
def yt(self, event):
|
2018-09-26 17:27:17 +00:00
|
|
|
"""
|
2018-09-30 16:29:09 +00:00
|
|
|
:help: Find a video on youtube
|
|
|
|
:usage: [query/URL]
|
2018-09-26 17:27:17 +00:00
|
|
|
"""
|
2016-03-29 11:56:58 +00:00
|
|
|
video_id = None
|
|
|
|
search = None
|
|
|
|
if event["args"]:
|
|
|
|
search = event["args"]
|
|
|
|
else:
|
2018-09-30 10:43:34 +00:00
|
|
|
last_youtube = event["target"].buffer.find(REGEX_YOUTUBE)
|
2016-03-29 11:56:58 +00:00
|
|
|
if last_youtube:
|
2018-10-29 23:13:32 +00:00
|
|
|
search = last_youtube.message
|
|
|
|
|
2019-01-11 12:03:23 +00:00
|
|
|
if search:
|
|
|
|
url_match = re.search(REGEX_YOUTUBE, search)
|
|
|
|
if url_match:
|
|
|
|
video_id = url_match.group(1)
|
2018-10-29 23:13:32 +00:00
|
|
|
|
2016-03-29 11:56:58 +00:00
|
|
|
if search or video_id:
|
2019-01-11 11:30:29 +00:00
|
|
|
safe_setting = event["target"].get_setting("youtube-safesearch",
|
|
|
|
True)
|
|
|
|
safe = "moderate" if safe_setting else "none"
|
|
|
|
|
2016-03-29 11:56:58 +00:00
|
|
|
if not video_id:
|
2018-12-11 22:26:38 +00:00
|
|
|
search_page = utils.http.request(URL_YOUTUBESEARCH,
|
2016-03-29 11:56:58 +00:00
|
|
|
get_params={"q": search, "part": "snippet",
|
|
|
|
"maxResults": "1", "type": "video",
|
2019-01-11 11:30:29 +00:00
|
|
|
"key": self.bot.config["google-api-key"],
|
|
|
|
"safeSearch": safe}, json=True)
|
2016-03-29 11:56:58 +00:00
|
|
|
if search_page:
|
2018-12-11 22:26:38 +00:00
|
|
|
if search_page.data["pageInfo"]["totalResults"] > 0:
|
|
|
|
video_id = search_page.data["items"][0]["id"]["videoId"]
|
2016-03-29 11:56:58 +00:00
|
|
|
else:
|
2019-02-14 01:00:16 +00:00
|
|
|
raise utils.EventError("No videos found")
|
2016-03-29 11:56:58 +00:00
|
|
|
else:
|
2018-10-20 19:51:29 +00:00
|
|
|
raise utils.EventsResultsError()
|
2016-03-29 11:56:58 +00:00
|
|
|
if video_id:
|
2019-01-21 19:30:39 +00:00
|
|
|
details = self.video_details(video_id)
|
|
|
|
if details:
|
|
|
|
event["stdout"].write(self.video_details(video_id))
|
|
|
|
else:
|
2019-01-21 19:32:37 +00:00
|
|
|
raise utils.EventsResultsError()
|
2016-03-29 11:56:58 +00:00
|
|
|
else:
|
|
|
|
event["stderr"].write("No search phrase provided")
|
|
|
|
else:
|
|
|
|
event["stderr"].write("No search phrase provided")
|
|
|
|
|
2019-05-18 17:35:47 +00:00
|
|
|
@utils.hook("command.regex",
|
2019-02-09 10:56:06 +00:00
|
|
|
priority=EventManager.PRIORITY_LOW)
|
2016-03-29 11:56:58 +00:00
|
|
|
def channel_message(self, event):
|
2019-05-18 17:35:47 +00:00
|
|
|
"""
|
|
|
|
:command: youtube
|
|
|
|
:-pattern: https?://(?:www.)?
|
|
|
|
(?:youtu.be/|youtube.com/watch\?[\S]*v=)([\w\-]{11})
|
|
|
|
"""
|
|
|
|
if event["target"].get_setting("auto-youtube", False):
|
|
|
|
youtube_id = event["match"].group(1)
|
2016-03-29 11:56:58 +00:00
|
|
|
video_details = self.video_details(youtube_id)
|
|
|
|
if video_details:
|
2019-05-18 17:35:47 +00:00
|
|
|
event["stdout"].write(video_details)
|
2019-02-09 10:56:06 +00:00
|
|
|
event.eat()
|