def update_position(self): """ Updates the position based on gravity and offsets """ gravity = self.gravity_map[settings.get_option( 'plugin/desktopcover/anchor', 'topleft')] cover_offset_x = settings.get_option('plugin/desktopcover/x', 0) cover_offset_y = settings.get_option('plugin/desktopcover/y', 0) allocation = self.get_allocation() workarea = get_workarea_dimensions() x, y = workarea.offset_x, workarea.offset_y if gravity in (gtk.gdk.GRAVITY_NORTH_WEST, gtk.gdk.GRAVITY_SOUTH_WEST): x += cover_offset_x else: x += workarea.width - allocation.width - cover_offset_x if gravity in (gtk.gdk.GRAVITY_NORTH_WEST, gtk.gdk.GRAVITY_NORTH_EAST): y += cover_offset_y else: y += workarea.height - allocation.height - cover_offset_y self.set_gravity(gravity) self.move(int(x), int(y))
def check_login(self): """ Tries to connect to the AudioScrobbler service with the existing login data """ username = settings.get_option('plugin/ascrobbler/user', '') password = settings.get_option('plugin/ascrobbler/password', '') url = settings.get_option( 'plugin/ascrobbler/url', 'http://post.audioscrobbler.com/' ) login_verified = False try: _scrobbler.login(username, password, post_url=url) except _scrobbler.AuthError: try: _scrobbler.login(username, password, hashpw=True, post_url=url) except _scrobbler.AuthError: pass else: login_verified = True else: login_verified = True if login_verified: GLib.idle_add(self.message.show_info, _('Verification successful'), '') else: GLib.idle_add( self.message.show_error, _('Verification failed'), _('Please make sure the entered data is correct.'), ) GLib.idle_add(self.widget.set_sensitive, True)
def setup_network(self): """ Tries to set up the network, retrieve the user and the initial list of loved tracks """ try: self.network = pylast.LastFMNetwork( api_key=settings.get_option('plugin/lastfmlove/api_key', 'K'), api_secret=settings.get_option('plugin/lastfmlove/api_secret', 'S'), username=settings.get_option('plugin/ascrobbler/user', ''), password_hash=settings.get_option('plugin/ascrobbler/password', ''), ) self.user = self.network.get_user(self.network.username) except Exception as e: self.network = None self.user = None if self.timer is not None and self.timer.is_alive(): self.timer.cancel() logger.warning('Error while connecting to Last.fm network: {0}'.format(e)) else: thread = Thread(target=self.get_loved_tracks) thread.daemon = True thread.start() logger.info('Connection to Last.fm network successful')
def _on_option_set(self, evtype, settings, option): if option == self.__opt_remove_item_when_played: self.__remove_item_on_playback = settings.get_option(option, True) if len(self): self.__queue_has_tracks = True elif option == self.__opt_disable_new_track_when_playing: self.__disable_new_track_when_playing = settings.get_option(option, False)
def find_covers(self, track, limit=-1): """ Searches amazon for album covers """ try: artist = track.get_tag_raw('artist')[0] album = track.get_tag_raw('album')[0] except (AttributeError, TypeError): return [] # get the settings for amazon key and secret key api_key = settings.get_option('plugin/amazoncovers/api_key', '') secret_key = settings.get_option('plugin/amazoncovers/secret_key', '') if not api_key or not secret_key: logger.warning( 'Please enter your Amazon API and secret ' 'keys in the Amazon Covers preferences' ) return [] # wait at least 1 second until the next attempt waittime = 1 - (time.time() - self.starttime) if waittime > 0: time.sleep(waittime) self.starttime = time.time() search = "%s - %s" % (artist, album) try: albums = ecs.search_covers(search, api_key, secret_key, USER_AGENT) except ecs.AmazonSearchError: return [] return albums
def __init__(self, location): """ :param location: The directory to load and store data in. """ providers.ProviderHandler.__init__(self, "covers") self.__cache = Cacher(os.path.join(location, 'cache')) self.location = location self.methods = {} self.order = settings.get_option( 'covers/preferred_order', []) self.db = {} self.load() for method in self.get_providers(): self.on_provider_added(method) default_cover_file = open(xdg.get_data_path('images', 'nocover.png'), 'rb') self.default_cover_data = default_cover_file.read() default_cover_file.close() self.tag_fetcher = TagCoverFetcher() self.localfile_fetcher = LocalFileCoverFetcher() if settings.get_option('covers/use_tags', True): providers.register('covers', self.tag_fetcher) if settings.get_option('covers/use_localfile', True): providers.register('covers', self.localfile_fetcher) event.add_callback(self._on_option_set, 'covers_option_set')
def _on_option_set(self, name, object, data): if data == "replaygain/album-mode": self.rgvol.set_property("album-mode", settings.get_option("replaygain/album-mode", True)) elif data == "replaygain/pre-amp": self.rgvol.set_property("pre-amp", settings.get_option("replaygain/pre-amp", 0)) elif data == "replaygain/fallback-gain": self.rgvol.set_property("fallback-gain", settings.get_option("replaygain/fallback-gain", 0))
def set_cover_from_track(self, track): """ Updates the cover image and triggers cross-fading """ cover_data = covers.MANAGER.get_cover(track, set_only=True) if cover_data is None: self.hide() return if not self.props.visible: self.show() size = settings.get_option('plugin/desktopcover/size', 200) upscale = settings.get_option('plugin/desktopcover/override_size', False) pixbuf = self.image.get_pixbuf() next_pixbuf = icons.MANAGER.pixbuf_from_data( cover_data, size=(size, size), upscale=upscale) fading = settings.get_option('plugin/desktopcover/fading', False) if fading and pixbuf is not None and self._cross_fade_id is None: # Prescale to allow for proper crossfading width, height = next_pixbuf.get_width(), next_pixbuf.get_height() pixbuf = pixbuf.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR) glib.idle_add(self.image.set_from_pixbuf, pixbuf) duration = settings.get_option( 'plugin/desktopcover/fading_duration', 50) self._cross_fade_id = glib.timeout_add(int(duration), self.cross_fade, pixbuf, next_pixbuf, duration) else: glib.idle_add(self.image.set_from_pixbuf, next_pixbuf)
def _on_option_set(self, name, object, option): """ Handles changes of settings """ if option == "gui/main_window_title_format": self.title_formatter.props.format = settings.get_option(option, self.title_formatter.props.format) if option == "gui/use_tray": usetray = settings.get_option(option, False) if self.controller.tray_icon and not usetray: glib.idle_add(self.controller.tray_icon.destroy) self.controller.tray_icon = None elif not self.controller.tray_icon and usetray: self.controller.tray_icon = tray.TrayIcon(self) if option == "gui/show_info_area": glib.idle_add(self.info_area.set_no_show_all, False) if settings.get_option(option, True): glib.idle_add(self.info_area.show_all) else: glib.idle_add(self.info_area.hide_all) glib.idle_add(self.info_area.set_no_show_all, True) if option == "gui/show_info_area_covers": def _setup_info_covers(): cover = self.info_area.cover cover.set_no_show_all(False) if settings.get_option(option, True): cover.show_all() else: cover.hide_all() cover.set_no_show_all(True) glib.idle_add(_setup_info_covers)
def sink_from_preset(player, preset): if preset == "custom": pipe = settings.get_option("%s/custom_sink_pipe" % player._name, "") if not pipe: logger.error("No custom sink pipe set for %s" % player._name) return None name = _("Custom") else: d = SINK_PRESETS.get(preset, "") if not d: logger.error("Could not find sink preset %s for %s." % (preset, player._name)) return None name = d['name'] pipe = d['pipe'] if preset != 'auto': dname = settings.get_option('%s/audiosink_device' % player._name) if dname: pipe += ' device=' + dname if 'pipeargs' in d: pipe += ' ' + d['pipeargs'] try: sink = AudioSink(name, pipe, player) except Exception: common.log_exception(log=logger, message="Could not enable audiosink %s for %s." % (preset, player._name)) return None return sink
def __autoconfig(): ''' If the user hasn't used our plugin before, then try to autoconfig their audio settings to use a different audio device if possible.. TODO: It would be cool if we could notify the user that a new device was plugged in... ''' from xl import settings if settings.get_option('preview_device/audiosink', None) is not None: return sink = settings.get_option('player/audiosink', None) if sink is None: return settings.set_option( 'preview_device/audiosink', sink ) main_device = settings.get_option('player/audiosink_device', None) if main_device is None: return from xl.player import pipe devices = pipe.sink_enumerate_devices(sink) if devices is not None: # pick the first one that isn't the main device and isn't 'Auto' # -> if the main device is '', then it's auto. So... we actually # iterate backwards, assuming that the ordering matters for device,name in reversed(devices): if device != main_device and name != _('Auto'): settings.set_option( 'preview_device/audiosink_device', device ) break
def _on_option_set(self, name, object, option): """ Handles changes of settings """ if option == 'gui/main_window_title_format': self.title_formatter.props.format = settings.get_option( option, self.title_formatter.props.format) elif option == 'gui/use_tray': usetray = settings.get_option(option, False) if self.controller.tray_icon and not usetray: self.controller.tray_icon.destroy() self.controller.tray_icon = None elif not self.controller.tray_icon and usetray: self.controller.tray_icon = tray.TrayIcon(self) elif option == 'gui/show_info_area': self.info_area.set_no_show_all(False) if settings.get_option(option, True): self.info_area.show_all() else: self.info_area.hide() self.info_area.set_no_show_all(True) elif option == 'gui/show_info_area_covers': cover = self.info_area.cover cover.set_no_show_all(False) if settings.get_option(option, True): cover.show_all() else: cover.hide() cover.set_no_show_all(True) elif option == 'gui/transparency': self._update_alpha()
def on_gui_loaded(self): save_on_exit = settings.get_option( 'plugin/history/save_on_exit', history_preferences.save_on_exit_default ) shown = settings.get_option('plugin/history/shown', False) # immutable playlist that stores everything we've played self.history_loc = os.path.join(xdg.get_data_dir(), 'history') self.history_playlist = HistoryPlaylist(player.PLAYER) if save_on_exit: self.history_playlist.load_from_location(self.history_loc) self.history_page = HistoryPlaylistPage(self.history_playlist, player.PLAYER) self.history_tab = NotebookTab(main.get_playlist_notebook(), self.history_page) # add menu item to 'view' to display our playlist self.menu = menu.check_menu_item( 'history', '', _('Playback history'), lambda *e: self.is_shown(), self.on_playback_history, ) providers.register('menubar-view-menu', self.menu) # add the history playlist to the primary notebook if save_on_exit and shown: self.show_history(True)
def do_init(self, captcha_id=None, captcha_solution=None): username = settings.get_option("plugin/douban_radio/username") password = settings.get_option("plugin/douban_radio/password") try: self.doubanfm = DoubanFM(username, password, captcha_id, captcha_solution) except DoubanLoginException as e: if e.data['captcha_id'] is None: self.exaile.gui.main.message.show_error( _('Douban FM Error'), _('Failed to login to douban.fm with your credential')) return else: captcha_id = e.data['captcha_id'] self.show_captcha_dialog(captcha_id) return self.channels = self.doubanfm.channels self.__create_menu_item__() self.check_to_enable_dbus() self.__register_events() self.doubanfm_cover = DoubanFMCover() providers.register('covers', self.doubanfm_cover) self.doubanfm_mode = DoubanFMMode(self.exaile, self)
def _restore_player_state(self, location): if not settings.get_option("%s/resume_playback" % self.player._name, True): return try: f = open(location, 'rb') state = pickle.load(f) f.close() except: return for req in ['state', 'position', '_playtime_stamp']: if req not in state: return if state['state'] in ['playing', 'paused']: event.log_event("playback_player_resume", self.player, None) vol = self.player._get_volume() self.player._set_volume(0) self.play(self.get_current()) if self.player.current: self.player.seek(state['position']) if state['state'] == 'paused' or \ settings.get_option("%s/resume_paused" % self.player._name, False): self.player.toggle_pause() self.player._playtime_stamp = state['_playtime_stamp'] self.player._set_volume(vol)
def create_device(player_name, return_errorsink=True): ''' Creates an audiosink based on the current settings. This will always return an audiosink, but sometimes it will return an audiosink that only sends error messages to the bus. ..note:: Only attempts to autoselect if the user has never specified a setting manually. Otherwise, they may be confused when it switches to a new output. For example, if they specified a USB device, and it is removed -- when restarting the program, they would not expect to automatically start playing on the builtin sound. ''' sink_type = settings.get_option('%s/audiosink' % player_name, 'auto') name = '%s-audiosink' % player_name sink = None errmsg = None if sink_type == 'auto': specified_device = settings.get_option('%s/audiosink_device' % player_name, 'auto') for _unused, device_id, create in get_devices(): if specified_device == device_id: sink = create(name) break if sink is None: errmsg = _("Could not create audiosink (device: %s, type: %s)") errmsg = errmsg % (specified_device, sink_type) elif sink_type == 'custom': pipeline = settings.get_option("%s/custom_sink_pipe" % player_name, "") if not pipeline: errmsg = _("No custom pipeline specified!") else: try: sink = CustomAudioSink(pipeline, name) except: errmsg = _("Error creating custom audiosink '%s'") % pipeline logger.exception(errmsg) else: preset = SINK_PRESETS.get(sink_type, None) if preset is None: errmsg = _("Invalid sink type '%s' specified") % sink_type else: sink = Gst.ElementFactory.make(preset['pipe'], name) if sink is None: errmsg = _("Could not create sink type '%s'") % preset['pipe'] if errmsg is not None: logger.error(errmsg) if return_errorsink: sink = _get_error_audiosink(errmsg) return sink
def _setup_position(self): width = settings.get_option('gui/trackprop_width', 600) height = settings.get_option('gui/trackprop_height', 350) x = settings.get_option('gui/trackprop_x', 100) y = settings.get_option('gui/trackprop_y', 100) self.dialog.move(x, y) self.dialog.resize(width, height)
def window_state_change_event(self, window, event): """ Saves the current maximized and fullscreen states and minimizes to tray if requested """ if event.changed_mask & gtk.gdk.WINDOW_STATE_MAXIMIZED: settings.set_option("gui/mainw_maximized", bool(event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED)) if event.changed_mask & gtk.gdk.WINDOW_STATE_FULLSCREEN: self._fullscreen = bool(event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN) # detect minimization state changes prev_minimized = self.minimized if not self.minimized: if ( event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED and not event.changed_mask & gtk.gdk.WINDOW_STATE_WITHDRAWN and event.new_window_state & gtk.gdk.WINDOW_STATE_ICONIFIED and not event.new_window_state & gtk.gdk.WINDOW_STATE_WITHDRAWN and not self.window_state & gtk.gdk.WINDOW_STATE_ICONIFIED ): self.minimized = True else: if event.changed_mask & gtk.gdk.WINDOW_STATE_WITHDRAWN and not event.new_window_state & ( gtk.gdk.WINDOW_STATE_WITHDRAWN ): # and \ self.minimized = False # track this self.window_state = event.new_window_state if settings.get_option("gui/minimize_to_tray", False): # old code to detect minimization # -> it must have worked at some point, perhaps this is a GTK version # specific set of behaviors? Current code works now on 2.24.17 # if wm_state is not None: # if '_NET_WM_STATE_HIDDEN' in wm_state[2]: # show tray # window.hide # else # destroy tray if self.minimized != prev_minimized and self.minimized == True: if not settings.get_option("gui/use_tray", False) and self.controller.tray_icon is None: self.controller.tray_icon = tray.TrayIcon(self) window.hide() elif window.window.property_get("_NET_WM_STATE") is None: if not settings.get_option("gui/use_tray", False) and self.controller.tray_icon is not None: self.controller.tray_icon.destroy() self.controller.tray_icon = None return False
def check_default_settings(): for band in range(10): if settings.get_option("plugin/equalizer/band%s" % band) is None: settings.set_option("plugin/equalizer/band%s" % band, 0.0) if settings.get_option("plugin/equalizer/pre") is None: settings.set_option("plugin/equalizer/pre", 0.0) if settings.get_option("plugin/equalizer/enabled") is None: settings.set_option("plugin/equalizer/enabled", True)
def migrate(): """ Enables the OSD plugin if the builtin OSD was originally enabled """ plugins = settings.get_option('plugins/enabled', []) if settings.get_option('osd/enabled', False) and 'osd' not in plugins: settings.set_option('plugins/enabled', plugins + ['osd']) settings.set_option('osd/enabled', False)
def check_alarms(main, exaile): """ Called every timeout. If the plugin is not enabled, it does nothing. If the current time matches the time specified and the current day is selected, it starts playing """ if not main: return True # TODO: new way? current = time.strftime("%H:%M", time.localtime()) currentDay = int(time.strftime("%w", time.localtime())) # generate list of alarms from model alist = [ Alarm(active=row[0], name=row[1], time=row[2], days=row[3]) for row in main.model ] # print current , [ a.time for a in alist if a.active ] for al in alist: if al.active and al.time == current and al.days[currentDay] == True: check = time.strftime("%m %d %Y %H:%M") # clever... if check in main.RANG: logger.debug('Alarm {0} in RANG'.format(al.name)) return True logger.info('Alarm {0} hit.'.format(al.name)) # tracks to play? count = len(player.QUEUE) if player.QUEUE.current_playlist: count += len(player.QUEUE.current_playlist) else: count += len(exaile.gui.main.get_selected_page().playlist) if count == 0: logger.warning('No tracks queued for alarm to play.') return True if player.PLAYER.is_playing(): # Check if there are songs in playlist and if it is already playing logger.info('Alarm hit, but already playing') return True if settings.get_option('plugin/multialarmclock/fading_on'): fade_in(main, exaile) # thread.start_new(fade_in, (main, exaile)) if settings.get_option('plugin/multialarmclock/restart_playlist_on'): logger.debug('try to restart playlist') if player.QUEUE.current_playlist: player.QUEUE.current_playlist.set_current_position(-1) else: player.QUEUE.set_current_playlist(exaile.gui.main.get_selected_page()) player.QUEUE.play() main.RANG[check] = True return True
def _save_position(self): (width, height) = self.dialog.get_size() if [width, height] != [settings.get_option('gui/trackprop_' + key, -1) for key in ['width', 'height']]: settings.set_option('gui/trackprop_height', height, save=False) settings.set_option('gui/trackprop_width', width, save=False) (x, y) = self.dialog.get_position() if [x, y] != [settings.get_option('gui/trackprop_' + key, -1) for key in ['x', 'y']]: settings.set_option('gui/trackprop_x', x, save=False) settings.set_option('gui/trackprop_y', y, save=False)
def _on_option_set(self, name, obj, data): if data == "covers/use_tags": if settings.get_option("covers/use_tags"): providers.register('covers', self.tag_fetcher) else: providers.unregister('covers', self.tag_fetcher) elif data == "covers/use_localfile": if settings.get_option("covers/use_localfile"): providers.register('covers', self.localfile_fetcher) else: providers.unregister('covers', self.localfile_fetcher)
def add_preset(self, _widget): new_preset = [] new_preset.append(self.combo_presets.get_child().get_text()) new_preset.append(settings.get_option("plugin/equalizer/pre")) for band in range(10): new_preset.append(settings.get_option("plugin/equalizer/band%s" % band)) self.presets.append(new_preset) self.save_presets()
def __init__(self): Gtk.Window.__init__(self) self.init_template() self.pre.set_value(settings.get_option("plugin/equalizer/pre")) self.chk_enabled.set_active(settings.get_option("plugin/equalizer/enabled")) # Setup bands/preamp from current equalizer settings for number in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9): band = getattr(self, 'band%s' % number) band.set_value(self.get_band(number)) self.combo_presets.set_entry_text_column(0) self.combo_presets.set_active(0) self.load_presets()
def migrate_settings(): '''Automatically migrate group tagger 0.1 settings to 0.2''' if settings.get_option(migrated_option, False): default_groups = settings.get_option('plugin/grouptagger/default_groups', None) if default_groups is not None: group_categories = {_('Uncategorized'): [True, default_groups]} set_group_categories(group_categories) # settings.remove_option( 'plugin/grouptagger/default_groups' ) settings.set_option(migrated_option, True)
def hide(self): """ Override for fade-out """ fading = settings.get_option('plugin/desktopcover/fading', False) if fading and self._fade_out_id is None: duration = settings.get_option('plugin/desktopcover/fading_duration', 50) self._fade_out_id = GLib.timeout_add(int(duration), self.fade_out) else: Gtk.Window.hide(self) self.image.set_from_pixbuf(None)
def on_gui_loaded(self): event.add_callback(self.__on_settings_changed, 'plugin_daapserver_option_set') port = int(settings.get_option('plugin/daapserver/port', 3689)) name = settings.get_option('plugin/daapserver/name', 'Exaile Share') host = settings.get_option('plugin/daapserver/host', '0.0.0.0') self.__daapserver = DaapServer( CollectionWrapper(self.__exaile.collection), port=port, name=name, host=host ) if settings.get_option('plugin/daapserver/enabled', True): self.__daapserver.start()
def on_page_removed(self, notebook, child, page_number): """ Updates appearance on page removal """ if self.get_n_pages() == 1: self.set_show_tabs(settings.get_option('gui/show_tabbar', True)) # closed tab history if not self._moving_tab and \ settings.get_option('gui/save_closed_tabs', True) and \ isinstance(child, PlaylistPage): self.save_closed_tab(child.playlist)
def migrate(): """ Migrates the old 'miscellaneous/rating_*' to the new 'rating/*' settings """ if settings.MANAGER.has_option('miscellaneous/rating_steps'): value = settings.get_option('miscellaneous/rating_steps', 5) settings.set_option('rating/maximum', value) if settings.MANAGER.has_option('miscellaneous/rating_widget_tracks_limit'): value = settings.get_option('miscellaneous/rating_widget_tracks_limit', 100) settings.set_option('rating/tracks_limit', value)
def __migrate_fixed_controls(): """ Makes sure fixed controls are selected, mostly for migration from older versions """ option_name = 'plugin/minimode/selected_controls' if settings.MANAGER.has_option(option_name): selected_controls = settings.get_option(option_name) if 'restore' not in selected_controls: selected_controls += ['restore'] settings.set_option(option_name, selected_controls)
def _start_crossfade(self, *args): tr = None if settings.get_option("%s/auto_advance" % self._name, True): tr = self.queue.next(autoplay=False) if tr is not None: self.play(tr, user=False) if self._timer_id: glib.source_remove(self._timer_id) if tr is None: self._timer_id = glib.timeout_add(1000 * \ (self.current.get_tag_raw('__length') - self.get_time()), self.stop) return False
def on_scroll_event(self, widget, event): """ Changes volume and skips tracks on scroll """ if event.get_state() & Gdk.ModifierType.SHIFT_MASK: if event.direction == Gdk.ScrollDirection.UP: player.QUEUE.prev() elif event.direction == Gdk.ScrollDirection.DOWN: player.QUEUE.next() else: if event.direction == Gdk.ScrollDirection.UP: volume = settings.get_option('player/volume', 1) settings.set_option('player/volume', min(volume + self.VOLUME_STEP, 1)) return True elif event.direction == Gdk.ScrollDirection.DOWN: volume = settings.get_option('player/volume', 1) settings.set_option('player/volume', max(0, volume - self.VOLUME_STEP)) return True elif event.direction == Gdk.ScrollDirection.LEFT: player.QUEUE.prev() elif event.direction == Gdk.ScrollDirection.RIGHT: player.QUEUE.next()
def get_user_agent_string(self, plugin_name=None): ''' Returns an approrpiately formatted User-agent string for web requests. When possible, plugins should use this to format user agent strings. Users can control this agent string by manually setting general/user_agent and general/user_agent_w_plugin in settings.ini :param plugin_name: the name of the plugin ''' version = __version__ if '+' in version: # strip out revision identifier version = version[:version.index('+')] fmt = {'version': version} if not hasattr(self, '_user_agent_no_plugin'): from xl import settings default_no_plugin = 'Exaile/%(version)s (+http://www.exaile.org)' default_plugin = 'Exaile/%(version)s %(plugin_name)s/%(plugin_version)s (+http://www.exaile.org)' self._user_agent_no_plugin = \ settings.get_option('general/user_agent', default_no_plugin) self._user_agent_w_plugin = \ settings.get_option('general/user_agent_w_plugin', default_plugin) if plugin_name is not None: plugin_info = self.plugins.get_plugin_info(plugin_name) fmt['plugin_name'] = plugin_info['Name'].replace(' ', '') fmt['plugin_version'] = plugin_info['Version'] return self._user_agent_w_plugin % fmt else: return self._user_agent_no_plugin % fmt
def __show_splash(self): """ Displays the splash screen """ from xl import settings if not settings.get_option('gui/use_splash', True): return from xlgui.widgets.info import Splash splash = Splash() splash.show()
def add_driver(self, driver): """ Adds a driver to the radio panel """ node = self.model.append(self.radio_root, [self.folder, str(driver), driver]) self.nodes[driver] = node self.load_nodes[driver] = self.model.append(node, [self.refresh_image, _('Loading streams...'), None]) self.tree.expand_row(self.model.get_path(self.radio_root), False) if settings.get_option('gui/radio/%s_station_expanded' % driver.name, False): self.tree.expand_row(self.model.get_path(node), False)
def _enable(exaile): """ Enable plugin. Create menu item. """ # add menuitem to tools menu item = menu.simple_menu_item('ipconsole', ['plugin-sep'], _('Show _IPython Console'), callback=lambda *x: show_console(exaile)) providers.register('menubar-tools-menu', item) if settings.get_option('plugin/ipconsole/autostart', False): show_console(exaile)
def adjust_band(self, widget): """ Adjust the specified band """ # Buildable.get_name clashes with Widget.get_name. See # https://bugzilla.gnome.org/show_bug.cgi?id=591085#c19 widget_name = Gtk.Buildable.get_name(widget) band = widget_name[-1] settings_value = settings.get_option("plugin/equalizer/band" + band) if not isclose(widget.get_value(), settings_value): settings.set_option("plugin/equalizer/band" + band, widget.get_value()) self.combo_presets.set_active(0)
def _on_option_set(self, name, object, option): """ Handles changes of settings """ if option == 'gui/main_window_title_format': self.title_formatter.props.format = settings.get_option( option, self.title_formatter.props.format ) elif option == 'gui/use_tray': usetray = settings.get_option(option, False) if self.controller.tray_icon and not usetray: self.controller.tray_icon.destroy() self.controller.tray_icon = None elif not self.controller.tray_icon and usetray: self.controller.tray_icon = tray.TrayIcon(self) elif option == 'gui/show_info_area': self.info_area.set_no_show_all(False) if settings.get_option(option, True): self.info_area.show_all() else: self.info_area.hide() self.info_area.set_no_show_all(True) elif option == 'gui/show_info_area_covers': cover = self.info_area.cover cover.set_no_show_all(False) if settings.get_option(option, True): cover.show_all() else: cover.hide() cover.set_no_show_all(True) elif option == 'gui/transparency': self._update_alpha() elif option == 'gui/gtk_dark_hint': self._update_dark_hint()
def configure_event(self, *e): """ Called when the window is resized or moved """ # Don't save window size if it is maximized or fullscreen. if settings.get_option('gui/mainw_maximized', False) or self._fullscreen: return False (width, height) = self.window.get_size() if [width, height] != [ settings.get_option("gui/mainw_" + key, -1) for key in ["width", "height"] ]: settings.set_option('gui/mainw_height', height, save=False) settings.set_option('gui/mainw_width', width, save=False) (x, y) = self.window.get_position() if [x, y] != [ settings.get_option("gui/mainw_" + key, -1) for key in ["x", "y"] ]: settings.set_option('gui/mainw_x', x, save=False) settings.set_option('gui/mainw_y', y, save=False) return False
def adjust_band(self, widget, data): """ Adjust the specified band """ # Buildable.get_name clashes with Widget.get_name. See # https://bugzilla.gnome.org/show_bug.cgi?id=591085#c19 widget_name = gtk.Buildable.get_name(widget) band = widget_name[-1] if widget.get_value() != settings.get_option("plugin/equalizer/band" + band): settings.set_option("plugin/equalizer/band" + band, widget.get_value()) self.ui.get_object("combo-presets").set_active(0)
def _on_about_to_finish(self, pbin): ''' This function exists solely to allow gapless playback for audio formats that support it. Setting the URI property of the playbin will queue the track for playback immediately after the previous track. ''' if settings.get_option("%s/auto_advance" % self._name, True): track = self.queue.get_next() if track: uri = track.get_loc_for_io() self._pipe.set_property("uri", uri) self._buffered_track = track
def load_settings( self ): prefix = "plugin/alarmclock/" # Setting name, property to save to, default value setting_values = ( ('alarm_use_fading', 'use_fading', False), ('alarm_min_volume', 'min_volume', 0), ('alarm_max_volume', 'max_volume', 100), ('alarm_increment', 'increment', 1), ('alarm_time_per_inc', 'time_per_inc', 1), ) for name, prop, default in setting_values: setattr(self, prop, settings.get_option(prefix + name, default))
class DefaultPage(ContextPage): def __init__(self, theme, base='default://', template='default.html', async=[]): self.user = None try: self.username = settings.get_option('plugin/lastfm/user') self.password_hash = pylast.md5( settings.get_option('plugin/lastfm/password')) except: self.username = None self.password_hash = None ContextPage.__init__( self, theme, base, template, async + [ 'last-played-tracks', 'last-played-artists', 'last-added-tracks', 'last-added-artists', 'most-played-tracks', 'most-played-artists', 'lfm-last-played', 'lfm-top-tracks', 'lfm-top-albums', 'lfm-top-artists' ])
def on_expose_event(self, widget, event): """ Paints the window alpha transparency """ opacity = 1 - settings.get_option('gui/transparency', 0.3) context = widget.window.cairo_create() background = widget.style.bg[gtk.STATE_NORMAL] context.set_source_rgba( float(background.red) / 256**2, float(background.green) / 256**2, float(background.blue) / 256**2, opacity) context.set_operator(cairo.OPERATOR_SOURCE) context.paint()
def restart_timer(self): """ Restarts the timer which starts the retrieval of tracks """ if self.timer is not None and self.timer.is_alive(): self.timer.cancel() self.timer = Timer( settings.get_option('plugin/lastfmlove/refresh_interval', 3600), self.get_loved_tracks, ) self.timer.daemon = True self.timer.start()
def set_rating(self, rating): """ Sets the current track rating from an integer, on the scale determined by the ``rating/maximum`` setting. Returns the scaled rating """ maximum = settings.get_option("rating/maximum", 5) rating = min(rating, maximum) rating = max(0, rating) rating = 100 * rating / maximum self.set_tags(__rating=rating) return rating
def save_closed_tab(self, playlist): # don't let the list grow indefinitely items = providers.get('playlist-closed-tab-menu', self) if len(self.tab_history) > settings.get_option('gui/max_closed_tabs', 10): self.remove_closed_tab(-1) # remove last item item_name = 'playlist%05d' % self.history_counter close_time = datetime.now() # define a MenuItem factory that supports dynamic labels def factory(menu_, parent, context): item = None dt = (datetime.now() - close_time) if dt.seconds > 60: display_name = _( '{playlist_name} ({track_count} tracks, closed {minutes} min ago)' ).format(playlist_name=playlist.name, track_count=len(playlist), minutes=dt.seconds // 60) else: display_name = _( '{playlist_name} ({track_count} tracks, closed {seconds} sec ago)' ).format(playlist_name=playlist.name, track_count=len(playlist), seconds=dt.seconds) item = gtk.ImageMenuItem(display_name) item.set_image( gtk.image_new_from_icon_name('music-library', gtk.ICON_SIZE_MENU)) # Add accelerator to top item if self.tab_history[0][1].name == item_name: key, mods = gtk.accelerator_parse(self.accelerator.keys) item.add_accelerator('activate', menu.FAKEACCELGROUP, key, mods, gtk.ACCEL_VISIBLE) item.connect( 'activate', lambda w: self.restore_closed_tab(item_name=item_name)) return item # create menuitem item = menu.MenuItem(item_name, factory, []) providers.register('playlist-closed-tab-menu', item, self) self.history_counter -= 1 # add self.tab_history.insert(0, (playlist, item))
def _check_compilation(self, ccheck, compilations, tr): """ This is the hacky way to test to see if a particular track is a part of a compilation. Basically, if there is more than one track in a directory that has the same album but different artist, we assume that it's part of a compilation. :param ccheck: dictionary for internal use :param compilations: if a compilation is found, it'll be appended to this list :param tr: the track to check """ # check for compilations if not settings.get_option('collection/file_based_compilations', True): return def joiner(value): if isinstance(value, list): return "\0".join(value) else: return value try: basedir = joiner(tr.get_tag_raw('__basedir')) album = joiner(tr.get_tag_raw('album')) artist = joiner(tr.get_tag_raw('artist')) except Exception: logger.warning("Error while checking for compilation: %s", tr) return if not basedir or not album or not artist: return album = album.lower() artist = artist.lower() try: if basedir not in ccheck: ccheck[basedir] = {} if album not in ccheck[basedir]: ccheck[basedir][album] = deque() except TypeError: logger.exception("Error adding to compilation") return if ccheck[basedir][album] and artist not in ccheck[basedir][album]: if not (basedir, album) in compilations: compilations.append((basedir, album)) logger.debug("Compilation %r detected in %r", album, basedir) ccheck[basedir][album].append(artist)
def show_gui(self, exaile): """ Display main window. """ if self.window: self.window.present() return signals = { 'on_main-window_destroy': self.destroy_gui, 'on_chk-enabled_toggled': self.toggle_enabled, 'on_combo-presets_changed': self.preset_changed, 'on_add-preset_clicked': self.add_preset, 'on_remove-preset_clicked': self.remove_preset, 'on_pre_format_value': self.adjust_preamp, 'on_band0_format_value': self.adjust_band, 'on_band1_format_value': self.adjust_band, 'on_band2_format_value': self.adjust_band, 'on_band3_format_value': self.adjust_band, 'on_band4_format_value': self.adjust_band, 'on_band5_format_value': self.adjust_band, 'on_band6_format_value': self.adjust_band, 'on_band7_format_value': self.adjust_band, 'on_band8_format_value': self.adjust_band, 'on_band9_format_value': self.adjust_band } self.ui = Gtk.Builder() self.ui.add_from_file( os.path.join(os.path.dirname(os.path.realpath(__file__)), 'equalizer.ui')) self.ui.connect_signals(signals) self.window = self.ui.get_object('main-window') #Setup bands/preamp from current equalizer settings for x in (0, 1, 2, 3, 4, 5, 6, 7, 8, 9): self.ui.get_object('band%s' % x).set_value(self.get_band(x)) self.ui.get_object("pre").set_value(self.get_pre()) #Put the presets into the presets combobox combobox = self.ui.get_object("combo-presets") combobox.set_model(self.presets) combobox.set_entry_text_column(0) combobox.set_active(0) self.ui.get_object('chk-enabled').set_active( settings.get_option("plugin/equalizer/enabled")) self.window.show_all()
def check_connection(self): """ Checks API key and secret for validity and opens the URI for access permission """ api_key = settings.get_option('plugin/lastfmlove/api_key', 'K') try: pylast.LastFMNetwork( api_key=api_key, api_secret=settings.get_option('plugin/lastfmlove/api_secret', 'S'), username=settings.get_option('plugin/ascrobbler/user', ''), password_hash=settings.get_option('plugin/ascrobbler/password', ''), ) except pylast.WSError as e: GLib.idle_add( self.message.show_error, self.errors[int(e.get_id())], _('Please make sure the entered data is correct.'), ) else: application_launched = Gtk.show_uri( Gdk.Screen.get_default(), 'http://www.last.fm/api/auth?api_key={0}'.format(api_key), Gdk.CURRENT_TIME, ) if not application_launched: url = 'http://www.last.fm/api/auth?api_key={0}'.format(api_key) GLib.idle_add( self.message.show_warning, _('Could not start web browser'), _('Please copy the following URL and ' 'open it with your web browser:\n' '<b><a href="{url}">{url}</a></b>').format(url=url), )
def _enable(eventname, exaile, nothing): global PLAYERMODE, EXAILE options = {'LyricColor': settings.get_option('plugin/LyricDisp/lc' , '#43AAD0'), \ 'Opacity': float(settings.get_option('plugin/LyricDisp/op', '0.8')), \ 'LyricFolder': settings.get_option('plugin/LyricDisp/lf', '~/lyrics'), \ 'WindowPositionx': settings.get_option('plugin/LyricDisp/windowpositionx', 'centre'), \ 'WindowPositiony': settings.get_option('plugin/LyricDisp/windowpositiony', 'centre'), \ 'LyricSpacing': settings.get_option('plugin/LyricDisp/lyricspacing', '2'), \ 'Filename': settings.get_option('plugin/LyricDisp/ln' , 'artist-title.lrc')} PLAYERMODE = settings.get_option('plugin/LyricDisp/ms', '窗口模式') if PLAYERMODE == '面板模式': Panel.enable(exaile, options) elif PLAYERMODE == '窗口模式': Win.enable(exaile, options) event.add_callback(ChangeMode, 'mode_change') EXAILE = exaile
def on_gui_loaded(self, event, object, nothing): """ Allows plugins to be the last selected panel """ try: last_selected_panel = settings.get_option( 'gui/last_selected_panel', 'collection') panel = self.panels[last_selected_panel]._child panel_num = self.panel_notebook.page_num(panel) self.panel_notebook.set_current_page(panel_num) # Fix track info not displaying properly when resuming after a restart. self.main._update_track_information() except KeyError: pass
def button_press(self, widget, event): """ Called when the user clicks on the tree """ #selection = self.tree.get_selection() (x, y) = map(int, event.get_coords()) #path = self.tree.get_path_at_pos(x, y) if event.type == Gdk.EventType._2BUTTON_PRESS: replace = settings.get_option('playlist/replace_content', False) self.append_to_playlist(replace=replace) return False elif event.button == Gdk.BUTTON_MIDDLE: self.append_to_playlist(replace=True) return False
def _update_dark_hint(self): gs = Gtk.Settings.get_default() # We should use reset_property, but that's only available in > 3.20... if not hasattr(self, '_default_dark_hint'): self._default_dark_hint = gs.props.gtk_application_prefer_dark_theme if settings.get_option('gui/gtk_dark_hint', False): gs.props.gtk_application_prefer_dark_theme = True elif gs.props.gtk_application_prefer_dark_theme != self._default_dark_hint: # don't set it explicitly otherwise the app will revert to a light # theme -- what we actually want is to leave it up to the OS gs.props.gtk_application_prefer_dark_theme = self._default_dark_hint
def do_button_release_event(self, event): """ Applies the selected rating """ if self.get_state_flags() & Gtk.StateType.INSENSITIVE: return allocation = self.get_allocation() maximum = settings.get_option('rating/maximum', 5) pixbuf_width = self._image.get_pixbuf().get_width() # Activate pixbuf if half of it has been passed threshold = (pixbuf_width / maximum) / 2 position = (event.x + threshold) / allocation.width self.props.rating = int(position * maximum)
def _do_restore_player_state(self, state): if state['state'] in ['playing', 'paused']: start_at = None if state['position'] is not None: start_at = state['position'] paused = state['state'] == 'paused' or settings.get_option( "%s/resume_paused" % self.player._name, False) self.player.play(self.get_current(), start_at=start_at, paused=paused)
def set_rating(self, rating): """ Sets the current track rating from an integer, on the scale determined by the ``rating/maximum`` setting. Returns the scaled rating """ rating = float(rating) maximum = float(settings.get_option("rating/maximum", 5)) rating = min(rating, maximum) rating = max(0, rating) rating = float(rating * 100.0 / maximum) self.set_tag_raw('__rating', rating) return rating
def __init__(self, player): Gtk.Box.__init__(self) self.init_template() self.button.add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.SCROLL_MASK) self.__volume_setting = '%s/volume' % player._name self.restore_volume = settings.get_option(self.__volume_setting, 1) self.icon_names = ['low', 'medium', 'high'] self.__update(self.restore_volume) event.add_ui_callback(self.on_option_set, '%s_option_set' % player._name)
def toggle_record(self, add_call): current_track = player.PLAYER.current if not current_track: return True if current_track.is_local(): logger.warning('Streamripper can only record streams') return True self.savedir = settings.get_option('plugin/streamripper/save_location', os.getenv('HOME')) options = [] options.append('streamripper') options.append(player.PLAYER._pipe.get_property('uri')) options.append('-D') options.append('%A/%a/%T') if settings.get_option('plugin/streamripper/single_file', False): options.append("-a") options.append("-A") options.append("-r") options.append(settings.get_option('plugin/streamripper/relay_port', '8888')) options.append("-d") options.append(self.savedir) try: self.process = subprocess.Popen(options, 0, None, subprocess.PIPE, subprocess.PIPE, subprocess.PIPE) except OSError: logger.error('There was an error executing streamripper') dialogs.error(self.exaile.gui.main.window, _('Error ' 'executing streamripper')) return True if add_call: event.add_callback(self.quit_application, 'quit_application') event.add_callback(self.start_track, 'playback_track_start', player.PLAYER) event.add_callback(self.stop_playback, 'playback_player_end', player.PLAYER) return False