mirror of
https://github.com/krateng/maloja.git
synced 2025-04-15 00:10:32 +03:00
Upgrade third party modules to use requests
This commit is contained in:
parent
139de02d9a
commit
76691a5b0f
@ -28,4 +28,5 @@ minor_release_name: "Nicole"
|
|||||||
- "[Bugfix] Fixed scrobbling of tracks when all artists have been removed by server parsing"
|
- "[Bugfix] Fixed scrobbling of tracks when all artists have been removed by server parsing"
|
||||||
- "[Bugfix] Fixed Spotify import of multiple files"
|
- "[Bugfix] Fixed Spotify import of multiple files"
|
||||||
- "[Bugfix] Fixed process control on FreeBSD"
|
- "[Bugfix] Fixed process control on FreeBSD"
|
||||||
- "[Bugfix] Fixed Spotify authentication thread blocking the process from terminating"
|
- "[Bugfix] Fixed Spotify authentication thread blocking the process from terminating"
|
||||||
|
- "[Technical] Upgraded all third party modules to use requests module and send User Agent"
|
58
maloja/thirdparty/__init__.py
vendored
58
maloja/thirdparty/__init__.py
vendored
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import xml.etree.ElementTree as ElementTree
|
import xml.etree.ElementTree as ElementTree
|
||||||
import json
|
import json
|
||||||
import urllib.parse, urllib.request
|
import requests
|
||||||
|
import urllib.parse
|
||||||
import base64
|
import base64
|
||||||
import time
|
import time
|
||||||
from doreah.logging import log
|
from doreah.logging import log
|
||||||
@ -16,6 +17,7 @@ from threading import BoundedSemaphore
|
|||||||
|
|
||||||
from ..pkg_global.conf import malojaconfig
|
from ..pkg_global.conf import malojaconfig
|
||||||
from .. import database
|
from .. import database
|
||||||
|
from ..__pkginfo__ import USER_AGENT
|
||||||
|
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
@ -100,6 +102,8 @@ class GenericInterface:
|
|||||||
scrobbleimport = {}
|
scrobbleimport = {}
|
||||||
metadata = {}
|
metadata = {}
|
||||||
|
|
||||||
|
useragent = USER_AGENT
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# populate from settings file once on creation
|
# populate from settings file once on creation
|
||||||
# avoid constant disk access, restart on adding services is acceptable
|
# avoid constant disk access, restart on adding services is acceptable
|
||||||
@ -127,16 +131,6 @@ class GenericInterface:
|
|||||||
return True
|
return True
|
||||||
# per default. no authorization is necessary
|
# per default. no authorization is necessary
|
||||||
|
|
||||||
# wrapper method
|
|
||||||
def request(self,url,data,responsetype):
|
|
||||||
response = urllib.request.urlopen(
|
|
||||||
url,
|
|
||||||
data=utf(data)
|
|
||||||
)
|
|
||||||
responsedata = response.read()
|
|
||||||
if responsetype == "xml":
|
|
||||||
data = ElementTree.fromstring(responsedata)
|
|
||||||
return data
|
|
||||||
|
|
||||||
# proxy scrobbler
|
# proxy scrobbler
|
||||||
class ProxyScrobbleInterface(GenericInterface,abstract=True):
|
class ProxyScrobbleInterface(GenericInterface,abstract=True):
|
||||||
@ -155,11 +149,15 @@ class ProxyScrobbleInterface(GenericInterface,abstract=True):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def scrobble(self,artists,title,timestamp):
|
def scrobble(self,artists,title,timestamp):
|
||||||
response = urllib.request.urlopen(
|
response = requests.post(
|
||||||
self.proxyscrobble["scrobbleurl"],
|
url=self.proxyscrobble["scrobbleurl"],
|
||||||
data=utf(self.proxyscrobble_postdata(artists,title,timestamp)))
|
data=self.proxyscrobble_postdata(artists,title,timestamp),
|
||||||
responsedata = response.read()
|
headers={
|
||||||
|
"User-Agent":self.useragent
|
||||||
|
}
|
||||||
|
)
|
||||||
if self.proxyscrobble["response_type"] == "xml":
|
if self.proxyscrobble["response_type"] == "xml":
|
||||||
|
responsedata = response.text
|
||||||
data = ElementTree.fromstring(responsedata)
|
data = ElementTree.fromstring(responsedata)
|
||||||
return self.proxyscrobble_parse_response(data)
|
return self.proxyscrobble_parse_response(data)
|
||||||
|
|
||||||
@ -211,13 +209,15 @@ class MetadataInterface(GenericInterface,abstract=True):
|
|||||||
artists, title = track
|
artists, title = track
|
||||||
artiststring = urllib.parse.quote(", ".join(artists))
|
artiststring = urllib.parse.quote(", ".join(artists))
|
||||||
titlestring = urllib.parse.quote(title)
|
titlestring = urllib.parse.quote(title)
|
||||||
response = urllib.request.urlopen(
|
response = requests.get(
|
||||||
self.metadata["trackurl"].format(artist=artiststring,title=titlestring,**self.settings)
|
self.metadata["trackurl"].format(artist=artiststring,title=titlestring,**self.settings),
|
||||||
|
headers={
|
||||||
|
"User-Agent":self.useragent
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
responsedata = response.read()
|
|
||||||
if self.metadata["response_type"] == "json":
|
if self.metadata["response_type"] == "json":
|
||||||
data = json.loads(responsedata)
|
data = response.json()
|
||||||
imgurl = self.metadata_parse_response_track(data)
|
imgurl = self.metadata_parse_response_track(data)
|
||||||
else:
|
else:
|
||||||
imgurl = None
|
imgurl = None
|
||||||
@ -227,13 +227,15 @@ class MetadataInterface(GenericInterface,abstract=True):
|
|||||||
|
|
||||||
def get_image_artist(self,artist):
|
def get_image_artist(self,artist):
|
||||||
artiststring = urllib.parse.quote(artist)
|
artiststring = urllib.parse.quote(artist)
|
||||||
response = urllib.request.urlopen(
|
response = requests.get(
|
||||||
self.metadata["artisturl"].format(artist=artiststring,**self.settings)
|
self.metadata["artisturl"].format(artist=artiststring,**self.settings),
|
||||||
|
headers={
|
||||||
|
"User-Agent":self.useragent
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
responsedata = response.read()
|
|
||||||
if self.metadata["response_type"] == "json":
|
if self.metadata["response_type"] == "json":
|
||||||
data = json.loads(responsedata)
|
data = response.json()
|
||||||
imgurl = self.metadata_parse_response_artist(data)
|
imgurl = self.metadata_parse_response_artist(data)
|
||||||
else:
|
else:
|
||||||
imgurl = None
|
imgurl = None
|
||||||
@ -245,13 +247,15 @@ class MetadataInterface(GenericInterface,abstract=True):
|
|||||||
artists, title = album
|
artists, title = album
|
||||||
artiststring = urllib.parse.quote(", ".join(artists or []))
|
artiststring = urllib.parse.quote(", ".join(artists or []))
|
||||||
titlestring = urllib.parse.quote(title)
|
titlestring = urllib.parse.quote(title)
|
||||||
response = urllib.request.urlopen(
|
response = requests.get(
|
||||||
self.metadata["albumurl"].format(artist=artiststring,title=titlestring,**self.settings)
|
self.metadata["albumurl"].format(artist=artiststring,title=titlestring,**self.settings),
|
||||||
|
headers={
|
||||||
|
"User-Agent":self.useragent
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
responsedata = response.read()
|
|
||||||
if self.metadata["response_type"] == "json":
|
if self.metadata["response_type"] == "json":
|
||||||
data = json.loads(responsedata)
|
data = response.json()
|
||||||
imgurl = self.metadata_parse_response_album(data)
|
imgurl = self.metadata_parse_response_album(data)
|
||||||
else:
|
else:
|
||||||
imgurl = None
|
imgurl = None
|
||||||
|
31
maloja/thirdparty/lastfm.py
vendored
31
maloja/thirdparty/lastfm.py
vendored
@ -1,6 +1,7 @@
|
|||||||
from . import MetadataInterface, ProxyScrobbleInterface, utf
|
from . import MetadataInterface, ProxyScrobbleInterface, utf
|
||||||
import hashlib
|
import hashlib
|
||||||
import urllib.parse, urllib.request
|
import requests
|
||||||
|
import xml.etree.ElementTree as ElementTree
|
||||||
from doreah.logging import log
|
from doreah.logging import log
|
||||||
|
|
||||||
class LastFM(MetadataInterface, ProxyScrobbleInterface):
|
class LastFM(MetadataInterface, ProxyScrobbleInterface):
|
||||||
@ -54,27 +55,37 @@ class LastFM(MetadataInterface, ProxyScrobbleInterface):
|
|||||||
|
|
||||||
def authorize(self):
|
def authorize(self):
|
||||||
try:
|
try:
|
||||||
result = self.request(
|
response = requests.post(
|
||||||
self.proxyscrobble['scrobbleurl'],
|
url=self.proxyscrobble['scrobbleurl'],
|
||||||
self.query_compose({
|
params=self.query_compose({
|
||||||
"method":"auth.getMobileSession",
|
"method":"auth.getMobileSession",
|
||||||
"username":self.settings["username"],
|
"username":self.settings["username"],
|
||||||
"password":self.settings["password"],
|
"password":self.settings["password"],
|
||||||
"api_key":self.settings["apikey"]
|
"api_key":self.settings["apikey"]
|
||||||
}),
|
}),
|
||||||
responsetype="xml"
|
headers={
|
||||||
|
"User-Agent":self.useragent
|
||||||
|
}
|
||||||
)
|
)
|
||||||
self.settings["sk"] = result.find("session").findtext("key")
|
|
||||||
|
data = ElementTree.fromstring(response.text)
|
||||||
|
self.settings["sk"] = data.find("session").findtext("key")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
log("Error while authenticating with LastFM: " + repr(e))
|
||||||
#log("Error while authenticating with LastFM: " + repr(e))
|
|
||||||
|
|
||||||
|
|
||||||
# creates signature and returns full query string
|
# creates signature and returns full query
|
||||||
def query_compose(self,parameters):
|
def query_compose(self,parameters):
|
||||||
m = hashlib.md5()
|
m = hashlib.md5()
|
||||||
keys = sorted(str(k) for k in parameters)
|
keys = sorted(str(k) for k in parameters)
|
||||||
m.update(utf("".join(str(k) + str(parameters[k]) for k in keys)))
|
m.update(utf("".join(str(k) + str(parameters[k]) for k in keys)))
|
||||||
m.update(utf(self.settings["secret"]))
|
m.update(utf(self.settings["secret"]))
|
||||||
sig = m.hexdigest()
|
sig = m.hexdigest()
|
||||||
return urllib.parse.urlencode(parameters) + "&api_sig=" + sig
|
return {**parameters,"api_sig":sig}
|
||||||
|
|
||||||
|
def handle_json_result_error(self,result):
|
||||||
|
if "track" in result and not result.get("track").get('album',{}):
|
||||||
|
return True
|
||||||
|
|
||||||
|
if "error" in result and result.get("error") == 6:
|
||||||
|
return True
|
||||||
|
6
maloja/thirdparty/maloja.py
vendored
6
maloja/thirdparty/maloja.py
vendored
@ -1,5 +1,5 @@
|
|||||||
from . import ProxyScrobbleInterface, ImportInterface
|
from . import ProxyScrobbleInterface, ImportInterface
|
||||||
import urllib.request
|
import requests
|
||||||
from doreah.logging import log
|
from doreah.logging import log
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@ -32,8 +32,8 @@ class OtherMalojaInstance(ProxyScrobbleInterface, ImportInterface):
|
|||||||
def get_remote_scrobbles(self):
|
def get_remote_scrobbles(self):
|
||||||
url = f"{self.settings['instance']}/apis/mlj_1/scrobbles"
|
url = f"{self.settings['instance']}/apis/mlj_1/scrobbles"
|
||||||
|
|
||||||
response = urllib.request.urlopen(url)
|
response = requests.get(url)
|
||||||
data = json.loads(response.read().decode('utf-8'))
|
data = response.json()
|
||||||
|
|
||||||
for scrobble in data['list']:
|
for scrobble in data['list']:
|
||||||
yield scrobble
|
yield scrobble
|
||||||
|
62
maloja/thirdparty/musicbrainz.py
vendored
62
maloja/thirdparty/musicbrainz.py
vendored
@ -1,9 +1,7 @@
|
|||||||
from . import MetadataInterface
|
from . import MetadataInterface
|
||||||
import urllib.parse, urllib.request
|
import requests
|
||||||
import json
|
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from ..__pkginfo__ import USER_AGENT
|
|
||||||
|
|
||||||
class MusicBrainz(MetadataInterface):
|
class MusicBrainz(MetadataInterface):
|
||||||
name = "MusicBrainz"
|
name = "MusicBrainz"
|
||||||
@ -11,7 +9,6 @@ class MusicBrainz(MetadataInterface):
|
|||||||
|
|
||||||
# musicbrainz is rate-limited
|
# musicbrainz is rate-limited
|
||||||
lock = threading.Lock()
|
lock = threading.Lock()
|
||||||
useragent = USER_AGENT
|
|
||||||
|
|
||||||
|
|
||||||
thumbnailsize_order = ['500','large','1200','250','small']
|
thumbnailsize_order = ['500','large','1200','250','small']
|
||||||
@ -35,30 +32,32 @@ class MusicBrainz(MetadataInterface):
|
|||||||
searchstr = f'release:"{title}"'
|
searchstr = f'release:"{title}"'
|
||||||
for artist in artists:
|
for artist in artists:
|
||||||
searchstr += f' artist:"{artist}"'
|
searchstr += f' artist:"{artist}"'
|
||||||
querystr = urllib.parse.urlencode({
|
res = requests.get(**{
|
||||||
"fmt":"json",
|
"url":"https://musicbrainz.org/ws/2/release",
|
||||||
"query":searchstr
|
"params":{
|
||||||
})
|
"fmt":"json",
|
||||||
req = urllib.request.Request(**{
|
"query":searchstr
|
||||||
"url":"https://musicbrainz.org/ws/2/release?" + querystr,
|
},
|
||||||
"method":"GET",
|
|
||||||
"headers":{
|
"headers":{
|
||||||
"User-Agent":self.useragent
|
"User-Agent":self.useragent
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
response = urllib.request.urlopen(req)
|
data = res.json()
|
||||||
responsedata = response.read()
|
|
||||||
data = json.loads(responsedata)
|
|
||||||
entity = data["releases"][0]
|
entity = data["releases"][0]
|
||||||
coverartendpoint = "release"
|
coverartendpoint = "release"
|
||||||
while True:
|
while True:
|
||||||
mbid = entity["id"]
|
mbid = entity["id"]
|
||||||
try:
|
try:
|
||||||
response = urllib.request.urlopen(
|
response = requests.get(
|
||||||
f"https://coverartarchive.org/{coverartendpoint}/{mbid}?fmt=json"
|
f"https://coverartarchive.org/{coverartendpoint}/{mbid}",
|
||||||
|
params={
|
||||||
|
"fmt":"json"
|
||||||
|
},
|
||||||
|
headers={
|
||||||
|
"User-Agent":self.useragent
|
||||||
|
}
|
||||||
)
|
)
|
||||||
responsedata = response.read()
|
data = response.json()
|
||||||
data = json.loads(responsedata)
|
|
||||||
thumbnails = data['images'][0]['thumbnails']
|
thumbnails = data['images'][0]['thumbnails']
|
||||||
for size in self.thumbnailsize_order:
|
for size in self.thumbnailsize_order:
|
||||||
if thumbnails.get(size) is not None:
|
if thumbnails.get(size) is not None:
|
||||||
@ -88,30 +87,29 @@ class MusicBrainz(MetadataInterface):
|
|||||||
searchstr = f'recording:"{title}"'
|
searchstr = f'recording:"{title}"'
|
||||||
for artist in artists:
|
for artist in artists:
|
||||||
searchstr += f' artist:"{artist}"'
|
searchstr += f' artist:"{artist}"'
|
||||||
querystr = urllib.parse.urlencode({
|
res = requests.get(**{
|
||||||
"fmt":"json",
|
"url":"https://musicbrainz.org/ws/2/recording",
|
||||||
"query":searchstr
|
"params":{
|
||||||
})
|
"fmt":"json",
|
||||||
req = urllib.request.Request(**{
|
"query":searchstr
|
||||||
"url":"https://musicbrainz.org/ws/2/recording?" + querystr,
|
},
|
||||||
"method":"GET",
|
|
||||||
"headers":{
|
"headers":{
|
||||||
"User-Agent":self.useragent
|
"User-Agent":self.useragent
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
response = urllib.request.urlopen(req)
|
data = res.json()
|
||||||
responsedata = response.read()
|
|
||||||
data = json.loads(responsedata)
|
|
||||||
entity = data["recordings"][0]["releases"][0]
|
entity = data["recordings"][0]["releases"][0]
|
||||||
coverartendpoint = "release"
|
coverartendpoint = "release"
|
||||||
while True:
|
while True:
|
||||||
mbid = entity["id"]
|
mbid = entity["id"]
|
||||||
try:
|
try:
|
||||||
response = urllib.request.urlopen(
|
response = requests.get(
|
||||||
f"https://coverartarchive.org/{coverartendpoint}/{mbid}?fmt=json"
|
f"https://coverartarchive.org/{coverartendpoint}/{mbid}",
|
||||||
|
params={
|
||||||
|
"fmt":"json"
|
||||||
|
}
|
||||||
)
|
)
|
||||||
responsedata = response.read()
|
data = response.json()
|
||||||
data = json.loads(responsedata)
|
|
||||||
thumbnails = data['images'][0]['thumbnails']
|
thumbnails = data['images'][0]['thumbnails']
|
||||||
for size in self.thumbnailsize_order:
|
for size in self.thumbnailsize_order:
|
||||||
if thumbnails.get(size) is not None:
|
if thumbnails.get(size) is not None:
|
||||||
|
19
maloja/thirdparty/spotify.py
vendored
19
maloja/thirdparty/spotify.py
vendored
@ -1,6 +1,5 @@
|
|||||||
from . import MetadataInterface, utf, b64
|
from . import MetadataInterface, utf, b64
|
||||||
import urllib.parse, urllib.request
|
import requests
|
||||||
import json
|
|
||||||
from threading import Timer
|
from threading import Timer
|
||||||
from doreah.logging import log
|
from doreah.logging import log
|
||||||
|
|
||||||
@ -31,15 +30,14 @@ class Spotify(MetadataInterface):
|
|||||||
try:
|
try:
|
||||||
keys = {
|
keys = {
|
||||||
"url":"https://accounts.spotify.com/api/token",
|
"url":"https://accounts.spotify.com/api/token",
|
||||||
"method":"POST",
|
|
||||||
"headers":{
|
"headers":{
|
||||||
"Authorization":"Basic " + b64(utf(self.settings["apiid"] + ":" + self.settings["secret"])).decode("utf-8")
|
"Authorization":"Basic " + b64(utf(self.settings["apiid"] + ":" + self.settings["secret"])).decode("utf-8"),
|
||||||
|
"User-Agent": self.useragent
|
||||||
},
|
},
|
||||||
"data":bytes(urllib.parse.urlencode({"grant_type":"client_credentials"}),encoding="utf-8")
|
"data":{"grant_type":"client_credentials"}
|
||||||
}
|
}
|
||||||
req = urllib.request.Request(**keys)
|
res = requests.post(**keys)
|
||||||
response = urllib.request.urlopen(req)
|
responsedata = res.json()
|
||||||
responsedata = json.loads(response.read())
|
|
||||||
if "error" in responsedata:
|
if "error" in responsedata:
|
||||||
log("Error authenticating with Spotify: " + responsedata['error_description'])
|
log("Error authenticating with Spotify: " + responsedata['error_description'])
|
||||||
expire = 3600
|
expire = 3600
|
||||||
@ -52,3 +50,8 @@ class Spotify(MetadataInterface):
|
|||||||
t.start()
|
t.start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log("Error while authenticating with Spotify: " + repr(e))
|
log("Error while authenticating with Spotify: " + repr(e))
|
||||||
|
|
||||||
|
def handle_json_result_error(self,result):
|
||||||
|
result = result.get('tracks') or result.get('albums') or result.get('artists')
|
||||||
|
if not result['items']:
|
||||||
|
return True
|
Loading…
x
Reference in New Issue
Block a user