Ejemplo n.º 1
0
 def __changed_and_signal_library(self, entry, section, name):
     config.set(section, name, str(entry.get_value()))
     print_d("Signalling \"changed\" to entire library. Hold tight...")
     # Cache over clicks
     self._songs = self._songs or app.library.values()
     copool.add(emit_signal, self._songs, funcid="library changed",
                name=_("Updating for new ratings"))
Ejemplo n.º 2
0
 def test_step(self):
     copool.add(self.__set_buffer, funcid="test")
     copool.pause("test")
     self.assertTrue(copool.step("test"))
     self.go = False
     self.assertFalse(copool.step("test"))
     self.assertRaises(ValueError, copool.step, "test")
Ejemplo n.º 3
0
 def test_timeout(self):
     copool.add(self.__set_buffer, funcid="test", timeout=100)
     copool.pause("test")
     copool.resume("test")
     copool.remove("test")
     with pytest.raises(ValueError):
         copool.step("test")
Ejemplo n.º 4
0
    def __drag_data_received(self, ctx, x, y, sel, tid, etime):
        if tid == 1: uris = sel.get_uris()
        if tid == 2:
            uri = sel.data.decode('utf16', 'replace').split('\n')[0]
            uris = [uri.encode('ascii', 'replace')]

        dirs = []
        error = False
        for uri in uris:
            try: uri = URI(uri)
            except ValueError: continue

            if uri.is_filename:
                loc = os.path.normpath(uri.filename)
                if os.path.isdir(loc): dirs.append(loc)
                else:
                    loc = os.path.realpath(loc)
                    if loc not in self.__library:
                        self.__library.add_filename(loc)
            elif player.can_play_uri(uri):
                if uri not in self.__library:
                    self.__library.add([RemoteFile(uri)])
            else:
                error = True
                break
        ctx.finish(not error, False, etime)
        if error:
            ErrorMessage(
                self, _("Unable to add songs"),
                _("<b>%s</b> uses an unsupported protocol.") % uri).run()
        else:
            if dirs:
                copool.add(
                    self.__library.scan, dirs, self.__status.bar.progress,
                    cofuncid="library", funcid="library")
Ejemplo n.º 5
0
    def plugin_playlist(self, playlist):
        # TODO - only get coordinator nodes, somehow
        self.device: SoCo = soco.discovery.any_soco()
        device = self.device
        if not device:
            qltk.ErrorMessage(
                app.window, _("Error finding Sonos device(s)"),
                _("Error finding Sonos. Please check settings")).run()
        else:
            sonos_pls = device.get_sonos_playlists()
            pl_id_to_name = {pl.item_id: pl.title for pl in sonos_pls}
            print_d("Sonos playlists: %s" % pl_id_to_name)
            ret = GetSonosPlaylistDialog(pl_id_to_name).run(playlist.name)
            if ret:
                spl_id, name = ret
                if spl_id:
                    spl: DidlPlaylistContainer = next(s for s in sonos_pls
                                                      if s.item_id == spl_id)
                    print_w(f"Replacing existing Sonos playlist {spl!r}")
                    device.remove_sonos_playlist(spl)

                print_d(f"Creating new playlist {name!r}")
                spl = device.create_sonos_playlist(name)
                task = Task("Sonos",
                            _("Export to Sonos playlist"),
                            stop=self.__cancel_add)
                copool.add(self.__add_songs,
                           task,
                           playlist.songs,
                           spl,
                           funcid="sonos-playlist-save")
Ejemplo n.º 6
0
 def __changed_and_signal_library(self, entry, section, name):
     config.set(section, name, str(entry.get_value()))
     print_d("Signalling \"changed\" to entire library. Hold tight...")
     # Cache over clicks
     self._songs = self._songs or app.library.values()
     copool.add(emit_signal, self._songs, funcid="library changed",
                name=_("Updating for new ratings"))
Ejemplo n.º 7
0
    def __drag_data_received(self, widget, ctx, x, y, sel, tid, etime):
        assert tid == DND_URI_LIST

        uris = sel.get_uris()

        dirs = []
        error = False
        for uri in uris:
            try:
                uri = URI(uri)
            except ValueError:
                continue

            if uri.is_filename:
                loc = os.path.normpath(uri.filename)
                if os.path.isdir(loc):
                    dirs.append(loc)
                else:
                    loc = os.path.realpath(loc)
                    if loc not in self.__library:
                        self.__library.add_filename(loc)
            elif app.player.can_play_uri(uri):
                if uri not in self.__library:
                    self.__library.add([RemoteFile(uri)])
            else:
                error = True
                break
        Gtk.drag_finish(ctx, not error, False, etime)
        if error:
            ErrorMessage(self, _("Unable to add songs"), _("%s uses an unsupported protocol.") % util.bold(uri)).run()
        else:
            if dirs:
                copool.add(self.__library.scan, dirs, cofuncid="library", funcid="library")
Ejemplo n.º 8
0
 def refresh_cb(button):
     from quodlibet.library import library
     from quodlibet.util import copool
     paths = util.split_scan_dirs(config.get("settings", "scan"))
     exclude = config.get("library", "exclude").split(":")
     copool.add(library.rebuild,
        paths, False, exclude, cofuncid="library", funcid="library")
Ejemplo n.º 9
0
 def test_step(self):
     copool.add(self.__set_buffer, funcid="test")
     copool.pause("test")
     self.assertTrue(copool.step("test"))
     self.go = False
     self.assertFalse(copool.step("test"))
     self.assertRaises(ValueError, copool.step, "test")
Ejemplo n.º 10
0
 def _on_songs_received(self, client, songs):
     print_d(f"Got {len(songs)} songs")
     self.add(songs)
     # Can't have multiple requests cancel each other's copools
     funcid = hash("".join(s["~uri"] for s in songs))
     # Rate limit a little to avoid 429s
     copool.add(self._get_stream_urls, songs, timeout=100, funcid=funcid)
Ejemplo n.º 11
0
    def start_watching(self, paths: Iterable[fsnative]):
        print_d(f"Setting up file watches on {paths}...", self._name)
        exclude_dirs = [e for e in get_exclude_dirs() if e]

        def watching_producer():
            # TODO: integrate this better with scanning.
            for fullpath in paths:
                desc = _("Adding watches for %s") % (fsn2text(unexpand(fullpath)))
                with Task(_("Library"), desc) as task:
                    normalised = Path(normalize_path(fullpath, True)).expanduser()
                    if any(Path(exclude) in normalised.parents
                           for exclude in exclude_dirs):
                        continue
                    unpulsed = 0
                    self.monitor_dir(normalised)
                    for path, dirs, files in os.walk(normalised):
                        normalised = Path(normalize_path(path, True))
                        for d in dirs:
                            self.monitor_dir(normalised / d)
                        unpulsed += len(dirs)
                        if unpulsed > 50:
                            task.pulse()
                            unpulsed = 0
                        yield

        copool.add(watching_producer, funcid="watch_library")
Ejemplo n.º 12
0
 def test_pause_all(self):
     self.buffer = None
     copool.add(self.__set_buffer, funcid="test")
     self._assert_eventually(True)
     copool.pause_all()
     self.buffer = None
     self._assert_never(True)
Ejemplo n.º 13
0
 def test_step(self):
     copool.add(self.__set_buffer, funcid="test")
     copool.pause("test")
     assert copool.step("test")
     self.go = False
     assert not copool.step("test")
     with pytest.raises(ValueError):
         copool.step("test")
Ejemplo n.º 14
0
 def __destroy(self):
     config.save()
     new_dirs = set(get_scan_dirs())
     gone_dirs = set(self.current_scan_dirs) - new_dirs
     if new_dirs - set(self.current_scan_dirs):
         print_d("Library paths have been added, re-scanning...")
         scan_library(app.library, force=False)
     elif gone_dirs:
         copool.add(app.librarian.remove_roots, gone_dirs)
Ejemplo n.º 15
0
    def open_chooser(self, action):
        last_dir = self.last_dir
        if not os.path.exists(last_dir):
            last_dir = get_home_dir()

        class MusicFolderChooser(FolderChooser):
            def __init__(self, parent, init_dir):
                super(MusicFolderChooser,
                      self).__init__(parent, _("Add Music"), init_dir)

                cb = Gtk.CheckButton(_("Watch this folder for new songs"))
                # enable if no folders are being watched
                cb.set_active(not get_scan_dirs())
                cb.show()
                self.set_extra_widget(cb)

            def run(self):
                fns = super(MusicFolderChooser, self).run()
                cb = self.get_extra_widget()
                return fns, cb.get_active()

        class MusicFileChooser(FileChooser):
            def __init__(self, parent, init_dir):
                super(MusicFileChooser,
                      self).__init__(parent, _("Add Music"), formats.filter,
                                     init_dir)

        if action.get_name() == "AddFolders":
            dialog = MusicFolderChooser(self, last_dir)
            fns, do_watch = dialog.run()
            dialog.destroy()
            if fns:
                fns = map(glib2fsnative, fns)
                # scan them
                self.last_dir = fns[0]
                copool.add(self.__library.scan,
                           fns,
                           cofuncid="library",
                           funcid="library")

                # add them as library scan directory
                if do_watch:
                    dirs = get_scan_dirs()
                    for fn in fns:
                        if fn not in dirs:
                            dirs.append(fn)
                    set_scan_dirs(dirs)
        else:
            dialog = MusicFileChooser(self, last_dir)
            fns = dialog.run()
            dialog.destroy()
            if fns:
                fns = map(glib2fsnative, fns)
                self.last_dir = os.path.dirname(fns[0])
                for filename in map(os.path.realpath, fns):
                    self.__library.add_filename(filename)
Ejemplo n.º 16
0
 def test_add_remove_with_funcid(self):
     copool.add(self.__set_buffer, funcid="test")
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, True)
     copool.remove("test")
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, None)
Ejemplo n.º 17
0
 def test_add_remove(self):
     copool.add(self.__set_buffer)
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.assertEquals(self.buffer, True)
     copool.remove(self.__set_buffer)
     self.buffer = None
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.assertEquals(self.buffer, None)
Ejemplo n.º 18
0
 def test_add_remove_with_funcid(self):
     copool.add(self.__set_buffer, funcid="test")
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.assertEquals(self.buffer, True)
     copool.remove("test")
     self.buffer = None
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.assertEquals(self.buffer, None)
Ejemplo n.º 19
0
 def test_pause_all(self):
     copool.add(self.__set_buffer, funcid="test")
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.failUnless(self.buffer)
     copool.pause_all()
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.failIf(self.buffer)
Ejemplo n.º 20
0
 def test_add_remove(self):
     copool.add(self.__set_buffer)
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, True)
     copool.remove(self.__set_buffer)
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, None)
Ejemplo n.º 21
0
 def test_pause_all(self):
     copool.add(self.__set_buffer, funcid="test")
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.failUnless(self.buffer)
     copool.pause_all()
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.failIf(self.buffer)
Ejemplo n.º 22
0
 def test_add_remove(self):
     copool.add(self.__set_buffer)
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, True)
     copool.remove(self.__set_buffer)
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, None)
Ejemplo n.º 23
0
def _add_location(app, value):
    if os.path.isfile(value):
        ret = app.library.add_filename(value)
        if not ret:
            print_e("Couldn't add file to library")
    elif os.path.isdir(value):
        copool.add(app.library.scan, [value], cofuncid="library",
                   funcid="library")
    else:
        print_e("Invalid location")
Ejemplo n.º 24
0
 def set_tag(self, tag, library):
     if not config.getboolean("settings", "eager_search"):
         return
     elif tag is None:
         return
     elif tag in ("bpm date discnumber isrc originaldate recordingdate " "tracknumber title").split() + MACHINE_TAGS:
         return
     elif tag in formats.PEOPLE:
         tag = "~people"
     copool.add(self.__fill_tag, tag, library)
Ejemplo n.º 25
0
def _add_location(app, value):
    if os.path.isfile(value):
        ret = app.library.add_filename(value)
        if not ret:
            print_e("Couldn't add file to library")
    elif os.path.isdir(value):
        copool.add(app.library.scan, [value], cofuncid="library",
                   funcid="library")
    else:
        print_e("Invalid location")
Ejemplo n.º 26
0
def scan_library(library, force):
    """Start the global library re-scan

    Args:
        library (Library)
        force (bool): if True, reload all existing valid items
    """

    paths = get_scan_dirs()
    exclude = get_exclude_dirs()
    copool.add(library.rebuild, paths, force, exclude, cofuncid="library", funcid="library")
Ejemplo n.º 27
0
def scan_library(library, force):
    """Start the global library re-scan

    If `force` is True, reload all existing valid items.
    """

    paths = get_scan_dirs()
    exclude = split_scan_dirs(config.get("library", "exclude"))
    exclude = [bytes2fsnative(e) for e in exclude]
    copool.add(library.rebuild, paths, force, exclude,
               cofuncid="library", funcid="library")
Ejemplo n.º 28
0
 def __init__(self, library):
     super(LibraryTagCompletion, self).__init__()
     try: model = self.__model
     except AttributeError:
         model = type(self).__model = gtk.ListStore(str)
         library.connect('changed', self.__update_song, model)
         library.connect('added', self.__update_song, model)
         library.connect('removed', self.__update_song, model)
         copool.add(self.__build_model, library, model)
     self.set_model(model)
     self.set_text_column(0)
Ejemplo n.º 29
0
def scan_library(library, force):
    """Start the global library re-scan

    If `force` is True, reload all existing valid items.
    """

    paths = get_scan_dirs()
    exclude = split_scan_dirs(config.get("library", "exclude"))
    exclude = [bytes2fsnative(e) for e in exclude]
    copool.add(library.rebuild, paths, force, exclude,
               cofuncid="library", funcid="library")
Ejemplo n.º 30
0
 def set_tag(self, tag, library):
     if not config.getboolean("settings", "eager_search"):
         return
     elif tag is None:
         return
     elif tag in ("bpm date discnumber isrc originaldate recordingdate "
                  "tracknumber title").split() + MACHINE_TAGS:
         return
     elif tag in formats.PEOPLE:
         tag = "~people"
     copool.add(self.__fill_tag, tag, library)
Ejemplo n.º 31
0
 def test_pause_resume(self):
     copool.add(self.__set_buffer)
     self._assert_eventually(True)
     copool.pause(self.__set_buffer)
     self.buffer = None
     self._assert_never(True)
     copool.resume(self.__set_buffer)
     self._assert_eventually(True)
     copool.remove(self.__set_buffer)
     self.buffer = None
     self._assert_never(True)
Ejemplo n.º 32
0
    def plugin_songs(self, songs):
        def check_songs():
            with Task(_("Refresh songs"), _("%d songs") % len(songs)) as task:
                task.copool(check_songs)
                for i, song in enumerate(songs):
                    song = song._song
                    if song in app.library:
                        app.library.reload(song)
                    task.update((float(i) + 1) / len(songs))
                    yield

        copool.add(check_songs)
Ejemplo n.º 33
0
def scan_library(library, force):
    """Start the global library re-scan

    Args:
        library (Library)
        force (bool): if True, reload all existing valid items
    """

    paths = get_scan_dirs()
    exclude = get_exclude_dirs()
    copool.add(library.rebuild, paths, force, exclude,
               cofuncid="library", funcid="library")
Ejemplo n.º 34
0
 def __init__(self, library):
     super(LibraryTagCompletion, self).__init__()
     try:
         model = self.__model
     except AttributeError:
         model = type(self).__model = Gtk.ListStore(str)
         library.connect('changed', self.__update_song, model)
         library.connect('added', self.__update_song, model)
         library.connect('removed', self.__update_song, model)
         copool.add(self.__build_model, library, model)
     self.set_model(model)
     self.set_text_column(0)
Ejemplo n.º 35
0
    def open_chooser(self, action):
        last_dir = self.last_dir
        if not os.path.exists(last_dir):
            last_dir = get_home_dir()

        class MusicFolderChooser(FolderChooser):
            def __init__(self, parent, init_dir):
                super(MusicFolderChooser, self).__init__(
                    parent, _("Add Music"), init_dir)

                cb = Gtk.CheckButton(_("Watch this folder for new songs"))
                # enable if no folders are being watched
                cb.set_active(not get_scan_dirs())
                cb.show()
                self.set_extra_widget(cb)

            def run(self):
                fns = super(MusicFolderChooser, self).run()
                cb = self.get_extra_widget()
                return fns, cb.get_active()

        class MusicFileChooser(FileChooser):
            def __init__(self, parent, init_dir):
                super(MusicFileChooser, self).__init__(
                    parent, _("Add Music"), formats.filter, init_dir)

        if action.get_name() == "AddFolders":
            dialog = MusicFolderChooser(self, last_dir)
            fns, do_watch = dialog.run()
            dialog.destroy()
            if fns:
                fns = map(glib2fsnative, fns)
                # scan them
                self.last_dir = fns[0]
                copool.add(self.__library.scan, fns, cofuncid="library",
                           funcid="library")

                # add them as library scan directory
                if do_watch:
                    dirs = get_scan_dirs()
                    for fn in fns:
                        if fn not in dirs:
                            dirs.append(fn)
                    set_scan_dirs(dirs)
        else:
            dialog = MusicFileChooser(self, last_dir)
            fns = dialog.run()
            dialog.destroy()
            if fns:
                fns = map(glib2fsnative, fns)
                self.last_dir = os.path.dirname(fns[0])
                for filename in map(os.path.realpath, fns):
                    self.__library.add_filename(filename)
Ejemplo n.º 36
0
 def test_pause_resume_with_funcid(self):
     self.buffer = None
     copool.add(self.__set_buffer, funcid="test")
     self._assert_eventually(True)
     copool.pause("test")
     self.buffer = None
     self._assert_never(True)
     copool.resume("test")
     copool.resume("test")
     self._assert_eventually(True)
     copool.remove("test")
     self.buffer = None
     self._assert_never(True)
Ejemplo n.º 37
0
    def plugin_songs(self, songs):
        def check_songs():
            desc = numeric_phrase("%d song", "%d songs", len(songs))
            with Task(_("Rescan songs"), desc) as task:
                task.copool(check_songs)
                for i, song in enumerate(songs):
                    song = song._song
                    if song in app.library:
                        app.library.reload(song)
                    task.update((float(i) + 1) / len(songs))
                    yield

        copool.add(check_songs)
Ejemplo n.º 38
0
    def plugin_songs(self, songs):

        def check_songs():
            desc = ngettext("%d song", "%d songs", len(songs)) % len(songs)
            with Task(_("Refresh songs"), desc) as task:
                task.copool(check_songs)
                for i, song in enumerate(songs):
                    song = song._song
                    if song in app.library:
                        app.library.reload(song)
                    task.update((float(i) + 1) / len(songs))
                    yield

        copool.add(check_songs)
Ejemplo n.º 39
0
    def __update_visible_rows(self, view, preload):
        self.__scan_timeout = None

        vrange = view.get_visible_range()
        if vrange is None:
            return

        model_filter = view.get_model()
        model = model_filter.get_model()

        #generate a path list so that cover scanning starts in the middle
        #of the visible area and alternately moves up and down
        start, end = vrange

        # pygtk2.12 sometimes returns empty tuples
        if not start or not end:
            return

        start = start.get_indices()[0] - preload - 1
        end = end.get_indices()[0] + preload

        vlist = range(end, start, -1)
        top = vlist[:len(vlist) / 2]
        bottom = vlist[len(vlist) / 2:]
        top.reverse()

        vlist_new = []
        for i in vlist:
            if top:
                vlist_new.append(top.pop())
            if bottom:
                vlist_new.append(bottom.pop())
        vlist_new = filter(lambda s: s >= 0, vlist_new)

        vlist_new = map(Gtk.TreePath, vlist_new)

        visible_paths = []
        for path in vlist_new:
            model_path = model_filter.convert_path_to_child_path(path)
            try:
                row = model[model_path]
            except TypeError:
                pass
            else:
                if self._row_needs_update(row):
                    visible_paths.append([model, model_path])

        if not self.__pending_paths and visible_paths:
            copool.add(self.__scan_paths)
        self.__pending_paths = visible_paths
Ejemplo n.º 40
0
    def plugin_playlist(self, playlist):
        pattern_text = CONFIG.default_pattern
        dialog = ExportToFolderDialog(self.plugin_window, pattern_text)
        if dialog.run() == Gtk.ResponseType.OK:
            directory = dialog.directory_chooser.get_filename()
            pattern = FileFromPattern(dialog.pattern_entry.get_text())

            task = Task("Export", _("Export Playlist to Folder"),
                        stop=self.__cancel_copy)
            copool.add(self.__copy_songs, task,
                       playlist.songs, directory, pattern,
                       funcid="export-playlist-folder")

        dialog.destroy()
Ejemplo n.º 41
0
 def open_chooser(self, action):
     if action.get_name() == "AddFolders":
         fns = choose_folders(self, _("Add Music"), _("_Add Folders"))
         if fns:
             # scan them
             copool.add(self.__library.scan, fns, cofuncid="library",
                        funcid="library")
     else:
         patterns = ["*" + path2fsn(k) for k in formats.loaders.keys()]
         choose_filter = create_chooser_filter(_("Music Files"), patterns)
         fns = choose_files(
             self, _("Add Music"), _("_Add Files"), choose_filter)
         if fns:
             for filename in fns:
                 self.__library.add_filename(filename)
Ejemplo n.º 42
0
 def plugin_playlist(self, playlist):
     self.init_server()
     if not self.server.is_connected:
         qltk.ErrorMessage(
             app.window,
             _("Error finding Squeezebox server"),
             _("Error finding %s. Please check settings") %
             self.server.config
         ).run()
     else:
         name = self.__get_playlist_name(name=playlist.name)
         if name:
             task = Task("Squeezebox", _("Export to Squeezebox playlist"),
                         stop=self.__cancel_add)
             copool.add(self.__add_songs, task, playlist.songs, name,
                        funcid="squeezebox-playlist-save")
Ejemplo n.º 43
0
 def plugin_playlist(self, playlist):
     self.init_server()
     if not self.server.is_connected:
         qltk.ErrorMessage(
             None,
             _("Error finding Squeezebox server"),
             _("Error finding %s. Please check settings") %
             self.server.config
         ).run()
     else:
         name = self.__get_playlist_name(name=playlist.name)
         if name:
             task = Task("Squeezebox", _("Export to Squeezebox playlist"),
                         stop=self.__cancel_add)
             copool.add(self.__add_songs, task, playlist.songs, name,
                        funcid="squeezebox-playlist-save")
Ejemplo n.º 44
0
def scan_library(library, force):
    """Start the global library re-scan

    Args:
        library (Library)
        force (bool): if True, reload all existing valid items
    TODO: consider storing scan_dirs in Library instead of passing around always
    """

    paths = get_scan_dirs()
    exclude = get_exclude_dirs()
    copool.add(library.rebuild,
               paths,
               force,
               exclude,
               cofuncid="library",
               funcid="library")
Ejemplo n.º 45
0
    def __update_visible_rows(self, view, preload):
        vrange = view.get_visible_range()
        if vrange is None:
            return

        model = view.get_model()

        # Generate a path list so that cover scanning starts in the middle
        # of the visible area and alternately moves up and down.
        start, end = vrange

        # pygtk2.12 sometimes returns empty tuples
        if not start or not end:
            return

        start = start.get_indices()[0] - preload - 1
        end = end.get_indices()[0] + preload

        vlist = range(end, start, -1)
        top = vlist[:len(vlist) / 2]
        bottom = vlist[len(vlist) / 2:]
        top.reverse()

        vlist_new = []
        for i in vlist:
            if top:
                vlist_new.append(top.pop())
            if bottom:
                vlist_new.append(bottom.pop())
        vlist_new = filter(lambda s: s >= 0, vlist_new)

        vlist_new = map(Gtk.TreePath, vlist_new)

        visible_paths = []
        for path in vlist_new:
            try:
                iter_ = model.get_iter(path)
            except ValueError:
                continue
            if self._row_needs_update(model, iter_):
                visible_paths.append((model, path))

        if not self.__pending_paths and visible_paths:
            copool.add(self.__scan_paths)
        self.__pending_paths = visible_paths
Ejemplo n.º 46
0
    def __update_visible_rows(self, view, preload):
        vrange = view.get_visible_range()
        if vrange is None:
            return

        model = view.get_model()

        # Generate a path list so that cover scanning starts in the middle
        # of the visible area and alternately moves up and down.
        start, end = vrange

        # pygtk2.12 sometimes returns empty tuples
        if not start or not end:
            return

        start = start.get_indices()[0] - preload - 1
        end = end.get_indices()[0] + preload

        vlist = list(range(end, start, -1))
        top = vlist[:len(vlist) // 2]
        bottom = vlist[len(vlist) // 2:]
        top.reverse()

        vlist_new = []
        for i in vlist:
            if top:
                vlist_new.append(top.pop())
            if bottom:
                vlist_new.append(bottom.pop())
        vlist_new = filter(lambda s: s >= 0, vlist_new)

        vlist_new = map(Gtk.TreePath, vlist_new)

        visible_paths = []
        for path in vlist_new:
            try:
                iter_ = model.get_iter(path)
            except ValueError:
                continue
            if self._row_needs_update(model, iter_):
                visible_paths.append((model, path))

        if not self.__pending_paths and visible_paths:
            copool.add(self.__scan_paths)
        self.__pending_paths = visible_paths
Ejemplo n.º 47
0
    def open_chooser(self, action):
        if not os.path.exists(self.last_dir):
            self.last_dir = const.HOME

        if action.get_name() == "AddFolders":
            chooser = FolderChooser(self, _("Add Music"), self.last_dir)
            cb = gtk.CheckButton(_("Watch this folder for new songs"))
            cb.set_active(not config.get("settings", "scan"))
            cb.show()
            chooser.set_extra_widget(cb)
        else:
            chooser = FileChooser(
                self, _("Add Music"), formats.filter, self.last_dir)
            cb = None

        fns = chooser.run()
        chooser.destroy()
        if fns:
            if action.get_name() == "AddFolders":
                self.last_dir = fns[0]
                copool.add(self.__library.scan, fns, funcid="library")
            else:
                self.last_dir = os.path.basename(fns[0])
                for filename in map(os.path.realpath, map(util.fsnative, fns)):
                    if filename in self.__library: continue
                    song = self.__library.add_filename(filename)
                    if not song:
                        from traceback import format_exception_only as feo
                        tb = feo(sys.last_type, sys.last_value)
                        msg = _("%s could not be added to your library.\n\n")
                        msg %= util.escape(util.fsdecode(
                            os.path.basename(filename)))
                        msg += util.escape("".join(tb).decode(
                            const.ENCODING, "replace"))
                        d = ErrorMessage(self, _("Unable to add song"), msg)
                        d.label.set_selectable(True)
                        d.run()
                        continue

        if cb and cb.get_active():
            dirs = util.split_scan_dirs(config.get("settings", "scan"))
            for fn in fns:
                if fn not in dirs: dirs.append(fn)
            dirs = ":".join(dirs)
            config.set("settings", "scan", dirs)
Ejemplo n.º 48
0
 def test_pause_resume_with_funcid(self):
     copool.add(self.__set_buffer, funcid="test")
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     copool.pause("test")
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, None)
     copool.resume("test")
     copool.resume("test")
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
     self.assertEquals(self.buffer, True)
     copool.remove("test")
     self.buffer = None
     Gtk.main_iteration_do(False)
     Gtk.main_iteration_do(False)
Ejemplo n.º 49
0
 def test_pause_restart_pause(self):
     copool.add(self.__set_buffer, funcid="test")
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.failUnless(self.buffer)
     copool.pause("test")
     self.buffer = None
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.failIf(self.buffer)
     copool.add(self.__set_buffer, funcid="test")
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.failUnless(self.buffer)
     copool.pause("test")
     self.buffer = None
     gtk.main_iteration(block=False)
     gtk.main_iteration(block=False)
     self.failIf(self.buffer)
Ejemplo n.º 50
0
    def __update_visible_rows(self, view, preload):
        vrange = view.get_visible_range()
        if vrange is None: return

        model_filter = view.get_model()
        model = model_filter.get_model()

        #generate a path list so that cover scanning starts in the middle
        #of the visible area and alternately moves up and down
        start, end = vrange

        # pygtk2.12 sometimes returns empty tuples
        if not start or not end:
            return

        start = start[0] - preload - 1
        end = end[0] + preload

        vlist = range(end, start, -1)
        top = vlist[:len(vlist)/2]
        bottom = vlist[len(vlist)/2:]
        top.reverse()

        vlist_new = []
        for i in vlist:
            if top: vlist_new.append(top.pop())
            if bottom: vlist_new.append(bottom.pop())
        vlist_new = filter(lambda s: s >= 0, vlist_new)

        visible_paths = []
        for path in vlist_new:
            model_path = model_filter.convert_path_to_child_path(path)
            try:
                row = model[model_path]
            except TypeError:
                pass
            else:
                if self._row_needs_update(row):
                    visible_paths.append([model, model_path])

        if not self.__pending_paths and visible_paths:
            copool.add(self.__scan_paths)
        self.__pending_paths = visible_paths
Ejemplo n.º 51
0
 def __move(self, widget):
     selection = self.view.get_selection()
     model, paths = selection.get_selected_rows()
     rows = [model[p] for p in paths or []]
     if len(rows) > 1:
         print_w("Can't do multiple moves at once")
         return
     elif not rows:
         return
     base_dir = rows[0][0]
     chooser = _get_chooser(_("Select This Directory"), _("_Cancel"))
     chooser.set_title(
         _("Select Actual / New Directory for {dir!r}").format(
             dir=base_dir))
     chooser.set_action(Gtk.FileChooserAction.SELECT_FOLDER)
     chooser.set_local_only(True)
     chooser.set_select_multiple(False)
     results = _run_chooser(self, chooser)
     if not results:
         return
     new_dir = results[0]
     desc = (_("This will move QL metadata:\n\n"
               "{old!r} -> {new!r}\n\n"
               "The audio files themselves are not moved by this.\n"
               "Nonetheless, a backup is recommended "
               "(including the Quodlibet 'songs' file)").format(
                   old=base_dir, new=new_dir))
     title = _("Move scan root {dir!r}?").format(dir=base_dir)
     value = ConfirmationPrompt(self,
                                title=title,
                                description=desc,
                                ok_button_text=_("OK, move it!")).run()
     if value != ConfirmationPrompt.RESPONSE_INVOKE:
         print_d("User aborted")
         return
     print_d(f"Migrate from {base_dir} -> {new_dir}")
     copool.add(app.librarian.move_root, base_dir, new_dir)
     path = paths[0]
     self.model[path] = [new_dir]
     self.model.row_changed(path, rows[0].iter)
     self.__save()
Ejemplo n.º 52
0
            def download_cb(menu_item):
                songs = relevant
                total = len(songs)
                msg = ngettext("Download {name!r} to",
                               "Download {total} files to", total)
                msg = msg.format(
                    name=next(iter(songs))("title")[:99] if total else "?",
                    total=total)
                chooser = folder_chooser or choose_folders
                paths = chooser(None,
                                msg,
                                _("Download here"),
                                allow_multiple=False)
                if not paths:
                    print_d("Cancelling download")
                    return
                path = paths[0]
                progress = DownloadProgress(songs)

                progress.connect('finished', _finished)
                copool.add(progress.download_songs, path)
Ejemplo n.º 53
0
def enable_periodic_save(save_library):
    import quodlibet.library
    from quodlibet.util import copool
    from quodlibet import config

    timeout = 5 * 60 * 1000  # 5 minutes

    def periodic_config_save():
        while 1:
            config.save(quodlibet.const.CONFIG)
            yield

    copool.add(periodic_config_save, timeout=timeout)

    if not save_library:
        return

    def periodic_library_save():
        while 1:
            quodlibet.library.save()
            yield

    copool.add(periodic_library_save, timeout=timeout)