Merge branch 'refs/heads/develop' into tv
This commit is contained in:
@@ -73,6 +73,12 @@ config = [{
|
||||
'type': 'choice',
|
||||
'options': rename_options
|
||||
},
|
||||
{
|
||||
'name': 'unrar',
|
||||
'type': 'bool',
|
||||
'description': 'Extract rar files if found.',
|
||||
'default': False,
|
||||
},
|
||||
{
|
||||
'name': 'cleanup',
|
||||
'type': 'bool',
|
||||
|
||||
@@ -9,6 +9,8 @@ from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.core.settings.model import Library, File, Profile, Release, \
|
||||
ReleaseInfo
|
||||
from couchpotato.environment import Env
|
||||
from unrar2 import RarFile, RarInfo
|
||||
from unrar2.rar_exceptions import *
|
||||
import errno
|
||||
import fnmatch
|
||||
import os
|
||||
@@ -126,6 +128,11 @@ class Renamer(Plugin):
|
||||
# Extend the download info with info stored in the downloaded release
|
||||
download_info = self.extendDownloadInfo(download_info)
|
||||
|
||||
# Unpack any archives
|
||||
if self.conf('unrar'):
|
||||
folder, movie_folder, files, extr_files = self.extractFiles(folder = folder, movie_folder = movie_folder, files = files, \
|
||||
cleanup = self.conf('cleanup') and not self.downloadIsTorrent(download_info))
|
||||
|
||||
groups = fireEvent('scanner.scan', folder = folder if folder else self.conf('from'),
|
||||
files = files, download_info = download_info, return_ignored = False, single = True)
|
||||
|
||||
@@ -179,6 +186,9 @@ class Renamer(Plugin):
|
||||
group['before_rename'] = []
|
||||
fireEvent('renamer.before', group)
|
||||
|
||||
# Add extracted files to the before_rename list
|
||||
group['before_rename'].extend(extr_files)
|
||||
|
||||
# Remove weird chars from moviename
|
||||
movie_name = re.sub(r"[\x00\/\\:\*\?\"<>\|]", '', movie_title)
|
||||
|
||||
@@ -213,8 +223,8 @@ class Renamer(Plugin):
|
||||
# Move nfo depending on settings
|
||||
if file_type is 'nfo' and not self.conf('rename_nfo'):
|
||||
log.debug('Skipping, renaming of %s disabled', file_type)
|
||||
if self.conf('cleanup') and not self.downloadIsTorrent(download_info):
|
||||
for current_file in group['files'][file_type]:
|
||||
for current_file in group['files'][file_type]:
|
||||
if self.conf('cleanup') and (not (self.conf('file_action') != 'move' and self.downloadIsTorrent(download_info)) or self.fileIsAdded(current_file, group)):
|
||||
remove_files.append(current_file)
|
||||
continue
|
||||
|
||||
@@ -394,14 +404,15 @@ class Renamer(Plugin):
|
||||
db.commit()
|
||||
|
||||
# Remove leftover files
|
||||
if self.conf('cleanup') and not self.conf('move_leftover') and remove_leftovers and \
|
||||
not self.downloadIsTorrent(download_info):
|
||||
log.debug('Removing leftover files')
|
||||
for current_file in group['files']['leftover']:
|
||||
remove_files.append(current_file)
|
||||
elif not remove_leftovers: # Don't remove anything
|
||||
if not remove_leftovers: # Don't remove anything
|
||||
break
|
||||
|
||||
log.debug('Removing leftover files')
|
||||
for current_file in group['files']['leftover']:
|
||||
if self.conf('cleanup') and not self.conf('move_leftover') and \
|
||||
(not (self.conf('file_action') != 'move' and self.downloadIsTorrent(download_info)) or self.fileIsAdded(current_file, group)):
|
||||
remove_files.append(current_file)
|
||||
|
||||
# Remove files
|
||||
delete_folders = []
|
||||
for src in remove_files:
|
||||
@@ -834,3 +845,127 @@ Remove it if you want it to be renamed (again, or at least let it try again)
|
||||
|
||||
def movieInFromFolder(self, movie_folder):
|
||||
return movie_folder and self.conf('from') in movie_folder or not movie_folder
|
||||
|
||||
def extractFiles(self, folder = None, movie_folder = None, files = [], cleanup = False):
|
||||
|
||||
# RegEx for finding rar files
|
||||
archive_regex = '(?P<file>^(?P<base>(?:(?!\.part\d+\.rar$).)*)\.(?:(?:part0*1\.)?rar)$)'
|
||||
restfile_regex = '(^%s\.(?:part(?!0*1\.rar$)\d+\.rar$|[rstuvw]\d+$))'
|
||||
extr_files = []
|
||||
|
||||
# Check input variables
|
||||
if not folder:
|
||||
folder = self.conf('from')
|
||||
|
||||
check_file_date = True
|
||||
if movie_folder:
|
||||
check_file_date = False
|
||||
|
||||
if not files:
|
||||
for root, folders, names in os.walk(folder):
|
||||
files.extend([os.path.join(root, name) for name in names])
|
||||
|
||||
# Find all archive files
|
||||
archives = [re.search(archive_regex, name).groupdict() for name in files if re.search(archive_regex, name)]
|
||||
|
||||
#Extract all found archives
|
||||
for archive in archives:
|
||||
# Check if it has already been processed by CPS
|
||||
if (self.hastagDir(os.path.dirname(archive['file']))):
|
||||
continue
|
||||
|
||||
# Find all related archive files
|
||||
archive['files'] = [name for name in files if re.search(restfile_regex % re.escape(archive['base']), name)]
|
||||
archive['files'].append(archive['file'])
|
||||
|
||||
# Check if archive is fresh and maybe still copying/moving/downloading, ignore files newer than 1 minute
|
||||
if check_file_date:
|
||||
file_too_new = False
|
||||
for cur_file in archive['files']:
|
||||
if not os.path.isfile(cur_file):
|
||||
file_too_new = time.time()
|
||||
break
|
||||
file_time = [os.path.getmtime(cur_file), os.path.getctime(cur_file)]
|
||||
for t in file_time:
|
||||
if t > time.time() - 60:
|
||||
file_too_new = tryInt(time.time() - t)
|
||||
break
|
||||
|
||||
if file_too_new:
|
||||
break
|
||||
|
||||
if file_too_new:
|
||||
try:
|
||||
time_string = time.ctime(file_time[0])
|
||||
except:
|
||||
try:
|
||||
time_string = time.ctime(file_time[1])
|
||||
except:
|
||||
time_string = 'unknown'
|
||||
|
||||
log.info('Archive seems to be still copying/moving/downloading or just copied/moved/downloaded (created on %s), ignoring for now: %s', (time_string, os.path.basename(archive['file'])))
|
||||
continue
|
||||
|
||||
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))
|
||||
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))):
|
||||
log.debug('Extracting %s...', packedinfo.filename)
|
||||
rar_handle.extract(condition = [packedinfo.index], path = extr_path, withSubpath = False, overwrite = False)
|
||||
extr_files.append(os.path.join(extr_path, os.path.basename(packedinfo.filename)))
|
||||
del rar_handle
|
||||
except Exception, e:
|
||||
log.error('Failed to extract %s: %s %s', (archive['file'], e, traceback.format_exc()))
|
||||
continue
|
||||
|
||||
# Delete the archive files
|
||||
for filename in archive['files']:
|
||||
if cleanup:
|
||||
try:
|
||||
os.remove(filename)
|
||||
except Exception, e:
|
||||
log.error('Failed to remove %s: %s %s', (filename, e, traceback.format_exc()))
|
||||
continue
|
||||
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'))):
|
||||
for leftoverfile in list(files):
|
||||
move_to = os.path.join(self.conf('from'), os.path.relpath(leftoverfile, folder))
|
||||
|
||||
try:
|
||||
self.makeDir(os.path.dirname(move_to))
|
||||
self.moveFile(leftoverfile, move_to, cleanup)
|
||||
except Exception, e:
|
||||
log.error('Failed moving left over file %s to %s: %s %s',(leftoverfile, move_to, e, traceback.format_exc()))
|
||||
# As we probably tried to overwrite the nfo file, check if it exists and then remove the original
|
||||
if os.path.isfile(move_to):
|
||||
if cleanup:
|
||||
log.info('Deleting left over file %s instead...', leftoverfile)
|
||||
os.unlink(leftoverfile)
|
||||
else:
|
||||
continue
|
||||
|
||||
files.remove(leftoverfile)
|
||||
extr_files.append(move_to)
|
||||
|
||||
if cleanup:
|
||||
# Remove all left over folders
|
||||
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')
|
||||
|
||||
if extr_files:
|
||||
files.extend(extr_files)
|
||||
|
||||
# Cleanup files and folder if movie_folder was not provided
|
||||
if not movie_folder:
|
||||
files = []
|
||||
folder = None
|
||||
|
||||
return (folder, movie_folder, files, extr_files)
|
||||
|
||||
@@ -277,7 +277,7 @@ class Scanner(Plugin):
|
||||
except:
|
||||
break
|
||||
|
||||
# Check if movie is fresh and maybe still unpacking, ignore files new then 1 minute
|
||||
# Check if movie is fresh and maybe still unpacking, ignore files newer than 1 minute
|
||||
file_too_new = False
|
||||
for cur_file in group['unsorted_files']:
|
||||
if not os.path.isfile(cur_file):
|
||||
|
||||
Reference in New Issue
Block a user