From b789d322b35c3f56ca9a1221358ebd56921803b1 Mon Sep 17 00:00:00 2001 From: James Barnsley Date: Mon, 3 Feb 2020 16:48:39 +1300 Subject: [PATCH] Formatting --- mopidy_iris/__init__.py | 8 +- mopidy_iris/core.py | 243 +++++++++++++++++++++++++++------------- mopidy_iris/frontend.py | 9 +- mopidy_iris/handlers.py | 110 ++++++++++++------ mopidy_iris/system.py | 26 +++-- 5 files changed, 269 insertions(+), 127 deletions(-) diff --git a/mopidy_iris/__init__.py b/mopidy_iris/__init__.py index 3d537a8b..7f8bc1e0 100755 --- a/mopidy_iris/__init__.py +++ b/mopidy_iris/__init__.py @@ -1,4 +1,6 @@ -import logging, json, pathlib +import logging +import json +import pathlib import pkg_resources from mopidy import config, ext @@ -37,7 +39,9 @@ class Extension(ext.Extension): from .frontend import IrisFrontend # Add web extension - registry.add("http:app", {"name": self.ext_name, "factory": iris_factory}) + registry.add( + "http:app", { + "name": self.ext_name, "factory": iris_factory}) # Add our frontend registry.add("frontend", IrisFrontend) diff --git a/mopidy_iris/core.py b/mopidy_iris/core.py index 9ef2f673..39af5372 100755 --- a/mopidy_iris/core.py +++ b/mopidy_iris/core.py @@ -1,13 +1,18 @@ -import random, string, logging, json, pathlib, pykka, urllib, os, sys, mopidy_iris, subprocess +import random +import string +import logging +import json +import pathlib +import pykka +import urllib +import os +import sys import tornado.web import tornado.ioloop -import requests import time import pickle -from mopidy import config, ext -from mopidy.core import CoreListener from pkg_resources import parse_version -from tornado.escape import json_encode, json_decode +from tornado.escape import json_encode from tornado.httpclient import AsyncHTTPClient, HTTPRequest from pathlib import Path @@ -75,7 +80,7 @@ class IrisCore(pykka.ThreadingActor): content = pickle.load(f) f.close() return content - except Exception as e: + except Exception: return {} ## @@ -114,7 +119,8 @@ class IrisCore(pykka.ThreadingActor): # @return string ## def generateGuid(self): - return "".join(random.choices(string.ascii_uppercase + string.digits, k=12)) + return "".join(random.choices( + string.ascii_uppercase + string.digits, k=12)) ## # Digest a protocol header into it's id/name parts @@ -124,10 +130,12 @@ class IrisCore(pykka.ThreadingActor): def digest_protocol(self, protocol): # if we're a string, split into list - # this handles the different ways we get this passed (select_subprotocols gives string, headers.get gives list) - if isinstance(protocol, basestring): + # this handles the different ways we get this passed + # (select_subprotocols gives string, headers.get gives list) + if isinstance(protocol, str): - # make sure we strip any spaces (IE gives "element,element", proper browsers give "element, element") + # make sure we strip any spaces (IE gives "element,element", proper + # browsers give "element, element") protocol = [i.strip() for i in protocol.split(",")] # if we've been given a valid array @@ -138,7 +146,7 @@ class IrisCore(pykka.ThreadingActor): generated = False # invalid, so just create a default connection, and auto-generate an ID - except: + except BaseException: client_id = self.generateGuid() connection_id = self.generateGuid() username = "Anonymous" @@ -197,7 +205,7 @@ class IrisCore(pykka.ThreadingActor): callback(response) else: return response - except: + except BaseException: error = "Failed to send message to " + data["recipient"] logger.error(error) @@ -234,9 +242,8 @@ class IrisCore(pykka.ThreadingActor): if send_to_this_connection: connection["connection"].write_message(json_encode(message)) - response = { - "message": "Broadcast to " + str(len(self.connections)) + " connections" - } + response = {"message": "Broadcast to " + + str(len(self.connections)) + " connections"} if callback: callback(response) else: @@ -245,9 +252,9 @@ class IrisCore(pykka.ThreadingActor): ## # Connections # - # Contains all our connections and client details. This requires updates - # when new clients connect, and old ones disconnect. These events are broadcast - # to all current connections + # Contains all our connections and client details. This requires + # updates when new clients connect, and old ones disconnect. These + # events are broadcast to all current connections ## def get_connections(self, *args, **kwargs): @@ -277,7 +284,10 @@ class IrisCore(pykka.ThreadingActor): } self.broadcast( - data={"method": "connection_added", "params": {"connection": client}} + data={ + "method": "connection_added", + "params": { + "connection": client}} ) def update_connection(self, *args, **kwargs): @@ -286,15 +296,19 @@ class IrisCore(pykka.ThreadingActor): connection_id = data["connection_id"] if connection_id in self.connections: - self.connections[connection_id]["client"]["username"] = data["username"] - self.connections[connection_id]["client"]["client_id"] = data["client_id"] + username = data["username"] + client_id = data["client_id"] + self.connections[connection_id]["client"]["username"] = username + self.connections[connection_id]["client"]["client_id"] = client_id self.broadcast( data={ "method": "connection_changed", - "params": {"connection": self.connections[connection_id]["client"]}, - } - ) - response = {"connection": self.connections[connection_id]["client"]} + "params": { + "connection": + self.connections[connection_id]["client"]}, + }) + response = { + "connection": self.connections[connection_id]["client"]} if callback: callback(response) else: @@ -321,7 +335,7 @@ class IrisCore(pykka.ThreadingActor): "params": {"connection": client}, } ) - except: + except BaseException: logger.error("Failed to close connection to " + connection_id) def set_username(self, *args, **kwargs): @@ -330,14 +344,18 @@ class IrisCore(pykka.ThreadingActor): connection_id = data["connection_id"] if connection_id in self.connections: - self.connections[connection_id]["client"]["username"] = data["username"] + username = data["username"] + self.connections[connection_id]["client"]["username"] = username self.broadcast( data={ "method": "connection_changed", - "params": {"connection": self.connections[connection_id]["client"]}, - } - ) - response = {"connection_id": connection_id, "username": data["username"]} + "params": { + "connection": + self.connections[connection_id]["client"]}, + }) + response = { + "connection_id": connection_id, + "username": data["username"]} if callback: callback(response) else: @@ -363,7 +381,8 @@ class IrisCore(pykka.ThreadingActor): callback = kwargs.get("callback", False) # handle config setups where there is no username/password - # Iris won't work properly anyway, but at least we won't get server errors + # Iris won't work properly anyway, but at least we won't get server + # errors if "spotify" in self.config and "username" in self.config["spotify"]: spotify_username = self.config["spotify"]["username"] else: @@ -410,7 +429,7 @@ class IrisCore(pykka.ThreadingActor): ) upgrade_available = upgrade_available == 1 - except (urllib.request.HTTPError, urllib.request.URLError) as e: + except (urllib.request.HTTPError, urllib.request.URLError): latest_version = "0.0.0" upgrade_available = False @@ -450,9 +469,15 @@ class IrisCore(pykka.ThreadingActor): if error: self.broadcast(data={"method": "restart_error", "params": error}) elif update: - self.broadcast(data={"method": "restart_updated", "params": update}) + self.broadcast( + data={ + "method": "restart_updated", + "params": update}) else: - self.broadcast(data={"method": "restart_finished", "params": response}) + self.broadcast( + data={ + "method": "restart_finished", + "params": response}) ## # Run an upgrade of Iris @@ -477,9 +502,15 @@ class IrisCore(pykka.ThreadingActor): if error: self.broadcast(data={"method": "upgrade_error", "params": error}) elif update: - self.broadcast(data={"method": "upgrade_updated", "params": update}) + self.broadcast( + data={ + "method": "upgrade_updated", + "params": update}) else: - self.broadcast(data={"method": "upgrade_finished", "params": response}) + self.broadcast( + data={ + "method": "upgrade_finished", + "params": response}) self.restart() ## @@ -491,7 +522,10 @@ class IrisCore(pykka.ThreadingActor): ioloop = kwargs.get("ioloop", False) # Trigger the action - IrisSystemThread("local_scan", ioloop, self.local_scan_callback).start() + IrisSystemThread( + "local_scan", + ioloop, + self.local_scan_callback).start() self.broadcast(data={"method": "local_scan_started"}) @@ -503,18 +537,28 @@ class IrisCore(pykka.ThreadingActor): def local_scan_callback(self, response, error, update): if error: - self.broadcast(data={"method": "local_scan_error", "params": error}) + self.broadcast( + data={ + "method": "local_scan_error", + "params": error}) elif update: - self.broadcast(data={"method": "local_scan_updated", "params": update}) + self.broadcast( + data={ + "method": "local_scan_updated", + "params": update}) else: - self.broadcast(data={"method": "local_scan_finished", "params": response}) + self.broadcast( + data={ + "method": "local_scan_finished", + "params": response}) ## # Spotify Radio # - # Accepts seed URIs and creates radio-like experience. When our tracklist is nearly - # empty, we fetch more recommendations. This can result in duplicates. We keep the - # recommendations limit low to avoid timeouts and slow UI + # Accepts seed URIs and creates radio-like experience. When our + # tracklist is nearly empty, we fetch more recommendations. This + # can result in duplicates. We keep the recommendations limit low + # to avoid timeouts and slow UI ## def get_radio(self, *args, **kwargs): @@ -578,11 +622,17 @@ class IrisCore(pykka.ThreadingActor): if starting: self.core.playback.play() self.broadcast( - data={"method": "radio_started", "params": {"radio": self.radio}} + data={ + "method": "radio_started", + "params": { + "radio": self.radio}} ) else: self.broadcast( - data={"method": "radio_changed", "params": {"radio": self.radio}} + data={ + "method": "radio_changed", + "params": { + "radio": self.radio}} ) self.get_radio(callback=callback) @@ -632,7 +682,7 @@ class IrisCore(pykka.ThreadingActor): await self.get_spotify_token() spotify_token = self.spotify_token access_token = spotify_token["access_token"] - except: + except BaseException: error = "IrisFrontend: access_token missing or invalid" logger.error(error) return False @@ -641,24 +691,29 @@ class IrisCore(pykka.ThreadingActor): url = ( url + "?seed_artists=" - + (",".join(self.radio["seed_artists"])).replace("spotify:artist:", "") + + (",".join(self.radio["seed_artists"]) + ).replace("spotify:artist:", "") ) url = ( url + "&seed_genres=" - + (",".join(self.radio["seed_genres"])).replace("spotify:genre:", "") + + (",".join(self.radio["seed_genres"]) + ).replace("spotify:genre:", "") ) url = ( url + "&seed_tracks=" - + (",".join(self.radio["seed_tracks"])).replace("spotify:track:", "") + + (",".join(self.radio["seed_tracks"]) + ).replace("spotify:track:", "") ) url = url + "&limit=50" http_client = AsyncHTTPClient() try: http_response = await http_client.fetch( - url, "POST", headers={"Authorization": "Bearer " + access_token} + url, "POST", headers={ + "Authorization": "Bearer " + access_token + } ) response_body = json.loads(http_response.body) @@ -675,7 +730,8 @@ class IrisCore(pykka.ThreadingActor): + error["error_description"] } logger.error( - "Could not fetch Spotify recommendations: " + error["error_description"] + "Could not fetch Spotify recommendations: " + + error["error_description"] ) logger.debug(error) return False @@ -687,7 +743,8 @@ class IrisCore(pykka.ThreadingActor): # Grab our loaded tracks uris = self.radio["results"] - # We've run out of pre-fetched tracks, so we need to get more recommendations + # We've run out of pre-fetched tracks, so we need to get more + # recommendations if len(uris) < 3: uris = self.load_more_tracks() @@ -753,8 +810,10 @@ class IrisCore(pykka.ThreadingActor): for tlid in data["tlids"]: item = { "tlid": tlid, - "added_from": data["added_from"] if "added_from" in data else None, - "added_by": data["added_by"] if "added_by" in data else None, + "added_from": + data["added_from"] if "added_from" in data else None, + "added_by": + data["added_by"] if "added_by" in data else None, } self.queue_metadata["tlid_" + str(tlid)] = item @@ -772,12 +831,12 @@ class IrisCore(pykka.ThreadingActor): return response def clean_queue_metadata(self, *args, **kwargs): - callback = kwargs.get("callback", False) cleaned_queue_metadata = {} for tltrack in self.core.tracklist.get_tl_tracks().get(): - # if we have metadata for this track, push it through to cleaned dictionary + # if we have metadata for this track, push it through to cleaned + # dictionary if "tlid_" + str(tltrack.tlid) in self.queue_metadata: cleaned_queue_metadata[ "tlid_" + str(tltrack.tlid) @@ -811,7 +870,10 @@ class IrisCore(pykka.ThreadingActor): self.save_to_file(self.commands, "commands") self.broadcast( - data={"method": "commands_changed", "params": {"commands": self.commands}} + data={ + "method": "commands_changed", + "params": { + "commands": self.commands}} ) response = {"message": "Commands saved"} @@ -822,14 +884,14 @@ class IrisCore(pykka.ThreadingActor): async def run_command(self, *args, **kwargs): callback = kwargs.get("callback", False) - ioloop = kwargs.get("ioloop", False) data = kwargs.get("data", {}) error = False if str(data["id"]) not in self.commands: error = { "message": "Command failed", - "description": 'Could not find command by ID "' + str(data["id"]) + '"', + "description": r'''Could not find command by ID + "' + str(data["id"]) + '"''', } else: command = self.commands[str(data["id"])] @@ -859,7 +921,8 @@ class IrisCore(pykka.ThreadingActor): d = command["additional_headers"].split("\n") lines = list(filter(lambda x: x.find(":") > 0, d)) fields = [ - (x.split(":", 1)[0].strip().lower(), x.split(":", 1)[1].strip()) + (x.split(":", 1)[0].strip().lower(), + x.split(":", 1)[1].strip()) for x in lines ] headers = dict(fields) @@ -882,8 +945,10 @@ class IrisCore(pykka.ThreadingActor): ) else: request = HTTPRequest( - command["url"], connect_timeout=5, validate_cert=False, headers=headers - ) + command["url"], + connect_timeout=5, + validate_cert=False, + headers=headers) # Make the request, and handle any request errors try: @@ -900,15 +965,18 @@ class IrisCore(pykka.ThreadingActor): # Attempt to parse body as JSON try: command_response_body = json.loads(command_response.body) - except: + except BaseException: # Perhaps it requires unicode encoding? try: - command_response_body = tornado.escape.to_unicode(command_response.body) - except: + command_response_body = tornado.escape.to_unicode( + command_response.body) + except BaseException: command_response_body = "" # Finally, return the result - response = {"message": "Command run", "response": command_response_body} + response = { + "message": "Command run", + "response": command_response_body} if callback: callback(response) @@ -919,16 +987,20 @@ class IrisCore(pykka.ThreadingActor): ## # Spotify authentication # - # Uses the Client Credentials Flow, so is invisible to the user. We need this token for - # any backend spotify requests (we don't tap in to Mopidy-Spotify, yet). Also used for - # passing token to frontend for javascript requests without use of the Authorization Code Flow. + # Uses the Client Credentials Flow, so is invisible to the user. + # We need this token for any backend spotify requests (we don't tap in + # to Mopidy-Spotify, yet). Also used for passing token to frontend for + # javascript requests without use of the Authorization Code Flow. ## async def get_spotify_token(self, *args, **kwargs): callback = kwargs.get("callback", False) # Expired, so go get a new one - if not self.spotify_token or self.spotify_token["expires_at"] <= time.time(): + if ( + not self.spotify_token or + self.spotify_token["expires_at"] <= time.time() + ): await self.refresh_spotify_token() response = {"spotify_token": self.spotify_token} @@ -977,8 +1049,8 @@ class IrisCore(pykka.ThreadingActor): except (urllib.error.HTTPError, urllib.error.URLError) as e: error = json.loads(e.read()) error = { - "message": "Could not refresh token: " + error["error_description"] - } + "message": "Could not refresh token: " + + error["error_description"]} if callback: callback(False, error) @@ -997,9 +1069,10 @@ class IrisCore(pykka.ThreadingActor): ## # Spotify authentication # - # Uses the Client Credentials Flow, so is invisible to the user. We need this token for - # any backend spotify requests (we don't tap in to Mopidy-Spotify, yet). Also used for - # passing token to frontend for javascript requests without use of the Authorization Code Flow. + # Uses the Client Credentials Flow, so is invisible to the user. + # We need this token for any backend spotify requests (we don't tap in + # to Mopidy-Spotify, yet). Also used for passing token to frontend for + # javascript requests without use of the Authorization Code Flow. ## async def get_lyrics(self, *args, **kwargs): @@ -1021,7 +1094,9 @@ class IrisCore(pykka.ThreadingActor): if connection_id not in self.connections: error = { "message": "Unauthorized request", - "description": "Connection " + connection_id + " not connected", + "description": "Connection " + + connection_id + + " not connected", } except Exception as e: @@ -1037,7 +1112,11 @@ class IrisCore(pykka.ThreadingActor): try: http_client = AsyncHTTPClient() http_response = await http_client.fetch(url) - callback(http_response.body.decode("utf-8", errors="replace"), False) + callback( + http_response.body.decode( + "utf-8", + errors="replace"), + False) except (urllib.error.HTTPError, urllib.error.URLError) as e: error = json.loads(e.read()) @@ -1046,7 +1125,8 @@ class IrisCore(pykka.ThreadingActor): + error["error_description"] } logger.error( - "Could not fetch Spotify recommendations: " + error["error_description"] + "Could not fetch Spotify recommendations: " + + error["error_description"] ) logger.debug(error) return error @@ -1075,4 +1155,7 @@ class IrisCore(pykka.ThreadingActor): elif error: self.broadcast(data={"method": "test_updated", "params": update}) else: - self.broadcast(data={"method": "test_finished", "params": response}) + self.broadcast( + data={ + "method": "test_finished", + "params": response}) diff --git a/mopidy_iris/frontend.py b/mopidy_iris/frontend.py index 2a71d9ac..60fcb740 100755 --- a/mopidy_iris/frontend.py +++ b/mopidy_iris/frontend.py @@ -1,6 +1,7 @@ -import pykka, logging, tornado, functools +import pykka +import logging +import functools from mopidy.core import CoreListener -from .core import IrisCore from .mem import iris # import logger @@ -22,7 +23,9 @@ class IrisFrontend(pykka.ThreadingActor, CoreListener): iris.stop() def track_playback_ended(self, tl_track, time_position): - iris.ioloop.add_callback(functools.partial(iris.check_for_radio_update)) + iris.ioloop.add_callback( + functools.partial( + iris.check_for_radio_update)) def tracklist_changed(self): iris.ioloop.add_callback(functools.partial(iris.clean_queue_metadata)) diff --git a/mopidy_iris/handlers.py b/mopidy_iris/handlers.py index e1b9b272..a6519383 100755 --- a/mopidy_iris/handlers.py +++ b/mopidy_iris/handlers.py @@ -1,7 +1,13 @@ from datetime import datetime from tornado.escape import json_encode, json_decode -import tornado.ioloop, tornado.web, tornado.websocket, tornado.template -import random, string, logging, uuid, subprocess, pykka, ast, logging, json, urllib, requests, time, asyncio +import tornado.ioloop +import tornado.web +import tornado.websocket +import tornado.template +import logging +import json +import time +import asyncio from .mem import iris @@ -24,10 +30,12 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): # Get the client's IP. If it's local, then use it's proxy origin ip = self.request.remote_ip - if ip == "127.0.0.1" and hasattr(self.request.headers, "X-Forwarded-For"): + if ip == "127.0.0.1" and hasattr( + self.request.headers, "X-Forwarded-For"): ip = self.request.headers["X-Forwarded-For"] - # Construct our initial client object, and add to our list of connections + # Construct our initial client object, and add to our list of + # connections client = { "connection_id": iris.generateGuid(), "ip": ip, @@ -54,7 +62,8 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): error={ "id": id, "code": 32602, - "message": 'Invalid JSON-RPC request (missing property "jsonrpc")', + "message": r'''Invalid JSON-RPC request (missing + property "jsonrpc")''', }, ) @@ -75,12 +84,15 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): if hasattr(iris, message["method"]): try: - # For async methods we need to await, but it must be ommited for syncronous methods - if asyncio.iscoroutinefunction(getattr(iris, message["method"])): + # For async methods we need to await, but it must be + # ommited for syncronous methods + if asyncio.iscoroutinefunction( + getattr(iris, message["method"])): await getattr(iris, message["method"])( ioloop=self.ioloop, data=params, - callback=lambda response, error=False: self.handle_result( + callback=lambda response, + error=False: self.handle_result( id=id, method=message["method"], response=response, @@ -88,10 +100,13 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): ), ) else: - getattr(iris, message["method"])( + getattr( + iris, + message["method"])( ioloop=self.ioloop, data=params, - callback=lambda response, error=False: self.handle_result( + callback=lambda response, + error=False: self.handle_result( id=id, method=message["method"], response=response, @@ -106,7 +121,9 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): error={ "id": id, "code": 32601, - "message": 'Method "' + message["method"] + '" does not exist', + "message": 'Method "' + + message["method"] + + '" does not exist', }, id=id, ) @@ -142,7 +159,8 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler): request_response["error"] = error # We've been handed an AsyncHTTPClient callback. This is the case - # when our request calls subsequent external requests (eg Spotify, Genius) + # when our request calls subsequent external requests (eg Spotify, + # Genius) elif isinstance(response, tornado.httpclient.HTTPResponse): request_response["result"] = response.body @@ -161,7 +179,8 @@ class HttpHandler(tornado.web.RequestHandler): self.set_header("Access-Control-Allow-Origin", "*") self.set_header( "Access-Control-Allow-Headers", - "Origin, X-Requested-With, Content-Type, Accept, Authorization, Client-Security-Token, Accept-Encoding", + r'''Origin, X-Requested-With, Content-Type, Accept, + Authorization, Client-Security-Token, Accept-Encoding''', ) def initialize(self, core, config): @@ -183,21 +202,29 @@ class HttpHandler(tornado.web.RequestHandler): if hasattr(iris, slug): try: - # For async methods we need to await, but it must be ommited for syncronous methods + # For async methods we need to await, but it must be ommited + # for syncronous methods if asyncio.iscoroutinefunction(getattr(iris, slug)): await getattr(iris, slug)( ioloop=self.ioloop, request=self, - callback=lambda response, error=False: self.handle_result( + callback=lambda response, + error=False: self.handle_result( id=id, method=slug, response=response, error=error ), ) else: - getattr(iris, slug)( + getattr( + iris, + slug)( ioloop=self.ioloop, request=self, - callback=lambda response, error=False: self.handle_result( - id=id, method=slug, response=response, error=error + callback=lambda response, + error=False: self.handle_result( + id=id, + method=slug, + response=response, + error=error ), ) except Exception as e: @@ -206,7 +233,11 @@ class HttpHandler(tornado.web.RequestHandler): else: self.handle_result( id=id, - error={"code": 32601, "message": "Method " + slug + " does not exist"}, + error={ + "code": 32601, + "message": "Method " + + slug + + " does not exist"}, ) return @@ -216,9 +247,10 @@ class HttpHandler(tornado.web.RequestHandler): try: params = json.loads(self.request.body.decode("utf-8")) - except: + except BaseException: self.handle_result( - id=id, error={"code": 32700, "message": "Missing or invalid payload"} + id=id, error={ + "code": 32700, "message": "Missing or invalid payload"} ) return @@ -229,29 +261,41 @@ class HttpHandler(tornado.web.RequestHandler): await getattr(iris, slug)( data=params, request=self.request, - callback=lambda response=False, error=False: self.handle_result( + callback=lambda response=False, + error=False: self.handle_result( id=id, method=slug, response=response, error=error ), ) else: - getattr(iris, slug)( + getattr( + iris, + slug)( data=params, request=self.request, - callback=lambda response=False, error=False: self.handle_result( - id=id, method=slug, response=response, error=error + callback=lambda response=False, + error=False: self.handle_result( + id=id, + method=slug, + response=response, + error=error ), ) - except tornado.web.HTTPError as e: + except tornado.web.HTTPError: self.handle_result( - id=id, error={"code": 32601, "message": "Invalid JSON payload"} + id=id, error={ + "code": 32601, "message": "Invalid JSON payload"} ) return else: self.handle_result( id=id, - error={"code": 32601, "message": "Method " + slug + " does not exist"}, + error={ + "code": 32601, + "message": "Method " + + slug + + " does not exist"}, ) return @@ -271,15 +315,17 @@ class HttpHandler(tornado.web.RequestHandler): self.set_status(400) # We've been handed an AsyncHTTPClient callback. This is the case - # when our request calls subsequent external requests (eg Spotify, Genius). + # when our request calls subsequent external requests. # We don't need to wrap non-HTTPResponse responses as these are dicts elif isinstance(response, tornado.httpclient.HTTPResponse): # Digest JSON responses into JSON content_type = response.headers.get("Content-Type") - if content_type.startswith("application/json") or content_type.startswith( - "text/json" - ): + if content_type.startswith( + "application/json" + ) or content_type.startswith( + "text/json" + ): body = json.loads(response.body) # Non-JSON so just copy as-is diff --git a/mopidy_iris/system.py b/mopidy_iris/system.py index 138a1b49..f061aa3e 100755 --- a/mopidy_iris/system.py +++ b/mopidy_iris/system.py @@ -1,5 +1,8 @@ from threading import Thread -import logging, os, pathlib, subprocess, json, sys +import logging +import os +import pathlib +import subprocess # import logger logger = logging.getLogger(__name__) @@ -14,9 +17,9 @@ class IrisSystemPermissionError(IrisSystemError): def __init__(self, path): message = ( - "Password-less access to %s was refused. Check your /etc/sudoers file." - % path.as_uri() - ) + r'''Password-less access to %s was refused. + Check your /etc/sudoers file.''' % + path.as_uri()) logger.error(message) super().__init__(message) @@ -63,7 +66,8 @@ class IrisSystemThread(Thread): command = self.get_command() logger.debug("Running '%s'", os.fsdecode(b" ".join(command))) - process = subprocess.Popen(command, stdout=subprocess.PIPE, encoding="utf8") + process = subprocess.Popen( + command, stdout=subprocess.PIPE, encoding="utf8") lines = "" while True: @@ -73,8 +77,6 @@ class IrisSystemThread(Thread): if line: logger.info(line) lines = lines + "\n" + line - # This seems to be ignored. Detected as spammy io? - # self.ioloop.add_callback(lambda: self.callback(None, None, {'output': line})) if process.returncode == 0: self.ioloop.add_callback( @@ -92,10 +94,14 @@ class IrisSystemThread(Thread): ## def can_run(self, *args, **kwargs): # Attempt an empty call to our system file - command_bytes = b" ".join(self.get_command("check", non_interactive=True)) + command_bytes = b" ".join( + self.get_command( + "check", non_interactive=True)) process = subprocess.Popen( - command_bytes, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True - ) + command_bytes, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True) result, error = process.communicate() exitCode = process.wait()