1
0
mirror of https://github.com/krateng/maloja.git synced 2023-08-10 21:12:55 +03:00

Experimental support for Listenbrainz scrobblers

This commit is contained in:
Krateng 2019-05-13 10:45:30 +02:00
parent 042f4f12fb
commit 5aa92a1ab8
5 changed files with 53 additions and 66 deletions

View File

@ -61,12 +61,24 @@ If you didn't install Maloja from the package (and therefore don't have it in `/
## How to scrobble ## How to scrobble
### Native API
If you use Plex Web or Youtube Music on Chromium, you can use the included extension. Make sure to enter the random key Maloja generates on first startup in the extension settings. If you use Plex Web or Youtube Music on Chromium, you can use the included extension. Make sure to enter the random key Maloja generates on first startup in the extension settings.
You can use any third-party scrobbler that supports the audioscrobbler protocol (GNUFM). This is still very experimental, but give it a try with these settings:
Gnukebox URL: Your Maloja URL followed by `/api/s/audioscrobbler`
Username: Any name, doesn't matter
Password: Any of your API keys (you can define new ones in `clients/authenticated_machines` in your Maloja folder)
If you want to implement your own method of scrobbling, it's very simple: You only need one POST request with the keys `artist`, `title` and `key`. If you want to implement your own method of scrobbling, it's very simple: You only need one POST request with the keys `artist`, `title` and `key`.
### Standard-compliant API
You can use any third-party scrobbler that supports the audioscrobbler (GNUFM) or the ListenBrainz protocol. This is still very experimental, but give it a try with these settings:
GNU FM |  
------ | ---------
Gnukebox URL | Your Maloja URL followed by `/api/s/audioscrobbler`
Username | Any name, doesn't matter
Password | Any of your API keys (you can define new ones in `clients/authenticated_machines` in your Maloja folder)
ListenBrainz |  
------ | ---------
API URL | Your Maloja URL followed by `api/s/listenbrainz`
Username | Any name, doesn't matter
Auth Token | Any of your API keys (you can define new ones in `clients/authenticated_machines` in your Maloja folder)

View File

@ -2,7 +2,9 @@ from doreah.logging import log
import hashlib import hashlib
import random import random
import database import database
import datetime
from cleanup import CleanerAgent from cleanup import CleanerAgent
from bottle import response
## GNU-FM-compliant scrobbling ## GNU-FM-compliant scrobbling
@ -51,6 +53,7 @@ def handle(path,keys,headers,auth):
response = {"error_message":"Invalid scrobble protocol"} response = {"error_message":"Invalid scrobble protocol"}
except: except:
response = {"error_message":"Unknown API error"} response = {"error_message":"Unknown API error"}
raise
print("Response: " + str(response)) print("Response: " + str(response))
return response return response
@ -113,8 +116,32 @@ def handle_listenbrainz(path,keys,headers):
if path[1] == "submit-listens": if path[1] == "submit-listens":
if headers.get("Authorization") is not None: if headers.get("Authorization") is not None:
print(headers.get("Authorization")) token = headers.get("Authorization").replace("token ","").strip()
return {"wat":"wut"} if token in database.allAPIkeys():
if "payload" in keys:
if keys["listen_type"] in ["single","import"]:
for listen in keys["payload"]:
metadata = listen["track_metadata"]
artiststr, titlestr = metadata["artist_name"], metadata["track_name"]
(artists,title) = cla.fullclean(artiststr,titlestr)
try:
timestamp = int(listen["listened_at"])
except:
timestamp = int(datetime.datetime.now(tz=datetime.timezone.utc).timestamp())
database.createScrobble(artists,title,timestamp)
return {"code":200,"status":"ok"}
else:
response.status = 400
return {"code":400,"error":"Invalid JSON document submitted."}
else:
return {"error":"Bad Auth"}
else:
return {"code":401,"error":"You need to provide an Authorization header."}
else:
return {"error_message":"Invalid API method"}
else: else:
return {"error_message":"API version not supported"} return {"error_message":"API version not supported"}

View File

@ -660,8 +660,11 @@ def post_scrobble():
def sapi(path): def sapi(path):
path = path.split("/") path = path.split("/")
path = list(filter(None,path)) path = list(filter(None,path))
keys = FormsDict.decode(request.params)
headers = request.headers headers = request.headers
if "application/json" in request.get_header("Content-Type"):
keys = request.json
else:
keys = FormsDict.decode(request.params)
auth = request.auth auth = request.auth
return compliant_api.handle(path,keys,headers,auth) return compliant_api.handle(path,keys,headers,auth)

View File

@ -69,59 +69,6 @@ def customerror(error):
#@webserver.get("/api/<pth:path>")
#def api(pth):
# return database.handle_get(pth,request)
#@webserver.post("/api/<pth:path>")
#def api_post(pth):
# return database.handle_post(pth,request)
# this is the fallback option. If you run this service behind a reverse proxy, it is recommended to rewrite /db/ requests to the port of the db server
# e.g. location /db { rewrite ^/db(.*)$ $1 break; proxy_pass http://yoururl:12349; }
#@webserver.get("/api/<pth:path>")
def database_get(pth):
keys = FormsDict.decode(request.query) # The Dal★Shabet handler
keystring = "?"
for k in keys:
keystring += urllib.parse.quote(k) + "=" + urllib.parse.quote(keys[k]) + "&"
response.set_header("Access-Control-Allow-Origin","*")
try:
proxyresponse = urllib.request.urlopen("http://[::1]:" + str(DATABASE_PORT) + "/" + pth + keystring)
contents = proxyresponse.read()
response.status = proxyresponse.getcode()
response.content_type = "application/json"
return contents
except HTTPError as e:
response.status = e.code
return
#@webserver.post("/api/<pth:path>")
def database_post(pth):
#print(request.headers)
#response.set_header("Access-Control-Allow-Origin","*")
try:
proxyrequest = urllib.request.Request(
url="http://[::1]:" + str(DATABASE_PORT) + "/" + pth,
data=request.body,
headers=request.headers,
method="POST"
)
proxyresponse = urllib.request.urlopen(proxyrequest)
contents = proxyresponse.read()
response.status = proxyresponse.getcode()
response.headers = proxyresponse.headers
response.content_type = "application/json"
return contents
except HTTPError as e:
response.status = e.code
return
return
def graceful_exit(sig=None,frame=None): def graceful_exit(sig=None,frame=None):
#urllib.request.urlopen("http://[::1]:" + str(DATABASE_PORT) + "/sync") #urllib.request.urlopen("http://[::1]:" + str(DATABASE_PORT) + "/sync")
database.sync() database.sync()
@ -231,9 +178,7 @@ signal.signal(signal.SIGTERM, graceful_exit)
#rename process, this is now required for the daemon manager to work #rename process, this is now required for the daemon manager to work
setproctitle.setproctitle("Maloja") setproctitle.setproctitle("Maloja")
## start database server ## start database
#_thread.start_new_thread(SourceFileLoader("database","database.py").load_module().runserver,(DATABASE_PORT,))
#_thread.start_new_thread(database.runserver,(DATABASE_PORT,))
database.start_db() database.start_db()
database.register_subroutes(webserver,"/api") database.register_subroutes(webserver,"/api")

View File

@ -76,7 +76,7 @@
If you use Vivaldi, Brave, Iridium or any other Chromium-based browser and listen to music on Plex or YouTube Music, download the extension and simply enter the server URL as well as your API key in the relevant fields. They will turn green if the server is accessible. If you use Vivaldi, Brave, Iridium or any other Chromium-based browser and listen to music on Plex or YouTube Music, download the extension and simply enter the server URL as well as your API key in the relevant fields. They will turn green if the server is accessible.
<br/><br/> <br/><br/>
You can also use any GNUFM-compliant scrobbler. Enter <span class="stats"><span name="serverurl">yourserver.tld</span>/api/s/audioscrobbler</span> as your Gnukebox server and your API key as the password. You can also use any standard-compliant scrobbler. For GNUFM (audioscrobbler) scrobblers, enter <span class="stats"><span name="serverurl">yourserver.tld</span>/api/s/audioscrobbler</span> as your Gnukebox server and your API key as the password. For Listenbrainz scrobblers, use <span class="stats"><span name="serverurl">yourserver.tld</span>/api/s/listenbrainz</span> as the API URL and your API key as token.
<br/><br/> <br/><br/>
If you use another browser or another music player, you could try to code your own extension. The API is super simple! Just send a POST HTTP request to If you use another browser or another music player, you could try to code your own extension. The API is super simple! Just send a POST HTTP request to