Ejemplo n.º 1
0
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!")
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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))
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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)))
Ejemplo n.º 6
0
 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)))
Ejemplo n.º 7
0
    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)))
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
    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)))
Ejemplo n.º 11
0
    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()
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
# 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')
Ejemplo n.º 18
0
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))