This commit is contained in:
@@ -24,6 +24,7 @@ import config
|
||||
from controller import Controller, TargetError
|
||||
from heos import HeosError
|
||||
from spotify import SpotifyClient, SpotifyError
|
||||
from zidoo import ZidooError
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@@ -80,7 +81,7 @@ def handle_errors(view):
|
||||
return view(*args, **kwargs)
|
||||
except (TargetError, ValueError) as exc:
|
||||
return jsonify({"error": str(exc)}), 400
|
||||
except (HeosError, SpotifyError) as exc:
|
||||
except (HeosError, SpotifyError, ZidooError) as exc:
|
||||
return jsonify({"error": str(exc)}), 502
|
||||
return wrapped
|
||||
|
||||
@@ -122,15 +123,11 @@ def _spotify_name(key: str) -> str:
|
||||
return target.get("spotify_name", target["heos_name"])
|
||||
|
||||
|
||||
def _mark_spotify_accounts(rooms: list):
|
||||
"""Tag each room HEOS says is on Spotify with the account playing it, so
|
||||
its card can pick out that account's button. Spotify is only asked when
|
||||
some room is on Spotify at all, and an account it refuses (a revoked
|
||||
token, say) just matches nothing instead of failing the whole poll."""
|
||||
on_spotify = [room for room in rooms if room.get("spotify")]
|
||||
if not (spotify and on_spotify):
|
||||
return
|
||||
playing_on = {} # device name -> account key
|
||||
def _spotify_playing_on() -> dict:
|
||||
"""Device name -> the key of the account playing on it. An account
|
||||
Spotify refuses (a revoked token, say) just plays on nothing, instead of
|
||||
failing whatever asked."""
|
||||
playing_on = {}
|
||||
for account, client in spotify.items():
|
||||
try:
|
||||
player = client.playback()
|
||||
@@ -140,6 +137,17 @@ def _mark_spotify_accounts(rooms: list):
|
||||
# Should two accounts both claim a device, the one actually playing wins.
|
||||
if device and (device not in playing_on or player.get("is_playing")):
|
||||
playing_on[device] = account
|
||||
return playing_on
|
||||
|
||||
|
||||
def _mark_spotify_accounts(rooms: list):
|
||||
"""Tag each room HEOS says is on Spotify with the account playing it, so
|
||||
its card can pick out that account's button. Spotify is only asked when
|
||||
some room is on Spotify at all."""
|
||||
on_spotify = [room for room in rooms if room.get("spotify")]
|
||||
if not (spotify and on_spotify):
|
||||
return
|
||||
playing_on = _spotify_playing_on()
|
||||
for room in on_spotify:
|
||||
room["spotify_account"] = playing_on.get(_spotify_name(room["key"]))
|
||||
|
||||
@@ -274,6 +282,27 @@ def api_skip():
|
||||
return jsonify({"target": key, "direction": direction})
|
||||
|
||||
|
||||
@app.post("/api/seek")
|
||||
@handle_errors
|
||||
def api_seek():
|
||||
"""Jump to a point in what a card is playing. HEOS itself cannot seek,
|
||||
so this goes around it: to the Zidoo for the AVR's card, and for a room,
|
||||
to Spotify, through whichever of your accounts is playing there."""
|
||||
data = _payload()
|
||||
key = _target_from(data)
|
||||
if data.get("position_ms") is None:
|
||||
raise ValueError("Provide 'position_ms', where to jump to")
|
||||
position = max(0, int(data["position_ms"]))
|
||||
if key == config.HOST_KEY:
|
||||
controller.zidoo_seek(position)
|
||||
else:
|
||||
account = _spotify_playing_on().get(_spotify_name(key))
|
||||
if account is None:
|
||||
raise ValueError("Only a Spotify stream one of your accounts is playing can seek -- HEOS itself cannot")
|
||||
spotify[account].seek(position)
|
||||
return jsonify({"target": key, "position_ms": position})
|
||||
|
||||
|
||||
@app.post("/api/group")
|
||||
@handle_errors
|
||||
def api_group():
|
||||
|
||||
Reference in New Issue
Block a user