Example #1
0
 def set_art(self, path):
     """Sets the album's cover art to the image at the given path.
     The image is copied into place, replacing any existing art.
     """
     path = bytestring_path(path)
     oldart = self.artpath
     artdest = self.art_destination(path)
     if oldart == artdest:
         util.soft_remove(oldart)
     
     shutil.copyfile(syspath(path), syspath(artdest))
     self.artpath = artdest
Example #2
0
    def remove(self, item, delete=False, with_album=True):
        """Removes this item. If delete, then the associated file is
        removed from disk. If with_album, then the item's album (if any)
        is removed if it the item was the last in the album.
        """
        album = self.get_album(item) if with_album else None

        self.conn.execute("DELETE FROM items WHERE id=?", (item.id,))

        if album:
            item_iter = album.items()
            try:
                item_iter.next()
            except StopIteration:
                # Album is empty.
                album.remove(delete, False)

        if delete:
            util.soft_remove(item.path)
            util.prune_dirs(os.path.dirname(item.path), self.directory)
Example #3
0
    def remove(self, delete=False, with_items=True):
        """Removes this album and all its associated items from the
        library. If delete, then the items' files are also deleted
        from disk, along with any album art. The directories
        containing the album are also removed (recursively) if empty.
        Set with_items to False to avoid removing the album's items.
        """
        if with_items:
            # Remove items.
            for item in self.items():
                self._library.remove(item, delete, False)

        if delete:
            # Delete art file.
            artpath = self.artpath
            if artpath:
                util.soft_remove(artpath)

        # Remove album from database.
        self._library.conn.execute("DELETE FROM albums WHERE id=?", (self.id,))
Example #4
0
    def remove(self, item, delete=False, with_album=True):
        """Removes this item. If delete, then the associated file is
        removed from disk. If with_album, then the item's album (if any)
        is removed if it the item was the last in the album.
        """
        album = self.get_album(item) if with_album else None

        self.conn.execute('DELETE FROM items WHERE id=?', (item.id, ))

        if album:
            item_iter = album.items()
            try:
                item_iter.next()
            except StopIteration:
                # Album is empty.
                album.remove(delete, False)

        if delete:
            util.soft_remove(item.path)
            util.prune_dirs(os.path.dirname(item.path), self.directory)
Example #5
0
    def set_art(self, path):
        """Sets the album's cover art to the image at the given path.
        The image is copied into place, replacing any existing art.
        """
        path = bytestring_path(path)
        oldart = self.artpath
        artdest = self.art_destination(path)

        if oldart and samefile(path, oldart):
            # Art already set.
            return
        elif samefile(path, artdest):
            # Art already in place.
            self.artpath = path
            return

        # Normal operation.
        if oldart == artdest:
            util.soft_remove(oldart)
        util.copy(path, artdest)
        self.artpath = artdest
Example #6
0
    def remove(self, delete=False, with_items=True):
        """Removes this album and all its associated items from the
        library. If delete, then the items' files are also deleted
        from disk, along with any album art. The directories
        containing the album are also removed (recursively) if empty.
        Set with_items to False to avoid removing the album's items.
        """
        if with_items:
            # Remove items.
            for item in self.items():
                self._library.remove(item, delete, False)

        if delete:
            # Delete art file.
            artpath = self.artpath
            if artpath:
                util.soft_remove(artpath)

        # Remove album from database.
        self._library.conn.execute('DELETE FROM albums WHERE id=?',
                                   (self.id, ))
Example #7
0
    def set_art(self, path):
        """Sets the album's cover art to the image at the given path.
        The image is copied into place, replacing any existing art.
        """
        path = bytestring_path(path)
        oldart = self.artpath
        artdest = self.art_destination(path)

        if oldart and samefile(path, oldart):
            # Art already set.
            return
        elif samefile(path, artdest):
            # Art already in place.
            self.artpath = path
            return

        # Normal operation.
        if oldart == artdest:
            util.soft_remove(oldart)
        util.copy(path, artdest)
        self.artpath = artdest
Example #8
0
def apply_choices(config):
    """A coroutine for applying changes to albums during the autotag
    process.
    """
    lib = _reopen_lib(config.lib)
    task = None
    while True:    
        task = yield task
        if task.should_skip():
            continue

        items = [i for i in task.items if i] if task.is_album else [task.item]
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.items, task.info)
            else:
                autotag.apply_item_metadata(task.item, task.info)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing (for
        # re-imports). Old album structures are automatically cleaned up
        # when the last item is removed.
        replaced_items = defaultdict(list)
        for item in items:
            dup_items = lib.items(library.MatchQuery('path', item.path))
            for dup_item in dup_items:
                replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' % (len(replaced_items),
                                               len(items)))

        # Find old items that should be replaced as part of a duplicate
        # resolution.
        duplicate_items = []
        if task.remove_duplicates:
            if task.is_album:
                for album in _duplicate_check(lib, task):
                    duplicate_items += album.items()
            else:
                duplicate_items = _item_duplicate_check(lib, task)
            log.debug('removing %i old duplicated items' %
                      len(duplicate_items))

            # Delete duplicate files that are located inside the library
            # directory.
            for duplicate_path in [i.path for i in duplicate_items]:
                if lib.directory in util.ancestry(duplicate_path):
                    log.debug(u'deleting replaced duplicate %s' %
                              util.displayable_path(duplicate_path))
                    util.soft_remove(duplicate_path)
                    util.prune_dirs(os.path.dirname(duplicate_path),
                                    lib.directory)

        # Move/copy files.
        task.old_paths = [item.path for item in items]
        for item in items:
            if config.copy:
                # If we're replacing an item, then move rather than
                # copying.
                old_path = item.path
                do_copy = not bool(replaced_items[item])
                lib.move(item, do_copy, task.is_album)
                if not do_copy:
                    # If we moved the item, remove the now-nonexistent
                    # file from old_paths.
                    task.old_paths.remove(old_path)
            if config.write and task.should_write_tags():
                item.write()

        # Add items to library. We consolidate this at the end to avoid
        # locking while we do the copying and tag updates.
        try:
            # Remove old items.
            for replaced in replaced_items.itervalues():
                for item in replaced:
                    lib.remove(item)
            for item in duplicate_items:
                lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    lib.add(item)
        finally:
            lib.save()
Example #9
0
def apply_choices(config):
    """A coroutine for applying changes to albums during the autotag
    process.
    """
    lib = _reopen_lib(config.lib)
    task = None
    while True:
        task = yield task
        if task.should_skip():
            continue

        items = [i for i in task.items if i] if task.is_album else [task.item]
        # Clear IDs in case the items are being re-tagged.
        for item in items:
            item.id = None
            item.album_id = None

        # Change metadata.
        if task.should_write_tags():
            if task.is_album:
                autotag.apply_metadata(task.items, task.info)
            else:
                autotag.apply_item_metadata(task.item, task.info)

        # Infer album-level fields.
        if task.is_album:
            _infer_album_fields(task)

        # Find existing item entries that these are replacing (for
        # re-imports). Old album structures are automatically cleaned up
        # when the last item is removed.
        replaced_items = defaultdict(list)
        for item in items:
            dup_items = lib.items(library.MatchQuery('path', item.path))
            for dup_item in dup_items:
                replaced_items[item].append(dup_item)
                log.debug('replacing item %i: %s' %
                          (dup_item.id, displayable_path(item.path)))
        log.debug('%i of %i items replaced' %
                  (len(replaced_items), len(items)))

        # Find old items that should be replaced as part of a duplicate
        # resolution.
        duplicate_items = []
        if task.remove_duplicates:
            if task.is_album:
                for album in _duplicate_check(lib, task):
                    duplicate_items += album.items()
            else:
                duplicate_items = _item_duplicate_check(lib, task)
            log.debug('removing %i old duplicated items' %
                      len(duplicate_items))

            # Delete duplicate files that are located inside the library
            # directory.
            for duplicate_path in [i.path for i in duplicate_items]:
                if lib.directory in util.ancestry(duplicate_path):
                    log.debug(u'deleting replaced duplicate %s' %
                              util.displayable_path(duplicate_path))
                    util.soft_remove(duplicate_path)
                    util.prune_dirs(os.path.dirname(duplicate_path),
                                    lib.directory)

        # Move/copy files.
        task.old_paths = [item.path for item in items]
        for item in items:
            if config.copy:
                # If we're replacing an item, then move rather than
                # copying.
                old_path = item.path
                do_copy = not bool(replaced_items[item])
                lib.move(item, do_copy, task.is_album)
                if not do_copy:
                    # If we moved the item, remove the now-nonexistent
                    # file from old_paths.
                    task.old_paths.remove(old_path)
            if config.write and task.should_write_tags():
                item.write()

        # Add items to library. We consolidate this at the end to avoid
        # locking while we do the copying and tag updates.
        try:
            # Remove old items.
            for replaced in replaced_items.itervalues():
                for item in replaced:
                    lib.remove(item)
            for item in duplicate_items:
                lib.remove(item)

            # Add new ones.
            if task.is_album:
                # Add an album.
                album = lib.add_album(items)
                task.album_id = album.id
            else:
                # Add tracks.
                for item in items:
                    lib.add(item)
        finally:
            lib.save()