Fix torrent file and folder renaming issues
Adds `sanitize_filepath` for use before passing to libtorrent rename_file
This commit is contained in:
parent
15ef668fef
commit
fcc13f454b
|
@ -51,6 +51,31 @@ TORRENT_STATE = deluge.common.TORRENT_STATE
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
def sanitize_filepath(filepath, folder=False):
|
||||||
|
"""
|
||||||
|
Returns a sanitized filepath to pass to libotorrent rename_file().
|
||||||
|
The filepath will have backslashes substituted along with whitespace
|
||||||
|
padding and duplicate slashes stripped. If `folder` is True a trailing
|
||||||
|
slash is appended to the returned filepath.
|
||||||
|
"""
|
||||||
|
def clean_filename(filename):
|
||||||
|
filename = filename.strip()
|
||||||
|
if filename.replace('.', '') == '':
|
||||||
|
return ''
|
||||||
|
return filename
|
||||||
|
|
||||||
|
if '\\' in filepath or '/' in filepath:
|
||||||
|
folderpath = filepath.replace('\\', '/').split('/')
|
||||||
|
folderpath = [clean_filename(x) for x in folderpath]
|
||||||
|
newfilepath = '/'.join(filter(None, folderpath))
|
||||||
|
else:
|
||||||
|
newfilepath = clean_filename(filepath)
|
||||||
|
|
||||||
|
if folder is True:
|
||||||
|
return newfilepath + '/'
|
||||||
|
else:
|
||||||
|
return newfilepath
|
||||||
|
|
||||||
class TorrentOptions(dict):
|
class TorrentOptions(dict):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
config = ConfigManager("core.conf").config
|
config = ConfigManager("core.conf").config
|
||||||
|
@ -955,6 +980,7 @@ class Torrent(object):
|
||||||
"""Renames files in the torrent. 'filenames' should be a list of
|
"""Renames files in the torrent. 'filenames' should be a list of
|
||||||
(index, filename) pairs."""
|
(index, filename) pairs."""
|
||||||
for index, filename in filenames:
|
for index, filename in filenames:
|
||||||
|
filename = sanitize_filepath(filename)
|
||||||
self.handle.rename_file(index, filename.encode("utf-8"))
|
self.handle.rename_file(index, filename.encode("utf-8"))
|
||||||
|
|
||||||
def rename_folder(self, folder, new_folder):
|
def rename_folder(self, folder, new_folder):
|
||||||
|
@ -965,8 +991,7 @@ class Torrent(object):
|
||||||
log.error("Attempting to rename a folder with an invalid folder name: %s", new_folder)
|
log.error("Attempting to rename a folder with an invalid folder name: %s", new_folder)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Make sure the new folder path is nice and has a trailing slash
|
new_folder = sanitize_filepath(new_folder, folder=True)
|
||||||
new_folder = os.path.normpath(new_folder) + "/"
|
|
||||||
|
|
||||||
wait_on_folder = (folder, new_folder, [])
|
wait_on_folder = (folder, new_folder, [])
|
||||||
for f in self.get_files():
|
for f in self.get_files():
|
||||||
|
|
|
@ -185,3 +185,19 @@ class CoreTestCase(unittest.TestCase):
|
||||||
|
|
||||||
d.addCallback(result)
|
d.addCallback(result)
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def test_sanitize_filepath(self):
|
||||||
|
pathlist = {
|
||||||
|
'\\backslash\\path\\' : 'backslash/path',
|
||||||
|
' single_file ': 'single_file',
|
||||||
|
'..' : '',
|
||||||
|
'/../..../': '',
|
||||||
|
' Def ////ad./ / . . /b d /file': 'Def/ad./. ./b d/file',
|
||||||
|
'/ test /\\.. /.file/': 'test/.file',
|
||||||
|
'mytorrent/subfold/file1': 'mytorrent/subfold/file1',
|
||||||
|
'Torrent/folder/': 'Torrent/folder',
|
||||||
|
}
|
||||||
|
|
||||||
|
for key in pathlist:
|
||||||
|
self.assertEquals(deluge.core.torrent.sanitize_filepath(key, folder=False), pathlist[key])
|
||||||
|
self.assertEquals(deluge.core.torrent.sanitize_filepath(key, folder=True), pathlist[key] + '/')
|
||||||
|
|
Loading…
Reference in New Issue