media-sucker/src/gnudb.py

87 lines
2.7 KiB
Python

#! /usr/bin/python3
import urllib.parse
import urllib.request
class Server:
def __init__(self, email):
spaced_email = email.replace("@", " ")
self.hello = "%s media-sucker 1.0" % spaced_email
self.baseURL = "https://gnudb.gnudb.org/~cddb/cddb.cgi?"
def open(self, *cmd):
query = {
"cmd": " ".join(("cddb",) + cmd),
"hello": self.hello,
"proto": 6,
}
url = self.baseURL + urllib.parse.urlencode(query)
return urllib.request.urlopen(url)
def query(self, discid):
req = self.open("query", discid)
header = req.readline().decode("utf-8").strip()
code, desc = header[:3], header[4:]
results = (l.decode("utf-8").strip() for l in req.readlines())
return [r.split(" ", 2) for r in results if r != "."]
def read(self, category, discid):
req = self.open("read", category, discid)
header = req.readline().decode("utf-8").strip()
code, desc = header[3:], header[4:]
ret = {
"tracks": [],
"extt": [],
}
for line in req.readlines():
line = line.decode("utf-8").strip()
if line[0] in ("#", "."):
continue
k, v = line.split("=", 1)
if k == "DTITLE":
parts = v.split("/", 1)
if len(parts) == 1:
ret["title"] = v
else:
ret["artist"] = parts[0].strip()
ret["title"] = parts[1].strip()
elif k == "DYEAR":
ret["year"] = v
elif k == "DGENRE":
ret["genre"] = v
elif k.startswith("TTITLE"):
ret["tracks"].append(v)
elif k.startswith("EXTT"):
ret["extt"].append(v)
else:
ret[k.lower()] = v
return ret
def bestguess(self, discid):
"""Return our best guess at the "correct" match.
This is probably wrong if there's more than one.
We calculate this by idiotically assuming whatever's longest is the best.
"""
matches = self.query(discid)
results = []
for genre, discid, title in matches:
result = self.read(genre, discid)
resultlen = len(repr(result))
results.append((resultlen, result))
if results:
return sorted(results)[-1][1]
else:
return []
if __name__ == "__main__":
import pprint
discid = "610ADF09 9 150 25620 49322 78800 100775 125492 154060 174270 189407 2785"
s = Server("test@example.org")
pprint.pprint(s.bestguess(discid))