summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2014-09-30 20:14:17 +0200
committerschneefux <schneefux+commit@schneefux.xyz>2014-10-01 14:15:46 +0200
commitd378caee59df005e94ba6f891976ceb64c2a48d2 (patch)
treea3c292056645e40d1385ae2a1939025554234206 /client
parent2bcceb3fe037355dbdfdc46ffbd036c7f719a7bf (diff)
downloadjasper-client-d378caee59df005e94ba6f891976ceb64c2a48d2.tar.gz
jasper-client-d378caee59df005e94ba6f891976ceb64c2a48d2.zip
Remove music mode
Diffstat (limited to 'client')
-rw-r--r--client/conversation.py33
-rw-r--r--client/music.py261
-rw-r--r--client/musicmode.py183
-rw-r--r--client/vocabcompiler.py2
4 files changed, 1 insertions, 478 deletions
diff --git a/client/conversation.py b/client/conversation.py
index 0746b7f..9b86295 100644
--- a/client/conversation.py
+++ b/client/conversation.py
@@ -1,10 +1,7 @@
# -*- coding: utf-8-*-
import logging
from notifier import Notifier
-from musicmode import *
from brain import Brain
-from mpd import MPDClient
-
class Conversation(object):
@@ -16,34 +13,6 @@ class Conversation(object):
self.brain = Brain(mic, profile)
self.notifier = Notifier(profile)
- def delegateInput(self, texts):
- """A wrapper for querying brain."""
-
- # check if input is meant to start the music module
- for text in texts:
- if any(x in text.upper() for x in ["SPOTIFY", "MUSIC"]):
- self._logger.debug("Preparing to start music module")
- # check if mpd client is running
- try:
- client = MPDClient()
- client.timeout = None
- client.idletimeout = None
- client.connect("localhost", 6600)
- except:
- self._logger.critical("Can't connect to mpd client, cannot start music mode.", exc_info=True)
- self.mic.say(
- "I'm sorry. It seems that Spotify is not enabled. Please read the documentation to learn how to configure Spotify.")
- return
-
- self.mic.say("Please give me a moment, I'm loading your Spotify playlists.")
- self._logger.debug("Starting music mode")
- music_mode = MusicMode(self.persona, self.mic)
- music_mode.handleForever()
- self._logger.debug("Exiting music mode")
- return
-
- self.brain.query(texts)
-
def handleForever(self):
"""Delegates user input to the handling function when activated."""
self._logger.info("Starting to handle conversation with keyword '%s'.", self.persona)
@@ -67,6 +36,6 @@ class Conversation(object):
self._logger.debug("Stopped to listen actively with threshold: %r", threshold)
if input:
- self.delegateInput(input)
+ self.brain.query(input)
else:
self.mic.say("Pardon?")
diff --git a/client/music.py b/client/music.py
deleted file mode 100644
index ca9b776..0000000
--- a/client/music.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# -*- coding: utf-8-*-
-import re
-import difflib
-from mpd import MPDClient
-
-
-def reconnect(func, *default_args, **default_kwargs):
- """
- Reconnects before running
- """
-
- def wrap(self, *default_args, **default_kwargs):
- try:
- self.client.connect("localhost", 6600)
- except:
- pass
-
- # sometimes not enough to just connect
- try:
- return func(self, *default_args, **default_kwargs)
- except:
- self.client = MPDClient()
- self.client.timeout = None
- self.client.idletimeout = None
- self.client.connect("localhost", 6600)
-
- return func(self, *default_args, **default_kwargs)
-
- return wrap
-
-
-class Song:
-
- def __init__(self, id, title, artist, album):
-
- self.id = id
- self.title = title
- self.artist = artist
- self.album = album
-
-
-class Music:
-
- client = None
- songs = [] # may have duplicates
- playlists = []
-
- # capitalized strings
- song_titles = []
- song_artists = []
-
- def __init__(self):
- """
- Prepare the client and music variables
- """
- # prepare client
- self.client = MPDClient()
- self.client.timeout = None
- self.client.idletimeout = None
- self.client.connect("localhost", 6600)
-
- # gather playlists
- self.playlists = [x["playlist"] for x in self.client.listplaylists()]
-
- # gather songs
- self.client.clear()
- for playlist in self.playlists:
- self.client.load(playlist)
-
- soup = self.client.playlist()
- for i in range(0, len(soup) / 10):
- index = i * 10
- id = soup[index].strip()
- title = soup[index + 3].strip().upper()
- artist = soup[index + 2].strip().upper()
- album = soup[index + 4].strip().upper()
-
- self.songs.append(Song(id, title, artist, album))
-
- self.song_titles.append(title)
- self.song_artists.append(artist)
-
- @reconnect
- def play(self, songs=False, playlist_name=False):
- """
- Plays the current song or accepts a song to play.
-
- Arguments:
- songs -- a list of song objects
- playlist_name -- user-defined, something like "Love Song Playlist"
- """
- if songs:
- self.client.clear()
- for song in songs:
- try: # for some reason, certain ids don't work
- self.client.add(song.id)
- except:
- pass
-
- if playlist_name:
- self.client.clear()
- self.client.load(playlist_name)
-
- self.client.play()
-
- @reconnect
- def current_song(self):
- item = self.client.playlistinfo(int(self.client.status()["song"]))[0]
- result = "%s by %s" % (item["title"], item["artist"])
- return result
-
- @reconnect
- def volume(self, level=None, interval=None):
-
- if level:
- self.client.setvol(int(level))
- return
-
- if interval:
- level = int(self.client.status()['volume']) + int(interval)
- self.client.setvol(int(level))
- return
-
- @reconnect
- def pause(self):
- self.client.pause()
-
- @reconnect
- def stop(self):
- self.client.stop()
-
- @reconnect
- def next(self):
- self.client.next()
- return
-
- @reconnect
- def previous(self):
- self.client.previous()
- return
-
- def get_soup(self):
- """
- returns the list of unique words that comprise song and artist titles
- """
-
- soup = []
-
- for song in self.songs:
- song_words = song.title.split(" ")
- artist_words = song.artist.split(" ")
- soup.extend(song_words)
- soup.extend(artist_words)
-
- title_trans = ''.join(
- chr(c) if chr(c).isupper() or chr(c).islower() else '_' for c in range(256))
- soup = [x.decode('utf-8').encode("ascii", "ignore").upper().translate(title_trans).replace("_", "")
- for x in soup]
- soup = [x for x in soup if x != ""]
-
- return list(set(soup))
-
- def get_soup_playlist(self):
- """
- returns the list of unique words that comprise playlist names
- """
-
- soup = []
-
- for name in self.playlists:
- soup.extend(name.split(" "))
-
- title_trans = ''.join(
- chr(c) if chr(c).isupper() or chr(c).islower() else '_' for c in range(256))
- soup = [x.decode('utf-8').encode("ascii", "ignore").upper().translate(title_trans).replace("_", "")
- for x in soup]
- soup = [x for x in soup if x != ""]
-
- return list(set(soup))
-
- def get_soup_separated(self):
- """
- returns the list of PHRASES that comprise song and artist titles
- """
-
- title_soup = [song.title for song in self.songs]
- artist_soup = [song.artist for song in self.songs]
-
- soup = list(set(title_soup + artist_soup))
-
- title_trans = ''.join(
- chr(c) if chr(c).isupper() or chr(c).islower() else '_' for c in range(256))
- soup = [x.decode('utf-8').encode("ascii", "ignore").upper().translate(title_trans).replace("_", " ")
- for x in soup]
- soup = [re.sub(' +', ' ', x) for x in soup if x != ""]
-
- return soup
-
- def fuzzy_songs(self, query):
- """
- Returns songs matching a query best as possible on either artist field, etc
- """
-
- query = query.upper()
-
- matched_song_titles = difflib.get_close_matches(
- query, self.song_titles)
- matched_song_artists = difflib.get_close_matches(
- query, self.song_artists)
-
- # if query is beautifully matched, then forget about everything else
- strict_priority_title = [x for x in matched_song_titles if x == query]
- strict_priority_artists = [
- x for x in matched_song_artists if x == query]
-
- if strict_priority_title:
- matched_song_titles = strict_priority_title
- if strict_priority_artists:
- matched_song_artists = strict_priority_artists
-
- matched_songs_bytitle = [
- song for song in self.songs if song.title in matched_song_titles]
- matched_songs_byartist = [
- song for song in self.songs if song.artist in matched_song_artists]
-
- matches = list(set(matched_songs_bytitle + matched_songs_byartist))
-
- return matches
-
- def fuzzy_playlists(self, query):
- """
- returns playlist names that match query best as possible
- """
- query = query.upper()
- lookup = {n.upper(): n for n in self.playlists}
- results = [lookup[r] for r in difflib.get_close_matches(query, lookup)]
- return results
-
-if __name__ == "__main__":
- """
- Plays music and performs unit-testing
- """
-
- print "Creating client"
-
- music = Music()
-
- print "Playing"
-
- music.play(songs=[music.songs[3]])
-
- print music.get_soup_separated()
-
- while True:
- query = raw_input("Query: ")
- songs = music.fuzzy_songs(query)
- print "Results"
- print "======="
- for song in songs:
- print "Title: %s Artist: %s" % (song.title, song.artist)
- music.play(songs=songs)
diff --git a/client/musicmode.py b/client/musicmode.py
deleted file mode 100644
index 900c4f1..0000000
--- a/client/musicmode.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# -*- coding: utf-8-*-
-"""
- Manages the conversation
-"""
-
-import os
-from mic import Mic
-import g2p
-from music import *
-import stt
-
-
-class MusicMode:
-
- def __init__(self, PERSONA, mic):
- self.persona = PERSONA
- # self.mic - we're actually going to ignore the mic they passed in
- self.music = Music()
-
- # index spotify playlists into new dictionary and language models
- original = self.music.get_soup_playlist(
- ) + ["STOP", "CLOSE", "PLAY", "PAUSE",
- "NEXT", "PREVIOUS", "LOUDER", "SOFTER", "LOWER", "HIGHER", "VOLUME", "PLAYLIST"]
- pronounced = g2p.translateWords(original)
- zipped = zip(original, pronounced)
- lines = ["%s %s" % (x, y) for x, y in zipped]
-
- with open("dictionary_spotify.dic", "w") as f:
- f.write("\n".join(lines) + "\n")
-
- with open("sentences_spotify.txt", "w") as f:
- f.write("\n".join(original) + "\n")
- f.write("<s> \n </s> \n")
- f.close()
-
- # make language model
- os.system(
- "text2idngram -vocab sentences_spotify.txt < sentences_spotify.txt -idngram spotify.idngram")
- os.system(
- "idngram2lm -idngram spotify.idngram -vocab sentences_spotify.txt -arpa languagemodel_spotify.lm")
-
- # create a new mic with the new music models
- self.mic = Mic(
- mic.speaker,
- stt.PocketSphinxSTT(lmd_music="languagemodel_spotify.lm", dictd_music="dictionary_spotify.dic"),
- stt.PocketSphinxSTT(lmd_music="languagemodel_spotify.lm", dictd_music="dictionary_spotify.dic")
- )
-
- def delegateInput(self, input):
-
- command = input.upper()
-
- # check if input is meant to start the music module
- if "PLAYLIST" in command:
- command = command.replace("PLAYLIST", "")
- elif "STOP" in command:
- self.mic.say("Stopping music")
- self.music.stop()
- return
- elif "PLAY" in command:
- self.mic.say("Playing %s" % self.music.current_song())
- self.music.play()
- return
- elif "PAUSE" in command:
- self.mic.say("Pausing music")
- # not pause because would need a way to keep track of pause/play
- # state
- self.music.stop()
- return
- elif any(ext in command for ext in ["LOUDER", "HIGHER"]):
- self.mic.say("Louder")
- self.music.volume(interval=10)
- self.music.play()
- return
- elif any(ext in command for ext in ["SOFTER", "LOWER"]):
- self.mic.say("Softer")
- self.music.volume(interval=-10)
- self.music.play()
- return
- elif "NEXT" in command:
- self.mic.say("Next song")
- self.music.play() # backwards necessary to get mopidy to work
- self.music.next()
- self.mic.say("Playing %s" % self.music.current_song())
- return
- elif "PREVIOUS" in command:
- self.mic.say("Previous song")
- self.music.play() # backwards necessary to get mopidy to work
- self.music.previous()
- self.mic.say("Playing %s" % self.music.current_song())
- return
-
- # SONG SELECTION... requires long-loading dictionary and language model
- # songs = self.music.fuzzy_songs(query = command.replace("PLAY", ""))
- # if songs:
- # self.mic.say("Found songs")
- # self.music.play(songs = songs)
-
- # print "SONG RESULTS"
- # print "============"
- # for song in songs:
- # print "Song: %s Artist: %s" % (song.title, song.artist)
-
- # self.mic.say("Playing %s" % self.music.current_song())
-
- # else:
- # self.mic.say("No songs found. Resuming current song.")
- # self.music.play()
-
- # PLAYLIST SELECTION
- playlists = self.music.fuzzy_playlists(query=command)
- if playlists:
- self.mic.say("Loading playlist %s" % playlists[0])
- self.music.play(playlist_name=playlists[0])
- self.mic.say("Playing %s" % self.music.current_song())
- else:
- self.mic.say("No playlists found. Resuming current song.")
- self.music.play()
-
- return
-
- def handleForever(self):
-
- self.music.play()
- self.mic.say("Playing %s" % self.music.current_song())
-
- while True:
-
- try:
- threshold, transcribed = self.mic.passiveListen(self.persona)
- except:
- continue
-
- if threshold:
-
- self.music.pause()
-
- input = self.mic.activeListen(MUSIC=True)
-
- if "close" in input.lower():
- self.mic.say("Closing Spotify")
- return
-
- if input:
- self.delegateInput(input)
- else:
- self.mic.say("Pardon?")
- self.music.play()
-
-if __name__ == "__main__":
- """
- Indexes the Spotify music library to dictionary_spotify.dic and languagemodel_spotify.lm
- """
-
- musicmode = MusicMode("JASPER", None)
- music = musicmode.music
-
- original = music.get_soup() + ["STOP", "CLOSE", "PLAY",
- "PAUSE", "NEXT", "PREVIOUS", "LOUDER", "SOFTER"]
- pronounced = g2p.translateWords(original)
- zipped = zip(original, pronounced)
- lines = ["%s %s" % (x, y) for x, y in zipped]
-
- with open("dictionary_spotify.dic", "w") as f:
- f.write("\n".join(lines) + "\n")
-
- with open("sentences_spotify.txt", "w") as f:
- f.write("\n".join(original) + "\n")
- f.write("<s> \n </s> \n")
- f.close()
-
- with open("sentences_spotify_separated.txt", "w") as f:
- f.write("\n".join(music.get_soup_separated()) + "\n")
- f.write("<s> \n </s> \n")
- f.close()
-
- # make language model
- os.system(
- "text2idngram -vocab sentences_spotify.txt < sentences_spotify_separated.txt -idngram spotify.idngram")
- os.system(
- "idngram2lm -idngram spotify.idngram -vocab sentences_spotify.txt -arpa languagemodel_spotify.lm")
-
- print "Language Model and Dictionary Done"
diff --git a/client/vocabcompiler.py b/client/vocabcompiler.py
index aba85ce..1ca0d26 100644
--- a/client/vocabcompiler.py
+++ b/client/vocabcompiler.py
@@ -35,8 +35,6 @@ def compile(sentences, dictionary, languagemodel):
for module in modules:
words.extend(module.WORDS)
- # for spotify module
- words.extend(["MUSIC", "SPOTIFY"])
words = list(set(words))
# create the dictionary