def migrate(force=False): if not force and not migration_needed(): logger.debug("Will not migrate and overwrite data.") return logger.info("Migrating data from 0.2.14....") # allow force to overwrite the new db newdbpath = os.path.join(xdg.get_data_dirs()[0], 'music.db') if os.path.exists(newdbpath): os.remove(newdbpath) oldsettings = SafeConfigParser() oldsettings.read(os.path.expanduser('~/.exaile/settings.ini')) if not olddb.SQLITE_AVAIL: raise MigrationException("Sqlite is not available. " "Unable to migrate 0.2.14 settings") # old database db = olddb.DBManager(os.path.expanduser('~/.exaile/music.db'), False) # new database newdb = collection.Collection('tdb', os.path.join(xdg.get_data_dirs()[0], 'music.db')) _migrate_old_tracks(oldsettings, db, newdb) _migrate_old_settings(oldsettings) settings.MANAGER.save() playlists = PlaylistManager() _migrate_playlists(db, newdb, playlists) logger.info("Migration complete!")
def __init__(self, exaile): """ Connects events to the player object, loads settings and cache """ scrobbler.set_user_agent( exaile.get_user_agent_string('audioscrobbler')) self.connected = False self.connecting = False self.use_menu = False self.exaile = exaile self.cachefile = os.path.join(xdg.get_data_dirs()[0], "audioscrobbler.cache") self.get_options('', '', 'plugin/ascrobbler/cache_size') self.get_options('', '', 'plugin/ascrobbler/user') self.load_cache() event.add_ui_callback(self.get_options, 'plugin_ascrobbler_option_set') event.add_callback(self._save_cache_cb, 'quit_application') # enable accelerator def toggle_submit(*x): logger.debug('Toggling AudioScrobbler submissions.') settings.set_option('plugin/ascrobbler/submit', not self.submit) self.accelerator = Accelerator('<Primary>b', _('Toggle AudioScrobbler submit'), toggle_submit) providers.register('mainwindow-accelerators', self.accelerator)
def load_list(self): '''Load alarms from file''' logger.debug('load_list() called.') path = os.path.join(xdg.get_data_dirs()[0],'alarmlist.dat') try: # Load Alarm List from file. with open(path,'rb') as f: raw = f.read() try: alist = _read(raw) assert isinstance(alist, list) # should be list of dicts (new format) except Exception: try: # try to import old format for line in raw.strip().split('\n'): a = Alarm(dict=eval(line, {'__builtin__':None})) logger.debug('loaded alarm {0} ({1}) from file.'.format(a.name, a.time)) self.add_alarm(a) # force save in new format logger.info('Old alarm file format found, converting.') self.save_list() except Exception as e: logger.warning('Failed to load alarm data from file: {0}'.format(e)) else: for a in alist: alarm = Alarm(dict=a) logger.debug('loaded alarm {0} ({1}) from file.'.format(alarm.name, alarm.time)) self.add_alarm(alarm) except IOError as e: # File might not exist logger.warning('Could not open file: {0}'.format(e.strerror))
def __init__(self, exaile): """ Connects events to the player object, loads settings and cache """ scrobbler.set_user_agent(exaile.get_user_agent_string('audioscrobbler')) self.connected = False self.connecting = False self.use_menu = False self.exaile = exaile self.cachefile = os.path.join(xdg.get_data_dirs()[0], "audioscrobbler.cache") self.get_options('', '', 'plugin/ascrobbler/cache_size') self.get_options('', '', 'plugin/ascrobbler/user') self.load_cache() event.add_ui_callback(self.get_options, 'plugin_ascrobbler_option_set') event.add_callback(self._save_cache_cb, 'quit_application') # enable accelerator def toggle_submit(*x): logger.debug('Toggling AudioScrobbler submissions.') settings.set_option('plugin/ascrobbler/submit', not self.submit) self.accelerator = Accelerator( '<Primary>b', _('Toggle AudioScrobbler submit'), toggle_submit ) providers.register('mainwindow-accelerators', self.accelerator)
def save_db(self): """ Save list of bookmarks to a file. """ # Save List path = os.path.join(xdg.get_data_dirs()[0],'bookmarklist.dat') with open(path,'wb') as f: f.write(_write(self.bookmarks)) logger.debug('saving {0} bookmarks'.format(len(self.bookmarks)))
def save_db(self): """ Save list of bookmarks to a file. """ # Save List path = os.path.join(xdg.get_data_dirs()[0], 'bookmarklist.dat') with open(path, 'wb') as f: f.write(_write(self.bookmarks)) logger.debug('saving {0} bookmarks'.format(len(self.bookmarks)))
def save_list(self): '''Save alarms to file''' logger.debug('save_list() called.') # Save List path = os.path.join(xdg.get_data_dirs()[0], 'alarmlist.dat') if len(self.model) > 0: alist = [ {'active': row[0], 'name': row[1], 'time': row[2], 'days': row[3]} for row in self.model ] with open(path, 'wb') as f: f.write(_write(alist)) logger.debug('saving {0} alarms.'.format(len(alist)))
def __init__(self, exaile, load=True): self.plugindirs = [os.path.join(p, 'plugins') for p in xdg.get_data_dirs()] if xdg.local_hack: self.plugindirs.insert(1, os.path.join(xdg.exaile_dir, 'plugins')) try: os.makedirs(self.plugindirs[0]) except Exception: pass self.plugindirs = [x for x in self.plugindirs if os.path.exists(x)] self.loaded_plugins = {} self.exaile = exaile self.enabled_plugins = {} self.load = load
def __init__(self, parent): panel.Panel.__init__(self, parent, 'contextinfo') cachedir = os.path.join(xdg.get_data_dirs()[0], 'context') if not os.path.isdir(cachedir): os.mkdir(cachedir) #TODO last.fm class pylast.network = pylast.get_lastfm_network(LFM_API_KEY) pylast.network.enable_caching(os.path.join(cachedir, 'lastfm.cache')) self.controller = parent self._theme = ContextTheme(settings.get_option('context/theme', 'classic')) self._browser = BrowserPage(self.builder, self._theme) self.setup_widgets()
def save_list(self): '''Save alarms to file''' logger.debug('save_list() called.') # Save List path = os.path.join(xdg.get_data_dirs()[0], 'alarmlist.dat') if len(self.model) > 0: alist = [ {'active': row[0], 'name': row[1], 'time': row[2], 'days': row[3]} for row in self.model ] # Open in non-binary mode, because we are writing json # string. with open(path, 'w') as f: f.write(_write(alist)) logger.debug('saving {0} alarms.'.format(len(alist)))
def __init__(self, parent): panel.Panel.__init__(self, parent, 'contextinfo') cachedir = os.path.join(xdg.get_data_dirs()[0], 'context') if not os.path.isdir(cachedir): os.mkdir(cachedir) #TODO last.fm class pylast.network = pylast.get_lastfm_network(LFM_API_KEY) pylast.network.enable_caching(os.path.join(cachedir, 'lastfm.cache')) self.controller = parent self._theme = ContextTheme( settings.get_option('context/theme', 'classic')) self._browser = BrowserPage(self.builder, self._theme) self.setup_widgets()
def load_db(self): """ Load previously saved bookmarks from a file. """ path = os.path.join(xdg.get_data_dirs()[0],'bookmarklist.dat') try: # Load Bookmark List from file. with open(path,'rb') as f: data = f.read() try: db = _read(data) for (key,pos) in db: self.bookmarks.append((key,pos)) self.display_bookmark(key, pos) logger.debug('loaded {0} bookmarks'.format(len(db))) except Exception as s: logger.error('BM: bad bookmark file: %s'%s) return None except IOError as e: # File might not exist logger.error('BM: could not open file: %s' % e.strerror)
def load_db(self): """ Load previously saved bookmarks from a file. """ path = os.path.join(xdg.get_data_dirs()[0], 'bookmarklist.dat') try: # Load Bookmark List from file. with open(path, 'rb') as f: data = f.read() try: db = _read(data) for (key, pos) in db: self.bookmarks.append((key, pos)) self.display_bookmark(key, pos) logger.debug('loaded {0} bookmarks'.format(len(db))) except Exception as s: logger.error('BM: bad bookmark file: %s' % s) return None except IOError as e: # File might not exist logger.error('BM: could not open file: %s' % e.strerror)
def migration_needed(): # check for the presence of old exaile settings for file in ('~/.exaile/music.db', '~/.exaile/settings.ini'): if not os.path.exists(os.path.expanduser(file)): logger.debug("%s did not exist, old exaile version not detected" % file) return False # check for Exaile 0.3.x+ settings and music database if os.path.exists(os.path.join(xdg.get_data_dirs()[0], 'music.db')): logger.debug( "Found a newer version of the database, no migration needed") return False if os.path.exists(os.path.join(xdg.get_config_dir(), 'settings.ini')): logger.debug("Found a newer version of the settings " \ "file, no migration needed") return False if not olddb.SQLITE_AVAIL: raise MigrationException("Sqlite not available. " "Cannot migrate 0.2.14 settings") # if we've gotten this far, check for sqlite, but if it's not available, # throw a migration exception # open up the old database, and make sure it's at least the version used # in 0.2.14 db = olddb.DBManager(os.path.expanduser('~/.exaile/music.db'), False) cur = db.cursor() row = db.read_one('db_version', 'version', '1=1', tuple()) db.close() if row[0] != 4: logger.debug("Cannot migrate from db_version %d" % row[0]) return False return True
def __init__(self, exaile): """ Connects events to the player object, loads settings and cache """ scrobbler.set_user_agent(exaile.get_user_agent_string("audioscrobbler")) self.connected = False self.connecting = False self.use_menu = False self.exaile = exaile self.cachefile = os.path.join(xdg.get_data_dirs()[0], "audioscrobbler.cache") self.get_options("", "", "plugin/ascrobbler/cache_size") self.get_options("", "", "plugin/ascrobbler/user") self.load_cache() event.add_callback(self.get_options, "plugin_ascrobbler_option_set") event.add_callback(self._save_cache_cb, "quit_application") # enable accelerator def toggle_submit(*x): logger.debug("Toggling AudioScrobbler submissions.") settings.set_option("plugin/ascrobbler/submit", not self.submit) self.accelerator = Accelerator("<Control>b", toggle_submit) providers.register("mainwindow-accelerators", self.accelerator)
def migration_needed(): # check for the presence of old exaile settings for file in ('~/.exaile/music.db', '~/.exaile/settings.ini'): if not os.path.exists(os.path.expanduser(file)): logger.debug("%s did not exist, old exaile version not detected" % file) return False # check for Exaile 0.3.x+ settings and music database if os.path.exists(os.path.join(xdg.get_data_dirs()[0], 'music.db')): logger.debug("Found a newer version of the database, no migration needed") return False if os.path.exists(os.path.join(xdg.get_config_dir(), 'settings.ini')): logger.debug("Found a newer version of the settings " \ "file, no migration needed") return False if not olddb.SQLITE_AVAIL: raise MigrationException("Sqlite not available. " "Cannot migrate 0.2.14 settings") # if we've gotten this far, check for sqlite, but if it's not available, # throw a migration exception # open up the old database, and make sure it's at least the version used # in 0.2.14 db = olddb.DBManager(os.path.expanduser('~/.exaile/music.db'), False) cur = db.cursor() row = db.read_one('db_version', 'version', '1=1', tuple()) db.close() if row[0] != 4: logger.debug("Cannot migrate from db_version %d" % row[0]) return False return True
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import gtk, threading, gobject, cgi, math from gettext import gettext as _ from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer from xl import event, covers, xdg # config DEFAULT_PORT = 10000 PLUGIN_DIR = '%(rootdir)s/plugins/httpserver/' % { 'rootdir': xdg.get_data_dirs()[0] } # used during life of plugin RESOURCES = None RESOURCE_LOOKUP = None APP = None eh_thread = None # ----------------------------------------------------------------------------- # Exaile 0.3 Wrapper - This plugin was only compatible up to Exaile 0.2 # ----------------------------------------------------------------------------- def enable(exaile): global APP APP = exaile if (exaile.loading): event.add_callback(_enable, 'exaile_loaded')
class BookmarksManager: """ Manages a list of bookmarks and the associated menu entries """ __PATH = os.path.join(xdg.get_data_dirs()[0], 'bookmarklist.dat') def __init__(self): self.__db_file_lock = threading.RLock() self.__bookmarks = [] # self.auto_db = {} self.menu = None self.delete_menu = None self.__setup_menu() # TODO: automatic bookmarks, not yet possible # - needs a way to get the time a file is interrupted at # set events - not functional yet # event.add_callback(self.on_start_track, 'playback_start') # event.add_callback(self.on_stop_track, 'playback_end') # playback_end, playback_pause, playback_resume, stop_track self.__load_db() def __setup_menu(self): self.menu = menu.Menu(self) self.delete_menu = menu.Menu(self) def factory_factory(display_name, icon_name, callback=None, submenu=None): "define factory-factory for sensitive-aware menuitems" def factory(_menu, _parent, _context): item = Gtk.ImageMenuItem.new_with_mnemonic(display_name) image = Gtk.Image.new_from_icon_name(icon_name, size=Gtk.IconSize.MENU) item.set_image(image) if callback is not None: item.connect('activate', callback) if submenu is not None: item.set_submenu(submenu) # insensitive if no bookmarks present if len(self.__bookmarks) == 0: item.set_sensitive(False) return item return factory items = [] items.append( _smi( 'bookmark', [], _('_Bookmark This Track'), 'bookmark-new', self.__on_add_bookmark, )) delete_cb = factory_factory(_('_Delete Bookmark'), 'gtk-close', submenu=self.delete_menu) items.append(menu.MenuItem('delete', delete_cb, ['bookmark'])) clear_cb = factory_factory(_('_Clear Bookmarks'), 'gtk-clear', callback=self.__clear_bookmarks) items.append(menu.MenuItem('clear', clear_cb, ['delete'])) items.append(_sep('sep', ['clear'])) for item in items: self.menu.add_item(item) def __on_add_bookmark(self, _widget, _name, _foo, _bookmarks_manager): self.__add_bookmark() def __add_bookmark(self, path=None, time=None, save_db=True): if not self.menu: return # this plugin is shutting down bookmark = Bookmark(self.menu, self.delete_menu, self.__delete_bookmark, path, time) self.__bookmarks.append(bookmark) if save_db: self.__save_db() def __clear_bookmarks(self, _widget): """ Delete all bookmarks. """ for bookmark in self.__bookmarks: self.delete_menu.remove_item(bookmark.get_menu_item()) self.menu.remove_item(bookmark.get_menu_item()) self.__bookmarks = [] self.__save_db() def __delete_bookmark(self, _widget, bookmark): """ Delete a bookmark. """ self.__bookmarks.remove(bookmark) self.delete_menu.remove_item(bookmark.get_menu_item()) self.menu.remove_item(bookmark.get_menu_item()) self.__save_db() @common.threaded def __load_db(self): """ Load previously saved bookmarks from a file. """ with self.__db_file_lock: if not os.path.exists(self.__PATH): LOGGER.info('Bookmarks file does not exist yet.') return try: with open(self.__PATH, 'rb') as bm_file: bookmarks = json.load(bm_file) self.__load_db_callback(bookmarks) except IOError as err: LOGGER.error('BM: could not open file: %s', err.strerror) @common.idle_add() def __load_db_callback(self, loaded_bookmarks): if not self.menu: return # this plugin is shutting down for (key, pos) in loaded_bookmarks: self.__add_bookmark(key, pos, save_db=False) def __save_db(self): """ Save list of bookmarks to a file. """ # lists are not thread-safe, so we need a copy. # we don't need a deep copy because keys and values are not mutated. bookmarks = copy.copy(self.__bookmarks) # cannot use common.threaded here because it must not be daemonized, # otherwise we might loose data on program shutdown. thread = threading.Thread(target=self.__do_save_db, args=[bookmarks]) thread.daemon = False thread.start() def __do_save_db(self, bookmarks): with self.__db_file_lock: with open(self.__PATH, 'wb') as bm_file: json.dump(bookmarks, bm_file, indent=2, default=Bookmark.serialize_bookmark) LOGGER.debug('saved %d bookmarks', len(bookmarks))