Ejemplo n.º 1
0
    def load_from_location(self, location=None):
        """
        Restores :class:`TrackDB` state from the pickled representation
        stored at the specified location.

        :param location: the location to load the data from
        :type location: string
        """
        if not location:
            location = self.location
        if not location:
            raise AttributeError(
                _("You did not specify a location to load the db from")
            )

        logger.debug("Loading %s DB from %s.", self.name, location)

        pdata = common.open_shelf(location)

        if "_dbversion" in pdata:
            if int(pdata['_dbversion']) > int(self._dbversion):
                raise common.VersionError("DB was created on a newer Exaile version.")
            elif pdata['_dbversion'] < self._dbversion:
                logger.info("Upgrading DB format....")
                import shutil

                shutil.copyfile(location, location + "-%s.bak" % pdata['_dbversion'])
                import xl.migrations.database as dbmig

                dbmig.handle_migration(
                    self, pdata, pdata['_dbversion'], self._dbversion
                )

        for attr in self.pickle_attrs:
            try:
                if 'tracks' == attr:
                    data = {}
                    for k in (x for x in pdata.keys() if x.startswith("tracks-")):
                        p = pdata[k]
                        tr = Track(_unpickles=p[0])
                        loc = tr.get_loc_for_io()
                        if loc not in data:
                            data[loc] = TrackHolder(tr, p[1], **p[2])
                        else:
                            logger.warning("Duplicate track found: %s", loc)
                            # presumably the second track was written because of an error,
                            # so use the first track found.
                            del pdata[k]

                    setattr(self, attr, data)
                else:
                    setattr(self, attr, pdata.get(attr, getattr(self, attr)))
            except Exception:
                # FIXME: Do something about this
                logger.exception("Exception occurred while loading %s", location)

        pdata.close()

        self._dirty = False
Ejemplo n.º 2
0
    def load_from_location(self, location=None):
        """
            Restores :class:`TrackDB` state from the pickled representation
            stored at the specified location.

            :param location: the location to load the data from
            :type location: string
        """
        if not location:
            location = self.location
        if not location:
            raise AttributeError(
                _("You did not specify a location to load the db from")
            )

        logger.debug("Loading %s DB from %s.", self.name, location)

        pdata = common.open_shelf(location)

        if "_dbversion" in pdata:
            if int(pdata['_dbversion']) > int(self._dbversion):
                raise common.VersionError("DB was created on a newer Exaile version.")
            elif pdata['_dbversion'] < self._dbversion:
                logger.info("Upgrading DB format....")
                import shutil

                shutil.copyfile(location, location + "-%s.bak" % pdata['_dbversion'])
                import xl.migrations.database as dbmig

                dbmig.handle_migration(
                    self, pdata, pdata['_dbversion'], self._dbversion
                )

        for attr in self.pickle_attrs:
            try:
                if 'tracks' == attr:
                    data = {}
                    for k in (x for x in pdata.keys() if x.startswith("tracks-")):
                        p = pdata[k]
                        tr = Track(_unpickles=p[0])
                        loc = tr.get_loc_for_io()
                        if loc not in data:
                            data[loc] = TrackHolder(tr, p[1], **p[2])
                        else:
                            logger.warning("Duplicate track found: %s", loc)
                            # presumably the second track was written because of an error,
                            # so use the first track found.
                            del pdata[k]

                    setattr(self, attr, data)
                else:
                    setattr(self, attr, pdata.get(attr, getattr(self, attr)))
            except Exception:
                # FIXME: Do something about this
                logger.exception("Exception occurred while loading %s", location)

        pdata.close()

        self._dirty = False
Ejemplo n.º 3
0
    def __init__(self, location, default=None):
        '''
            @param location: specify the shelve file location

            @param default: can specify a default to return from getter when
                there is nothing in the shelve
        '''
        self.location = location
        self.db = common.open_shelf(location)
        self.lock = threading.Lock()
        self.default = default

        # Callback to close db
        event.add_callback(self.on_quit_application, 'quit_application')
Ejemplo n.º 4
0
    def __init__(self, location, default=None):
        '''
            @param location: specify the shelve file location

            @param default: can specify a default to return from getter when
                there is nothing in the shelve
        '''
        self.location = location
        self.db = common.open_shelf(location)
        self.lock = threading.Lock()
        self.default = default

        # Callback to close db
        event.add_callback(self.on_quit_application, 'quit_application')
Ejemplo n.º 5
0
def test_migration(data):
    truth, loc, dbtype = data

    print(os.listdir(loc))

    try:
        db = open_shelf(join(loc, 'music.db'))
    except Exception as e:
        if dbtype == 'dbm' and getattr(e, 'args', (None,))[0] == 2:
            # on fedora it seems like dbm is linked to gdbm, and on debian based
            # systems that dbm uses a bsd implementation. Ignore these errors,
            # as (presumably) users will only try to migrate databases on systems
            # that were previously able to read the database.
            pytest.skip("Invalid dbm module")
            return
        raise

    for k, v in truth.iteritems():
        assert k in db
        assert v == db[k]

    assert os.listdir(loc) == ['music.db']

    db.close()
Ejemplo n.º 6
0
def test_migration(data):
    truth, loc, dbtype = data

    print(os.listdir(loc))

    try:
        db = open_shelf(join(loc, 'music.db'))
    except Exception as e:
        if dbtype == 'dbm' and getattr(e, 'args', (None, ))[0] == 2:
            # on fedora it seems like dbm is linked to gdbm, and on debian based
            # systems that dbm uses a bsd implementation. Ignore these errors,
            # as (presumably) users will only try to migrate databases on systems
            # that were previously able to read the database.
            pytest.skip("Invalid dbm module")
            return
        raise

    for k, v in truth.items():
        assert k in db
        assert v == db[k]

    assert os.listdir(loc) == ['music.db']

    db.close()
Ejemplo n.º 7
0
    def save_to_location(self, location=None):
        """
            Saves a pickled representation of this :class:`TrackDB` to the
            specified location.

            :param location: the location to save the data to
            :type location: string
        """
        if not self._dirty:
            for track in self.tracks.values():
                if track._track._dirty:
                    self._dirty = True
                    break

        if not self._dirty:
            return

        if not location:
            location = self.location
        if not location:
            raise AttributeError(
                _("You did not specify a location to save the db"))

        if self._saving:
            return
        self._saving = True

        logger.debug("Saving %s DB to %s.", self.name, location)

        try:
            pdata = common.open_shelf(location)
            if pdata.get('_dbversion', self._dbversion) > self._dbversion:
                raise common.VersionError("DB was created on a newer Exaile.")
        except Exception:
            logger.exception("Failed to open music DB for writing.")
            return

        for attr in self.pickle_attrs:
            # bad hack to allow saving of lists/dicts of Tracks
            if 'tracks' == attr:
                for k, track in self.tracks.items():
                    key = "tracks-%s" % track._key
                    if track._track._dirty or key not in pdata:
                        pdata[key] = (
                            track._track._pickles(),
                            track._key,
                            deepcopy(track._attrs),
                        )
            else:
                pdata[attr] = deepcopy(getattr(self, attr))

        pdata['_dbversion'] = self._dbversion

        for key in self._deleted_keys:
            key = "tracks-%s" % key
            if key in pdata:
                del pdata[key]

        pdata.sync()
        pdata.close()

        for track in self.tracks.values():
            track._track._dirty = False

        self._dirty = False
        self._saving = False
Ejemplo n.º 8
0
    def save_to_location(self, location=None):
        """
            Saves a pickled representation of this :class:`TrackDB` to the
            specified location.

            :param location: the location to save the data to
            :type location: string
        """
        if not self._dirty:
            for track in self.tracks.itervalues():
                if track._track._dirty:
                    self._dirty = True
                    break

        if not self._dirty:
            return

        if not location:
            location = self.location
        if not location:
            raise AttributeError(_("You did not specify a location to save the db"))

        if self._saving:
            return
        self._saving = True

        logger.debug("Saving %s DB to %s.", self.name, location)

        try:
            pdata = common.open_shelf(location)
            if pdata.get('_dbversion', self._dbversion) > self._dbversion:
                raise common.VersionError("DB was created on a newer Exaile.")
        except Exception:
            logger.exception("Failed to open music DB for writing.")
            return

        for attr in self.pickle_attrs:
            # bad hack to allow saving of lists/dicts of Tracks
            if 'tracks' == attr:
                for k, track in self.tracks.iteritems():
                    key = "tracks-%s" % track._key
                    if track._track._dirty or key not in pdata:
                        pdata[key] = (
                            track._track._pickles(),
                            track._key,
                            deepcopy(track._attrs),
                        )
            else:
                pdata[attr] = deepcopy(getattr(self, attr))

        pdata['_dbversion'] = self._dbversion

        for key in self._deleted_keys:
            key = "tracks-%s" % key
            if key in pdata:
                del pdata[key]

        pdata.sync()
        pdata.close()

        for track in self.tracks.itervalues():
            track._track._dirty = False

        self._dirty = False
        self._saving = False