Ejemplo n.º 1
0
	def populate(self):
		if self.connected():
			self.playlistsdata.clear()
			playlistinfo = []
			playlists = mpdh.call(self.client, 'listplaylists')
			if playlists is None:
				playlists = mpdh.call(self.client, 'lsinfo')
			for item in playlists:
				if 'playlist' in item:
					playlistinfo.append(misc.escape_html(mpdh.get(item, 'playlist')))
			playlistinfo.sort(key=lambda x: x.lower()) # Remove case sensitivity
			for item in playlistinfo:
				self.playlistsdata.append([gtk.STOCK_JUSTIFY_FILL, item])
			if mpdh.mpd_major_version(self.client) >= 0.13:
				self.populate_playlists_for_menu(playlistinfo)
Ejemplo n.º 2
0
 def populate(self):
     if self.connected():
         self.playlistsdata.clear()
         playlistinfo = []
         playlists = mpdh.call(self.client, 'listplaylists')
         if playlists is None:
             playlists = mpdh.call(self.client, 'lsinfo')
         for item in playlists:
             if 'playlist' in item:
                 playlistinfo.append(misc.escape_html(mpdh.get(item, 'playlist')))
         playlistinfo.sort(key=lambda x: x.lower()) # Remove case sensitivity
         for item in playlistinfo:
             self.playlistsdata.append([gtk.STOCK_JUSTIFY_FILL, item])
         if mpdh.mpd_major_version(self.client) >= 0.13:
             self.populate_playlists_for_menu(playlistinfo)
Ejemplo n.º 3
0
	def library_return_search_items(self, genre=None, artist=None, album=None, year=None):
		# Returns all mpd items, using mpd's 'search', along with
		# playtime and num_songs.
		searches = self.library_compose_search_searchlist(genre, artist, album, year)
		for s in searches:
			args_tuple = tuple(map(str, s))
			playtime = 0
			num_songs = 0
			results = []
			
			if '' in s and mpdh.mpd_major_version(self.client) <= 0.13:
				
				# Can't search for empty tags, search broader and filter instead:
				
				# Strip empty tag args from tuple:
				pos = list(args_tuple).index('')
				strip_type = list(args_tuple)[pos-1]
				new_lst = []
				for i, item in enumerate(list(args_tuple)):
					if i != pos and i != pos-1:
						new_lst.append(item)
				args_tuple = tuple(new_lst)

			else:
				strip_type = None
			
			if len(args_tuple) == 0:
				return None, 0, 0
				
			items = mpdh.call(self.client, 'search', *args_tuple)
			if items is not None:
				for item in items:
					if strip_type is None or (strip_type is not None and not strip_type in item.keys()):
						match = True
						pos = 0
						# Ensure that if, e.g., "foo" is searched, "foobar" isn't returned too
						for arg in args_tuple[::2]:
							if arg in item and unicode(mpdh.get(item, arg)).upper() != unicode(args_tuple[pos+1]).upper():
								match = False
								break
							pos += 2
						if match:
							results.append(item)
							num_songs += 1
							playtime += mpdh.get(item, 'time', 0, True)
		return (results, int(playtime), num_songs)
Ejemplo n.º 4
0
	def library_return_search_items(self, genre=None, artist=None, album=None, year=None):
		# Returns all mpd items, using mpd's 'search', along with
		# playtime and num_songs.
		searches = self.library_compose_search_searchlist(genre, artist, album, year)
		for s in searches:
			args_tuple = tuple(map(str, s))
			playtime = 0
			num_songs = 0
			results = []
			
			if '' in s and mpdh.mpd_major_version(self.client) <= 0.13:
				
				# Can't search for empty tags, search broader and filter instead:
				
				# Strip empty tag args from tuple:
				pos = list(args_tuple).index('')
				strip_type = list(args_tuple)[pos-1]
				new_lst = []
				for i, item in enumerate(list(args_tuple)):
					if i != pos and i != pos-1:
						new_lst.append(item)
				args_tuple = tuple(new_lst)

			else:
				strip_type = None
			
			if len(args_tuple) == 0:
				return None, 0, 0
				
			items = mpdh.call(self.client, 'search', *args_tuple)
			if items is not None:
				for item in items:
					if strip_type is None or (strip_type is not None and not strip_type in item.keys()):
						match = True
						pos = 0
						# Ensure that if, e.g., "foo" is searched, "foobar" isn't returned too
						for arg in args_tuple[::2]:
							if arg in item and unicode(mpdh.get(item, arg)).upper() != unicode(args_tuple[pos+1]).upper():
								match = False
								break
							pos += 2
						if match:
							results.append(item)
							num_songs += 1
							playtime += int(mpdh.get(item, 'time', '0'))
		return (results, int(playtime), num_songs)
Ejemplo n.º 5
0
	def library_return_count(self, genre=None, artist=None, album=None, year=None):
		# Because mpd's 'count' is case sensitive, we have to
		# determine all equivalent items (case insensitive) and
		# call 'count' for each of them. Using 'list' + 'count'
		# involves much less data to be transferred back and
		# forth than to use 'search' and count manually.
		searches = self.library_compose_list_count_searchlist(genre, artist, album, year)
		playtime = 0
		num_songs = 0
		for s in searches:

			if '' in s and mpdh.mpd_major_version(self.client) <= 0.13:
				
				# Can't return count for empty tags, use search instead:
				
				_results, playtime, num_songs = self.library_return_search_items(genre=genre, artist=artist, album=album, year=year)

			else:

				count = mpdh.call(self.client, 'count', *s)
				playtime += mpdh.get(count, 'playtime', 0, True)
				num_songs += mpdh.get(count, 'songs', 0, True)
				
		return (playtime, num_songs)
Ejemplo n.º 6
0
	def library_return_count(self, genre=None, artist=None, album=None, year=None):
		# Because mpd's 'count' is case sensitive, we have to
		# determine all equivalent items (case insensitive) and
		# call 'count' for each of them. Using 'list' + 'count'
		# involves much less data to be transferred back and
		# forth than to use 'search' and count manually.
		searches = self.library_compose_list_count_searchlist(genre, artist, album, year)
		playtime = 0
		num_songs = 0
		for s in searches:

			if '' in s and mpdh.mpd_major_version(self.client) <= 0.13:
				
				# Can't return count for empty tags, use search instead:
				
				_results, playtime, num_songs = self.library_return_search_items(genre=genre, artist=artist, album=album, year=year)

			else:

				count = mpdh.call(self.client, 'count', *s)
				playtime += int(mpdh.get(count, 'playtime'))
				num_songs += int(mpdh.get(count, 'songs'))
				
		return (playtime, num_songs)
Ejemplo n.º 7
0
    def on_dnd(self, treeview, drag_context, x, y, selection, _info, timestamp):
        drop_info = treeview.get_dest_row_at_pos(x, y)

        if selection.data is not None:
            if not os.path.isdir(misc.file_from_utf8(self.config.musicdir[self.config.profile_num])):
                return
                # DND from outside sonata:
            uri = selection.data.strip()
            path = urllib.url2pathname(uri)
            paths = path.rsplit("\n")
            mpdpaths = []
            # Strip off paranthesis so that we can DND entire music dir
            # if we wish.
            musicdir = self.config.musicdir[self.config.profile_num][:-1]
            for i, path in enumerate(paths):
                paths[i] = path.rstrip("\r")
                if paths[i].startswith("file://"):
                    paths[i] = paths[i][7:]
                elif paths[i].startswith("file:"):
                    paths[i] = paths[i][5:]
                if paths[i].startswith(musicdir):
                    paths[i] = paths[i][len(self.config.musicdir[self.config.profile_num]) :]
                    if len(paths[i]) == 0:
                        paths[i] = "/"
                    listallinfo = mpdh.call(self.client, "listallinfo", paths[i])
                    for item in listallinfo:
                        if "file" in item:
                            mpdpaths.append(mpdh.get(item, "file"))
                elif mpdh.mpd_major_version(self.client) >= 0.14:
                    # Add local file, available in mpd 0.14. This currently won't
                    # work because python-mpd does not support unix socket paths,
                    # which is needed for authentication for local files. It's also
                    # therefore untested.
                    if os.path.isdir(misc.file_from_utf8(paths[i])):
                        filenames = misc.get_files_recursively(paths[i])
                    else:
                        filenames = [paths[i]]
                    for filename in filenames:
                        if os.path.exists(misc.file_from_utf8(filename)):
                            mpdpaths.append("file://" + urllib.quote(filename))
            if len(mpdpaths) > 0:
                # Items found, add to list at drop position:
                if drop_info:
                    destpath, position = drop_info
                    if position in (gtk.TREE_VIEW_DROP_BEFORE, gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
                        songid = destpath[0]
                    else:
                        songid = destpath[0] + 1
                else:
                    songid = len(self.currentdata)
                for mpdpath in mpdpaths:
                    mpdh.call(self.client, "addid", mpdpath, songid)
            self.iterate_now()
            return

            # Otherwise, it's a DND just within the current playlist
        model = treeview.get_model()
        _foobar, selected = self.current_selection.get_selected_rows()

        # calculate all this now before we start moving stuff
        drag_sources = []
        for path in selected:
            index = path[0]
            i = model.get_iter(path)
            songid = self.current_get_songid(i, model)
            text = model.get_value(i, 1)
            drag_sources.append([index, i, songid, text])

            # Keep track of the moved iters so we can select them afterwards
        moved_iters = []

        # We will manipulate self.current_songs and model to prevent the entire playlist
        # from refreshing
        offset = 0
        mpdh.call(self.client, "command_list_ok_begin")
        for source in drag_sources:
            index, i, songid, text = source
            if drop_info:
                destpath, position = drop_info
                dest = destpath[0] + offset
                if dest < index:
                    offset = offset + 1
                if position in (gtk.TREE_VIEW_DROP_BEFORE, gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
                    self.current_songs.insert(dest, self.current_songs[index])
                    if dest < index + 1:
                        self.current_songs.pop(index + 1)
                        mpdh.call(self.client, "moveid", songid, dest)
                    else:
                        self.current_songs.pop(index)
                        mpdh.call(self.client, "moveid", songid, dest - 1)
                    model.insert(dest, model[index])
                    moved_iters += [model.get_iter((dest,))]
                    model.remove(i)
                else:
                    self.current_songs.insert(dest + 1, self.current_songs[index])
                    if dest < index:
                        self.current_songs.pop(index + 1)
                        mpdh.call(self.client, "moveid", songid, dest + 1)
                    else:
                        self.current_songs.pop(index)
                        mpdh.call(self.client, "moveid", songid, dest)
                    model.insert(dest + 1, model[index])
                    moved_iters += [model.get_iter((dest + 1,))]
                    model.remove(i)
            else:
                # dest = int(self.status['playlistlength']) - 1
                dest = len(self.currentdata) - 1
                mpdh.call(self.client, "moveid", songid, dest)
                self.current_songs.insert(dest + 1, self.current_songs[index])
                self.current_songs.pop(index)
                model.insert(dest + 1, model[index])
                moved_iters += [model.get_iter((dest + 1,))]
                model.remove(i)
                # now fixup
            for source in drag_sources:
                if dest < index:
                    # we moved it back, so all indexes inbetween increased by 1
                    if dest < source[0] < index:
                        source[0] += 1
                else:
                    # we moved it ahead, so all indexes inbetween decreased by 1
                    if index < source[0] < dest:
                        source[0] -= 1
        mpdh.call(self.client, "command_list_end")

        # we are manipulating the model manually for speed, so...
        self.current_update_skip = True

        if drag_context.action == gtk.gdk.ACTION_MOVE:
            drag_context.finish(True, True, timestamp)
            self.header_hide_all_indicators(self.current, False)
        self.iterate_now()

        gobject.idle_add(self.dnd_retain_selection, treeview.get_selection(), moved_iters)
Ejemplo n.º 8
0
    def on_dnd(self, treeview, drag_context, x, y, selection, _info,
               timestamp):
        drop_info = treeview.get_dest_row_at_pos(x, y)

        if selection.data is not None:
            if not os.path.isdir(
                    misc.file_from_utf8(
                        self.config.musicdir[self.config.profile_num])):
                return
            # DND from outside sonata:
            uri = selection.data.strip()
            path = urllib.url2pathname(uri)
            paths = path.rsplit('\n')
            mpdpaths = []
            # Strip off paranthesis so that we can DND entire music dir
            # if we wish.
            musicdir = self.config.musicdir[self.config.profile_num][:-1]
            for i, path in enumerate(paths):
                paths[i] = path.rstrip('\r')
                if paths[i].startswith('file://'):
                    paths[i] = paths[i][7:]
                elif paths[i].startswith('file:'):
                    paths[i] = paths[i][5:]
                if paths[i].startswith(musicdir):
                    paths[i] = paths[i][
                        len(self.config.musicdir[self.config.profile_num]):]
                    if len(paths[i]) == 0:
                        paths[i] = "/"
                    listallinfo = mpdh.call(self.client, 'listallinfo',
                                            paths[i])
                    for item in listallinfo:
                        if 'file' in item:
                            mpdpaths.append(mpdh.get(item, 'file'))
                elif mpdh.mpd_major_version(self.client) >= 0.14:
                    # Add local file, available in mpd 0.14. This currently won't
                    # work because python-mpd does not support unix socket paths,
                    # which is needed for authentication for local files. It's also
                    # therefore untested.
                    if os.path.isdir(misc.file_from_utf8(paths[i])):
                        filenames = misc.get_files_recursively(paths[i])
                    else:
                        filenames = [paths[i]]
                    for filename in filenames:
                        if os.path.exists(misc.file_from_utf8(filename)):
                            mpdpaths.append("file://" + urllib.quote(filename))
            if len(mpdpaths) > 0:
                # Items found, add to list at drop position:
                if drop_info:
                    destpath, position = drop_info
                    if position in (gtk.TREE_VIEW_DROP_BEFORE,
                                    gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
                        songid = destpath[0]
                    else:
                        songid = destpath[0] + 1
                else:
                    songid = len(self.currentdata)
                for mpdpath in mpdpaths:
                    mpdh.call(self.client, 'addid', mpdpath, songid)
            self.iterate_now()
            return

        # Otherwise, it's a DND just within the current playlist
        model = treeview.get_model()
        _foobar, selected = self.current_selection.get_selected_rows()

        # calculate all this now before we start moving stuff
        drag_sources = []
        for path in selected:
            index = path[0]
            i = model.get_iter(path)
            songid = self.current_get_songid(i, model)
            text = model.get_value(i, 1)
            drag_sources.append([index, i, songid, text])

        # Keep track of the moved iters so we can select them afterwards
        moved_iters = []

        # We will manipulate self.current_songs and model to prevent the entire playlist
        # from refreshing
        offset = 0
        mpdh.call(self.client, 'command_list_ok_begin')
        for source in drag_sources:
            index, i, songid, text = source
            if drop_info:
                destpath, position = drop_info
                dest = destpath[0] + offset
                if dest < index:
                    offset = offset + 1
                if position in (gtk.TREE_VIEW_DROP_BEFORE,
                                gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
                    self.current_songs.insert(dest, self.current_songs[index])
                    if dest < index + 1:
                        self.current_songs.pop(index + 1)
                        mpdh.call(self.client, 'moveid', songid, dest)
                    else:
                        self.current_songs.pop(index)
                        mpdh.call(self.client, 'moveid', songid, dest - 1)
                    model.insert(dest, model[index])
                    moved_iters += [model.get_iter((dest, ))]
                    model.remove(i)
                else:
                    self.current_songs.insert(dest + 1,
                                              self.current_songs[index])
                    if dest < index:
                        self.current_songs.pop(index + 1)
                        mpdh.call(self.client, 'moveid', songid, dest + 1)
                    else:
                        self.current_songs.pop(index)
                        mpdh.call(self.client, 'moveid', songid, dest)
                    model.insert(dest + 1, model[index])
                    moved_iters += [model.get_iter((dest + 1, ))]
                    model.remove(i)
            else:
                #dest = int(self.status['playlistlength']) - 1
                dest = len(self.currentdata) - 1
                mpdh.call(self.client, 'moveid', songid, dest)
                self.current_songs.insert(dest + 1, self.current_songs[index])
                self.current_songs.pop(index)
                model.insert(dest + 1, model[index])
                moved_iters += [model.get_iter((dest + 1, ))]
                model.remove(i)
            # now fixup
            for source in drag_sources:
                if dest < index:
                    # we moved it back, so all indexes inbetween increased by 1
                    if dest < source[0] < index:
                        source[0] += 1
                else:
                    # we moved it ahead, so all indexes inbetween decreased by 1
                    if index < source[0] < dest:
                        source[0] -= 1
        mpdh.call(self.client, 'command_list_end')

        # we are manipulating the model manually for speed, so...
        self.current_update_skip = True

        if drag_context.action == gtk.gdk.ACTION_MOVE:
            drag_context.finish(True, True, timestamp)
            self.header_hide_all_indicators(self.current, False)
        self.iterate_now()

        gobject.idle_add(self.dnd_retain_selection, treeview.get_selection(),
                         moved_iters)