class DeviceView(View): """ Playlist synchronisation to MTP """ def get_files(uri): """ Get files for uri @param uri as str @return [str] """ files = [] try: d = Gio.File.new_for_uri(uri) if not d.query_exists(None): d.make_directory_with_parents(None) infos = d.enumerate_children( 'standard::name', Gio.FileQueryInfoFlags.NONE, None) for info in infos: files.append(info.get_name()) infos.close(None) except Exception as e: print("DeviceManagerView::_get_files: %s: %s" % (uri, e)) files = [] return files def __init__(self, device, progress): """ Init view @param device as Device @param progress as Gtk.ProgressBar """ View.__init__(self) self._timeout_id = None self._device = device self._progress = progress builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerView.ui') self._memory_combo = builder.get_object('memory_combo') self._syncing_btn = builder.get_object('sync_btn') self._syncing_btn.set_label(_("Synchronize %s") % device.name) builder.connect_signals(self) grid = builder.get_object('device') self.add(grid) self._device_widget = DeviceManagerWidget(progress, self) self._device_widget.connect('sync-finished', self._on_sync_finished) self._device_widget.show() self._viewport.add(self._device_widget) self.add(self._scrolled) def populate(self): """ Populate combo box @thread safe """ files = DeviceView.get_files(self._device.uri) if files: GLib.idle_add(self._set_combo_text, files) else: GLib.idle_add(self.destroy) def is_syncing(self): """ Check if lollypop is syncing @return bool """ return self._device_widget.is_syncing() ####################### # PRIVATE # ####################### def _on_destroy(self, widget): """ Remove running timeout @param widget as Gtk.Widget """ if self._timeout_id is not None: GLib.source_remove(self._timeout_id) self._timeout_id = None def _on_sync_clicked(self, widget): """ Start synchronisation @param widget as Gtk.Button """ if self._device_widget.is_syncing(): self._device_widget.cancel_sync() self._on_sync_finished(None) elif not self._progress.is_visible(): self._memory_combo.hide() self._syncing_btn.set_label(_("Cancel synchronization")) self._device_widget.sync() def _on_sync_finished(self, device_widget): """ Restore widgets state @param device widget as DeviceManager """ self._progress.hide() self._progress.set_fraction(0) self._memory_combo.show() self._syncing_btn.set_label(_("Synchronize %s") % self._device.name) def _on_memory_combo_changed(self, combo): """ Update path @param combo as Gtk.ComboxText """ self._timeout_id = None text = combo.get_active_text() uri = "%s%s/Music/%s" % (self._device.uri, text, "lollypop") on_disk_playlists = DeviceView.get_files(uri) self._device_widget.set_playlists(on_disk_playlists, uri) self._device_widget.populate() def _set_combo_text(self, text_list): """ Set combobox text @param text list as [str] """ for text in text_list: self._memory_combo.append_text(text) self._memory_combo.set_active(0)
class DeviceView(View): """ Playlist synchronisation to MTP """ def exists_old_sync(uri): """ True if exists an old sync on device @param uri as str @return bool """ d = Lio.File.new_for_uri(uri+"/Music/lollypop/tracks") return d.query_exists() def get_files(uri): """ Get files for uri @param uri as str @return [str] """ files = [] try: d = Lio.File.new_for_uri(uri) if not d.query_exists(): d.make_directory_with_parents() infos = d.enumerate_children( 'standard::name,standard::type', Gio.FileQueryInfoFlags.NONE, None) for info in infos: if info.get_file_type() != Gio.FileType.DIRECTORY: continue f = infos.get_child(info) # We look to this folder to select an already synced uri suburi = f.get_uri() + "/Music/unsync" sub = Lio.File.new_for_uri(suburi) if sub.query_exists(): files.insert(0, info.get_name()) else: files.append(info.get_name()) infos.close(None) except Exception as e: print("DeviceManagerView::_get_files: %s: %s" % (uri, e)) files = [] return files def __init__(self, device): """ Init view @param device as Device """ View.__init__(self) self.__timeout_id = None self.__device = device builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerView.ui') self.__memory_combo = builder.get_object('memory_combo') self.__syncing_btn = builder.get_object('sync_btn') self.__syncing_btn.set_label(_("Synchronize %s") % device.name) builder.connect_signals(self) grid = builder.get_object('device') self.add(grid) self.__device_widget = DeviceManagerWidget(self) self.__device_widget.connect('sync-finished', self.__on_sync_finished) self.__device_widget.show() self._viewport.add(self.__device_widget) self.add(self._scrolled) self.__sanitize_non_mtp() def populate(self): """ Populate combo box @thread safe """ files = DeviceView.get_files(self.__device.uri) if files: GLib.idle_add(self.__set_combo_text, files) else: GLib.idle_add(self.destroy) def is_syncing(self): """ Check if lollypop is syncing @return bool """ return self.__device_widget.is_syncing() ####################### # PROTECTED # ####################### def _on_destroy(self, widget): """ Remove running timeout @param widget as Gtk.Widget """ if self.__timeout_id is not None: GLib.source_remove(self.__timeout_id) self.__timeout_id = None View._on_destroy(self, widget) def _on_sync_clicked(self, widget): """ Start synchronisation @param widget as Gtk.Button """ if self.__device_widget.is_syncing(): self.__device_widget.cancel_sync() elif not Lp().window.progress.is_visible(): self.__memory_combo.hide() self.__syncing_btn.set_label(_("Cancel synchronization")) self.__device_widget.sync() def _on_memory_combo_changed(self, combo): """ Update path @param combo as Gtk.ComboxText """ self.__timeout_id = None text = combo.get_active_text() uri = "%s%s/Music" % (self.__device.uri, text) self.__device_widget.set_uri(uri) self.__device_widget.populate() ####################### # PRIVATE # ####################### def __sanitize_non_mtp(self): """ Sanitize non MTP device by changing uri and creating a default folder """ uri = self.__device.uri # Mtp device contain a virtual folder # For others, just go up in path if uri.find('mtp:') == -1: m = re.search('(.*)/[^/]*', uri) if m: uri = m.group(1) # Add / to uri if needed, some gvfs modules add one and some not if uri is not None and len(uri) > 1 and uri[-1:] != '/': uri += '/' self.__device.uri = uri def stop(self): """ Stop syncing """ self.__device_widget.cancel_sync() def __on_sync_finished(self, device_widget): """ Restore widgets state @param device widget as DeviceManager """ self.__memory_combo.show() self.__syncing_btn.set_label(_("Synchronize %s") % self.__device.name) def __set_combo_text(self, text_list): """ Set combobox text @param text list as [str] """ # Just update device widget if already populated if self.__memory_combo.get_active_text() is not None: if not self.__device_widget.is_syncing(): self.__device_widget.populate() return for text in text_list: self.__memory_combo.append_text(text) self.__memory_combo.set_active(0)
class DeviceView(View): """ Playlist synchronisation to MTP """ def get_files(uri): """ Get files for uri @param uri as str @return [str] """ files = [] try: d = Gio.File.new_for_uri(uri) if not d.query_exists(None): d.make_directory_with_parents(None) infos = d.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, None) for info in infos: suburi = uri + info.get_name() + "/Music/lollypop" sub = Gio.File.new_for_uri(suburi) if sub.query_exists(None): files.insert(0, info.get_name()) else: files.append(info.get_name()) infos.close(None) except Exception as e: print("DeviceManagerView::_get_files: %s: %s" % (uri, e)) files = [] return files def __init__(self, device, progress): """ Init view @param device as Device @param progress as Gtk.ProgressBar """ View.__init__(self) self._timeout_id = None self._device = device self._progress = progress builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerView.ui') self._memory_combo = builder.get_object('memory_combo') self._syncing_btn = builder.get_object('sync_btn') self._syncing_btn.set_label(_("Synchronize %s") % device.name) builder.connect_signals(self) grid = builder.get_object('device') self.add(grid) self._device_widget = DeviceManagerWidget(progress, self) self._device_widget.connect('sync-finished', self._on_sync_finished) self._device_widget.show() self._viewport.add(self._device_widget) self.add(self._scrolled) def populate(self): """ Populate combo box @thread safe """ files = DeviceView.get_files(self._device.uri) if files: GLib.idle_add(self._set_combo_text, files) else: GLib.idle_add(self.destroy) def is_syncing(self): """ Check if lollypop is syncing @return bool """ return self._device_widget.is_syncing() ####################### # PRIVATE # ####################### def stop(self): """ Stop syncing """ self._device_widget.cancel_sync() def _on_destroy(self, widget): """ Remove running timeout @param widget as Gtk.Widget """ if self._timeout_id is not None: GLib.source_remove(self._timeout_id) self._timeout_id = None def _on_sync_clicked(self, widget): """ Start synchronisation @param widget as Gtk.Button """ if self._device_widget.is_syncing(): self._device_widget.cancel_sync() elif not self._progress.is_visible(): self._memory_combo.hide() self._syncing_btn.set_label(_("Cancel synchronization")) self._device_widget.sync() def _on_sync_finished(self, device_widget): """ Restore widgets state @param device widget as DeviceManager """ self._progress.hide() self._progress.set_fraction(0) self._memory_combo.show() self._syncing_btn.set_label(_("Synchronize %s") % self._device.name) def _on_memory_combo_changed(self, combo): """ Update path @param combo as Gtk.ComboxText """ self._timeout_id = None text = combo.get_active_text() uri = "%s%s/Music/%s" % (self._device.uri, text, "lollypop") self._device_widget.set_uri(uri) self._device_widget.populate() def _set_combo_text(self, text_list): """ Set combobox text @param text list as [str] """ for text in text_list: self._memory_combo.append_text(text) self._memory_combo.set_active(0)
class DeviceView(View): """ @param device as Device @param progress as Gtk.ProgressBar @param width as int """ def __init__(self, device, progress, width): View.__init__(self) self._device = device self._progress = progress builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerView.ui') self._memory_combo = builder.get_object('memory_combo') self._syncing_btn = builder.get_object('sync_btn') self._syncing_btn.set_label(_("Synchronize %s") % device.name) builder.connect_signals(self) grid = builder.get_object('widget') self.add(grid) self._device_widget = DeviceManagerWidget(progress, self) self._device_widget.connect('sync-finished', self._on_sync_finished) self._device_widget.show() self._scrolledWindow.set_property('halign', Gtk.Align.CENTER) self._scrolledWindow.set_property('width-request', width) self._viewport.add(self._device_widget) self.add(self._scrolledWindow) def populate(self): files = self._get_files(self._device.uri) GLib.idle_add(self._set_combo_text, files) def is_syncing(self): return self._device_widget.is_syncing() ####################### # PRIVATE # ####################### """ Start synchronisation @param widget as Gtk.Button """ def _on_sync_clicked(self, widget): if self._device_widget.is_syncing(): self._device_widget.cancel_sync() self._on_sync_finished(None) elif not self._progress.is_visible(): self._memory_combo.hide() self._syncing_btn.set_label(_("Cancel synchronization")) self._device_widget.sync() """ Restore widgets state @param device widget as DeviceManager """ def _on_sync_finished(self, device_widget): self._memory_combo.show() self._syncing_btn.set_label(_("Synchronize %s") % self._device.name) """ Get files for uri @param uri as str @return [str] """ def _get_files(self, uri): files = [] try: d = Gio.File.new_for_uri(uri) if not d.query_exists(None): d.make_directory_with_parents(None) infos = d.enumerate_children( 'standard::name', Gio.FileQueryInfoFlags.NONE, None) for info in infos: files.append(info.get_name()) except Exception as e: print("DeviceManagerWidget::_get_files: %s: %s" % (uri, e)) files = [] return files """ Update progress bar. Do nothing """ def _update_progress(self): pass """ Update path @param combo as Gtk.ComboxText """ def _on_memory_combo_changed(self, combo): text = combo.get_active_text() uri = "%s%s/Music/%s" % (self._device.uri, text, "lollypop") on_disk_playlists = self._get_files(uri) self._device_widget.set_playlists(on_disk_playlists, uri) start_new_thread(self._device_widget.populate, ()) """ Set combobox text @param text list as [str] """ def _set_combo_text(self, text_list): for text in text_list: self._memory_combo.append_text(text) self._memory_combo.set_active(0)
class DeviceView(View): """ Playlist synchronisation to MTP """ def __init__(self, device, progress, width): """ Init view @param device as Device @param progress as Gtk.ProgressBar @param width as int """ View.__init__(self) self._device = device self._progress = progress builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerView.ui') self._memory_combo = builder.get_object('memory_combo') self._syncing_btn = builder.get_object('sync_btn') self._syncing_btn.set_label(_("Synchronize %s") % device.name) builder.connect_signals(self) grid = builder.get_object('widget') self.add(grid) self._device_widget = DeviceManagerWidget(progress, self) self._device_widget.connect('sync-finished', self._on_sync_finished) self._device_widget.show() self._scrolledWindow.set_property('halign', Gtk.Align.CENTER) self._scrolledWindow.set_property('width-request', width) self._viewport.add(self._device_widget) self.add(self._scrolledWindow) def populate(self): files = self._get_files(self._device.uri) GLib.idle_add(self._set_combo_text, files) def is_syncing(self): return self._device_widget.is_syncing() ####################### # PRIVATE # ####################### def _on_sync_clicked(self, widget): """ Start synchronisation @param widget as Gtk.Button """ if self._device_widget.is_syncing(): self._device_widget.cancel_sync() self._on_sync_finished(None) elif not self._progress.is_visible(): self._memory_combo.hide() self._syncing_btn.set_label(_("Cancel synchronization")) self._device_widget.sync() def _on_sync_finished(self, device_widget): """ Restore widgets state @param device widget as DeviceManager """ self._memory_combo.show() self._syncing_btn.set_label(_("Synchronize %s") % self._device.name) def _get_files(self, uri): """ Get files for uri @param uri as str @return [str] """ files = [] try: d = Gio.File.new_for_uri(uri) if not d.query_exists(None): d.make_directory_with_parents(None) infos = d.enumerate_children('standard::name', Gio.FileQueryInfoFlags.NONE, None) for info in infos: files.append(info.get_name()) except Exception as e: print("DeviceManagerWidget::_get_files: %s: %s" % (uri, e)) files = [] return files def _update_progress(self): """ Update progress bar. Do nothing """ pass def _on_memory_combo_changed(self, combo): """ Update path @param combo as Gtk.ComboxText """ text = combo.get_active_text() uri = "%s%s/Music/%s" % (self._device.uri, text, "lollypop") on_disk_playlists = self._get_files(uri) self._device_widget.set_playlists(on_disk_playlists, uri) self._device_widget.populate() def _set_combo_text(self, text_list): """ Set combobox text @param text list as [str] """ for text in text_list: self._memory_combo.append_text(text) self._memory_combo.set_active(0)
class DeviceView(View): """ @param device as Device @param progress as Gtk.ProgressBar @param width as int """ def __init__(self, device, progress, width): View.__init__(self) self._device = device self._progress = progress builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/DeviceManagerView.ui') self._memory_combo = builder.get_object('memory_combo') self._syncing_btn = builder.get_object('sync_btn') self._syncing_btn.set_label(_("Synchronize %s") % device.name) builder.connect_signals(self) grid = builder.get_object('widget') self.add(grid) self._device_widget = DeviceManagerWidget(device, progress, self) self._device_widget.connect('sync-finished', self._on_sync_finished) self._device_widget.show() self._scrolledWindow.set_property('halign', Gtk.Align.CENTER) self._scrolledWindow.set_property('width-request', width) self._viewport.add(self._device_widget) self.add(self._scrolledWindow) def populate(self): files = os.listdir(self._device.path) GLib.idle_add(self._set_combo_text, files) def is_syncing(self): return self._device_widget.is_syncing() ####################### # PRIVATE # ####################### """ Start synchronisation @param widget as Gtk.Button """ def _on_sync_clicked(self, widget): if self._device_widget.is_syncing(): self._device_widget.cancel_sync() self._on_sync_finished(None) elif not self._progress.is_visible(): self._memory_combo.hide() self._syncing_btn.set_label(_("Cancel synchronization")) self._device_widget.sync() """ Restore widgets state @param device widget as DeviceManager """ def _on_sync_finished(self, device_widget): self._memory_combo.show() self._syncing_btn.set_label(_("Synchronize %s") % self._device.name) """ Update path @param combo as Gtk.ComboxText """ def _on_memory_combo_changed(self, combo): text = combo.get_active_text() path = "%s/%s/Music/%s" % (self._device.path, text, "lollypop") try: if not os.path.exists(path+"/tracks"): self._mkdir(path+"/tracks") on_disk_playlists = os.listdir(path) except Exception as e: print("DeviceManagerWidget::_on_memory_combo_changed: %s" % e) on_disk_playlists = [] self._device_widget.set_playlists(on_disk_playlists, path) start_new_thread(self._device_widget.populate, ()) """ Set combobox text @param text list as [str] """ def _set_combo_text(self, text_list): for text in text_list: self._memory_combo.append_text(text) self._memory_combo.set_active(0)