From b6607c65734b146e15351c5cd084b61a9b79942e Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Sun, 26 Jan 2020 17:37:11 -0700 Subject: [PATCH] Fix cover file saving with /tmp on different FS If the directory used by tempfile.NamedTemporaryFile is on a different filesystem (e.g. /tmp on tmpfs), `whipper cd rip --cover-art` will fail with an error such as: Traceback (most recent call last): File "/usr/bin/whipper", line 11, in load_entry_point('whipper==0.9.0', 'console_scripts', 'whipper')() File "/home/kevin/tmp/whipper/whipper/command/main.py", line 43, in main ret = cmd.do() File "/home/kevin/tmp/whipper/whipper/command/basecommand.py", line 139, in do return self.cmd.do() File "/home/kevin/tmp/whipper/whipper/command/basecommand.py", line 139, in do return self.cmd.do() File "/home/kevin/tmp/whipper/whipper/command/cd.py", line 191, in do self.doCommand() File "/home/kevin/tmp/whipper/whipper/command/cd.py", line 363, in doCommand self.program.metadata.mbid) File "/home/kevin/tmp/whipper/whipper/common/program.py", line 498, in getCoverArt os.replace(f.name, cover_art_path) OSError: [Errno 18] Invalid cross-device link: '/tmp/tmprmx4d9c9.cover.jpg' -> './Boston/Greatest Hits/cover.jpg' due to calling os.replace with paths on different filesystems. Instead of os.replace, use shutil.move, which falls back to shutil.copy2 if os.replace doesn't work. Signed-off-by: Kevin Locke --- whipper/common/program.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/whipper/common/program.py b/whipper/common/program.py index dd1f824..c4c706d 100644 --- a/whipper/common/program.py +++ b/whipper/common/program.py @@ -25,6 +25,7 @@ Common functionality and class for all programs using whipper. import musicbrainzngs import re import os +import shutil import time from tempfile import NamedTemporaryFile @@ -495,7 +496,7 @@ class Program: with NamedTemporaryFile(suffix='.cover.jpg', delete=False) as f: f.write(data) os.chmod(f.name, 0o644) - os.replace(f.name, cover_art_path) + shutil.move(f.name, cover_art_path) logger.debug('cover art fetched at: %r', cover_art_path) return cover_art_path return