def on_play_random_mix(self, intent, session, pid=None): server = self._server try: slots = [ v.get('value') for k, v in intent['slots'].items() if k.endswith('Genre') ] print_d("Extracted genre slots: {slots}", slots=slots) except KeyError: print_d("Couldn't process genres from: {intent}", intent=intent) else: lms_genres = self._genres_from_slots(slots, server.genres) if lms_genres: server.play_genres(lms_genres, player_id=pid) gs = english_join(sanitise_text(g) for g in lms_genres) text = _("Playing mix of {genres}").format(genres=gs) return self.smart_response(text=text, speech=text) else: genres_text = english_join(slots, _("or")) text = _("Don't understand requested genres {genres}").format( genres=genres_text) speech = _("Can't find genres: {genres}").format( genres=genres_text) return self.smart_response(text=text, speech=speech) err_text = "Don't understand intent '{intent}'".format(intent=intent) raise ValueError(err_text)
def on_play_artist(self, intent, session, pid=None): server = self._server try: artist = intent['slots']['Artist']['value'] print_d("Extracted artist slot: {}".format(artist)) except KeyError: print_d("Couldn't process artist from: {intent}", intent=intent) return speech_response(text=_("Couldn't process that artist. ")) else: matched_artists = server.search_for_artist(artist) print_d( "Found Matching artists on squeezebox server " "{matched_artists}", matched_artists=matched_artists) try: server.play_artist(matched_artists[0], player_id=pid) artist_name = sanitise_text(matched_artists[0]) text = _( "Playing albums by \"{artist_name}\" on squeezebox".format( artist_name=artist_name)) return self.smart_response(text=text, speech=text) except KeyError: return speech_response( text=_("Couldn't find the artist on squeezebox. ")) raise ValueError("Don't understand intent '{}'".format(intent))
def on_select_player(self, intent, session, pid=None): srv = self._server srv.refresh_status() # Do it again, yes, but not defaulting this time. pid = self.player_id_from(intent, defaulting=False) if pid: player = srv.players[pid] srv.cur_player_id = player.id text = _("Selected {player}").format(player=player.name) title = _("Selected player {player}").format(player=player) return speech_response(title=title, text=text, store={"player_id": pid}) speech = (_("I only found these players: {players}. " "Could you try again?").format( players=english_join(srv.player_names))) reprompt = (_("You can select a player by saying \"{utterance}\" " "and then the player name.").format( utterance=Utterances.SELECT_PLAYER)) try: player = intent['slots']['Player']['value'] title = (_("No player called \"{name}\"").format(name=player)) except KeyError: title = "Didn't recognise a player name" return speech_response(title, speech, reprompt_text=reprompt, end=False)
def on_player_off(self, intent, session, pid=None): if not pid: return self.on_all_off(intent, session) server = self._server server.set_power(on=False, player_id=pid) player = server.players[pid] text = _("Switched {player} off").format(player=player.name) speech = _("{player} is now off").format(player=player.name) return self.smart_response(title=text, text=text, speech=speech)
def on_launch(self, launch_request, session): print_d("Entering interactive mode for sessionId={}", session['sessionId']) speech_output = _("Squeezebox is online. Please try some commands.") reprompt_text = _("Try resume, pause, next, previous, play some jazz, " "or ask Squeezebox to turn it up or down") return speech_response("Welcome", speech_output, reprompt_text, end=False)
def on_current(self, intent, session, pid=None): details = self._server.get_track_details(player_id=pid) title = details['current_title'] artist = details['artist'] if title: desc = _("Currently playing: \"{title}\"").format(title=title) if artist: desc += _(", by {artist}").format(artist=artist) heading = _("Now playing: \"{title}\"").format(title=title) else: desc = _("Nothing playing.") heading = None return self.smart_response(text=heading, speech=desc)
def now_playing(self, intent, session, pid=None): details = self._server.get_track_details(player_id=pid) title = details.get('title', [None])[0] artists = people_from(details) if title: desc = _("Currently playing: \"{title}\"").format(title=title) if artists: desc += _(", by {artists}.").format( artists=human_join(artists)) heading = _("Now playing: \"{title}\"").format(title=title) else: desc = _("Nothing playing.") heading = None return self.smart_response(text=heading, speech=desc)
def on_intent(self, intent_request, session): intent = intent_request['intent'] intent_name = intent['name'] pid = self.player_id_from(intent) print_d("Received {intent_name}: {intent} (for player {pid})", **locals()) intent_handler = handler.for_name(intent_name) if intent_handler: return intent_handler(self, intent, session, pid=pid) speech = _("Sorry, I don't know how to process a \"{intent}\"").format( intent=intent_name) text = _("Unknown intent: '{intent}'").format(intent=intent_name) return self.smart_response(speech=speech, text=text)
def __init__(self, transport, user=None, password=None, cur_player_id=None, debug=False): self.transport = transport self._debug = debug self.user = user self.password = password if user and password: self.log_in() print_d("Authenticated with %s!" % self) self.players = {} self.refresh_status() players = list(self.players.values()) if not players: raise SqueezeboxException(_("Uh-oh. No connected players found.")) if not cur_player_id: self.cur_player_id = players[0].id elif cur_player_id not in self.players: print_w( "Couldn't find player {id} (found: {all}). " "Check your DEFAULT_PLAYER config.", id=cur_player_id, all=", ".join(list(self.players.keys()))) self.cur_player_id = players[0].id else: self.cur_player_id = cur_player_id print_d("Current player is now: {player}", player=self.players[self.cur_player_id]) self.__genres = [] self.__playlists = [] self.__favorites = []
def english_join(items, final=_("and")): """Like join, but in English (no Oxford commas...) Kinda works in some other languages (French, German)""" items = list(filter(None, items)) most = ", ".join(items[0:-1]) sep = " %s " % final.strip() return sep.join(filter(None, [most] + items[-1:]))
def lambda_handler(event, context): """ Route the incoming request based on type (LaunchRequest, IntentRequest, etc.) The JSON body of the request is provided in the event parameter. """ sqa = SqueezeAlexa(app_id=APPLICATION_ID) try: return sqa.handle(event, context) except Exception as e: if not settings.USE_SPOKEN_ERRORS: raise e # Work with AWS stack-trace log magic print_w(format_exc().replace('\n', '\r')) error = str(e.msg if hasattr(e, "msg") else e) return speech_response(title=_("All went wrong"), text=_("Oh dear: {type}. {message}").format( type=type(e).__name__, message=error))
def lambda_handler(event, context, server=None): """ Route the incoming request based on type (LaunchRequest, IntentRequest, etc.) The JSON body of the request is provided in the event parameter. """ try: sqa = SqueezeAlexa(server=server or get_server(), app_id=SKILL_SETTINGS.application_id) return sqa.handle(event, context) except Exception as e: if not SKILL_SETTINGS.use_spoken_errors: raise e # Work with AWS stack-trace log magic print(format_exc().replace('\n', '\r')) error = str(e.msg if hasattr(e, "msg") else e) text = _("Oh dear: {type}. {message}").format( type=type(e).__name__, message=error) return speech_response(title=_("All went wrong"), text=text)
def on_set_vol(self, intent, session, pid=None): try: vol = float(intent['slots']['Volume']['value']) print_d("Extracted volume slot: {:1f}", vol) except KeyError: print_d("Couldn't process volume from: {!s}", intent) desc = _("Select a volume value between 0 and 10") heading = _("Invalid volume value") return self.smart_response(text=heading, speech=desc) if (vol > 10) or (vol < 0): desc = _("Select a volume value between 0 and 10") heading = _("Volume value out of range: {volume}").format(vol) return self.smart_response(text=heading, speech=desc) self._server.set_volume(vol * 10, pid) desc = "OK" vol_out = vol if (vol != int(vol)) else int(vol) heading = _("Set volume to {}").format(vol_out) return self.smart_response(text=heading, speech=desc)
def on_player_on(self, intent, session, pid=None): if not pid: return self.on_all_on(intent, session) server = self._server server.set_power(on=True, player_id=pid) player = server.players[pid] speech = "{player} is now on".format(player=player.name) if server.cur_player_id != pid: speech += ", and is selected." server.cur_player_id = pid text = _("Switched {player} on").format(player=player.name) return self.smart_response(title=text, text=text, speech=speech)
def on_play_playlist(self, intent, session, pid=None): server = self._server try: slot = intent['slots']['Playlist']['value'] print_d("Extracted playlist slot: {slot}", slot=slot) except KeyError: print_d("Couldn't process playlist from: {intent}", intent=intent) if not server.playlists: return speech_response(text=_("There are no playlists")) pl = random.choice(server.playlists) text = _("Didn't hear a playlist there. " "You could try the \"{name}\" playlist?").format(name=pl) return speech_response(text=text) else: if not server.playlists: return speech_response(text=_("No Squeezebox playlists found")) result = process.extractOne(slot, server.playlists) print_d("{guess} was the best guess for '{slot}' from {choices}", guess=str(result), slot=slot, choices=server.playlists) if result and int(result[1]) >= MinConfidences.PLAYLIST: pl = result[0] server.playlist_resume(pl, player_id=pid) name = sanitise_text(pl) return self.smart_response( speech=_("Playing \"{name}\" playlist").format(name=name), text=_("Playing \"{name}\" playlist").format(name=name)) pl = random.choice(server.playlists) template = _("Couldn't find a playlist matching \"{name}\"." "How about the \"{suggestion}\" playlist?") return speech_response(template.format(name=slot, suggestion=pl))
def wait_for(func, timeout=3, what=None, context=None, exc_cls=Exception): nt = t = perf_counter() while not func(context): sleep(0.05) nt = perf_counter() if nt - t > timeout: msg = _("Failed \"{task}\", " "after {secs:.1f} seconds").format(task=what, context=str(context), secs=nt - t) raise exc_cls(msg) print_d("Task \"{task}\" took < {duration:.2f} seconds", task=what, duration=nt - t)
def refresh_status(self): """ Updates the list of the Squeezebox players available and other server metadata.""" print_d("Refreshing server and player statuses.") response = self.__a_request("serverstatus 0 99", raw=True) self.players = {} for data in self._groups(response, 'playerid', extra_bools=['power', 'connected']): if data.get('connected', False): self.players[data['playerid']] = SqueezeboxPlayerSettings(data) print_d("Found {total} connected player(s): {players}", total=len(self.players), players=[p.get('name', _("Unknown player")) for p in self.players.values()]) if self._debug: print_d("Player(s): {players}", players=self.players.values())
def on_set_vol_percent(self, intent, session, pid=None): try: vol = int(float(intent['slots']['Volume']['value'])) print_d("Extracted volume slot: %d".format(vol)) except KeyError: print_d("Couldn't process volume from: {}", intent) desc = _("Select a volume value between 0 and 100 percent") heading = _("Invalid volume value") return self.smart_response(text=heading, speech=desc) if (vol > 100) or (vol < 0): desc = _("Select a volume value between 0 and 100 percent") heading = _("Volume value out of range: %d percent").format(vol) return self.smart_response(text=heading, speech=desc) self._server.set_volume(vol, pid) desc = _("OK") heading = _("Set Volume to %d percent").format(vol) return self.smart_response(text=heading, speech=desc)
def on_dec_vol(self, intent, session, pid=None): self._server.change_volume(-12.5, player_id=pid) return self.smart_response(text=_("Decrease Volume"), speech=_("OK, quieter now."))
def test_binding_uses_settings_locale(): with NewLocale("fr_FR"): _ = set_up_gettext("en_GB.UTF-8") assert _("favorites") == "favourites"
def test_gettext_uses_fallback(): _ = set_up_gettext("fr_FR.UTF-8") assert _("favorites") == "favorites"
def test_binding_respects_language(): _ = set_up_gettext("en_US.UTF-8") assert _("favorites") == "favorites"
def test_gettext_basic(): assert _(AN_UNTRANSLATED_STRING) == AN_UNTRANSLATED_STRING
def on_shuffle_off(self, intent, session, pid=None): self._server.set_shuffle(False, player_id=pid) return self.smart_response(text=_("Shuffle off"), speech=_("Shuffle is now off"))
def on_loop_off(self, intent, session, pid=None): self._server.set_repeat(False, player_id=pid) return self.smart_response(text=_("Repeat Off"), speech=_("Repeat is now off"))
def on_session_ended(self, intent, session): print_d("Session {id} ended", id=session['sessionId']) speech_output = _("Hasta la vista. Baby.") return speech_response("Session Ended", speech_output, end=True)
def on_inc_vol(self, intent, session, pid=None): self._server.change_volume(+12.5, player_id=pid) return self.smart_response(text=_("Increase Volume"), speech=_("Pumped it up."))
def on_all_on(self, intent, session, pid=None): self._server.set_all_power(on=True) return self.smart_response(text=_("All On."), speech=_("Ready to rock"))
from squeezealexa.alexa.response import speech_response from squeezealexa.main import SqueezeAlexa from squeezealexa.settings import SKILL_SETTINGS, LMS_SETTINGS from squeezealexa.squeezebox.server import ServerFactory from squeezealexa.transport.factory import TransportFactory try: from squeezealexa.i18n import _ except ImportError: def _(s): return s ERROR_SPEECH = _("<speak><say-as interpret-as='interjection'>d'oh</say-as>: " "{type} - {message}.</speak>") factory = ServerFactory(TransportFactory()) def get_server(): return factory.create(user=LMS_SETTINGS.username, password=LMS_SETTINGS.password, cur_player_id=LMS_SETTINGS.default_player, debug=LMS_SETTINGS.debug) def lambda_handler(event, context, server=None): """ Route the incoming request based on type (LaunchRequest, IntentRequest, etc.) The JSON body of the request is provided in the event parameter. """
def on_all_off(self, intent, session, pid=None): self._server.set_all_power(on=False) return self.smart_response(text=_("Players all off"), speech=_("Silence."))