Browse Source

Introduce path cleaning

A new function sp is introduced. It does the same as ss but also cleans
the path.
pull/2414/head
mano3m 12 years ago
parent
commit
fa1baa73e8
  1. 10
      couchpotato/core/downloaders/deluge/main.py
  2. 4
      couchpotato/core/downloaders/nzbget/main.py
  3. 6
      couchpotato/core/downloaders/nzbvortex/main.py
  4. 8
      couchpotato/core/downloaders/rtorrent/main.py
  5. 4
      couchpotato/core/downloaders/sabnzbd/main.py
  6. 8
      couchpotato/core/downloaders/transmission/main.py
  7. 8
      couchpotato/core/downloaders/utorrent/main.py
  8. 5
      couchpotato/core/helpers/encoding.py
  9. 39
      couchpotato/core/plugins/renamer/main.py
  10. 6
      couchpotato/core/plugins/scanner/main.py

10
couchpotato/core/downloaders/deluge/main.py

@ -1,6 +1,6 @@
from base64 import b64encode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import isInt, ss
from couchpotato.core.helpers.encoding import isInt, sp
from couchpotato.core.helpers.variable import tryFloat
from couchpotato.core.logger import CPLog
from datetime import timedelta
@ -111,13 +111,13 @@ class Deluge(Downloader):
elif torrent['is_seed'] and torrent['is_finished'] and torrent['paused'] and torrent['state'] == 'Paused':
status = 'completed'
download_dir = torrent['save_path']
download_dir = sp(torrent['save_path'])
if torrent['move_on_completed']:
download_dir = torrent['move_completed_path']
torrent_files = []
for file_item in torrent['files']:
torrent_files.append(os.path.join(download_dir, file_item['path']))
torrent_files.append(os.path.join(download_dir), sp(file_item['path']))
release_downloads.append({
'id': torrent['hash'],
@ -126,8 +126,8 @@ class Deluge(Downloader):
'original_status': torrent['state'],
'seed_ratio': torrent['ratio'],
'timeleft': str(timedelta(seconds = torrent['eta'])),
'folder': ss(download_dir) if len(torrent_files) == 1 else ss(os.path.join(download_dir, torrent['name'])),
'files': ss('|'.join(torrent_files)),
'folder': sp(download_dir) if len(torrent_files) == 1 else os.path.join(sp(download_dir), torrent['name']),
'files': '|'.join(torrent_files),
})
return release_downloads

4
couchpotato/core/downloaders/nzbget/main.py

@ -1,6 +1,6 @@
from base64 import standard_b64encode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import ss
from couchpotato.core.helpers.encoding import ss, sp
from couchpotato.core.helpers.variable import tryInt, md5
from couchpotato.core.logger import CPLog
from datetime import timedelta
@ -145,7 +145,7 @@ class NZBGet(Downloader):
'status': 'completed' if nzb['ParStatus'] in ['SUCCESS', 'NONE'] and nzb['ScriptStatus'] in ['SUCCESS', 'NONE'] else 'failed',
'original_status': nzb['ParStatus'] + ', ' + nzb['ScriptStatus'],
'timeleft': str(timedelta(seconds = 0)),
'folder': ss(nzb['DestDir'])
'folder': sp(nzb['DestDir'])
})
return release_downloads

6
couchpotato/core/downloaders/nzbvortex/main.py

@ -1,6 +1,6 @@
from base64 import b64encode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import tryUrlencode, ss
from couchpotato.core.helpers.encoding import tryUrlencode, sp
from couchpotato.core.helpers.variable import cleanHost
from couchpotato.core.logger import CPLog
from urllib2 import URLError
@ -30,7 +30,7 @@ class NZBVortex(Downloader):
# Send the nzb
try:
nzb_filename = self.createFileName(data, filedata, movie)
self.call('nzb/add', params = {'file': (ss(nzb_filename), filedata)}, multipart = True)
self.call('nzb/add', params = {'file': (sp(nzb_filename), filedata)}, multipart = True)
raw_statuses = self.call('nzb')
nzb_id = [nzb['id'] for nzb in raw_statuses.get('nzbs', []) if nzb['name'] == nzb_filename][0]
@ -59,7 +59,7 @@ class NZBVortex(Downloader):
'status': status,
'original_status': nzb['state'],
'timeleft':-1,
'folder': ss(nzb['destinationPath']),
'folder': sp(nzb['destinationPath']),
})
return release_downloads

8
couchpotato/core/downloaders/rtorrent/main.py

@ -1,7 +1,7 @@
from base64 import b16encode, b32decode
from bencode import bencode, bdecode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import ss
from couchpotato.core.helpers.encoding import sp
from couchpotato.core.logger import CPLog
from datetime import timedelta
from hashlib import sha1
@ -157,7 +157,7 @@ class rTorrent(Downloader):
for torrent in torrents:
torrent_files = []
for file_item in torrent.get_files():
torrent_files.append(os.path.join(torrent.directory, file_item.path))
torrent_files.append(os.path.join(sp(torrent.directory), sp(file_item.path)))
status = 'busy'
if torrent.complete:
@ -173,8 +173,8 @@ class rTorrent(Downloader):
'seed_ratio': torrent.ratio,
'original_status': torrent.state,
'timeleft': str(timedelta(seconds = float(torrent.left_bytes) / torrent.down_rate)) if torrent.down_rate > 0 else -1,
'folder': ss(torrent.directory),
'files': ss('|'.join(torrent_files))
'folder': sp(torrent.directory),
'files': '|'.join(torrent_files)
})
return release_downloads

4
couchpotato/core/downloaders/sabnzbd/main.py

@ -1,5 +1,5 @@
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import tryUrlencode, ss
from couchpotato.core.helpers.encoding import tryUrlencode, ss, sp
from couchpotato.core.helpers.variable import cleanHost, mergeDicts
from couchpotato.core.logger import CPLog
from couchpotato.environment import Env
@ -118,7 +118,7 @@ class Sabnzbd(Downloader):
'status': status,
'original_status': nzb['status'],
'timeleft': str(timedelta(seconds = 0)),
'folder': os.path.dirname(ss(nzb['storage'])) if os.path.isfile(ss(nzb['storage'])) else ss(nzb['storage']),
'folder': os.path.dirname(sp(nzb['storage'])) if os.path.isfile(sp(nzb['storage'])) else sp(nzb['storage']),
})
return release_downloads

8
couchpotato/core/downloaders/transmission/main.py

@ -1,6 +1,6 @@
from base64 import b64encode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import isInt, ss
from couchpotato.core.helpers.encoding import isInt, sp
from couchpotato.core.helpers.variable import tryInt, tryFloat
from couchpotato.core.logger import CPLog
from datetime import timedelta
@ -105,7 +105,7 @@ class Transmission(Downloader):
torrent_files = []
for file_item in torrent['files']:
torrent_files.append(os.path.normpath(os.path.join(ss(torrent['downloadDir']), ss(file_item['name']))))
torrent_files.append(os.path.join(sp(torrent['downloadDir']), sp(file_item['name'])))
status = 'busy'
if torrent.get('isStalled') and self.conf('stalled_as_failed'):
@ -122,8 +122,8 @@ class Transmission(Downloader):
'original_status': torrent['status'],
'seed_ratio': torrent['uploadRatio'],
'timeleft': str(timedelta(seconds = torrent['eta'])),
'folder': os.path.normpath(ss(torrent['downloadDir'])) if len(torrent_files) == 1 else os.path.normpath(os.path.join(ss(torrent['downloadDir']), ss(torrent['name']))),
'files': ss('|'.join(torrent_files))
'folder': sp(torrent['downloadDir']) if len(torrent_files) == 1 else os.path.join(sp(torrent['downloadDir']), sp(torrent['name'])),
'files': '|'.join(torrent_files)
})
return release_downloads

8
couchpotato/core/downloaders/utorrent/main.py

@ -1,7 +1,7 @@
from base64 import b16encode, b32decode
from bencode import bencode as benc, bdecode
from couchpotato.core.downloaders.base import Downloader, ReleaseDownloadList
from couchpotato.core.helpers.encoding import isInt, ss
from couchpotato.core.helpers.encoding import isInt, ss, sp
from couchpotato.core.helpers.variable import tryInt, tryFloat
from couchpotato.core.logger import CPLog
from datetime import timedelta
@ -134,7 +134,7 @@ class uTorrent(Downloader):
torrent_files = []
try:
torrent_files = json.loads(self.utorrent_api.get_files(torrent[0]))
torrent_files = [os.path.join(torrent[26], torrent_file[0]) for torrent_file in torrent_files['files'][1]]
torrent_files = [os.path.join(sp(torrent[26]), sp(torrent_file[0])) for torrent_file in torrent_files['files'][1]]
except:
log.debug('Failed getting files from torrent: %s', torrent[2])
@ -167,8 +167,8 @@ class uTorrent(Downloader):
'seed_ratio': float(torrent[7]) / 1000,
'original_status': torrent[1],
'timeleft': str(timedelta(seconds = torrent[10])),
'folder': ss(torrent[26]),
'files': ss('|'.join(torrent_files))
'folder': sp(torrent[26]),
'files': '|'.join(torrent_files)
})
return release_downloads

5
couchpotato/core/helpers/encoding.py

@ -1,6 +1,7 @@
from couchpotato.core.logger import CPLog
from string import ascii_letters, digits
from urllib import quote_plus
import os
import re
import traceback
import unicodedata
@ -47,6 +48,10 @@ def ss(original, *args):
log.debug('Failed ss encoding char, force UTF8: %s', e)
return u_original.encode('UTF-8')
def sp(path, *args):
# Standardise encoding, normalise case, path and strip trailing '/' or '\'
return os.path.normcase(os.path.normpath(ss(path, *args))).rstrip(os.path.sep)
def ek(original, *args):
if isinstance(original, (str, unicode)):
try:

39
couchpotato/core/plugins/renamer/main.py

@ -1,7 +1,7 @@
from couchpotato import get_session
from couchpotato.api import addApiView
from couchpotato.core.event import addEvent, fireEvent, fireEventAsync
from couchpotato.core.helpers.encoding import toUnicode, ss
from couchpotato.core.helpers.encoding import toUnicode, ss, sp
from couchpotato.core.helpers.variable import getExt, mergeDicts, getTitle, \
getImdb, link, symlink, tryInt, splitString
from couchpotato.core.logger import CPLog
@ -63,7 +63,7 @@ class Renamer(Plugin):
def scanView(self, **kwargs):
async = tryInt(kwargs.get('async', 0))
movie_folder = kwargs.get('movie_folder')
movie_folder = sp(kwargs.get('movie_folder'))
downloader = kwargs.get('downloader')
download_id = kwargs.get('download_id')
status = kwargs.get('status', 'completed')
@ -93,7 +93,7 @@ class Renamer(Plugin):
movie_folder = release_download and release_download.get('folder')
# Get all folders that should not be processed
no_process = [self.conf('to')]
no_process = [sp(self.conf('to'))]
cat_list = fireEvent('category.all', single = True) or []
no_process.extend([item['destination'] for item in cat_list])
try:
@ -103,12 +103,12 @@ class Renamer(Plugin):
pass
# Check to see if the no_process folders are inside the "from" folder.
if not os.path.isdir(self.conf('from')) or not os.path.isdir(self.conf('to')):
if not os.path.isdir(sp(self.conf('from'))) or not os.path.isdir(sp(self.conf('to'))):
log.error('Both the "To" and "From" have to exist.')
return
else:
for item in no_process:
if self.conf('from') in item:
if sp(self.conf('from')) in item:
log.error('To protect your data, the movie libraries can\'t be inside of or the same as the "from" folder.')
return
@ -133,7 +133,6 @@ class Renamer(Plugin):
files = []
if movie_folder:
log.info('Scanning movie folder %s...', movie_folder)
movie_folder = movie_folder.rstrip(os.path.sep)
folder = os.path.dirname(movie_folder)
if release_download.get('files', ''):
@ -161,7 +160,7 @@ class Renamer(Plugin):
folder, movie_folder, files, extr_files = self.extractFiles(folder = folder, movie_folder = movie_folder, files = files,
cleanup = self.conf('cleanup') and not self.downloadIsTorrent(release_download))
groups = fireEvent('scanner.scan', folder = folder if folder else self.conf('from'),
groups = fireEvent('scanner.scan', folder = folder if folder else sp(self.conf('from')),
files = files, release_download = release_download, return_ignored = False, single = True) or []
folder_name = self.conf('folder_name')
@ -200,7 +199,7 @@ class Renamer(Plugin):
movie_title = getTitle(library)
# Overwrite destination when set in category
destination = self.conf('to')
destination = sp(self.conf('to'))
category_label = ''
for movie in library_ent.movies:
@ -465,12 +464,12 @@ class Renamer(Plugin):
log.info('Removing "%s"', src)
try:
src = ss(src)
src = sp(src)
if os.path.isfile(src):
os.remove(src)
parent_dir = os.path.normpath(os.path.dirname(src))
if delete_folders.count(parent_dir) == 0 and os.path.isdir(parent_dir) and not parent_dir in [destination, movie_folder] and not self.conf('from') in parent_dir:
parent_dir = os.path.dirname(src)
if delete_folders.count(parent_dir) == 0 and os.path.isdir(parent_dir) and not parent_dir in [destination, movie_folder] and not sp(self.conf('from')) in parent_dir:
delete_folders.append(parent_dir)
except:
@ -519,7 +518,7 @@ class Renamer(Plugin):
group_folder = movie_folder
else:
# Delete the first empty subfolder in the tree relative to the 'from' folder
group_folder = os.path.join(self.conf('from'), os.path.relpath(group['parentdir'], self.conf('from')).split(os.path.sep)[0])
group_folder = os.path.join(sp(self.conf('from')), os.path.relpath(group['parentdir'], sp(self.conf('from'))).split(os.path.sep)[0])
try:
log.info('Deleting folder: %s', group_folder)
@ -802,7 +801,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
fireEvent('release.update_status', rel.id, status = snatched_status, single = True)
# Tag folder if it is in the 'from' folder and it will not be processed because it is still downloading
if release_download['folder'] and self.conf('from') in release_download['folder']:
if self.movieInFromFolder(release_download['folder']):
self.tagRelease(release_download = release_download, tag = 'downloading')
elif release_download['status'] == 'seeding':
@ -948,7 +947,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
return release_download['id'] and release_download['downloader'] and release_download['folder']
def movieInFromFolder(self, movie_folder):
return movie_folder and self.conf('from') in movie_folder or not movie_folder
return movie_folder and sp(self.conf('from')) in movie_folder or not movie_folder
def extractFiles(self, folder = None, movie_folder = None, files = None, cleanup = False):
if not files: files = []
@ -960,7 +959,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
# Check input variables
if not folder:
folder = self.conf('from')
folder = sp(self.conf('from'))
check_file_date = True
if movie_folder:
@ -1014,7 +1013,7 @@ Remove it if you want it to be renamed (again, or at least let it try again)
log.info('Archive %s found. Extracting...', os.path.basename(archive['file']))
try:
rar_handle = RarFile(archive['file'])
extr_path = os.path.join(self.conf('from'), os.path.relpath(os.path.dirname(archive['file']), folder))
extr_path = os.path.join(sp(self.conf('from')), os.path.relpath(os.path.dirname(archive['file']), folder))
self.makeDir(extr_path)
for packedinfo in rar_handle.infolist():
if not packedinfo.isdir and not os.path.isfile(os.path.join(extr_path, os.path.basename(packedinfo.filename))):
@ -1037,9 +1036,9 @@ Remove it if you want it to be renamed (again, or at least let it try again)
files.remove(filename)
# Move the rest of the files and folders if any files are extracted to the from folder (only if folder was provided)
if extr_files and os.path.normpath(os.path.normcase(folder)) != os.path.normpath(os.path.normcase(self.conf('from'))):
if extr_files and folder != sp(self.conf('from')):
for leftoverfile in list(files):
move_to = os.path.join(self.conf('from'), os.path.relpath(leftoverfile, folder))
move_to = os.path.join(sp(self.conf('from')), os.path.relpath(leftoverfile, folder))
try:
self.makeDir(os.path.dirname(move_to))
@ -1062,8 +1061,8 @@ Remove it if you want it to be renamed (again, or at least let it try again)
log.debug('Removing old movie folder %s...', movie_folder)
self.deleteEmptyFolder(movie_folder)
movie_folder = os.path.join(self.conf('from'), os.path.relpath(movie_folder, folder))
folder = self.conf('from')
movie_folder = os.path.join(sp(self.conf('from')), os.path.relpath(movie_folder, folder))
folder = sp(self.conf('from'))
if extr_files:
files.extend(extr_files)

6
couchpotato/core/plugins/scanner/main.py

@ -1,6 +1,6 @@
from couchpotato import get_session
from couchpotato.core.event import fireEvent, addEvent
from couchpotato.core.helpers.encoding import toUnicode, simplifyString, ss
from couchpotato.core.helpers.encoding import toUnicode, simplifyString, ss, sp
from couchpotato.core.helpers.variable import getExt, getImdb, tryInt, \
splitString
from couchpotato.core.logger import CPLog
@ -106,7 +106,7 @@ class Scanner(Plugin):
def scan(self, folder = None, files = None, release_download = None, simple = False, newer_than = 0, return_ignored = True, on_found = None):
folder = ss(os.path.normpath(folder))
folder = sp(folder)
if not folder or not os.path.isdir(folder):
log.error('Folder doesn\'t exists: %s', folder)
@ -122,7 +122,7 @@ class Scanner(Plugin):
try:
files = []
for root, dirs, walk_files in os.walk(folder):
files.extend(os.path.join(root, filename) for filename in walk_files)
files.extend([os.path.join(root, filename) for filename in walk_files])
# Break if CP wants to shut down
if self.shuttingDown():

Loading…
Cancel
Save