mirror of
https://github.com/SickGear/SickGear.git
synced 2025-01-05 17:43:37 +00:00
Change process episodes with utf8 dir and nzb names, handle failed episodes without a dir, add log output streaming.
This commit is contained in:
parent
24276db858
commit
1fb9bbc6ff
5 changed files with 65 additions and 20 deletions
|
@ -24,6 +24,7 @@
|
|||
* Change refactor email notifier
|
||||
* Change emails to Unicode aware
|
||||
* Add force episode recent search to API
|
||||
* Change process episodes with utf8 dir and nzb names, handle failed episodes without a dir, add log output streaming
|
||||
|
||||
|
||||
### 0.11.5 (2016-02-01 19:40:00 UTC)
|
||||
|
|
|
@ -23,6 +23,7 @@ import os
|
|||
import re
|
||||
import subprocess
|
||||
import stat
|
||||
import threading
|
||||
|
||||
import sickbeard
|
||||
|
||||
|
@ -60,7 +61,7 @@ class PostProcessor(object):
|
|||
|
||||
IGNORED_FILESTRINGS = ['/.AppleDouble/', '.DS_Store']
|
||||
|
||||
def __init__(self, file_path, nzb_name=None, process_method=None, force_replace=None, use_trash=None):
|
||||
def __init__(self, file_path, nzb_name=None, process_method=None, force_replace=None, use_trash=None, webhandler=None):
|
||||
"""
|
||||
Creates a new post processor with the given file path and optionally an NZB name.
|
||||
|
||||
|
@ -86,6 +87,8 @@ class PostProcessor(object):
|
|||
|
||||
self.use_trash = use_trash
|
||||
|
||||
self.webhandler = webhandler
|
||||
|
||||
self.in_history = False
|
||||
|
||||
self.release_group = None
|
||||
|
@ -817,7 +820,7 @@ class PostProcessor(object):
|
|||
Post-process a given file
|
||||
"""
|
||||
|
||||
self._log(u'Processing %s%s' % (self.file_path, (u'<br />.. from nzb %s' % str(self.nzb_name), u'')[None is self.nzb_name]))
|
||||
self._log(u'Processing %s%s' % (self.file_path, (u'<br />.. from nzb %s' % self.nzb_name, u'')[None is self.nzb_name]))
|
||||
|
||||
if ek.ek(os.path.isdir, self.file_path):
|
||||
self._log(u'File %s<br />.. seems to be a directory' % self.file_path)
|
||||
|
@ -963,6 +966,16 @@ class PostProcessor(object):
|
|||
if sickbeard.ANIDB_USE_MYLIST and ep_obj.show.is_anime:
|
||||
self._add_to_anidb_mylist(self.file_path)
|
||||
|
||||
if self.webhandler:
|
||||
def keep_alive(webh, stop_event):
|
||||
while not stop_event.is_set():
|
||||
stop_event.wait(60)
|
||||
webh('.')
|
||||
webh(u'\n')
|
||||
|
||||
keepalive_stop = threading.Event()
|
||||
keepalive = threading.Thread(target=keep_alive, args=(self.webhandler, keepalive_stop))
|
||||
|
||||
try:
|
||||
# move the episode and associated files to the show dir
|
||||
args_link = {'file_path': self.file_path, 'new_path': dest_path,
|
||||
|
@ -971,6 +984,9 @@ class PostProcessor(object):
|
|||
args_cpmv = {'subtitles': sickbeard.USE_SUBTITLES and ep_obj.show.subtitles,
|
||||
'action_tmpl': u' %s<br />.. to %s'}
|
||||
args_cpmv.update(args_link)
|
||||
if self.webhandler:
|
||||
self.webhandler('Processing method is "%s"' % self.process_method)
|
||||
keepalive.start()
|
||||
if 'copy' == self.process_method:
|
||||
self._copy(**args_cpmv)
|
||||
elif 'move' == self.process_method:
|
||||
|
@ -984,7 +1000,11 @@ class PostProcessor(object):
|
|||
raise exceptions.PostProcessingFailed(u'Unable to move the files to the new location')
|
||||
except (OSError, IOError):
|
||||
raise exceptions.PostProcessingFailed(u'Unable to move the files to the new location')
|
||||
|
||||
finally:
|
||||
if self.webhandler:
|
||||
#stop the keep_alive
|
||||
keepalive_stop.set()
|
||||
|
||||
# download subtitles
|
||||
dosubs = sickbeard.USE_SUBTITLES and ep_obj.show.subtitles
|
||||
|
||||
|
|
|
@ -47,10 +47,11 @@ except ImportError:
|
|||
class ProcessTVShow(object):
|
||||
""" Process a TV Show """
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, webhandler=None):
|
||||
self.files_passed = 0
|
||||
self.files_failed = 0
|
||||
self._output = []
|
||||
self.webhandler = webhandler
|
||||
|
||||
@property
|
||||
def any_vid_processed(self):
|
||||
|
@ -63,6 +64,10 @@ class ProcessTVShow(object):
|
|||
def _buffer(self, text=None):
|
||||
if None is not text:
|
||||
self._output.append(text)
|
||||
if self.webhandler:
|
||||
logger_msg = re.sub(r'(?i)<br(?:[\s/]+)>', '\n', text)
|
||||
logger_msg = re.sub('(?i)<a[^>]+>([^<]+)<[/]a>', r'\1', logger_msg)
|
||||
self.webhandler('%s%s' % (logger_msg, u'\n'))
|
||||
|
||||
def _log_helper(self, message, log_level=logger.DEBUG):
|
||||
logger_msg = re.sub(r'(?i)<br(?:[\s/]+)>\.*', '', message)
|
||||
|
@ -153,22 +158,26 @@ class ProcessTVShow(object):
|
|||
"""
|
||||
|
||||
# if they passed us a real directory then assume it's the one we want
|
||||
if ek.ek(os.path.isdir, dir_name):
|
||||
if dir_name and ek.ek(os.path.isdir, dir_name):
|
||||
self._log_helper(u'Processing folder... ' + dir_name)
|
||||
dir_name = ek.ek(os.path.realpath, dir_name)
|
||||
|
||||
# if the client and SickGear are not on the same machine translate the directory in a network directory
|
||||
elif sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR)\
|
||||
elif dir_name and sickbeard.TV_DOWNLOAD_DIR and ek.ek(os.path.isdir, sickbeard.TV_DOWNLOAD_DIR)\
|
||||
and ek.ek(os.path.normpath, dir_name) != ek.ek(os.path.normpath, sickbeard.TV_DOWNLOAD_DIR):
|
||||
dir_name = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, ek.ek(os.path.abspath, dir_name).split(os.path.sep)[-1])
|
||||
self._log_helper(u'SickGear PP Config, completed TV downloads folder: ' + sickbeard.TV_DOWNLOAD_DIR)
|
||||
self._log_helper(u'Trying to use folder... ' + dir_name)
|
||||
|
||||
# if we didn't find a real directory then quit
|
||||
if not ek.ek(os.path.isdir, dir_name):
|
||||
self._log_helper(
|
||||
u'Unable to figure out what folder to process. If your downloader and SickGear aren\'t on the same PC then make sure you fill out your completed TV download folder in the PP config.')
|
||||
return self.result
|
||||
if not dir_name or not ek.ek(os.path.isdir, dir_name):
|
||||
if nzb_name and failed:
|
||||
self._process_failed(dir_name, nzb_name)
|
||||
return self.result
|
||||
else:
|
||||
self._log_helper(
|
||||
u'Unable to figure out what folder to process. If your downloader and SickGear aren\'t on the same PC then make sure you fill out your completed TV download folder in the PP config.')
|
||||
return self.result
|
||||
|
||||
path, dirs, files = self._get_path_dir_files(dir_name, nzb_name, pp_type)
|
||||
|
||||
|
@ -503,7 +512,7 @@ class ProcessTVShow(object):
|
|||
cur_video_file_path = ek.ek(os.path.join, process_path, cur_video_file)
|
||||
|
||||
try:
|
||||
processor = postProcessor.PostProcessor(cur_video_file_path, nzb_name, process_method, force_replace, use_trash=use_trash)
|
||||
processor = postProcessor.PostProcessor(cur_video_file_path, nzb_name, process_method, force_replace, use_trash=use_trash, webhandler=self.webhandler)
|
||||
file_success = processor.process()
|
||||
process_fail_message = ''
|
||||
except exceptions.PostProcessingFailed as e:
|
||||
|
@ -577,6 +586,6 @@ class ProcessTVShow(object):
|
|||
|
||||
|
||||
# backward compatibility prevents the case of this function name from being updated to PEP8
|
||||
def processDir(dir_name, nzb_name=None, process_method=None, force=False, force_replace=None, failed=False, type='auto', cleanup=False):
|
||||
def processDir(dir_name, nzb_name=None, process_method=None, force=False, force_replace=None, failed=False, type='auto', cleanup=False, webhandler=None):
|
||||
# backward compatibility prevents the case of this function name from being updated to PEP8
|
||||
return ProcessTVShow().process_dir(dir_name, nzb_name, process_method, force, force_replace, failed, type, cleanup)
|
||||
return ProcessTVShow(webhandler).process_dir(dir_name, nzb_name, process_method, force, force_replace, failed, type, cleanup)
|
||||
|
|
|
@ -285,7 +285,7 @@ def determineReleaseName(dir_name=None, nzb_name=None):
|
|||
logger.log(u'Using nzb name for release name.')
|
||||
return nzb_name.rpartition('.')[0]
|
||||
|
||||
if dir_name is None:
|
||||
if not dir_name or not ek.ek(os.path.isdir, dir_name):
|
||||
return None
|
||||
|
||||
# try to get the release name from nzb/nfo
|
||||
|
|
|
@ -28,6 +28,7 @@ import re
|
|||
import time
|
||||
import traceback
|
||||
import urllib
|
||||
import threading
|
||||
|
||||
from mimetypes import MimeTypes
|
||||
from Cheetah.Template import Template
|
||||
|
@ -287,6 +288,10 @@ class IsAliveHandler(BaseHandler):
|
|||
|
||||
|
||||
class WebHandler(BaseHandler):
|
||||
def __init__(self, *arg, **kwargs):
|
||||
super(BaseHandler, self).__init__(*arg, **kwargs)
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def page_not_found(self):
|
||||
t = PageTemplate(headers=self.request.headers, file='404.tmpl')
|
||||
return t.respond()
|
||||
|
@ -308,6 +313,11 @@ class WebHandler(BaseHandler):
|
|||
if result:
|
||||
self.finish(result)
|
||||
|
||||
def send_message(self, message):
|
||||
with self.lock:
|
||||
self.write(message)
|
||||
self.flush()
|
||||
|
||||
post = get
|
||||
|
||||
|
||||
|
@ -1043,9 +1053,12 @@ class Home(MainHandler):
|
|||
else:
|
||||
if change:
|
||||
output.append(change)
|
||||
change = None
|
||||
if line.startswith('* '):
|
||||
change_parts = re.findall(r'^[\*\W]+(Add|Change|Fix|Port|Remove|Update)\W(.*)', line)
|
||||
change = change_parts and {'type': change_parts[0][0], 'text': change_parts[0][1].strip()} or {}
|
||||
elif not max_rel:
|
||||
break
|
||||
elif line.startswith('### '):
|
||||
rel_data = re.findall(r'(?im)^###\W*([^\s]+)\W\(([^\)]+)\)', line)
|
||||
rel_data and output.append({'type': 'rel', 'ver': rel_data[0][0], 'date': rel_data[0][1]})
|
||||
|
@ -1053,8 +1066,6 @@ class Home(MainHandler):
|
|||
elif line.startswith('# '):
|
||||
max_data = re.findall(r'^#\W*([\d]+)\W*$', line)
|
||||
max_rel = max_data and helpers.tryInt(max_data[0], None) or 5
|
||||
if not max_rel:
|
||||
break
|
||||
if change:
|
||||
output.append(change)
|
||||
|
||||
|
@ -2110,17 +2121,21 @@ class HomePostProcess(Home):
|
|||
return t.respond()
|
||||
|
||||
def processEpisode(self, dir=None, nzbName=None, jobName=None, quiet=None, process_method=None, force=None,
|
||||
force_replace=None, failed='0', type='auto', **kwargs):
|
||||
force_replace=None, failed='0', type='auto', stream='0', **kwargs):
|
||||
|
||||
if not dir:
|
||||
if not dir and ('0' == failed or not nzbName):
|
||||
self.redirect('/home/postprocess/')
|
||||
else:
|
||||
result = processTV.processDir(dir, nzbName, process_method=process_method, type=type,
|
||||
result = processTV.processDir(dir.decode('utf-8') if dir else None, nzbName.decode('utf-8') if nzbName else None,
|
||||
process_method=process_method, type=type,
|
||||
cleanup='cleanup' in kwargs and kwargs['cleanup'] in ['on', '1'],
|
||||
force=force in ['on', '1'],
|
||||
force_replace=force_replace in ['on', '1'],
|
||||
failed=not '0' == failed)
|
||||
failed='0' != failed,
|
||||
webhandler=self.send_message if stream != '0' else None)
|
||||
|
||||
if '0' != stream:
|
||||
return
|
||||
result = re.sub(r'(?i)<br(?:[\s/]+)>', '\n', result)
|
||||
if None is not quiet and 1 == int(quiet):
|
||||
return u'%s' % re.sub('(?i)<a[^>]+>([^<]+)<[/]a>', r'\1', result)
|
||||
|
|
Loading…
Reference in a new issue