Exemple #1
0
 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)
Exemple #2
0
 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))
Exemple #3
0
    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)
Exemple #4
0
 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)
Exemple #5
0
    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)
Exemple #6
0
 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)
Exemple #7
0
 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)
Exemple #8
0
    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)
Exemple #9
0
    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 = []
Exemple #10
0
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:]))
Exemple #11
0
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))
Exemple #12
0
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)
Exemple #13
0
 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)
Exemple #14
0
 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)
Exemple #15
0
 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))
Exemple #16
0
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)
Exemple #17
0
 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())
Exemple #18
0
 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)
Exemple #19
0
 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."))
Exemple #20
0
def test_binding_uses_settings_locale():
    with NewLocale("fr_FR"):
        _ = set_up_gettext("en_GB.UTF-8")
        assert _("favorites") == "favourites"
Exemple #21
0
def test_gettext_uses_fallback():
    _ = set_up_gettext("fr_FR.UTF-8")
    assert _("favorites") == "favorites"
Exemple #22
0
def test_binding_respects_language():
    _ = set_up_gettext("en_US.UTF-8")
    assert _("favorites") == "favorites"
Exemple #23
0
def test_gettext_basic():
    assert _(AN_UNTRANSLATED_STRING) == AN_UNTRANSLATED_STRING
Exemple #24
0
 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"))
Exemple #25
0
 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"))
Exemple #26
0
 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)
Exemple #27
0
 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."))
Exemple #28
0
 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.
    """
Exemple #30
0
 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."))