Skip to content

Commit

Permalink
convert: add option to hardlink instead of copying.
Browse files Browse the repository at this point in the history
Overrides the --link option.

As proposed in beetbox#2324.
  • Loading branch information
Vexatos committed Aug 20, 2019
1 parent 4820cee commit a61aa74
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 7 deletions.
42 changes: 36 additions & 6 deletions beetsplug/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def __init__(self):
u'dest': None,
u'pretend': False,
u'link': False,
u'hardlink': False,
u'threads': util.cpu_count(),
u'format': u'mp3',
u'id3v23': u'inherit',
Expand Down Expand Up @@ -171,6 +172,9 @@ def commands(self):
cmd.parser.add_option('-l', '--link', action='store_true', dest='link',
help=u'symlink files that do not need transcoding. \
Don\'t use with \'embed\'.')
cmd.parser.add_option('-H', '--hardlink', action='store_true', dest='hardlink',
help=u'hardlink files that do not need transcoding. \
Overrides --link. Don\'t use with \'embed\'.')
cmd.parser.add_album_option()
cmd.func = self.convert_func
return [cmd]
Expand Down Expand Up @@ -255,7 +259,7 @@ def encode(self, command, source, dest, pretend=False):
util.displayable_path(source))

def convert_item(self, dest_dir, keep_new, path_formats, fmt,
pretend=False, link=False):
pretend=False, link=False, hardlink=False):
"""A pipeline thread that converts `Item` objects from a
library.
"""
Expand Down Expand Up @@ -308,7 +312,17 @@ def convert_item(self, dest_dir, keep_new, path_formats, fmt,
except subprocess.CalledProcessError:
continue
else:
if link:
if hardlink:
if pretend:
self._log.info(u'ln {0} {1}',
util.displayable_path(original),
util.displayable_path(converted))
else:
# No transcoding necessary.
self._log.info(u'Hardlinking {0}',
util.displayable_path(item.path))
util.hardlink(original, converted)
elif link:
if pretend:
self._log.info(u'ln -s {0} {1}',
util.displayable_path(original),
Expand Down Expand Up @@ -362,7 +376,7 @@ def convert_item(self, dest_dir, keep_new, path_formats, fmt,
dest=converted, keepnew=False)

def copy_album_art(self, album, dest_dir, path_formats, pretend=False,
link=False):
link=False, hardlink=False):
"""Copies or converts the associated cover art of the album. Album must
have at least one track.
"""
Expand Down Expand Up @@ -415,7 +429,17 @@ def copy_album_art(self, album, dest_dir, path_formats, pretend=False,
if not pretend:
ArtResizer.shared.resize(maxwidth, album.artpath, dest)
else:
if link:
if hardlink:
if pretend:
self._log.info(u'ln {0} {1}',
util.displayable_path(album.artpath),
util.displayable_path(dest))
else:
self._log.info(u'Hardlinking cover art from {0} to {1}',
util.displayable_path(album.artpath),
util.displayable_path(dest))
util.hardlink(album.artpath, dest)
elif link:
if pretend:
self._log.info(u'ln -s {0} {1}',
util.displayable_path(album.artpath),
Expand Down Expand Up @@ -458,6 +482,11 @@ def convert_func(self, lib, opts, args):
else:
link = self.config['link'].get(bool)

if opts.hardlink is not None:
hardlink = opts.hardlink
else:
hardlink = self.config['hardlink'].get(bool)

if opts.album:
albums = lib.albums(ui.decargs(args))
items = [i for a in albums for i in a.items()]
Expand All @@ -478,14 +507,15 @@ def convert_func(self, lib, opts, args):

if opts.album and self.config['copy_album_art']:
for album in albums:
self.copy_album_art(album, dest, path_formats, pretend, link)
self.copy_album_art(album, dest, path_formats, pretend, link, hardlink)

convert = [self.convert_item(dest,
opts.keep_new,
path_formats,
fmt,
pretend,
link)
link,
hardlink)
for _ in range(threads)]
pipe = util.pipeline.Pipeline([iter(items), convert])
pipe.run_parallel()
Expand Down
4 changes: 4 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ New features:
* :doc:`/plugins/convert`: Added new ``-l`` (``--link``) flag and ``link`` option
which symlinks files that do not need to be converted instead of copying them.
:bug:`2324`
* :doc:`/plugins/convert`: Added new ``-H`` (``--hardlink``) flag and ``hardlink``
option which hardlinks files that do not need to be converted
instead of copying them.
:bug:`2324`
* :doc:`/plugins/bpd`: BPD now supports most of the features of version 0.16
of the MPD protocol. This is enough to get it talking to more complicated
clients like ncmpcpp, but there are still some incompatibilities, largely due
Expand Down
13 changes: 12 additions & 1 deletion docs/plugins/convert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ them.

By default, files that do not need to be transcoded will be copied to their
destination. Passing the ``-l`` (``--link``) flag creates symbolic links
instead. Refer to the ``link`` option below for potential issues with this.
instead, passing ``-H`` (``--hardlink``) creates hard links.
Refer to the ``link`` and ``hardlink`` options below
for potential issues with this.


Configuration
Expand Down Expand Up @@ -104,6 +106,15 @@ file. The available options are:
enabled. For this reason, it is highly recommended not use to ``link`` and
``embed`` at the same time.
Default: ``false``.
- **hardlink**: By default, files that do not need to be transcoded will be
copied to their destination. This option creates hard links instead. Note that
options such as ``embed`` that modify the output files after the transcoding
step will cause the original files to be modified as well if ``hardlink`` is
enabled. For this reason, it is highly recommended not use to ``hardlink`` and
``embed`` at the same time.
This option overrides ``link``. Only works when converting to a directory
on the same filesystem as the library.
Default: ``false``.

You can also configure the format to use for transcoding (see the next
section):
Expand Down

0 comments on commit a61aa74

Please sign in to comment.