mirror of
https://github.com/beetbox/beets.git
synced 2026-01-14 04:01:43 +01:00
Added URL to config and deprecated old configuration
This commit is contained in:
parent
60bba370c0
commit
1690c08e77
2 changed files with 84 additions and 37 deletions
|
|
@ -25,16 +25,68 @@ a "subsonic" section like the following:
|
|||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets import config
|
||||
import requests
|
||||
import string
|
||||
import hashlib
|
||||
import random
|
||||
import string
|
||||
|
||||
import requests
|
||||
|
||||
from beets import config
|
||||
from beets.plugins import BeetsPlugin
|
||||
|
||||
__author__ = 'https://github.com/maffo999'
|
||||
|
||||
|
||||
def build_payload():
|
||||
""" To avoid sending plaintext passwords, authentication will be
|
||||
performed via username, a token, and a 6 random
|
||||
letters/numbers sequence.
|
||||
The token is the concatenation of your password and the 6 random
|
||||
letters/numbers (the salt) which is hashed with MD5.
|
||||
"""
|
||||
|
||||
user = config['subsonic']['user'].as_str()
|
||||
password = config['subsonic']['pass'].as_str()
|
||||
|
||||
# Pick the random sequence and salt the password
|
||||
r = string.ascii_letters + string.digits
|
||||
salt = "".join([random.choice(r) for n in range(6)])
|
||||
t = password + salt
|
||||
token = hashlib.md5()
|
||||
token.update(t.encode('utf-8'))
|
||||
|
||||
# Put together the payload of the request to the server and the URL
|
||||
return {
|
||||
'u': user,
|
||||
't': token.hexdigest(),
|
||||
's': salt,
|
||||
'v': '1.15.0', # Subsonic 6.1 and newer.
|
||||
'c': 'beets'
|
||||
}
|
||||
|
||||
|
||||
def formal_url():
|
||||
""" Formats URL to send request to Subsonic
|
||||
DEPRECATED schema, host, port, contextpath; use ${url}
|
||||
"""
|
||||
|
||||
host = config['subsonic']['host'].as_str()
|
||||
port = config['subsonic']['port'].get(int)
|
||||
|
||||
context_path = config['subsonic']['contextpath'].as_str()
|
||||
if context_path == '/':
|
||||
context_path = ''
|
||||
|
||||
url = config['subsonic']['url'].as_str()
|
||||
if url and url.endsWith('/'):
|
||||
url = url[:-1]
|
||||
|
||||
if not url:
|
||||
url = "http://{}:{}{}".format(host, port, context_path)
|
||||
|
||||
return url + '/rest/startScan'
|
||||
|
||||
|
||||
class SubsonicUpdate(BeetsPlugin):
|
||||
def __init__(self):
|
||||
super(SubsonicUpdate, self).__init__()
|
||||
|
|
@ -46,42 +98,23 @@ class SubsonicUpdate(BeetsPlugin):
|
|||
'user': 'admin',
|
||||
'pass': 'admin',
|
||||
'contextpath': '/',
|
||||
'url': 'http://localhost:4040'
|
||||
})
|
||||
|
||||
config['subsonic']['pass'].redact = True
|
||||
self.register_listener('import', self.loaded)
|
||||
self.register_listener('import', self.start_scan)
|
||||
|
||||
def loaded(self):
|
||||
host = config['subsonic']['host'].as_str()
|
||||
port = config['subsonic']['port'].get(int)
|
||||
user = config['subsonic']['user'].as_str()
|
||||
passw = config['subsonic']['pass'].as_str()
|
||||
contextpath = config['subsonic']['contextpath'].as_str()
|
||||
def start_scan(self):
|
||||
url = formal_url()
|
||||
payload = build_payload()
|
||||
|
||||
# To avoid sending plaintext passwords, authentication will be
|
||||
# performed via username, a token, and a 6 random
|
||||
# letters/numbers sequence.
|
||||
# The token is the concatenation of your password and the 6 random
|
||||
# letters/numbers (the salt) which is hashed with MD5.
|
||||
|
||||
# Pick the random sequence and salt the password
|
||||
r = string.ascii_letters + string.digits
|
||||
salt = "".join([random.choice(r) for n in range(6)])
|
||||
t = passw + salt
|
||||
token = hashlib.md5()
|
||||
token.update(t.encode('utf-8'))
|
||||
|
||||
# Put together the payload of the request to the server and the URL
|
||||
payload = {
|
||||
'u': user,
|
||||
't': token.hexdigest(),
|
||||
's': salt,
|
||||
'v': '1.15.0', # Subsonic 6.1 and newer.
|
||||
'c': 'beets'
|
||||
}
|
||||
if contextpath == '/':
|
||||
contextpath = ''
|
||||
url = "http://{}:{}{}/rest/startScan".format(host, port, contextpath)
|
||||
response = requests.post(url, params=payload)
|
||||
|
||||
if response.status_code != 200:
|
||||
self._log.error(u'Generic error, please try again later.')
|
||||
if response.status_code == 403:
|
||||
self._log.error(u'Server authentication failed')
|
||||
elif response.status_code == 200:
|
||||
self._log.debug(u'Updating Subsonic')
|
||||
else:
|
||||
self._log.error(
|
||||
u'Generic error, please try again later [Status Code: {}]'
|
||||
.format(response.status_code))
|
||||
|
|
|
|||
|
|
@ -12,6 +12,12 @@ Then, you'll probably want to configure the specifics of your Subsonic server.
|
|||
You can do that using a ``subsonic:`` section in your ``config.yaml``,
|
||||
which looks like this::
|
||||
|
||||
subsonic:
|
||||
url: https://mydomain.com:443/subsonic
|
||||
user: username
|
||||
pass: password
|
||||
|
||||
# DEPRECATED
|
||||
subsonic:
|
||||
host: X.X.X.X
|
||||
port: 4040
|
||||
|
|
@ -30,6 +36,14 @@ Configuration
|
|||
|
||||
The available options under the ``subsonic:`` section are:
|
||||
|
||||
- **url**: The Subsonic server resource. Default: ``http://localhost:4040``
|
||||
|
||||
Example: ``https://mydomain.com:443/subsonic``
|
||||
|
||||
\* Note: context path is optional
|
||||
|
||||
DEPRECATED:
|
||||
|
||||
- **host**: The Subsonic server name/IP. Default: ``localhost``
|
||||
- **port**: The Subsonic server port. Default: ``4040``
|
||||
- **user**: The Subsonic user. Default: ``admin``
|
||||
|
|
|
|||
Loading…
Reference in a new issue