diff options
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | URLget.py | 8 | ||||
-rw-r--r-- | _.txt | 19 | ||||
-rwxr-xr-x | applemusic.py | 8 | ||||
-rwxr-xr-x | bandcamp.py | 11 | ||||
-rw-r--r-- | commands.py | 21 | ||||
-rw-r--r-- | config.py | 4 | ||||
-rw-r--r-- | requirements.txt | 4 | ||||
-rwxr-xr-x | soundcloud.py | 4 | ||||
-rwxr-xr-x | spotify.py | 17 | ||||
-rw-r--r-- | stuff.py | 39 | ||||
-rw-r--r-- | util.py | 8 | ||||
-rwxr-xr-x | youtube_abstract.py | 241 | ||||
-rwxr-xr-x | youtube_oembed.py | 38 | ||||
-rwxr-xr-x | youtube_oembed_old.py | 17 | ||||
-rwxr-xr-x | youtube_scrape.py | 37 |
16 files changed, 338 insertions, 140 deletions
diff --git a/README b/README index fe0c472..fa6f089 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -code is formatted with "black" +code is formatted with "black --line-length=120" #remember to install the libraries, and you probably should use venvs anyway pip --require-venv install -r requirements.txt diff --git a/URLget.py b/URLget.py index 701b10d..0f3f7c7 100644 --- a/URLget.py +++ b/URLget.py @@ -1,4 +1,6 @@ import sys + + class URLgetException(Exception): pass @@ -7,7 +9,8 @@ try: from curl_cffi import requests # from curl_cffi.requests.exceptions import HTTPError - if sys.stderr.isatty(): print("using curl_cffi",file=sys.stderr) + if sys.stderr.isatty(): + print("using curl_cffi", file=sys.stderr) def urlget(url): # probably want to impersonate "chrome", "safari" or "safari_ios" @@ -25,7 +28,8 @@ except ModuleNotFoundError: from urllib.request import Request, urlopen # from urllib.error import HTTPError - if sys.stderr.isatty(): print("using urllib.request",file=sys.stderr) + if sys.stderr.isatty(): + print("using urllib.request", file=sys.stderr) def urlget(url): # update as needed I guess diff --git a/_.txt b/_.txt new file mode 100644 index 0000000..6737b50 --- /dev/null +++ b/_.txt @@ -0,0 +1,19 @@ +import urllib.request, json + +req = urllib.request.Request("https://www.youtube.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8") +req.add_header("Content-Type", "application/json") +j = json.loads( + urllib.request.urlopen( + req, + b'{"context":{"client":{"clientName":"TVHTML5_SIMPLY_EMBEDDED_PLAYER","clientVersion":"2.0"},"thirdParty":{"embedUrl":"https://www.youtube.com"}},"videoId": "VpGjqueO0b4"}', + ) + .read() + .decode() +) +j = j["videoDetails"] +print( + f'{j["title"]} ({j["lengthSeconds"]} sec), uploaded by {j["author"]}, {j["viewCount"]} views', + j["isCrawlable"], + j["isUnpluggedCorpus"], + j["isLiveContent"], +) diff --git a/applemusic.py b/applemusic.py index 9e10ab9..8334e5b 100755 --- a/applemusic.py +++ b/applemusic.py @@ -78,7 +78,9 @@ class AppleMusic: url = url.rstrip("\x01") title = "" artist = "" - irc_string = "[\x0304AppleMusic\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + irc_string = ( + "[\x0304AppleMusic\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + ) ansi_string = "[\x1b[31mAppleMusic\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" if self.is_album(url): title, artist = self.applemusic_oembed(url) @@ -93,9 +95,7 @@ class AppleMusic: if title == "": print(ansi_string) return irc_string, True - irc_string = ( - f"[\x0303AppleMusic\x03] \x02{title}\x02 uploaded by \x1d{artist}\x1d" - ) + irc_string = f"[\x0303AppleMusic\x03] \x02{title}\x02 uploaded by \x1d{artist}\x1d" ansi_string = f"[\x1b[32mAppleMusic\x1b[0m] \x1b[1m{title}\x1b[0m uploaded by \x1b[03m{artist}\x1b[0m" # """ # irc_string="dummy";ansi_string="dummy" diff --git a/bandcamp.py b/bandcamp.py index 2d76b22..727181d 100755 --- a/bandcamp.py +++ b/bandcamp.py @@ -13,12 +13,7 @@ class Bandcamp: self.util.mesg(msg, t) def match_urls(self, str): - r = [ - i - for i in str.split() - if "https://" in i - and ("bandcamp.com/album/" in i or "bandcamp.com/track/" in i) - ] + r = [i for i in str.split() if "https://" in i and ("bandcamp.com/album/" in i or "bandcamp.com/track/" in i)] r = list(dict.fromkeys(r)) n = 0 for i in r: @@ -53,7 +48,9 @@ class Bandcamp: p = self.parseprop() data = urlopen(url).read().decode() p.feed(data) - irc_string = "[\x0304BandCamp\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + irc_string = ( + "[\x0304BandCamp\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + ) ansi_string = "[\x1b[31mBandCamp\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" data = json.loads(Bandcamp.ldjson) try: diff --git a/commands.py b/commands.py index 0740916..0493054 100644 --- a/commands.py +++ b/commands.py @@ -150,11 +150,7 @@ class Command: if not ctcp.endswith("\x01"): ctcp = ctcp + "\x01" if ctcp_upper.startswith("PING"): - ctcp = ( - "\x01PING" - + ("" if 1 == len(ctcp.split(" ")) else " ") - + " ".join(ctcp.split(" ")[1:]) - ) + ctcp = "\x01PING" + ("" if 1 == len(ctcp.split(" ")) else " ") + " ".join(ctcp.split(" ")[1:]) print(ctcp) self.notice(ctcp) if ctcp_upper.startswith("SOURCE"): @@ -190,11 +186,7 @@ class Command: args = args + ["", 3] elif len(args) < 3: args = args + ["3"] - for i in ( - popen(f"git log --pretty=oneline --abbrev-commit {args[1]}") - .read() - .split("\n", int(args[2])) - ): + for i in popen(f"git log --pretty=oneline --abbrev-commit {args[1]}").read().split("\n", int(args[2])): mesg(i) else: mesg(popen("git pull").read()) @@ -253,17 +245,12 @@ class Command: amount = 1 if not str(faces).isnumeric() or faces > 100: faces = 6 - mesg( - f"rolling {amount}d{faces}: " - + str([random.choice([i for i in range(faces)]) for n in range(amount)]) - ) + mesg(f"rolling {amount}d{faces}: " + str([random.choice([i for i in range(faces)]) for n in range(amount)])) @cmd def version(self, prefix, cmd, pm, line, admin, mesg): """version""" - mesg( - f"{self.config.self.nick} version {self.getversion()} ({self.config.self.source})" - ) + mesg(f"{self.config.self.nick} version {self.getversion()} ({self.config.self.source})") @adm def dbg2(self, prefix, cmd, pm, line, admin, mesg): diff --git a/config.py b/config.py index 51d4364..ee4cc81 100644 --- a/config.py +++ b/config.py @@ -24,9 +24,7 @@ class config(config): port = 6667 ssl = False nickserv_auth = False - nickserv_mask = ( - "NickServ!NickServ@localhost" # the mask you receive from server - ) + nickserv_mask = "NickServ!NickServ@localhost" # the mask you receive from server nickserv_squery = False # squery seems to only be a thing on ngircd nickserv_path = "NickServ@localhost" # the mask you actually send commands to # get password from secret file diff --git a/requirements.txt b/requirements.txt index cb7e46d..76a56fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -ircstates -#OPTIONAL: only for TLS fingerprint spoofing, used by youtube.alt.py +ircstates +# OPTIONAL: only for TLS fingerprint spoofing, used by youtube.alt.py curl_cffi diff --git a/soundcloud.py b/soundcloud.py index 7fa6a53..a56dfc8 100755 --- a/soundcloud.py +++ b/soundcloud.py @@ -43,9 +43,7 @@ class SoundCloud: ansi_string = "[\x1b[31mSoundCloud\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" print(ansi_string) return irc_string, True - irc_string = ( - f"[\x0303SoundCloud\x03] \x02{title}\x02 uploaded by \x1d{artist}\x1d" - ) + irc_string = f"[\x0303SoundCloud\x03] \x02{title}\x02 uploaded by \x1d{artist}\x1d" ansi_string = f"[\x1b[32mSoundCloud\x1b[0m] \x1b[1m{title}\x1b[0m uploaded by \x1b[03m{artist}\x1b[0m" # """ # irc_string="dummy";ansi_string="dummy" diff --git a/spotify.py b/spotify.py index e9b0790..609b2e2 100755 --- a/spotify.py +++ b/spotify.py @@ -48,24 +48,22 @@ class Spotify: p = self.parseprop() data = urlopen(url).read().decode() p.feed(data) - irc_string = "[\x0304Spotify\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + irc_string = ( + "[\x0304Spotify\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + ) ansi_string = "[\x1b[31mSpotify\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" data = json.loads(Spotify.ldjson) try: type = data["@type"] except KeyError: - print(ansi_string) + if __import__("sys").stdout.isatty(): + print(ansi_string) return irc_string, True id = data["@id"] name = data["name"] date = data["datePublished"] artists = data["description"] - artists = ( - artists.removeprefix(f"Listen to {name} on Spotify") - .removeprefix(".") - .strip() - .removeprefix("· ") - ) + artists = artists.removeprefix(f"Listen to {name} on Spotify").removeprefix(".").strip().removeprefix("· ") if artists.startswith("Song · "): artists = artists.removeprefix("Song · ") elif artists.startswith("Album · "): @@ -77,7 +75,8 @@ class Spotify: ansi_string = f"[\x1b[32mSpotify\x1b[0m] \x1b[1m{name}\x1b[0m by \x1b[03m{artists}\x1b[0m published on {date}" # print(("Song: " if type=="MusicRecording" else "Album: " if type=="MusicAlbum" else f"Unknown type ({type}): ")+'"'+name+'"'+" by "+'"'+artists+'"'+" released on "+date) # irc_string="dummy" - print(ansi_string) + if __import__("sys").stdout.isatty(): + print(ansi_string) return irc_string, False diff --git a/stuff.py b/stuff.py index 299555b..1a873c1 100644 --- a/stuff.py +++ b/stuff.py @@ -39,11 +39,7 @@ def stuff(bot, sock): if nickserv_auth: nick_override = True if config.server.nickserv_squery: - util.send( - irctokens.build( - "SQUERY", ["NickServ", f"IDENTIFY {nick} {passwd}"] - ).format() - ) + util.send(irctokens.build("SQUERY", ["NickServ", f"IDENTIFY {nick} {passwd}"]).format()) util.send( irctokens.build( "SQUERY", @@ -94,11 +90,7 @@ def stuff(bot, sock): send = util.send send(irctokens.build("NICK", [config.self.nick]).format()) - send( - irctokens.build( - "USER", [config.self.username, "0", "*", config.self.realname] - ).format() - ) + send(irctokens.build("USER", [config.self.username, "0", "*", config.self.realname]).format()) while True: self_nick = server.nickname recv_data = sock.recv(1024) @@ -126,9 +118,7 @@ def stuff(bot, sock): auth() if line.command == "433": # 433 is ERR_NICKNAMEINUSE util.nick(config.self.nick + "_") - if ( - line.command == "376" or line.command == "422" - ): # 376 is RPL_ENDOFMOTD and 422 is ERR_NOMOTD + if line.command == "376" or line.command == "422": # 376 is RPL_ENDOFMOTD and 422 is ERR_NOMOTD if config.server.nickserv_auth == True: auth() send(irctokens.build("CAP", ["LS", "302"]).format()) @@ -215,10 +205,7 @@ def stuff(bot, sock): command.prefix = prefix cmd = cmd.strip() try: - is_adm = ( - line.tags["account"] in admin_accounts - or line.source in admin_users - ) + is_adm = line.tags["account"] in admin_accounts or line.source in admin_users except ( KeyError, TypeError, @@ -259,28 +246,18 @@ def stuff(bot, sock): command.util = util command.util.target = target mesg("reloaded") - elif ( - cmd.startswith("eval ") - and "eval" not in config.cmd.disabled - ): + elif cmd.startswith("eval ") and "eval" not in config.cmd.disabled: if is_adm: try: - result = eval( - cmd[len("eval ") :].strip() or "None" - ) + result = eval(cmd[len("eval ") :].strip() or "None") except Exception as e: mesg("Error: " + str(e)) else: mesg("Error: you're not authorized to eval") - elif ( - cmd.startswith("exec ") - and "exec" not in config.cmd.disabled - ): + elif cmd.startswith("exec ") and "exec" not in config.cmd.disabled: if is_adm: try: - result = exec( - cmd[len("exec ") :].strip() or "None" - ) + result = exec(cmd[len("exec ") :].strip() or "None") except Exception as e: mesg("Error: " + str(e)) else: diff --git a/util.py b/util.py index 8538ef3..6525160 100644 --- a/util.py +++ b/util.py @@ -78,9 +78,7 @@ class Util: def action(self, msg: str, t=None): t, msg = self._m(msg, t) - self.send( - irctokens.build("PRIVMSG", [t, "\x01ACTION " + str(msg) + "\x01"]).format() - ) + self.send(irctokens.build("PRIVMSG", [t, "\x01ACTION " + str(msg) + "\x01"]).format()) def notice(self, msg: str, t=None): t, msg = self._m(msg, t) @@ -89,7 +87,5 @@ class Util: def maskmatch(self, string: str, hostmask: str): """DOES NOT HANDLE CASEMAPPING (yet), just dumb case-sensitive match, only ? and * are special""" print("string is", string, "and hostmask is", hostmask) - pat = "[[]".join( - [x.replace("]", "[]]") for x in hostmask.split("[")] - ) # escape all [ and ] into [[] and []] + pat = "[[]".join([x.replace("]", "[]]") for x in hostmask.split("[")]) # escape all [ and ] into [[] and []] return fnmatchcase(string, pat) diff --git a/youtube_abstract.py b/youtube_abstract.py new file mode 100755 index 0000000..fb93ad7 --- /dev/null +++ b/youtube_abstract.py @@ -0,0 +1,241 @@ +#!/usr/bin/env python3 +from urllib.parse import urlencode, urlparse, parse_qs +from json import loads as json_loads +from URLget import urlget, URLgetException + + +class YouTube: + def __init__(self): + # whether urls with a playlist included, should title the video, or the playlist? + try: + YouTube.prefer_playlist = YouTube.prefer_playlist + except AttributeError: # we probably want video title, default to that + YouTube.prefer_playlist = False + self.irc_pal = { + "rst": "\x0f", ######### reset + "ylw": "\x0307", ####### yellow + "b_ylw": "\x0307\x02", # bold yellow + "wht": "\x0315", ####### white + "red": "\x0304", ####### red + "grn": "\x0303", ####### green + "itl": "\x1d", ######### italic + "bld": "\x02", ######### bold + } + self.ansi_pal = { + "rst": "\x1b[0m", ###### reset + "ylw": "\x1b[33;2m", ### yellow + "b_ylw": "\x1b[33;1m", # bold yellow + "wht": "\x1b[37;2m", ### white + "red": "\x1b[31m", ##### red + "grn": "\x1b[32m", ##### green + "itl": "\x1b[03m", ##### italic + "bld": "\x1b[1m", ###### bold + } + + def mesg(self, msg, t=None): # just an alias to shorten full name + self.util.mesg(msg, t) + + def match_urls(self, str, r=[]): + if str.startswith("http://"): + str = "https://" + str[7:] + if str.startswith( + "https://" + ): # first string has to be trimmed outside this func + if ( + str.startswith("https://youtu.be/") + or str.startswith("https://www.youtube.com/watch?") + or str.startswith("https://music.youtube.com/watch?") + or str.startswith("https://m.youtube.com/watch?") + or str.startswith("https://www.youtube.com/playlist?") + or str.startswith("https://music.youtube.com/playlist?") + or str.startswith("https://m.youtube.com/playlist?") + or str.startswith("https://www.youtube.com/shorts/") + or str.startswith("https://youtube.com/shorts/") + or str.startswith("https://m.youtube.com/shorts/") + or str.startswith("https://www.youtube.com/embed/") + or str.startswith("https://www.youtube-nocookie.com/embed/") + or str.startswith("https://www.youtube.com/embed/videoseries?") + ): + r += [str[: str.find(" ")]] + i = str.find(" ") + 1 + return match_urls(self, str[i:].strip(), r=r) if i != 0 else r + + """ + def match_urls(self, str): + str = str.replace("http://", "https://") + r = [ + i + for i in str.split() + # shorturl + if "https://youtu.be/" in i + # desktop + or "https://www.youtube.com/watch?" in i or "https://www.youtube.com/playlist?" in i + # mobile + or "https://m.youtube.com/watch?" in i or "https://m.youtube.com/playlist?" in i + # music + or "https://music.youtube.com/watch?" in i or "https://music.youtube.com/playlist?" in i + # shorts + or "https://www.youtube.com/shorts/" in i + or "https://m.youtube.com/shorts/" in i + or "https://youtube.com/shorts/" in i + # embed + or "https://www.youtube.com/embed/" in i or "https://www.youtube-nocookie.com/embed/" in i + # or "https://www.youtube.com/embed/videoseries?" in i # embed playlist, lol + # just in case (shouldn't happen) + or "https://youtube.com/watch?" in i or "https://youtube.com/playlist?" in i + ] + r = list(dict.fromkeys(r)) + n = 0 + for i in r: + if not i.startswith("http"): + r.pop(n) + n += 1 + + return r + """ + + # makes for a little better syntax than a bunch of str.startswith calls + def matchstart(self, str, *arr): + for i in arr: + if str.startswith(i): + return True + return False + + def is_clip(self, str): + return self.matchstart( + str, "https://youtube.com/clip/", "https://www.youtube.com/clip/" + ) + + # boil down to video id + playlist id + def normalize_url(self, url): + raw_url = url + # youtu.be + if self.matchstart(url, "https://youtu.be/"): + videoId = url.split("/")[3].split("?")[0] + elif self.matchstart( + url, "https://youtube.com/shorts/", "https://www.youtube.com/shorts/" + ): + videoId = url.split("?")[0].split("/")[-1] + # embed + elif self.matchstart( + url, + "https://www.youtube.com/embed/", + "https://www.youtube-nocookie.com/embed/", + ): + # try: + listId = parse_qs(urlparse(url).query)["list"][0] + # except + if not url.split("/")[4].startswith("videoseries"): + videoId = url.split("/")[4] + # print("embed", videoId, listId) + elif "v=" in url: # handles yt music, normal url, etc + for i in url.split("?")[1].split("&"): + if i[0:2] == "v=": + videoId = i[2:] + elif i[0:5] == "list=": + listId = i[5:] + if "videoId" in locals(): + url = "https://www.youtube.com/watch?" + if "videoId" in locals(): + if videoId != "": + url += f"v={videoId}" + if "listId" in locals(): + if listId != "": + if not url.endswith("?"): + url += "&" + url += f"list={listId}" + print("clean url", url) + return url + + # very close to normalize_url, maybe could reorganize better? + def normalize_playlist(self, url): + url = urlparse(url) + qs = parse_qs(url.query) + try: + video_id = qs["v"][0] + except KeyError: + video_id = None + try: + playlist_id = qs["list"][0] + # ignore the programmatic "mix" / "radio" lists, actual playlists start with "PL" + if playlist_id.startswith("RD"): + playlist_id = None + except KeyError: + playlist_id = None + if (self.prefer_playlist and playlist_id) or (playlist_id and not video_id): + url = url.scheme + "://" + url.netloc + "/playlist?list=" + playlist_id + elif video_id: + url = url.scheme + "://" + url.netloc + url.path + "?v=" + video_id + else: + self.setstring( + "string", "{{i}_prefix_err} unable to detect video ID!{pal['rst']}" + ) + return {"irc": irc_string, "ansi": ansi_string}, True + return url + + # set both irc_name and ansi_name, using the appropriate palette + def setstring(self, name, val, mylocals=locals()): + prefixes = ["irc", "ansi"] + for i in prefixes: + value = val.replace("{i}", i) + mylocals.update(locals()) # merge the local variables + exec( + f"global {i}_{name}; pal=self.{i}_pal; {i}_{name}=f{repr(value)}", + globals(), + mylocals, + ) + + def yt(self, url): + self.setstring( + "prefix", + "[{pal['grn']}YouTube{pal['rst']}]", + ) + self.setstring( + "prefix_err", + "[{pal['red']}YouTube{pal['rst']}] {pal['ylw']}ERROR:{pal['b_ylw']}", + ) + self.setstring( + "string", + "{{i}_prefix_err} got no data from server! {pal['wht']}(check your URL for typos!){pal['rst']}", + ) + url = url.rstrip("\x01") # I forget exactly why, might be due to /me ? + url = self.normalize_url(url) + url = self.normalize_playlist(url) + url = f"https://www.youtube.com/oembed?{urlencode([('url',url),('format','json')])}" + try: + # print(url, " and ", playlist_id) + status, data = urlget(url) + if status != 200: + self.setstring( + "string", "{{i}_prefix_err} {status}{pal['rst']}", locals() + ) + return {"irc": irc_string, "ansi": ansi_string}, True + data = json_loads(data) + title, channelName = data["title"], data["author_name"] + except URLgetException as e: + self.setstring("string", "{{i}_prefix_err} {e}{pal['rst']}", locals()) + if __import__("sys").stdout.isatty(): + print(ansi_string) + return {"irc": irc_string, "ansi": ansi_string}, True + self.setstring( + "string", + "{{i}_prefix} {pal['bld']}{title}{pal['rst']} uploaded by {pal['itl']}{channelName}{pal['rst']}", + mylocals=locals(), + ) + if __import__("sys").stdout.isatty(): + print("ansi", ansi_string) + print("irc", irc_string) + return {"irc": irc_string, "ansi": ansi_string}, False + + +if __name__ == "__main__": + import sys + + # if url is a video that's part of a playlist, return playlist (True) or video (False, default)? + # YouTube.prefer_playlist=False + + # YouTube.yt(YouTube, sys.argv[1]) + # YouTube().yt(sys.argv[1]) + YT = YouTube() + print(YT.match_urls(sys.argv[1])) + YT.yt(sys.argv[1]) diff --git a/youtube_oembed.py b/youtube_oembed.py index 4a0ca20..4ed427c 100755 --- a/youtube_oembed.py +++ b/youtube_oembed.py @@ -3,6 +3,7 @@ from urllib.parse import urlencode, urlparse, parse_qs from json import loads as json_loads from URLget import urlget, URLgetException + class YouTube: def __init__(self): try: @@ -14,6 +15,7 @@ class YouTube: self.util.mesg(msg, t) def match_urls(self, str): + str = str.replace("http://", "https://") r = [ i for i in str.split() @@ -57,18 +59,14 @@ class YouTube: str = self else: str = str[0] - return str.startswith("https://youtube.com/shorts/") or str.startswith( - "https://www.youtube.com/shorts/" - ) + return str.startswith("https://youtube.com/shorts/") or str.startswith("https://www.youtube.com/shorts/") def is_clip(self, *str): if type(self) == type("a"): str = self else: str = str[0] - return str.startswith("https://youtube.com/clip/") or str.startswith( - "https://www.youtube.com/clip/" - ) + return str.startswith("https://youtube.com/clip/") or str.startswith("https://www.youtube.com/clip/") def is_shorturl(self, *str): if type(self) == type("a"): @@ -78,8 +76,10 @@ class YouTube: return str.startswith("https://youtu.be/") def yt(self, url): - irc_string = "[\x0304Youtube\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" - ansi_string = "[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" + irc_string = ( + "[\x0304YouTube\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + ) + ansi_string = "[\x1b[31mYouTube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" # self.util.mesg("dbg hello") url = url.rstrip("\x01") if self.is_embed(url): @@ -116,23 +116,23 @@ class YouTube: url = f"https://www.youtube.com/oembed?{urlencode([('url',url),('format','json')])}" try: # print(url, " and ", playlist_id) - status,data = urlget(url) + status, data = urlget(url) if status != 200: - irc_string = f"[\x0304Youtube\x03] \x0307ERROR:\x0308 {status} \x0315\x03" - ansi_string = f"[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m {status} \x1b[37;2m\x1b[0m" + irc_string = f"[\x0304YouTube\x03] \x0307ERROR:\x0308 {status} \x0315\x03" + ansi_string = f"[\x1b[31mYouTube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m {status} \x1b[37;2m\x1b[0m" data = json_loads(data) title = data["title"] channelName = data["author_name"] except URLgetException as e: - irc_string = f"[\x0304Youtube\x03] \x0307ERROR:\x0308 {e} \x0315\x03" - ansi_string = f"[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m {e} \x1b[37;2m\x1b[0m" - print(ansi_string) + irc_string = f"[\x0304YouTube\x03] \x0307ERROR:\x0308 {e} \x0315\x03" + ansi_string = f"[\x1b[31mYouTube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m {e} \x1b[37;2m\x1b[0m" + if __import__("sys").stdout.isatty(): + print(ansi_string) return irc_string, True - irc_string = ( - f"[\x0303Youtube\x03] \x02{title}\x02 uploaded by \x1d{channelName}\x1d" - ) - ansi_string = f"[\x1b[32mYoutube\x1b[0m] \x1b[1m{title}\x1b[0m uploaded by \x1b[03m{channelName}\x1b[0m" - if __import__("sys").stdout.isatty(): print(ansi_string) + irc_string = f"[\x0303YouTube\x03] \x02{title}\x02 uploaded by \x1d{channelName}\x1d" + ansi_string = f"[\x1b[32mYouTube\x1b[0m] \x1b[1m{title}\x1b[0m uploaded by \x1b[03m{channelName}\x1b[0m" + if __import__("sys").stdout.isatty(): + print(ansi_string) return irc_string, False diff --git a/youtube_oembed_old.py b/youtube_oembed_old.py index 0d51e16..9719757 100755 --- a/youtube_oembed_old.py +++ b/youtube_oembed_old.py @@ -16,6 +16,7 @@ class YouTube: self.util.mesg(msg, t) def match_urls(self, str): + str = str.replace("http://", "https://") r = [ i for i in str.split() @@ -59,21 +60,19 @@ class YouTube: str = self else: str = str[0] - return str.startswith("https://youtube.com/shorts/") or str.startswith( - "https://www.youtube.com/shorts/" - ) + return str.startswith("https://youtube.com/shorts/") or str.startswith("https://www.youtube.com/shorts/") def is_clip(self, *str): if type(self) == type("a"): str = self else: str = str[0] - return str.startswith("https://youtube.com/clip/") or str.startswith( - "https://www.youtube.com/clip/" - ) + return str.startswith("https://youtube.com/clip/") or str.startswith("https://www.youtube.com/clip/") def yt(self, url): - irc_string = "[\x0304Youtube\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + irc_string = ( + "[\x0304Youtube\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + ) ansi_string = "[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" # self.util.mesg("dbg hello") url = url.rstrip("\x01") @@ -117,9 +116,7 @@ class YouTube: ansi_string = f"[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m {e} \x1b[37;2m\x1b[0m" print(ansi_string) return irc_string, True - irc_string = ( - f"[\x0303Youtube\x03] \x02{title}\x02 uploaded by \x1d{channelName}\x1d" - ) + irc_string = f"[\x0303Youtube\x03] \x02{title}\x02 uploaded by \x1d{channelName}\x1d" ansi_string = f"[\x1b[32mYoutube\x1b[0m] \x1b[1m{title}\x1b[0m uploaded by \x1b[03m{channelName}\x1b[0m" print(ansi_string) return irc_string, False diff --git a/youtube_scrape.py b/youtube_scrape.py index 82671a2..951af3b 100755 --- a/youtube_scrape.py +++ b/youtube_scrape.py @@ -21,6 +21,7 @@ class YouTube: self.util.mesg(msg, t) def match_urls(self, str): + str = str.replace("http://", "https://") r = [ i for i in str.split() @@ -54,14 +55,10 @@ class YouTube: return str.startswith("https://music.youtube.com/watch?v=") def is_ytshorts(self, str): - return str.startswith("https://youtube.com/shorts/") or str.startswith( - "https://www.youtube.com/shorts/" - ) + return str.startswith("https://youtube.com/shorts/") or str.startswith("https://www.youtube.com/shorts/") def is_clip(self, str): - return str.startswith("https://youtube.com/clip/") or str.startswith( - "https://www.youtube.com/clip/" - ) + return str.startswith("https://youtube.com/clip/") or str.startswith("https://www.youtube.com/clip/") class parseprop(HTMLParser): def __init__(self): @@ -84,10 +81,7 @@ class YouTube: if tag == "title": self.title = True if (tag != "meta" and tag != "link") or ( - ( - [i for i in attrs if "itemprop" in i] == [] - and ("name", "title") not in attrs - ) + ([i for i in attrs if "itemprop" in i] == [] and ("name", "title") not in attrs) or (tag == "meta" and ("itemprop", "name") in attrs) ): return @@ -129,7 +123,9 @@ class YouTube: return f"{m}m {s}s" def yt(self, url): - irc_string = "[\x0304Youtube\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + irc_string = ( + "[\x0304Youtube\x03] \x0307ERROR:\x0308 got no data from server! \x0315(check your URL for typos!)\x03" + ) ansi_string = "[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m got no data from server! \x1b[37;2m(check your URL for typos!)\x1b[0m" # self.util.mesg("dbg hello") url = url.rstrip("\x01") @@ -139,11 +135,7 @@ class YouTube: else ( "shorts" if self.is_ytshorts(url) - else ( - "music" - if self.is_ytmusic(url) - else "embed" if self.is_embed(url) else "video" - ) + else ("music" if self.is_ytmusic(url) else "embed" if self.is_embed(url) else "video") ) ) video_type = self.video_type @@ -161,16 +153,11 @@ class YouTube: p = self.parseprop() data = b"" data = data.decode() # bytes to utf-8 - if ( - data.find('meta itemprop="duration"') == -1 - or data.find('meta itemprop="name"') == -1 - ): + if data.find('meta itemprop="duration"') == -1 or data.find('meta itemprop="name"') == -1: try: status, data = urlget(url) if status != 200: - irc_string = ( - f"[\x0304Youtube\x03] \x0307ERROR:\x0308 {status} \x0315\x03" - ) + irc_string = f"[\x0304Youtube\x03] \x0307ERROR:\x0308 {status} \x0315\x03" ansi_string = f"[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m {status} \x1b[37;2m\x1b[0m" except URLgetException as e: irc_string = f"[\x0304Youtube\x03] \x0307ERROR:\x0308 {e} \x0315\x03" @@ -182,9 +169,7 @@ class YouTube: print(ansi_string) return irc_string, True elif p.h == {"html_title": "YouTube"}: - irc_string = ( - "[\x0304Youtube\x03] \x0307ERROR:\x0308 flagged as bot \x0315\x03" - ) + irc_string = "[\x0304Youtube\x03] \x0307ERROR:\x0308 flagged as bot \x0315\x03" ansi_string = "[\x1b[31mYoutube\x1b[0m] \x1b[33;2mERROR:\x1b[33;1m flagged as bot \x1b[37;2m\x1b[0m" print(ansi_string) return irc_string, True |