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
|