mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 08:39:17 +01:00
Fix subsonicupdate plugin
This commit is contained in:
parent
0f9ffeec3e
commit
653181a296
2 changed files with 22 additions and 49 deletions
|
|
@ -20,6 +20,14 @@ a "subsonic" section like the following:
|
||||||
url: https://mydomain.com:443/subsonic
|
url: https://mydomain.com:443/subsonic
|
||||||
user: username
|
user: username
|
||||||
pass: password
|
pass: password
|
||||||
|
auth: token
|
||||||
|
For older Subsonic versions, token authentication
|
||||||
|
is not supported, use password instead:
|
||||||
|
subsonic:
|
||||||
|
url: https://mydomain.com:443/subsonic
|
||||||
|
user: username
|
||||||
|
pass: password
|
||||||
|
auth: pass
|
||||||
"""
|
"""
|
||||||
from __future__ import division, absolute_import, print_function
|
from __future__ import division, absolute_import, print_function
|
||||||
|
|
||||||
|
|
@ -34,8 +42,6 @@ from beets import config
|
||||||
from beets.plugins import BeetsPlugin
|
from beets.plugins import BeetsPlugin
|
||||||
|
|
||||||
__author__ = 'https://github.com/maffo999'
|
__author__ = 'https://github.com/maffo999'
|
||||||
AUTH_TOKEN_VERSION = (1, 12)
|
|
||||||
|
|
||||||
|
|
||||||
class SubsonicUpdate(BeetsPlugin):
|
class SubsonicUpdate(BeetsPlugin):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
@ -45,30 +51,11 @@ class SubsonicUpdate(BeetsPlugin):
|
||||||
'user': 'admin',
|
'user': 'admin',
|
||||||
'pass': 'admin',
|
'pass': 'admin',
|
||||||
'url': 'http://localhost:4040',
|
'url': 'http://localhost:4040',
|
||||||
|
'auth': 'token',
|
||||||
})
|
})
|
||||||
config['subsonic']['pass'].redact = True
|
config['subsonic']['pass'].redact = True
|
||||||
self._version = None
|
|
||||||
self._auth = None
|
|
||||||
self.register_listener('import', self.start_scan)
|
self.register_listener('import', self.start_scan)
|
||||||
|
|
||||||
@property
|
|
||||||
def version(self):
|
|
||||||
if self._version is None:
|
|
||||||
self._version = self.__get_version()
|
|
||||||
return self._version
|
|
||||||
|
|
||||||
@property
|
|
||||||
def auth(self):
|
|
||||||
if self._auth is None:
|
|
||||||
if self.version is not None:
|
|
||||||
if self.version > AUTH_TOKEN_VERSION:
|
|
||||||
self._auth = "token"
|
|
||||||
else:
|
|
||||||
self._auth = "password"
|
|
||||||
self._log.info(
|
|
||||||
u"using '{}' authentication method".format(self._auth))
|
|
||||||
return self._auth
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __create_token():
|
def __create_token():
|
||||||
"""Create salt and token from given password.
|
"""Create salt and token from given password.
|
||||||
|
|
@ -110,48 +97,30 @@ class SubsonicUpdate(BeetsPlugin):
|
||||||
|
|
||||||
return url + '/rest/{}'.format(endpoint)
|
return url + '/rest/{}'.format(endpoint)
|
||||||
|
|
||||||
def __get_version(self):
|
|
||||||
url = self.__format_url("ping.view")
|
|
||||||
payload = {
|
|
||||||
'c': 'beets',
|
|
||||||
'f': 'json'
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
response = requests.get(url, params=payload)
|
|
||||||
if response.status_code == 200:
|
|
||||||
json = response.json()
|
|
||||||
version = json['subsonic-response']['version']
|
|
||||||
self._log.info(
|
|
||||||
u'subsonic version:{0} '.format(version))
|
|
||||||
return tuple(int(s) for s in version.split('.'))
|
|
||||||
else:
|
|
||||||
self._log.error(u'Error: {0}', json)
|
|
||||||
return None
|
|
||||||
except Exception as error:
|
|
||||||
self._log.error(u'Error: {0}'.format(error))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def start_scan(self):
|
def start_scan(self):
|
||||||
user = config['subsonic']['user'].as_str()
|
user = config['subsonic']['user'].as_str()
|
||||||
url = self.__format_url("startScan.view")
|
auth = config['subsonic']['auth'].as_str()
|
||||||
|
url = self.__format_url("startScan")
|
||||||
|
self._log.info(u'URL is {0}', url)
|
||||||
|
self._log.info(u'auth type is {0}', config['subsonic']['auth'])
|
||||||
|
|
||||||
if self.auth == 'token':
|
if auth == "token":
|
||||||
salt, token = self.__create_token()
|
salt, token = self.__create_token()
|
||||||
payload = {
|
payload = {
|
||||||
'u': user,
|
'u': user,
|
||||||
't': token,
|
't': token,
|
||||||
's': salt,
|
's': salt,
|
||||||
'v': self.version, # Subsonic 6.1 and newer.
|
'v': '1.13.0', # Subsonic 5.3 and newer
|
||||||
'c': 'beets',
|
'c': 'beets',
|
||||||
'f': 'json'
|
'f': 'json'
|
||||||
}
|
}
|
||||||
elif self.auth == 'password':
|
elif auth == "password":
|
||||||
password = config['subsonic']['pass'].as_str()
|
password = config['subsonic']['pass'].as_str()
|
||||||
encpass = hexlify(password.encode()).decode()
|
encpass = hexlify(password.encode()).decode()
|
||||||
payload = {
|
payload = {
|
||||||
'u': user,
|
'u': user,
|
||||||
'p': 'enc:{}'.format(encpass),
|
'p': 'enc:{}'.format(encpass),
|
||||||
'v': self.version,
|
'v': '1.12.0',
|
||||||
'c': 'beets',
|
'c': 'beets',
|
||||||
'f': 'json'
|
'f': 'json'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,13 @@ which looks like this::
|
||||||
url: https://example.com:443/subsonic
|
url: https://example.com:443/subsonic
|
||||||
user: username
|
user: username
|
||||||
pass: password
|
pass: password
|
||||||
|
auth: token
|
||||||
|
|
||||||
With that all in place, beets will send a Rest API to your Subsonic
|
With that all in place, beets will send a Rest API to your Subsonic
|
||||||
server every time you import new music.
|
server every time you import new music.
|
||||||
Due to a current limitation of the API, all libraries visible to that user will be scanned.
|
Due to a current limitation of the API, all libraries visible to that user will be scanned.
|
||||||
|
|
||||||
This plugin requires Subsonic v6.1 or higher and an active Premium license (or trial).
|
This plugin requires Subsonic with an active Premium license (or active trial).
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
-------------
|
-------------
|
||||||
|
|
@ -32,3 +33,6 @@ The available options under the ``subsonic:`` section are:
|
||||||
- **user**: The Subsonic user. Default: ``admin``
|
- **user**: The Subsonic user. Default: ``admin``
|
||||||
- **pass**: The Subsonic user password. (This may either be a clear-text
|
- **pass**: The Subsonic user password. (This may either be a clear-text
|
||||||
password or hex-encoded with the prefix ``enc:``.) Default: ``admin``
|
password or hex-encoded with the prefix ``enc:``.) Default: ``admin``
|
||||||
|
- **auth**: The authentication method. Possible choices are ``token`` or
|
||||||
|
``password``. ``token`` authentication is preferred to avoid sending
|
||||||
|
cleartext password.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue