Пример #1
0
    def move_art(self, copy=False, link=False):
        """Move or copy any existing album art so that it remains in the
        same directory as the items.
        """
        old_art = self.artpath
        if not old_art:
            return

        new_art = self.art_destination(old_art)
        if new_art == old_art:
            return

        new_art = util.unique_path(new_art)
        log.debug(u'moving album art {0} to {1}',
                  util.displayable_path(old_art),
                  util.displayable_path(new_art))
        if copy:
            util.copy(old_art, new_art)
        elif link:
            util.link(old_art, new_art)
        else:
            util.move(old_art, new_art)
        self.artpath = new_art

        # Prune old path when moving.
        if not copy:
            util.prune_dirs(os.path.dirname(old_art),
                            self._db.directory)
Пример #2
0
    def _record_items(self, lib, basename, items):
        """Records relative paths to the given items for each feed format
        """
        feedsdir = bytestring_path(self.config['dir'].as_filename())
        formats = self.config['formats'].as_str_seq()
        relative_to = self.config['relative_to'].get() \
            or self.config['dir'].as_filename()
        relative_to = bytestring_path(relative_to)

        paths = []
        for item in items:
            if self.config['absolute_path']:
                paths.append(item.path)
            else:
                try:
                    relpath = os.path.relpath(item.path, relative_to)
                except ValueError:
                    # On Windows, it is sometimes not possible to construct a
                    # relative path (if the files are on different disks).
                    relpath = item.path
                paths.append(relpath)

        if 'm3u' in formats:
            m3u_basename = bytestring_path(
                self.config['m3u_name'].as_str())
            m3u_path = os.path.join(feedsdir, m3u_basename)
            _write_m3u(m3u_path, paths)

        if 'm3u_multi' in formats:
            m3u_path = _build_m3u_filename(basename)
            _write_m3u(m3u_path, paths)

        if 'link' in formats:
            for path in paths:
                dest = os.path.join(feedsdir, os.path.basename(path))
                if not os.path.exists(syspath(dest)):
                    link(path, dest)

        if 'echo' in formats:
            self._log.info(u"Location of imported music:")
            for path in paths:
                self._log.info(u"  {0}", path)
Пример #3
0
    def move_file(self, dest, copy=False, link=False):
        """Moves or copies the item's file, updating the path value if
        the move succeeds. If a file exists at ``dest``, then it is
        slightly modified to be unique.
        """
        if not util.samefile(self.path, dest):
            dest = util.unique_path(dest)
        if copy:
            util.copy(self.path, dest)
            plugins.send("item_copied", item=self, source=self.path, destination=dest)
        elif link:
            util.link(self.path, dest)
            plugins.send("item_linked", item=self, source=self.path, destination=dest)
        else:
            plugins.send("before_item_moved", item=self, source=self.path, destination=dest)
            util.move(self.path, dest)
            plugins.send("item_moved", item=self, source=self.path, destination=dest)

        # Either copying or moving succeeded, so update the stored path.
        self.path = dest
Пример #4
0
    def move_file(self, dest, copy=False, link=False):
        """Moves or copies the item's file, updating the path value if
        the move succeeds. If a file exists at ``dest``, then it is
        slightly modified to be unique.
        """
        if not util.samefile(self.path, dest):
            dest = util.unique_path(dest)
        if copy:
            util.copy(self.path, dest)
            plugins.send("item_copied", item=self, source=self.path,
                         destination=dest)
        elif link:
            util.link(self.path, dest)
            plugins.send("item_linked", item=self, source=self.path,
                         destination=dest)
        else:
            plugins.send("before_item_moved", item=self, source=self.path,
                         destination=dest)
            util.move(self.path, dest)
            plugins.send("item_moved", item=self, source=self.path,
                         destination=dest)

        # Either copying or moving succeeded, so update the stored path.
        self.path = dest
Пример #5
0
    def copy_album_art(self, album, dest_dir, path_formats, pretend=False,
                       link=False, hardlink=False):
        """Copies or converts the associated cover art of the album. Album must
        have at least one track.
        """
        if not album or not album.artpath:
            return

        album_item = album.items().get()
        # Album shouldn't be empty.
        if not album_item:
            return

        # Get the destination of the first item (track) of the album, we use
        # this function to format the path accordingly to path_formats.
        dest = album_item.destination(basedir=dest_dir,
                                      path_formats=path_formats)

        # Remove item from the path.
        dest = os.path.join(*util.components(dest)[:-1])

        dest = album.art_destination(album.artpath, item_dir=dest)
        if album.artpath == dest:
            return

        if not pretend:
            util.mkdirall(dest)

        if os.path.exists(util.syspath(dest)):
            self._log.info(u'Skipping {0} (target file exists)',
                           util.displayable_path(album.artpath))
            return

        # Decide whether we need to resize the cover-art image.
        resize = False
        maxwidth = None
        if self.config['album_art_maxwidth']:
            maxwidth = self.config['album_art_maxwidth'].get(int)
            size = ArtResizer.shared.get_size(album.artpath)
            self._log.debug('image size: {}', size)
            if size:
                resize = size[0] > maxwidth
            else:
                self._log.warning(u'Could not get size of image (please see '
                                  u'documentation for dependencies).')

        # Either copy or resize (while copying) the image.
        if resize:
            self._log.info(u'Resizing cover art from {0} to {1}',
                           util.displayable_path(album.artpath),
                           util.displayable_path(dest))
            if not pretend:
                ArtResizer.shared.resize(maxwidth, album.artpath, dest)
        else:
            if pretend:
                msg = 'ln' if hardlink else ('ln -s' if link else 'cp')

                self._log.info(u'{2} {0} {1}',
                               util.displayable_path(album.artpath),
                               util.displayable_path(dest),
                               msg)
            else:
                msg = 'Hardlinking' if hardlink \
                    else ('Linking' if link else 'Copying')

                self._log.info(u'{2} cover art from {0} to {1}',
                               util.displayable_path(album.artpath),
                               util.displayable_path(dest),
                               msg)
                if hardlink:
                    util.hardlink(album.artpath, dest)
                elif link:
                    util.link(album.artpath, dest)
                else:
                    util.copy(album.artpath, dest)
Пример #6
0
    def convert_item(self, dest_dir, keep_new, path_formats, fmt,
                     pretend=False, link=False, hardlink=False):
        """A pipeline thread that converts `Item` objects from a
        library.
        """
        command, ext = get_format(fmt)
        item, original, converted = None, None, None
        while True:
            item = yield (item, original, converted)
            dest = item.destination(basedir=dest_dir,
                                    path_formats=path_formats)

            # When keeping the new file in the library, we first move the
            # current (pristine) file to the destination. We'll then copy it
            # back to its old path or transcode it to a new path.
            if keep_new:
                original = dest
                converted = item.path
                if should_transcode(item, fmt):
                    converted = replace_ext(converted, ext)
            else:
                original = item.path
                if should_transcode(item, fmt):
                    dest = replace_ext(dest, ext)
                converted = dest

            # Ensure that only one thread tries to create directories at a
            # time. (The existence check is not atomic with the directory
            # creation inside this function.)
            if not pretend:
                with _fs_lock:
                    util.mkdirall(dest)

            if os.path.exists(util.syspath(dest)):
                self._log.info(u'Skipping {0} (target file exists)',
                               util.displayable_path(item.path))
                continue

            if keep_new:
                if pretend:
                    self._log.info(u'mv {0} {1}',
                                   util.displayable_path(item.path),
                                   util.displayable_path(original))
                else:
                    self._log.info(u'Moving to {0}',
                                   util.displayable_path(original))
                    util.move(item.path, original)

            if should_transcode(item, fmt):
                linked = False
                try:
                    self.encode(command, original, converted, pretend)
                except subprocess.CalledProcessError:
                    continue
            else:
                linked = link or hardlink
                if pretend:
                    msg = 'ln' if hardlink else ('ln -s' if link else 'cp')

                    self._log.info(u'{2} {0} {1}',
                                   util.displayable_path(original),
                                   util.displayable_path(converted),
                                   msg)
                else:
                    # No transcoding necessary.
                    msg = 'Hardlinking' if hardlink \
                        else ('Linking' if link else 'Copying')

                    self._log.info(u'{1} {0}',
                                   util.displayable_path(item.path),
                                   msg)

                    if hardlink:
                        util.hardlink(original, converted)
                    elif link:
                        util.link(original, converted)
                    else:
                        util.copy(original, converted)

            if pretend:
                continue

            id3v23 = self.config['id3v23'].as_choice([True, False, 'inherit'])
            if id3v23 == 'inherit':
                id3v23 = None

            # Write tags from the database to the converted file.
            item.try_write(path=converted, id3v23=id3v23)

            if keep_new:
                # If we're keeping the transcoded file, read it again (after
                # writing) to get new bitrate, duration, etc.
                item.path = converted
                item.read()
                item.store()  # Store new path and audio data.

            if self.config['embed'] and not linked:
                album = item._cached_album
                if album and album.artpath:
                    self._log.debug(u'embedding album art from {}',
                                    util.displayable_path(album.artpath))
                    art.embed_item(self._log, item, album.artpath,
                                   itempath=converted, id3v23=id3v23)

            if keep_new:
                plugins.send('after_convert', item=item,
                             dest=dest, keepnew=True)
            else:
                plugins.send('after_convert', item=item,
                             dest=converted, keepnew=False)
Пример #7
0
 def create_symlink(self, item):
     dest = self.destination(item)
     util.mkdirall(dest)
     link = (os.path.relpath(item.path, os.path.dirname(dest))
             if self.relativelinks == self.LINK_RELATIVE else item.path)
     util.link(link, dest)
 def create_symlink(self, item):
     dest = self.destination(item)
     util.mkdirall(dest)
     util.link(item.path, dest)