From 6cfb862906ab2aca7d7db774b837c4f557393496 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Wed, 13 Apr 2011 20:23:33 -0700 Subject: [PATCH] conditional deletes in some cases (suggested in #170) --- NEWS | 1 + beets/library.py | 6 +++--- beets/util/__init__.py | 6 ++++++ test/test_files.py | 19 +++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 277933ead..bf00aed0b 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,7 @@ to the @listen decorator (Thanks again, Lugoues!) * In path formats, $albumartist now falls back to $artist (as well as the other way around). +* Fix some crashes when deleting files that don't exist. * Fix adding individual tracks in BPD. 1.0b7 diff --git a/beets/library.py b/beets/library.py index b987ef6d4..33a36add4 100644 --- a/beets/library.py +++ b/beets/library.py @@ -910,7 +910,7 @@ class Library(BaseLibrary): album.remove(delete, False) if delete: - os.unlink(syspath(item.path)) + util.soft_remove(item.path) util.prune_dirs(os.path.dirname(item.path), self.directory) @@ -1111,7 +1111,7 @@ class Album(BaseAlbum): # Delete art file. artpath = self.artpath if artpath: - os.unlink(syspath(artpath)) + util.soft_remove(artpath) # Remove album from database. self._library.conn.execute( @@ -1170,7 +1170,7 @@ class Album(BaseAlbum): oldart = self.artpath artdest = self.art_destination(path) if oldart == artdest: - os.unlink(syspath(oldart)) + os.soft_remove(oldart) shutil.copyfile(syspath(path), syspath(artdest)) self.artpath = artdest diff --git a/beets/util/__init__.py b/beets/util/__init__.py index 53ef89b6c..f49ea578c 100644 --- a/beets/util/__init__.py +++ b/beets/util/__init__.py @@ -167,6 +167,12 @@ def syspath(path, pathmod=None): return path +def soft_remove(path): + """Remove the file if it exists.""" + path = syspath(path) + if os.path.exists(path): + os.remove(path) + # Note: POSIX actually supports \ and : -- I just think they're # a pain. And ? has caused problems for some. CHAR_REPLACE = [ diff --git a/test/test_files.py b/test/test_files.py index b52d56ff1..9b75f9d6f 100644 --- a/test/test_files.py +++ b/test/test_files.py @@ -287,6 +287,25 @@ class RemoveTest(unittest.TestCase): self.lib.remove(self.i, True) self.assertTrue(os.path.exists(parent)) +# Tests that we can "delete" nonexistent files. +class SoftRemoveTest(unittest.TestCase, _common.ExtraAsserts): + def setUp(self): + self.path = os.path.join(_common.RSRC, 'testfile') + touch(self.path) + def tearDown(self): + if os.path.exists(self.path): + os.remove(self.path) + + def test_soft_remove_deletes_file(self): + util.soft_remove(self.path) + self.assertNotExists(self.path) + + def test_soft_remove_silent_on_no_file(self): + try: + util.soft_remove(self.path + 'XXX') + except OSError: + self.fail('OSError when removing path') + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)