Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to link files instead of moving or copying them. #710

Merged
merged 8 commits into from
Nov 15, 2014
1 change: 1 addition & 0 deletions beets/config_default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import:
write: yes
copy: yes
move: no
link: no
delete: no
resume: ask
incremental: no
Expand Down
10 changes: 8 additions & 2 deletions beets/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ def try_sync(self, write=None):

# Files themselves.

def move_file(self, dest, copy=False):
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.
Expand All @@ -535,6 +535,10 @@ def move_file(self, dest, copy=False):
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)
Expand Down Expand Up @@ -814,7 +818,7 @@ def remove(self, delete=False, with_items=True):
for item in self.items():
item.remove(delete, False)

def move_art(self, copy=False):
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.
"""
Expand All @@ -832,6 +836,8 @@ def move_art(self, copy=False):
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
Expand Down
20 changes: 20 additions & 0 deletions beets/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,26 @@ def move(path, dest, replace=False):
traceback.format_exc())


def link(path, dest, replace=False):
"""Create a symbolic link from path to `dest`. Raises an OSError if
`dest` already exists, unless `replace` is True. Does nothing if
`path` == `dest`."""
if (samefile(path, dest)):
return

path = syspath(path)
dest = syspath(dest)
if os.path.exists(dest) and not replace:
raise FilesystemError('file exists', 'rename', (path, dest),
traceback.format_exc())
try:
os.symlink(path, dest)
except OSError:
raise FilesystemError('Operating system does not support symbolic '
'links.', 'link', (path, dest),
traceback.format_exc())


def unique_path(path):
"""Returns a version of ``path`` that does not exist on the
filesystem. Specifically, if ``path` itself already exists, then
Expand Down