Black run
This commit is contained in:
@ -40,8 +40,8 @@ class Extension(ext.Extension):
|
||||
|
||||
# Add web extension
|
||||
registry.add(
|
||||
"http:app", {
|
||||
"name": self.ext_name, "factory": iris_factory})
|
||||
"http:app", {"name": self.ext_name, "factory": iris_factory}
|
||||
)
|
||||
|
||||
# Add our frontend
|
||||
registry.add("frontend", IrisFrontend)
|
||||
|
||||
@ -119,8 +119,9 @@ 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
|
||||
@ -242,8 +243,11 @@ 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:
|
||||
@ -286,8 +290,8 @@ class IrisCore(pykka.ThreadingActor):
|
||||
self.broadcast(
|
||||
data={
|
||||
"method": "connection_added",
|
||||
"params": {
|
||||
"connection": client}}
|
||||
"params": {"connection": client},
|
||||
}
|
||||
)
|
||||
|
||||
def update_connection(self, *args, **kwargs):
|
||||
@ -304,11 +308,11 @@ class IrisCore(pykka.ThreadingActor):
|
||||
data={
|
||||
"method": "connection_changed",
|
||||
"params": {
|
||||
"connection":
|
||||
self.connections[connection_id]["client"]},
|
||||
})
|
||||
response = {
|
||||
"connection": self.connections[connection_id]["client"]}
|
||||
"connection": self.connections[connection_id]["client"]
|
||||
},
|
||||
}
|
||||
)
|
||||
response = {"connection": self.connections[connection_id]["client"]}
|
||||
if callback:
|
||||
callback(response)
|
||||
else:
|
||||
@ -350,12 +354,14 @@ class IrisCore(pykka.ThreadingActor):
|
||||
data={
|
||||
"method": "connection_changed",
|
||||
"params": {
|
||||
"connection":
|
||||
self.connections[connection_id]["client"]},
|
||||
})
|
||||
"connection": self.connections[connection_id]["client"]
|
||||
},
|
||||
}
|
||||
)
|
||||
response = {
|
||||
"connection_id": connection_id,
|
||||
"username": data["username"]}
|
||||
"username": data["username"],
|
||||
}
|
||||
if callback:
|
||||
callback(response)
|
||||
else:
|
||||
@ -469,15 +475,11 @@ 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})
|
||||
data={"method": "restart_finished", "params": response}
|
||||
)
|
||||
|
||||
##
|
||||
# Run an upgrade of Iris
|
||||
@ -502,15 +504,11 @@ 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})
|
||||
data={"method": "upgrade_finished", "params": response}
|
||||
)
|
||||
self.restart()
|
||||
|
||||
##
|
||||
@ -522,10 +520,7 @@ 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"})
|
||||
|
||||
@ -537,20 +532,15 @@ 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})
|
||||
data={"method": "local_scan_updated", "params": update}
|
||||
)
|
||||
else:
|
||||
self.broadcast(
|
||||
data={
|
||||
"method": "local_scan_finished",
|
||||
"params": response})
|
||||
data={"method": "local_scan_finished", "params": response}
|
||||
)
|
||||
|
||||
##
|
||||
# Spotify Radio
|
||||
@ -624,15 +614,15 @@ class IrisCore(pykka.ThreadingActor):
|
||||
self.broadcast(
|
||||
data={
|
||||
"method": "radio_started",
|
||||
"params": {
|
||||
"radio": self.radio}}
|
||||
"params": {"radio": self.radio},
|
||||
}
|
||||
)
|
||||
else:
|
||||
self.broadcast(
|
||||
data={
|
||||
"method": "radio_changed",
|
||||
"params": {
|
||||
"radio": self.radio}}
|
||||
"params": {"radio": self.radio},
|
||||
}
|
||||
)
|
||||
|
||||
self.get_radio(callback=callback)
|
||||
@ -691,29 +681,30 @@ 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)
|
||||
|
||||
@ -730,8 +721,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
|
||||
@ -810,17 +801,19 @@ 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
|
||||
|
||||
self.broadcast(
|
||||
data={
|
||||
"method": "queue_metadata_changed",
|
||||
"params": {"queue_metadata": self.queue_metadata},
|
||||
"params": {
|
||||
"queue_metadata": self.queue_metadata
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@ -873,7 +866,9 @@ class IrisCore(pykka.ThreadingActor):
|
||||
data={
|
||||
"method": "commands_changed",
|
||||
"params": {
|
||||
"commands": self.commands}}
|
||||
"commands": self.commands
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
response = {"message": "Commands saved"}
|
||||
@ -890,8 +885,8 @@ class IrisCore(pykka.ThreadingActor):
|
||||
if str(data["id"]) not in self.commands:
|
||||
error = {
|
||||
"message": "Command failed",
|
||||
"description": r'''Could not find command by ID
|
||||
"' + str(data["id"]) + '"''',
|
||||
"description": "Could not find command by ID "
|
||||
+ '"' + str(data["id"]) + '"',
|
||||
}
|
||||
else:
|
||||
command = self.commands[str(data["id"])]
|
||||
@ -921,8 +916,7 @@ 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)
|
||||
@ -948,7 +942,8 @@ class IrisCore(pykka.ThreadingActor):
|
||||
command["url"],
|
||||
connect_timeout=5,
|
||||
validate_cert=False,
|
||||
headers=headers)
|
||||
headers=headers,
|
||||
)
|
||||
|
||||
# Make the request, and handle any request errors
|
||||
try:
|
||||
@ -969,14 +964,13 @@ class IrisCore(pykka.ThreadingActor):
|
||||
# Perhaps it requires unicode encoding?
|
||||
try:
|
||||
command_response_body = tornado.escape.to_unicode(
|
||||
command_response.body)
|
||||
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)
|
||||
@ -998,8 +992,8 @@ class IrisCore(pykka.ThreadingActor):
|
||||
|
||||
# Expired, so go get a new one
|
||||
if (
|
||||
not self.spotify_token or
|
||||
self.spotify_token["expires_at"] <= time.time()
|
||||
not self.spotify_token
|
||||
or self.spotify_token["expires_at"] <= time.time()
|
||||
):
|
||||
await self.refresh_spotify_token()
|
||||
|
||||
@ -1036,7 +1030,9 @@ class IrisCore(pykka.ThreadingActor):
|
||||
self.broadcast(
|
||||
data={
|
||||
"method": "spotify_token_changed",
|
||||
"params": {"spotify_token": self.spotify_token},
|
||||
"params": {
|
||||
"spotify_token": self.spotify_token
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@ -1049,8 +1045,9 @@ 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)
|
||||
@ -1094,9 +1091,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:
|
||||
@ -1113,10 +1110,8 @@ class IrisCore(pykka.ThreadingActor):
|
||||
http_client = AsyncHTTPClient()
|
||||
http_response = await http_client.fetch(url)
|
||||
callback(
|
||||
http_response.body.decode(
|
||||
"utf-8",
|
||||
errors="replace"),
|
||||
False)
|
||||
http_response.body.decode("utf-8", errors="replace"), False
|
||||
)
|
||||
|
||||
except (urllib.error.HTTPError, urllib.error.URLError) as e:
|
||||
error = json.loads(e.read())
|
||||
@ -1125,8 +1120,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
|
||||
@ -1155,7 +1150,4 @@ 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})
|
||||
|
||||
@ -23,9 +23,7 @@ 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))
|
||||
|
||||
@ -31,7 +31,8 @@ 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"):
|
||||
self.request.headers, "X-Forwarded-For"
|
||||
):
|
||||
ip = self.request.headers["X-Forwarded-For"]
|
||||
|
||||
# Construct our initial client object, and add to our list of
|
||||
@ -62,8 +63,8 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
error={
|
||||
"id": id,
|
||||
"code": 32602,
|
||||
"message": r'''Invalid JSON-RPC request (missing
|
||||
property "jsonrpc")''',
|
||||
"message": r"""Invalid JSON-RPC request (missing
|
||||
property "jsonrpc")""",
|
||||
},
|
||||
)
|
||||
|
||||
@ -87,12 +88,12 @@ class WebsocketHandler(tornado.websocket.WebSocketHandler):
|
||||
# For async methods we need to await, but it must be
|
||||
# ommited for syncronous methods
|
||||
if asyncio.iscoroutinefunction(
|
||||
getattr(iris, message["method"])):
|
||||
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,
|
||||
@ -100,13 +101,10 @@ 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,
|
||||
@ -121,9 +119,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,
|
||||
)
|
||||
@ -179,8 +177,8 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
self.set_header("Access-Control-Allow-Origin", "*")
|
||||
self.set_header(
|
||||
"Access-Control-Allow-Headers",
|
||||
r'''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):
|
||||
@ -208,23 +206,16 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
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:
|
||||
@ -235,9 +226,8 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
id=id,
|
||||
error={
|
||||
"code": 32601,
|
||||
"message": "Method " +
|
||||
slug +
|
||||
" does not exist"},
|
||||
"message": "Method " + slug + " does not exist",
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
@ -249,8 +239,8 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
params = json.loads(self.request.body.decode("utf-8"))
|
||||
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
|
||||
|
||||
@ -261,30 +251,23 @@ 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:
|
||||
self.handle_result(
|
||||
id=id, error={
|
||||
"code": 32601, "message": "Invalid JSON payload"}
|
||||
id=id,
|
||||
error={"code": 32601, "message": "Invalid JSON payload"},
|
||||
)
|
||||
return
|
||||
|
||||
@ -293,9 +276,8 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
id=id,
|
||||
error={
|
||||
"code": 32601,
|
||||
"message": "Method " +
|
||||
slug +
|
||||
" does not exist"},
|
||||
"message": "Method " + slug + " does not exist",
|
||||
},
|
||||
)
|
||||
return
|
||||
|
||||
@ -322,10 +304,8 @@ class HttpHandler(tornado.web.RequestHandler):
|
||||
# Digest JSON responses into JSON
|
||||
content_type = response.headers.get("Content-Type")
|
||||
if content_type.startswith(
|
||||
"application/json"
|
||||
) or content_type.startswith(
|
||||
"text/json"
|
||||
):
|
||||
"application/json"
|
||||
) or content_type.startswith("text/json"):
|
||||
body = json.loads(response.body)
|
||||
|
||||
# Non-JSON so just copy as-is
|
||||
|
||||
@ -17,9 +17,10 @@ class IrisSystemPermissionError(IrisSystemError):
|
||||
|
||||
def __init__(self, path):
|
||||
message = (
|
||||
r'''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)
|
||||
|
||||
@ -67,7 +68,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")
|
||||
command, stdout=subprocess.PIPE, encoding="utf8"
|
||||
)
|
||||
|
||||
lines = ""
|
||||
while True:
|
||||
@ -95,13 +97,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))
|
||||
self.get_command("check", non_interactive=True)
|
||||
)
|
||||
process = subprocess.Popen(
|
||||
command_bytes,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=True)
|
||||
shell=True,
|
||||
)
|
||||
result, error = process.communicate()
|
||||
exitCode = process.wait()
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ from mopidy_iris import handlers
|
||||
from mopidy_iris import core
|
||||
from mopidy_iris.mem import iris
|
||||
|
||||
|
||||
|
||||
def async_return_helper(result):
|
||||
f = Future()
|
||||
f.set_result(result)
|
||||
@ -22,22 +22,13 @@ class HttpHandlerTest(tornado.testing.AsyncHTTPTestCase):
|
||||
@pytest.fixture(autouse=True)
|
||||
def inject_fixtures(self, caplog):
|
||||
self._caplog = caplog
|
||||
|
||||
|
||||
def get_app(self):
|
||||
http_handler = handlers.HttpHandler
|
||||
# http_handler.handle_result = mock.Mock()
|
||||
# self.handler_mock = http_handler.handle_result
|
||||
return tornado.web.Application(
|
||||
[
|
||||
(
|
||||
r"/(.*)",
|
||||
http_handler,
|
||||
{
|
||||
'core': None,
|
||||
'config': {},
|
||||
},
|
||||
)
|
||||
]
|
||||
[(r"/(.*)", http_handler, {"core": None, "config": {},},)]
|
||||
)
|
||||
|
||||
def test_get_method(self):
|
||||
@ -69,7 +60,7 @@ class HttpHandlerTest(tornado.testing.AsyncHTTPTestCase):
|
||||
iris_mock.foo = mock.Mock()
|
||||
|
||||
response = self.fetch("/foo", method="GET")
|
||||
|
||||
|
||||
iris_mock.foo.assert_called_once()
|
||||
assert 200 == response.code
|
||||
|
||||
@ -78,14 +69,14 @@ class HttpHandlerTest(tornado.testing.AsyncHTTPTestCase):
|
||||
iris_mock.foo = mock.Mock(side_effect=Exception("bar"))
|
||||
|
||||
response = self.fetch("/foo", method="GET")
|
||||
|
||||
|
||||
iris_mock.foo.assert_called_once()
|
||||
assert 200 == response.code
|
||||
assert "bar" in self._caplog.text
|
||||
|
||||
@mock.patch.object(handlers.iris, "do_fetch")
|
||||
def test_get_method_with_fetch(self, fetch_mock):
|
||||
iris.config = {"spotify" : {"client_id": 123, "client_secret": 456}}
|
||||
iris.config = {"spotify": {"client_id": 123, "client_secret": 456}}
|
||||
result = mock.Mock(spec=HTTPResponse, body='{"expires_in":88}')
|
||||
fetch_mock.return_value = async_return_helper(result)
|
||||
|
||||
|
||||
@ -5,54 +5,55 @@ from mopidy_iris.system import IrisSystemThread, IrisSystemPermissionError
|
||||
|
||||
|
||||
def test_system_sh_path():
|
||||
iris_system = IrisSystemThread('foo', None, None)
|
||||
iris_system = IrisSystemThread("foo", None, None)
|
||||
assert iris_system.script_path.is_file()
|
||||
assert iris_system.script_path.name == "system.sh"
|
||||
|
||||
|
||||
def test_can_run():
|
||||
iris_system = IrisSystemThread('foo', None, None)
|
||||
iris_system = IrisSystemThread("foo", None, None)
|
||||
iris_system._USE_SUDO = False
|
||||
assert iris_system.can_run() is True
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def popen_mock():
|
||||
patcher = mock.patch("subprocess.Popen", spec=True)
|
||||
yield patcher.start()
|
||||
patcher.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def process_mock(popen_mock):
|
||||
mock_process = popen_mock.return_value
|
||||
mock_process.communicate.return_value = ('', None)
|
||||
mock_process.communicate.return_value = ("", None)
|
||||
mock_process.wait.return_value = 0
|
||||
yield mock_process
|
||||
|
||||
|
||||
def test_can_run_args(popen_mock, process_mock):
|
||||
IrisSystemThread('foo', None, None).can_run()
|
||||
IrisSystemThread("foo", None, None).can_run()
|
||||
popen_mock.assert_called_once_with(
|
||||
mock.ANY,
|
||||
shell=True,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE
|
||||
mock.ANY, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE
|
||||
)
|
||||
|
||||
|
||||
def test_can_run_uses_sudo_non_interactive(popen_mock, process_mock):
|
||||
IrisSystemThread('foo', None, None).can_run()
|
||||
IrisSystemThread("foo", None, None).can_run()
|
||||
|
||||
popen_mock.assert_called_once()
|
||||
assert popen_mock.call_args[0][0].startswith(b"sudo -n ")
|
||||
|
||||
|
||||
def test_can_run_calls_script_check(popen_mock, process_mock):
|
||||
IrisSystemThread('foo', None, None).can_run()
|
||||
IrisSystemThread("foo", None, None).can_run()
|
||||
|
||||
assert popen_mock.call_args[0][0].endswith(b"system.sh check")
|
||||
|
||||
|
||||
def test_can_run_sudo_refused_raises(popen_mock, process_mock, caplog):
|
||||
process_mock.wait.return_value = 1
|
||||
iris_system = IrisSystemThread('foo', None, None)
|
||||
iris_system = IrisSystemThread("foo", None, None)
|
||||
|
||||
with pytest.raises(IrisSystemPermissionError) as excinfo:
|
||||
iris_system.can_run()
|
||||
@ -66,20 +67,18 @@ def test_can_run_sudo_refused_raises(popen_mock, process_mock, caplog):
|
||||
|
||||
|
||||
def test_run_args(popen_mock, process_mock):
|
||||
iris_system = IrisSystemThread('foo', mock.Mock(), None)
|
||||
iris_system.can_run = mock.Mock(return_value = True)
|
||||
iris_system = IrisSystemThread("foo", mock.Mock(), None)
|
||||
iris_system.can_run = mock.Mock(return_value=True)
|
||||
iris_system.run()
|
||||
|
||||
popen_mock.assert_called_once_with(
|
||||
mock.ANY,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE
|
||||
mock.ANY, stderr=subprocess.PIPE, stdout=subprocess.PIPE
|
||||
)
|
||||
|
||||
|
||||
def test_run_uses_sudo(popen_mock, process_mock):
|
||||
iris_system = IrisSystemThread('foo', mock.Mock(), None)
|
||||
iris_system.can_run = mock.Mock(return_value = True)
|
||||
iris_system = IrisSystemThread("foo", mock.Mock(), None)
|
||||
iris_system.can_run = mock.Mock(return_value=True)
|
||||
iris_system.run()
|
||||
|
||||
popen_mock.assert_called_once()
|
||||
|
||||
Reference in New Issue
Block a user