def processTasks(self, task):
        """
        Processes tasks picked up e.g. by Companion listener

        task = {
            'action':       'playlist'
            'data':         as received from Plex companion
        }
        """
        log.debug('Processing: %s' % task)
        data = task['data']

        if task['action'] == 'playlist':
            try:
                _, queueId, query = ParseContainerKey(data['containerKey'])
            except Exception as e:
                log.error('Exception while processing: %s' % e)
                import traceback
                log.error("Traceback:\n%s" % traceback.format_exc())
                return
            if self.playlist is not None:
                if self.playlist.Typus() != data.get('type'):
                    log.debug('Switching to Kodi playlist of type %s'
                              % data.get('type'))
                    self.playlist = None
            if self.playlist is None:
                if data.get('type') == 'music':
                    self.playlist = playlist.Playlist('music')
                else:
                    self.playlist = playlist.Playlist('video')
            if queueId != self.playlist.QueueId():
                log.info('New playlist received, updating!')
                xml = GetPlayQueue(queueId)
                if xml in (None, 401):
                    log.error('Could not download Plex playlist.')
                    return
                # Clear existing playlist on the Kodi side
                self.playlist.clear()
                # Set new values
                self.playlist.QueueId(queueId)
                self.playlist.PlayQueueVersion(int(
                    xml.attrib.get('playQueueVersion')))
                self.playlist.Guid(xml.attrib.get('guid'))
                items = []
                for item in xml:
                    items.append({
                        'playQueueItemID': item.get('playQueueItemID'),
                        'plexId': item.get('ratingKey'),
                        'kodiId': None})
                self.playlist.playAll(
                    items,
                    startitem=self._getStartItem(data.get('key', '')),
                    offset=ConvertPlexToKodiTime(data.get('offset', 0)))
                log.info('Initiated playlist no %s with version %s'
                         % (self.playlist.QueueId(),
                            self.playlist.PlayQueueVersion()))
            else:
                log.error('This has never happened before!')
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.userid = window('currUserId')
        self.server = window('pms_server')

        if self.API.getType() == 'track':
            self.pl = playlist.Playlist(typus='music')
        else:
            self.pl = playlist.Playlist(typus='video')
Exemple #3
0
    def leaf_node(self, branch, data, menuw):
        """
        last node in branch generates a playlist.
        """
        logger.debug('leaf_node(branch=%r, data=%r, menuw=%r)', branch, data,
                     menuw)
        title = '-'.join(data)
        #creating of audio items is slow.
        #need a progress-bar.
        pl = playlist.Playlist(name='-'.join(data),
                               playlist=[],
                               display_type='audiocd')

        tracks = branch.execute(data)  #returns list of (desc, path, filename)

        pop = ProgressBox(text=_('Generating playlist...'), full=len(tracks))
        pop.show()
        items = []
        i = 0
        for desc, path, filename in tracks:
            filepath = os.path.join(path, filename)
            item = audioitem.AudioItem(filepath, parent=pl)
            item.name = desc
            item.track = i
            items.append(item)
            pop.tick()
            i += 1
        pop.destroy()

        pl.playlist = items

        mymenu = menu.Menu(title, pl.playlist, item_types="audio")
        menuw.pushmenu(mymenu)
Exemple #4
0
    def _play(cls, data):

        item_ids = data['ItemIds']
        command = data['PlayCommand']

        playlist_ = playlist.Playlist()

        if command == 'PlayNow':
            startat = data.get('StartPositionTicks', 0)
            playlist_.play_all(item_ids, startat)
            dialog(type_="notification",
                   heading="{emby}",
                   message="%s %s" % (len(item_ids), lang(33004)),
                   icon="{emby}",
                   sound=False)

        elif command == 'PlayNext':
            new_playlist = playlist_.modify_playlist(item_ids)
            dialog(type_="notification",
                   heading="{emby}",
                   message="%s %s" % (len(item_ids), lang(33005)),
                   icon="{emby}",
                   sound=False)
            player = xbmc.Player()
            if not player.isPlaying():
                # Only start the playlist if nothing is playing
                player.play(new_playlist)
Exemple #5
0
def callback():
    code = flask.request.args.get('code')
    url = 'https://accounts.spotify.com/api/token'
    body = {
        'grant_type': 'authorization_code',
        'code': code,
        'redirect_uri': 'http://localhost:5000/callback',
        'client_id': client,
        'client_secret': secret
    }

    res = requests.post(url=url, data=body)
    token = json.loads(res.text)['access_token']

    bar = playlist.Playlist(id='37i9dQZF1E35k73659EuOH', auth_token=token)
    songs = bar.get_tracks()
    songs_short = songs[:10]

    dataset = build_dataset(
        genre_list=[
            'rap', 'country', 'rock', 'edm', 'folk', 'christian', 'metal',
            'punk'
        ],
        token=token,
    )
    print(dataset)
    return ({'set': dataset})
Exemple #6
0
    def newpl(self, args):
        """
        makes a new playlist
        1 arg : blank playlist with given name
        2 args: playlist with given name and contents given by file argument
        """
        if not args:
            self.err_print('One argument required')
            return
        elif len(args) == 1:
            plname = args[0]

            if self.pl_exists(plname) >= 0:
                self.err_print('Playlist "{}" already exists'.format(plname))
                return

            playlist.Playlist.init_pl(plname, self.ui.db)
            newpl = menu.Music_menu(win=self.ui.rightwin.win,
                                    data=playlist.Playlist(name=plname,
                                                           db=self.ui.db),
                                    form=config.SONG_DISP,
                                    palette=self.ui.palette[0],
                                    ui=self)
        else:
            plname = args[0]
            plfile = args[1]
            if not os.path.isfile(plfile):
                self.err_print('File does not exist: {}.'.format(plfile))
                return

            if self.pl_exists(plname) >= 0:
                self.err_print('Playlist "{}" already exists'.format(plname))
                return

            playlist.init_pl(plname, self.ui.db)
            newpl = menu.Menu(win=self.ui.rightwin.win,
                              data=playlist.Playlist(name=plname,
                                                     db=self.ui.db),
                              form=config.SONG_DISP,
                              cursor_colour=config.CURSOR[0],
                              highlight_colour=config.HIGHLIGHT_COLOUR[0],
                              normal_colour=config.NORMAL[0])

            newpl.insert_from_file(plfile)

        self.ui.leftwin.insert(newpl)
        self.ui.leftwin.disp()
    def playlist(self, pos):
        playlist_struct = self.__container_interface.playlist(
            self.__container_struct, pos)

        if playlist_struct is not None:
            pi = _playlist.PlaylistInterface()
            pi.add_ref(playlist_struct)
            return playlist.Playlist(playlist_struct)
Exemple #8
0
    def add_playlist(self):
        print("So you want to add playlist. Ok, follow instructions below.")
        name = input("Enter playlist name: ")

        id = self.insert_playlist_into_db(name)
        playlist_ = playlist.Playlist(name, id, self.id, self.conn,
                                      self.cursor)
        self.playlists.append(playlist_)
def main():
    my_pl = playlist.Playlist()
    my_pl.add_path_to_playlist(sys.argv[1])

    stream_thread = threading.Thread(target=stream.stream_main, args=(my_pl, ))
    stream_thread.start()
    # rest_thread = threading.Thread(target=rest_interface.app.run)
    # rest_thread.start()

    stream_thread.join()
Exemple #10
0
    def get_recommendations(self, name):
        tracks_dict = {}
        features_dict = {}
        recs_dict = {}
        generated_playlists = []

        df = self.l.csv('my_playlists')

        #getting five tracks from playlists
        print(name)
        tracks_dict[name] = []
        rows = df.loc[df['name'].isin([name])]
        named = rows.loc[df['name'] == name]
        t = self.g.playlist_tracks(named['id'].values[0])
        t = pandas.DataFrame(t[-5:])
        for track in t['track']:
            tracks_dict[name].append(track['id'])

        self.s.csv(t, "playlist_tracks_" + name)

        #get audio features
        # a = self.sp.audio_features(t)
        # features_frame = pandas.DataFrame(a)
        for p in tracks_dict:
            features_dict[p] = self.g.features_ideal(tracks_dict[p], name)

        #get recommendations and put them in a playlist or make a new one
        recs_dict[name] = []
        recs_frame = pandas.DataFrame()
        recs = self.g.recommendations(tracks_dict[name], **features_dict[name])
        for track in recs['tracks']:
            recs_frame = recs_frame.append(track, ignore_index=True)
            recs_dict[name].append(track['id'])
        self.s.csv(recs_frame, "playlist_recs_" + name)

        print(recs_dict)

        p = playlist.Playlist(
            self.user, self.sp, name + "_recs", False,
            "Auto generated recommendations for " + name + " playlist")
        vals = df[df['name'].str.match(name + "_recs")]['id'].values
        if len(vals) > 0 & len(vals) < 2:
            existing_id = vals
            print(existing_id[0])
            p.add_tracks(existing_id[0], recs_dict[name])
        elif len(vals) > 2:
            print("ya f****d up")
        else:
            generated = p.create()
            print(generated['id'])
            p.add_tracks(generated['id'], recs_dict[name])
        return
    def __init__(self, item):

        self.item = item
        self.API = api.API(self.item)

        self.doUtils = downloadutils.DownloadUtils().downloadUrl

        self.userid = window('emby_currUser')
        self.server = window('emby_server%s' % self.userid)

        self.artwork = artwork.Artwork()
        self.emby = embyserver.Read_EmbyServer()
        self.pl = playlist.Playlist()
Exemple #12
0
 def __init__(self):
     p = playlist.Playlist()
     self.list = p.newGET()
     self.TITLE = []
     self.MP3 = []
     self.TIME = []
     self.PIC = []
     self.os_path = []
     for i in range(len(self.list)):
         self.TITLE += [self.list[i][0]]
         self.MP3 += [playlist.retrowave + self.list[i][1]]
         self.TIME += [self.list[i][2]]
         self.PIC += [playlist.retrowave + self.list[i][3]]
         self.os_path += ['media/' + self.list[i][0]]
Exemple #13
0
    def __init__(self, item):

        self.item = item
        self.API = PlexAPI.API(item)

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()

        self.userid = utils.window('currUserId')
        self.server = utils.window('pms_server')

        self.artwork = artwork.Artwork()
        self.emby = embyserver.Read_EmbyServer()
        self.pl = playlist.Playlist()
Exemple #14
0
    def onJoin(self, details):
        self.playlist = playlist.Playlist(PLAYLIST_STORE)
        self.thread_pool = ThreadPool(processes=20)

        # jukebox actions
        yield self.register(self.get_playlist,
                'com.forrestli.jukebox.get_playlist')
        yield self.register(self.add, 'com.forrestli.jukebox.add')
        yield self.register(self.remove, 'com.forrestli.jukebox.remove')
        yield self.register(self.play, 'com.forrestli.jukebox.play')
        yield self.register(self.move_song, 'com.forrestli.jukebox.move_song')

        yield self.subscribe(self.on_finish_song,
                'com.forrestli.jukebox.event.player.finished')
    def __init__(self):
        log.info("----===## Starting PlexCompanion ##===----")
        self.settings = plexsettings.getSettings()
        # Start GDM for server/client discovery
        self.client = plexgdm.plexgdm()
        self.client.clientDetails(self.settings)
        log.debug("Registration string is: %s "
                  % self.client.getClientDetails())
        # Initialize playlist/queue stuff
        self.playlist = playlist.Playlist('video')
        # kodi player instance
        self.player = player.Player()

        threading.Thread.__init__(self)
Exemple #16
0
    def __init__(self, item):

        self.item = item
        self.API = api.API(self.item)

        self.clientInfo = clientinfo.ClientInfo()
        self.addonName = self.clientInfo.getAddonName()
        self.doUtils = downloadutils.DownloadUtils().downloadUrl

        self.userid = utils.window('emby_currUser')
        self.server = utils.window('emby_server%s' % self.userid)

        self.artwork = artwork.Artwork()
        self.emby = embyserver.Read_EmbyServer()
        self.pl = playlist.Playlist()
Exemple #17
0
def main():
    global playlist, control, song_history

    playlist = playlist.Playlist()

    control = radiocontrol.RadioControlThread(playlist)

    song_history = []

    print "connecting..."
    icecast.connect()

    radio_loop()

    print "shutting down..."
    icecast.close()
Exemple #18
0
    def search_for_playlists_in_db(self):
        sql = (
            "SELECT playlist_name, playlistID FROM playlists WHERE userID = ?")
        self.cursor.execute(sql, (self.id, ))

        fetched_playlists = self.cursor.fetchall()
        if (fetched_playlists != None):
            playlists = []
            for row in fetched_playlists:
                playlists.append(
                    playlist.Playlist(row[0], row[1], self.id, self.conn,
                                      self.cursor))

            return playlists

        else:
            return []
Exemple #19
0
    def __init_windows(self):
        hh, ww, cc = config.set_size(self.stdscr)

        win = threadwin.Threadwin(hh, cc - ww, 0, ww)
        data = [
            menu.Music_menu(win=win,
                            data=playlist.Playlist(name=pl, db=self.db),
                            form=config.SONG_DISP,
                            palette=self.palette[0],
                            ui=self) for pl in self.db.list_pl()
        ]

        leftwin = menu.Menu(0, 0, ww, hh, data=data, palette=self.palette[1])

        botwin = window.Window(0, hh, cc, song_info_bar_height)
        textwin = window.Window(0, hh + song_info_bar_height, cc,
                                command_bar_height)
        return leftwin, botwin, textwin
 async def cmdStationAdd(self, message=None, cmd=None, failed=False):
     for s in stations:
         if (s.waveLength == cmd[2]):
             try:
                 addedPlaylist = playlist.Playlist(
                     spotifyConInstance.loadPlaylist(cmd[3]))
             except Exception as e:
                 await message.channel.send("Invalid Playlist!")
                 self.console(e)
                 return
             else:
                 numAdded = s.addPlaylist(addedPlaylist,
                                          verbose=self.verbose)
                 s.saveToFile(verbose=self.verbose)
                 await message.channel.send("Added " + str(numAdded) +
                                            " songs to " + s.waveLength)
                 return
     await message.channel.send("Could not find station " + cmd[2])
    async def cmdPlay(self, message=None, cmd=None, failed=False):
        await message.add_reaction("\U0001F4FB")
        reqStation = None
        for s in stations:
            if (cmd[1] == s.waveLength):
                reqStation = s
        if (reqStation):
            self.playlist = reqStation
            self.voice = self.playlist.host
            for c in convertToEmoji(reqStation.waveLength):
                await message.add_reaction(c)
        else:
            try:
                self.playlist = playlist.Playlist(
                    spotifyConInstance.loadPlaylist(cmd[1]))
            except Exception as e:
                await message.channel.send("Invalid Playlist!")
                self.console(e)
                return
            else:
                await message.add_reaction("\U0001F44C")

        random.shuffle(self.playlist.songs)
        self.playlist.prepareNextSongs(2,
                                       verbose=self.verbose,
                                       voice=self.voice,
                                       welcome=True)

        while (True):
            try:
                self.console("Connecting to voice channel " +
                             message.author.voice.channel.name)
                #connect to the voice channel that the person who wrote the message is in
                if self.VC and (not self.VC == message.author.voice.channel):
                    await self.VC.disconnect()

                self.VC = await message.author.voice.channel.connect()

                await self.playNextSong(None, welcome=True)
            except Exception as e:
                print(e)
            else:
                break
Exemple #22
0
	def __init__(self, targets):
		
		window = gtk.Window(gtk.WINDOW_TOPLEVEL)  #create window
		window.connect("destroy", self.quit)
		window.set_title(self.versionString)
		window.set_icon(self.getIcon())
		
		self.window = window
		
		self.prefs = prefs.Prefs(self)
		
		self.mplayer = mplayer.Mplayer(self)
		self.remote = remote.Remote(self)
		self.playlist = playlist.Playlist(self)
		self.systray = systray.Systray(self)
		self.control = control.Control(self)
		self.menu = menu.Menu(self)
		
		vbox = gtk.VBox(False, 0)
		vbox.pack_start(self.playlist.scrollview, True, True, 0) 
		vbox.pack_start(self.control.hbox, False, False, 0)
		
		window.add(vbox)  #prepare to start ui
		window.show_all()
		
		window.move(self.prefs.getInt("x"), self.prefs.getInt("y"))
		window.resize(self.prefs.getInt("width"), self.prefs.getInt("height"))
		
		if targets:  #process targets
			
			self.playlist.load(targets)
			
			if self.playlist.continuous:  #and begin playback
				self.playlist.jump(0)
			
		else:  #or load last list
			self.playlist.loadm3u()
			
		gtk.main()
Exemple #23
0
    def __init__(self, config: dict):

        self.download_dir = Path(config["download_dir"])
        self.download_dir.mkdir(exist_ok=True)

        self.playlist_dir = Path(config["playlist_dir"])
        self.download_dir.mkdir(exist_ok=True)

        self.tmp_dir = dir_script.joinpath(config["tmp_dir"])
        self.max_threads = config["max_threads"]
        self.URIs = config["URIs"]
        self.noextract = config["noextract"]

        playlist_name = config.get("playlist")
        self.playlist = playlist.Playlist(
            config) if playlist_name is not None else None

        # Only when filtering
        if self.URIs == []:
            self.ranked_only = config["ranked_only"]
            self.scoresaber_sorting = config["scoresaber_sorting"]
            self.levels_to_download = config["levels_to_download"]
            self.scoresaber_maxlimit = config["scoresaber_maxlimit"]
            self.stars_min = config["stars_min"]
            self.stars_max = config["stars_max"]
            self.beatmap_rating_min = config["beatmap_rating_min"]
            self.beatmap_rating_max = config["beatmap_rating_max"]
            self.length_min = config["length_min"]
            self.length_max = config["length_max"]
            self.notes_min = config["notes_min"]
            self.notes_max = config["notes_max"]
            self.nps_min = config["nps_min"]
            self.nps_max = config["nps_max"]
            self.gamemode = config["gamemode"]

        # Initialize
        self.cache = cache.Cache(config)
Exemple #24
0
    def onchoose_last_node(self, tree, data, menuw):
        """
        last node in tree generates a playlist.
        """
        title = '-'.join(data)
        #creating of audio items is slow.
        #need a progress-bar.
        pl = playlist.Playlist(name='-'.join(data), playlist=[], display_type='audiocd')

        tracks = tree.execute(data)  #returns list of (desc, path, filename)

        pop = ProgressBox(text=_('Generating playlist...'), full=len(tracks))
        pop.show()
        items = []
        i = 0
        for desc, path, filename in tracks:
            filepath = os.path.join(path, filename)
            item = audioitem.AudioItem(filepath, parent=pl)
            item.name = desc
            item.track = i
            items.append( item)
            pop.tick()
            i+=1
        pop.destroy()

        pl.playlist = items

        #note/question for core developers:
        #command below causes strange errors?
        #plugin.__plugin_type_list__ is empty??? but it's Not?
        #pl.browse(arg=None, menuw=menuw)
        #print 'LIST=', plugin.__plugin_type_list__['mimetype']
        #workaround: not all features of a real playlist :(

        mymenu = menu.Menu(title, pl.playlist, item_types="audio")
        menuw.pushmenu(mymenu)
for item in arquivo_filme:
    item = item.strip("\n")
    linha = item.split("-")
    lista_programas.append(filme.Filme(linha[0], linha[1], linha[2]))

for item in arquivo_serie:
    item = item.strip("\n")
    linha = item.split("-")
    lista_programas.append(serie.Serie(linha[0], linha[1], linha[2]))

var_numero = random.randrange(1, 10)
var_aux1 = var_aux2 = 0

while (var_aux1 < len(lista_programas)):

    while (var_aux2 <= var_numero):
        lista_programas.__getitem__(var_aux1).dar_like()
        var_aux2 += 1

    var_numero = random.randrange(1, 20)
    var_aux1 += 1
    var_aux2 = 0

lista = playlist.Playlist("Playlist", lista_programas)

for item in lista:
    print(item)

print("", end="\n")
input("Digite <ENTER> para sair...")
Exemple #26
0
def main():
    p = argparse.ArgumentParser(description='Raspberry pi Digital Signage')
    p.add_argument('-c', '--conf', help="configuration yaml filename")
    p.add_argument('--quiet', action='store_true', help="quiet mode")
    args = p.parse_args()

    if not args.conf:
        print("configuration file is not supplied")
        return

    global isQuiet
    isQuiet = args.quiet

    conf = Configure.Configure(args.conf)
    gpiomap = conf.getGPIOMap()
    gpion = conf.getGPION()
    option = conf.getOption()
    command = conf.getCommand()

    with Playlist.Playlist(conf.getPlaylist(), option) as playlist:
        playlist.start()

        gpio = GPIOController.GPIOController(
            gpiomap.keys() + gpion,
            pullup=option.get("pullup", False),
            bouncetime=option.get("bouncetime", 20))

        def do_num(num):
            if option.get("exit", -1) == num:
                reactor.stop()
                return

            if num in command:
                playlist.command(command[num])
                return

            playlist.play(num)

        def sw_pressed(gpiopin):
            num = gpiomap[gpiopin]
            if num == "ntri":
                num = gpio.getBinary(gpion)

            myprint("gpio {0} is pressed: funcnum {1}".format(gpiopin, num))
            do_num(num)

        def sw_released(gpiopin):
            num = gpiomap[gpiopin]
            if num == "ntri":
                num = gpio.getBinary(gpion)
            else:
                return

            myprint("gpio {0} is released: funcnum {1}".format(gpiopin, num))
            do_num(num)

        gpio.allocate(gpiomap.keys(), sw_pressed,
                      sw_released if option.get("ntritoggle", False) else None)
        gpio.allocate(gpion)

        remote = RemoteController.RemoteController(
            port=option.get("port", 9999)) if option.get("remote",
                                                         False) else None

        if remote:

            def cmd_received(data):
                myprint("data is received from remote")
                if not "command" in data:
                    return False

                if data["command"] == "exit":
                    reactor.stop()
                    return True

                if data["command"] == "func" and "num" in data:
                    num = int(data["num"])
                    myprint("remote control: funcnum {0}".format(num))
                    do_num(num)
                    return True
                return False

            remote.start(cmd_received)

        reactor.run()

        if remote:
            remote.stop()
 def add_playlist(self, link):
     return playlist.Playlist(
         self.__container_interface.add_playlist(self.__container_struct,
                                                 link.get_struct()))
 def add_new_playlist(self, name):
     return playlist.Playlist(
         self.__container_interface.add_new_playlist(
             self.__container_struct, name))
Exemple #29
0
def write_playlists(music, playlist_dir='.', relative=True):
    """
    Write playlists based on the music metadata.

    This function will write a number of playlists:
        Artist - All of the artists songs
        Album - All tracks on the album
        Year - All songs released in a year
        Decade - All songs released in a decade

    Args:
        playlist_dir:  The directory below which to create the playlists
        relative:  Use relative paths in the playlists?

    """
    log = logging.getLogger(__name__)
    # Create a dictionary to hold the songs for each year
    years = {}
    # Sort out the directories
    basedir = os.path.abspath(playlist_dir)
    basedir = os.path.join(basedir, 'playlists')
    log.debug("Playlists will be stored here: " + basedir)
    releaseddir = os.path.join(basedir, 'released')
    log.debug("Year and decade playlists will be stored here: " + releaseddir)
    albumdir = os.path.join(basedir, 'albums')
    log.debug("Artist/album playlists will be stored here: " + albumdir)

    # Create the release date directory  if needed
    if not os.path.exists(releaseddir):
        log.info("Creating year/decade playlist directory: " + releaseddir)
        os.makedirs(releaseddir)

    # Loop over the artists
    for artist in music:
        log.debug("Artist: " + str(artist))
        # Create an artist directory if needed
        artist_dir = os.path.join(albumdir, artist)
        if not os.path.exists(artist_dir):
            log.info("Creating artist playlist directory: " + artist_dir)
            os.makedirs(artist_dir)
        # Create the artist playlist
        pl_filename = 'all_' + artist + '.m3u'
        pl_filename = ''.join(c for c in pl_filename if c not in '/\\')
        pl_filename = os.path.join(artist_dir, pl_filename)
        artist_pl = playlist.Playlist(filename=pl_filename)

        # Loop over the artists albums
        for album in music[artist]:
            log.debug("Album: " + str(album))
            # Create an album playlist
            pl_filename = album + '.m3u'
            pl_filename = ''.join(c for c in pl_filename if c not in '/\\')
            pl_filename = os.path.join(artist_dir, pl_filename)
            album_pl = playlist.Playlist(filename=pl_filename)

            # Loop over the songs on the album
            for song in music[artist][album]:
                log.debug("Song: " + song['title'])
                # Add song to the playlists
                try:
                    artist_pl.append(song)
                    album_pl.append(song)
                    # Place the song in the correct year list
                    yr = get_year(song['release_date'])
                    if yr is not None:
                        if yr not in years:
                            log.debug("First song from year: " + str(yr))
                            years[yr] = [song]
                        else:
                            years[yr].append(song)

                except ValueError:
                    log.error("Missing playlist data for: " + str(song))

            # Write the album playlist
            log.info("Saving album playlist: " + str(album_pl))
            album_pl.write(relative=relative)
        # Write the artist playlist
        log.info("Saving artist playlist: " + str(artist_pl))
        artist_pl.write(relative=relative)

    # Create the year and decade playlists
    log.debug("Starting to process time-based playlists")
    decade = None
    dc_pl = None
    for yr in sorted(years):
        log.debug("Processing year: " + str(yr))
        # Decade playlist
        if decade != str(math.floor(yr / 10) * 10):
            # We have changed decades so write the old playlist
            if decade is not None:
                # Not the first year processed so write decade playlist
                log.info("Saving decade playlist: " + str(dc_pl))
                dc_pl.write(relative=relative)
            # Set the decade and create the playlist
            decade = str(math.floor(yr / 10) * 10)
            log.debug("New Decade: " + decade)
            pl_filename = os.path.join(releaseddir, decade + '_s.m3u')
            dc_pl = playlist.Playlist(filename=pl_filename)

        # Year playlist
        pl_filename = os.path.join(releaseddir, str(yr) + '.m3u')
        yr_pl = playlist.Playlist(filename=pl_filename)

        # Loop over the songs adding to the playlists
        for song in years[yr]:
            yr_pl.append(song)
            dc_pl.append(song)

        # Write the "year" playlist
        log.info("Saving year playlist: " + str(yr_pl))
        yr_pl.write(relative=relative)

    # Write the last Decade playlist
    log.info("Saving decade playlist: " + str(dc_pl))
    dc_pl.write(relative=relative)
    def on_message(self, ws, message):

        log = self.logMsg
        window = utils.window
        lang = utils.language

        result = json.loads(message)
        messageType = result['MessageType']
        data = result['Data']

        if messageType not in ('SessionEnded'):
            # Mute certain events
            log("Message: %s" % message, 1)

        if messageType == "Play":
            # A remote control play command has been sent from the server.
            itemIds = data['ItemIds']
            command = data['PlayCommand']

            pl = playlist.Playlist()
            dialog = xbmcgui.Dialog()

            if command == "PlayNow":
                dialog.notification(
                    heading="Emby for Kodi",
                    message="%s %s" % (len(itemIds), lang(33004)),
                    icon="special://home/addons/plugin.video.emby/icon.png",
                    sound=False)
                startat = data.get('StartPositionTicks', 0)
                pl.playAll(itemIds, startat)

            elif command == "PlayNext":
                dialog.notification(
                    heading="Emby for Kodi",
                    message="%s %s" % (len(itemIds), lang(33005)),
                    icon="special://home/addons/plugin.video.emby/icon.png",
                    sound=False)
                newplaylist = pl.modifyPlaylist(itemIds)
                player = xbmc.Player()
                if not player.isPlaying():
                    # Only start the playlist if nothing is playing
                    player.play(newplaylist)

        elif messageType == "Playstate":
            # A remote control update playstate command has been sent from the server.
            command = data['Command']
            player = xbmc.Player()

            actions = {
                'Stop': player.stop,
                'Unpause': player.pause,
                'Pause': player.pause,
                'NextTrack': player.playnext,
                'PreviousTrack': player.playprevious,
                'Seek': player.seekTime
            }
            action = actions[command]
            if command == "Seek":
                seekto = data['SeekPositionTicks']
                seektime = seekto / 10000000.0
                action(seektime)
                log("Seek to %s." % seektime, 1)
            else:
                action()
                log("Command: %s completed." % command, 1)

            window('emby_command', value="true")

        elif messageType == "UserDataChanged":
            # A user changed their personal rating for an item, or their playstate was updated
            userdata_list = data['UserDataList']
            self.librarySync.triage_items("userdata", userdata_list)

        elif messageType == "LibraryChanged":

            librarySync = self.librarySync
            processlist = {
                'added': data['ItemsAdded'],
                'update': data['ItemsUpdated'],
                'remove': data['ItemsRemoved']
            }
            for action in processlist:
                librarySync.triage_items(action, processlist[action])

        elif messageType == "GeneralCommand":

            command = data['Name']
            arguments = data['Arguments']

            if command in ('Mute', 'Unmute', 'SetVolume',
                           'SetSubtitleStreamIndex', 'SetAudioStreamIndex'):

                player = xbmc.Player()
                # These commands need to be reported back
                if command == "Mute":
                    xbmc.executebuiltin('Mute')
                elif command == "Unmute":
                    xbmc.executebuiltin('Mute')
                elif command == "SetVolume":
                    volume = arguments['Volume']
                    xbmc.executebuiltin('SetVolume(%s[,showvolumebar])' %
                                        volume)
                elif command == "SetAudioStreamIndex":
                    index = int(arguments['Index'])
                    player.setAudioStream(index - 1)
                elif command == "SetSubtitleStreamIndex":
                    embyindex = int(arguments['Index'])
                    currentFile = player.getPlayingFile()

                    mapping = window('emby_%s.indexMapping' % currentFile)
                    if mapping:
                        externalIndex = json.loads(mapping)
                        # If there's external subtitles added via playbackutils
                        for index in externalIndex:
                            if externalIndex[index] == embyindex:
                                player.setSubtitleStream(int(index))
                                break
                        else:
                            # User selected internal subtitles
                            external = len(externalIndex)
                            audioTracks = len(
                                player.getAvailableAudioStreams())
                            player.setSubtitleStream(external + embyindex -
                                                     audioTracks - 1)
                    else:
                        # Emby merges audio and subtitle index together
                        audioTracks = len(player.getAvailableAudioStreams())
                        player.setSubtitleStream(index - audioTracks - 1)

                # Let service know
                window('emby_command', value="true")

            elif command == "DisplayMessage":

                header = arguments['Header']
                text = arguments['Text']
                xbmcgui.Dialog().notification(
                    heading=header,
                    message=text,
                    icon="special://home/addons/plugin.video.emby/icon.png",
                    time=4000)

            elif command == "SendString":

                string = arguments['String']
                text = {
                    'jsonrpc': "2.0",
                    'id': 0,
                    'method': "Input.SendText",
                    'params': {
                        'text': "%s" % string,
                        'done': False
                    }
                }
                result = xbmc.executeJSONRPC(json.dumps(text))

            else:
                builtin = {
                    'ToggleFullscreen': 'Action(FullScreen)',
                    'ToggleOsdMenu': 'Action(OSD)',
                    'ToggleContextMenu': 'Action(ContextMenu)',
                    'MoveUp': 'Action(Up)',
                    'MoveDown': 'Action(Down)',
                    'MoveLeft': 'Action(Left)',
                    'MoveRight': 'Action(Right)',
                    'Select': 'Action(Select)',
                    'Back': 'Action(back)',
                    'GoHome': 'ActivateWindow(Home)',
                    'PageUp': 'Action(PageUp)',
                    'NextLetter': 'Action(NextLetter)',
                    'GoToSearch': 'VideoLibrary.Search',
                    'GoToSettings': 'ActivateWindow(Settings)',
                    'PageDown': 'Action(PageDown)',
                    'PreviousLetter': 'Action(PrevLetter)',
                    'TakeScreenshot': 'TakeScreenshot',
                    'ToggleMute': 'Mute',
                    'VolumeUp': 'Action(VolumeUp)',
                    'VolumeDown': 'Action(VolumeDown)',
                }
                action = builtin.get(command)
                if action:
                    xbmc.executebuiltin(action)

        elif messageType == "ServerRestarting":
            if utils.settings('supressRestartMsg') == "true":
                xbmcgui.Dialog().notification(
                    heading="Emby for Kodi",
                    message=lang(33006),
                    icon="special://home/addons/plugin.video.emby/icon.png")

        elif messageType == "UserConfigurationUpdated":
            # Update user data set in userclient
            userclient.UserClient().userSettings = data
            self.librarySync.refresh_views = True