1
0
mirror of https://github.com/moparisthebest/SickRage synced 2024-12-14 03:52:22 -05:00

Merge branch 'origin/dev'

This commit is contained in:
echel0n 2014-05-13 04:51:18 -07:00
commit 3a2f3ff7a2
14 changed files with 203 additions and 181 deletions

View File

@ -2,20 +2,20 @@
# Author: Nic Wolfe <nic@wolfeden.ca> # Author: Nic Wolfe <nic@wolfeden.ca>
# URL: http://code.google.com/p/sickbeard/ # URL: http://code.google.com/p/sickbeard/
# #
# This file is part of Sick Beard. # This file is part of SickRage.
# #
# Sick Beard is free software: you can redistribute it and/or modify # SickRage is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# Sick Beard is distributed in the hope that it will be useful, # SickRage is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details. # GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Sick Beard. If not, see <http://www.gnu.org/licenses/>. # along with SickRage. If not, see <http://www.gnu.org/licenses/>.
# Check needed software dependencies to nudge users to fix their setup # Check needed software dependencies to nudge users to fix their setup
import sys import sys
@ -96,9 +96,10 @@ def daemonize():
try: try:
pid = os.fork() # @UndefinedVariable - only available in UNIX pid = os.fork() # @UndefinedVariable - only available in UNIX
if pid != 0: if pid != 0:
sys.exit(0) os._exit(0)
except OSError, e: except OSError, e:
raise RuntimeError("1st fork failed: %s [%d]" % (e.strerror, e.errno)) sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
os.setsid() # @UndefinedVariable - only available in UNIX os.setsid() # @UndefinedVariable - only available in UNIX
@ -110,18 +111,33 @@ def daemonize():
try: try:
pid = os.fork() # @UndefinedVariable - only available in UNIX pid = os.fork() # @UndefinedVariable - only available in UNIX
if pid != 0: if pid != 0:
sys.exit(0) os._exit(0)
except OSError, e: except OSError, e:
raise RuntimeError("2nd fork failed: %s [%d]" % (e.strerror, e.errno)) sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
sys.exit(1)
dev_null = file('/dev/null', 'r')
os.dup2(dev_null.fileno(), sys.stdin.fileno())
# Write pid
if sickbeard.CREATEPID: if sickbeard.CREATEPID:
pid = str(os.getpid()) pid = str(os.getpid())
logger.log(u"Writing PID " + pid + " to " + str(sickbeard.PIDFILE)) logger.log(u"Writing PID: " + pid + " to " + str(sickbeard.PIDFILE))
file(sickbeard.PIDFILE, 'w').write("%s\n" % pid) try:
file(sickbeard.PIDFILE, 'w').write("%s\n" % pid)
except IOError, e:
logger.log_error_and_exit(
u"Unable to write PID file: " + sickbeard.PIDFILE + " Error: " + str(e.strerror) + " [" + str(
e.errno) + "]")
# Redirect all output
sys.stdout.flush()
sys.stderr.flush()
devnull = getattr(os, 'devnull', '/dev/null')
stdin = file(devnull, 'r')
stdout = file(devnull, 'a+')
stderr = file(devnull, 'a+')
os.dup2(stdin.fileno(), sys.stdin.fileno())
os.dup2(stdout.fileno(), sys.stdout.fileno())
os.dup2(stderr.fileno(), sys.stderr.fileno())
def main(): def main():
""" """
@ -134,8 +150,8 @@ def main():
sickbeard.PROG_DIR = os.path.dirname(sickbeard.MY_FULLNAME) sickbeard.PROG_DIR = os.path.dirname(sickbeard.MY_FULLNAME)
sickbeard.DATA_DIR = sickbeard.PROG_DIR sickbeard.DATA_DIR = sickbeard.PROG_DIR
sickbeard.MY_ARGS = sys.argv[1:] sickbeard.MY_ARGS = sys.argv[1:]
sickbeard.CREATEPID = False
sickbeard.DAEMON = False sickbeard.DAEMON = False
sickbeard.CREATEPID = False
sickbeard.SYS_ENCODING = None sickbeard.SYS_ENCODING = None
@ -157,7 +173,7 @@ def main():
# On non-unicode builds this will raise an AttributeError, if encoding type is not valid it throws a LookupError # On non-unicode builds this will raise an AttributeError, if encoding type is not valid it throws a LookupError
sys.setdefaultencoding(sickbeard.SYS_ENCODING) sys.setdefaultencoding(sickbeard.SYS_ENCODING)
except: except:
print 'Sorry, you MUST add the Sick Beard folder to the PYTHONPATH environment variable' print 'Sorry, you MUST add the SickRage folder to the PYTHONPATH environment variable'
print 'or find another way to force Python to use ' + sickbeard.SYS_ENCODING + ' for string encoding.' print 'or find another way to force Python to use ' + sickbeard.SYS_ENCODING + ' for string encoding.'
sys.exit(1) sys.exit(1)
@ -196,13 +212,15 @@ def main():
if o in ('-p', '--port'): if o in ('-p', '--port'):
forcedPort = int(a) forcedPort = int(a)
# Run as a daemon # Run as a double forked daemon
if o in ('-d', '--daemon'): if o in ('-d', '--daemon'):
sickbeard.DAEMON = True
# When running as daemon disable consoleLogging and don't start browser
consoleLogging = False
noLaunch = True
if sys.platform == 'win32': if sys.platform == 'win32':
print "Daemonize not supported under Windows, starting normally" sickbeard.DAEMON = False
else:
consoleLogging = False
sickbeard.DAEMON = True
# Specify folder to load the config file from # Specify folder to load the config file from
if o in ('--config',): if o in ('--config',):
@ -214,21 +232,27 @@ def main():
# Write a pidfile if requested # Write a pidfile if requested
if o in ('--pidfile',): if o in ('--pidfile',):
sickbeard.CREATEPID = True
sickbeard.PIDFILE = str(a) sickbeard.PIDFILE = str(a)
# If the pidfile already exists, sickbeard may still be running, so exit # If the pidfile already exists, sickbeard may still be running, so exit
if os.path.exists(sickbeard.PIDFILE): if os.path.exists(sickbeard.PIDFILE):
sys.exit("PID file '" + sickbeard.PIDFILE + "' already exists. Exiting.") sys.exit("PID file: " + sickbeard.PIDFILE + " already exists. Exiting.")
# The pidfile is only useful in daemon mode, make sure we can write the file properly # The pidfile is only useful in daemon mode, make sure we can write the file properly
if sickbeard.DAEMON: if sickbeard.CREATEPID:
sickbeard.CREATEPID = True if sickbeard.DAEMON:
try: pid_dir = os.path.dirname(sickbeard.PIDFILE)
file(sickbeard.PIDFILE, 'w').write("pid\n") if not os.access(pid_dir, os.F_OK):
except IOError, e: sys.exit("PID dir: " + pid_dir + " doesn't exist. Exiting.")
raise SystemExit("Unable to write PID file: %s [%d]" % (e.strerror, e.errno)) if not os.access(pid_dir, os.W_OK):
else: sys.exit("PID dir: " + pid_dir + " must be writable (write permissions). Exiting.")
logger.log(u"Not running in daemon mode. PID file creation disabled.")
else:
if consoleLogging:
sys.stdout.write("Not running in daemon mode. PID file creation disabled.\n")
sickbeard.CREATEPID = False
# If they don't specify a config file then put it in the data dir # If they don't specify a config file then put it in the data dir
if not sickbeard.CONFIG_FILE: if not sickbeard.CONFIG_FILE:
@ -255,7 +279,7 @@ def main():
os.chdir(sickbeard.DATA_DIR) os.chdir(sickbeard.DATA_DIR)
if consoleLogging: if consoleLogging:
print "Starting up Sick Beard " + SICKBEARD_VERSION + " from " + sickbeard.CONFIG_FILE print "Starting up SickRage " + SICKBEARD_VERSION + " from " + sickbeard.CONFIG_FILE
# Load the config and publish it to the sickbeard package # Load the config and publish it to the sickbeard package
if not os.path.isfile(sickbeard.CONFIG_FILE): if not os.path.isfile(sickbeard.CONFIG_FILE):
@ -266,13 +290,13 @@ def main():
CUR_DB_VERSION = db.DBConnection().checkDBVersion() CUR_DB_VERSION = db.DBConnection().checkDBVersion()
if CUR_DB_VERSION > 0: if CUR_DB_VERSION > 0:
if CUR_DB_VERSION < MIN_DB_VERSION: if CUR_DB_VERSION < MIN_DB_VERSION:
raise SystemExit("Your database version (" + str(db.DBConnection().checkDBVersion()) + ") is too old to migrate from with this version of Sick Beard (" + str(MIN_DB_VERSION) + ").\n" + \ raise SystemExit("Your database version (" + str(db.DBConnection().checkDBVersion()) + ") is too old to migrate from with this version of SickRage (" + str(MIN_DB_VERSION) + ").\n" + \
"Upgrade using a previous version of SB first, or start with no database file to begin fresh.") "Upgrade using a previous version of SB first, or start with no database file to begin fresh.")
if CUR_DB_VERSION > MAX_DB_VERSION: if CUR_DB_VERSION > MAX_DB_VERSION:
raise SystemExit("Your database version (" + str(db.DBConnection().checkDBVersion()) + ") has been incremented past what this version of Sick Beard supports (" + str(MAX_DB_VERSION) + ").\n" + \ raise SystemExit("Your database version (" + str(db.DBConnection().checkDBVersion()) + ") has been incremented past what this version of SickRage supports (" + str(MAX_DB_VERSION) + ").\n" + \
"If you have used other forks of SB, your database may be unusable due to their modifications.") "If you have used other forks of SB, your database may be unusable due to their modifications.")
# Initialize the config and our threads # Initialize the config and our threads
sickbeard.initialize(consoleLogging=consoleLogging) sickbeard.initialize(consoleLogging=consoleLogging)
sickbeard.showList = [] sickbeard.showList = []
@ -306,17 +330,17 @@ def main():
try: try:
initWebServer({ initWebServer({
'port': startPort, 'port': startPort,
'host': webhost, 'host': webhost,
'data_root': os.path.join(sickbeard.PROG_DIR, 'gui/'+sickbeard.GUI_NAME), 'data_root': os.path.join(sickbeard.PROG_DIR, 'gui/'+sickbeard.GUI_NAME),
'web_root': sickbeard.WEB_ROOT, 'web_root': sickbeard.WEB_ROOT,
'log_dir': log_dir, 'log_dir': log_dir,
'username': sickbeard.WEB_USERNAME, 'username': sickbeard.WEB_USERNAME,
'password': sickbeard.WEB_PASSWORD, 'password': sickbeard.WEB_PASSWORD,
'enable_https': sickbeard.ENABLE_HTTPS, 'enable_https': sickbeard.ENABLE_HTTPS,
'https_cert': sickbeard.HTTPS_CERT, 'https_cert': sickbeard.HTTPS_CERT,
'https_key': sickbeard.HTTPS_KEY, 'https_key': sickbeard.HTTPS_KEY,
}) })
except IOError: except IOError:
logger.log(u"Unable to start web server, is something else running on port %d?" % startPort, logger.ERROR) logger.log(u"Unable to start web server, is something else running on port %d?" % startPort, logger.ERROR)
if sickbeard.LAUNCH_BROWSER and not sickbeard.DAEMON: if sickbeard.LAUNCH_BROWSER and not sickbeard.DAEMON:
@ -341,12 +365,13 @@ def main():
# Stay alive while my threads do the work # Stay alive while my threads do the work
while (True): while (True):
time.sleep(1)
if sickbeard.invoked_command: if sickbeard.invoked_command:
sickbeard.invoked_command() sickbeard.invoked_command()
sickbeard.invoked_command = None sickbeard.invoked_command = None
time.sleep(1)
return return
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -107,11 +107,18 @@
<span class="component-desc">Prefer to download seperate episodes, not complete seasons?</span> <span class="component-desc">Prefer to download seperate episodes, not complete seasons?</span>
</label> </label>
</div> </div>
<div class="field-pair">
<input type="checkbox" name="rssupdate_startup" id="backlog_startup" #if $sickbeard.RSSUPDATE_STARTUP == True then "checked=\"checked\"" else ""# />
<label class="clearfix" for="rssupdate_startup">
<span class="component title">RSS Cache Updates on startup</span>
<span class="component-desc">Start RSS Cache updates upon startup of SickRage?</span>
</label>
</div>
<div class="field-pair"> <div class="field-pair">
<input type="checkbox" name="backlog_startup" id="backlog_startup" #if $sickbeard.BACKLOG_STARTUP == True then "checked=\"checked\"" else ""# /> <input type="checkbox" name="backlog_startup" id="backlog_startup" #if $sickbeard.BACKLOG_STARTUP == True then "checked=\"checked\"" else ""# />
<label class="clearfix" for="backlog_startup"> <label class="clearfix" for="backlog_startup">
<span class="component title">Process backlog on startup</span> <span class="component title">Process backlog on startup</span>
<span class="component-desc">Start processing backlogged episodes upon startup of Sick Beard?</span> <span class="component-desc">Start processing backlogged episodes upon startup of SickRage?</span>
</label> </label>
</div> </div>

View File

@ -248,8 +248,10 @@
#if int($show.air_by_date) != 1 and int($show.sports) != 1 #if int($show.air_by_date) != 1 and int($show.sports) != 1
#if (epResult["season"], epResult["episode"]) in $xem_numbering: #if (epResult["season"], epResult["episode"]) in $xem_numbering:
#set ($dfltSeas, $dfltEpis) = $xem_numbering[(epResult["season"], epResult["episode"])] #set ($dfltSeas, $dfltEpis) = $xem_numbering[(epResult["season"], epResult["episode"])]
#else #elif $xem_numbering and (epResult["season"], epResult["episode"]) not in $xem_numbering:
#set ($dfltSeas, $dfltEpis) = (0,0) #set ($dfltSeas, $dfltEpis) = (0,0)
#else:
#set ($dfltSeas, $dfltEpis) = (epResult["season"], epResult["episode"])
#end if #end if
#if (epResult["season"], epResult["episode"]) in $scene_numbering: #if (epResult["season"], epResult["episode"]) in $scene_numbering:
#set ($scSeas, $scEpis) = $scene_numbering[(epResult["season"], epResult["episode"])] #set ($scSeas, $scEpis) = $scene_numbering[(epResult["season"], epResult["episode"])]

View File

@ -176,6 +176,7 @@ ALLOW_HIGH_PRIORITY = None
RSSUPDATE_FREQUENCY = None RSSUPDATE_FREQUENCY = None
UPDATE_FREQUENCY = None UPDATE_FREQUENCY = None
BACKLOG_FREQUENCY = 21 BACKLOG_FREQUENCY = 21
RSSUPDATE_STARTUP = None
BACKLOG_STARTUP = None BACKLOG_STARTUP = None
MIN_SEARCH_FREQUENCY = 10 MIN_SEARCH_FREQUENCY = 10
@ -496,8 +497,8 @@ def initialize(consoleLogging=True):
NEWZNAB_DATA, NZBS, NZBS_UID, NZBS_HASH, EZRSS, TVTORRENTS, TVTORRENTS_DIGEST, TVTORRENTS_HASH, TVTORRENTS_OPTIONS, BTN, BTN_API_KEY, BTN_OPTIONS, \ NEWZNAB_DATA, NZBS, NZBS_UID, NZBS_HASH, EZRSS, TVTORRENTS, TVTORRENTS_DIGEST, TVTORRENTS_HASH, TVTORRENTS_OPTIONS, BTN, BTN_API_KEY, BTN_OPTIONS, \
THEPIRATEBAY, THEPIRATEBAY_TRUSTED, THEPIRATEBAY_PROXY, THEPIRATEBAY_PROXY_URL, THEPIRATEBAY_BLACKLIST, THEPIRATEBAY_OPTIONS, TORRENTLEECH, TORRENTLEECH_USERNAME, TORRENTLEECH_PASSWORD, TORRENTLEECH_OPTIONS, \ THEPIRATEBAY, THEPIRATEBAY_TRUSTED, THEPIRATEBAY_PROXY, THEPIRATEBAY_PROXY_URL, THEPIRATEBAY_BLACKLIST, THEPIRATEBAY_OPTIONS, TORRENTLEECH, TORRENTLEECH_USERNAME, TORRENTLEECH_PASSWORD, TORRENTLEECH_OPTIONS, \
IPTORRENTS, IPTORRENTS_USERNAME, IPTORRENTS_PASSWORD, IPTORRENTS_FREELEECH, IPTORRENTS_OPTIONS, KAT, KAT_VERIFIED, KAT_OPTIONS, PUBLICHD, PUBLICHD_OPTIONS, SCC, SCC_USERNAME, SCC_PASSWORD, SCC_OPTIONS, HDTORRENTS, HDTORRENTS_USERNAME, HDTORRENTS_PASSWORD, HDTORRENTS_UID, HDTORRENTS_HASH, HDTORRENTS_OPTIONS, TORRENTDAY, TORRENTDAY_USERNAME, TORRENTDAY_PASSWORD, TORRENTDAY_UID, TORRENTDAY_HASH, TORRENTDAY_FREELEECH, TORRENTDAY_OPTIONS, \ IPTORRENTS, IPTORRENTS_USERNAME, IPTORRENTS_PASSWORD, IPTORRENTS_FREELEECH, IPTORRENTS_OPTIONS, KAT, KAT_VERIFIED, KAT_OPTIONS, PUBLICHD, PUBLICHD_OPTIONS, SCC, SCC_USERNAME, SCC_PASSWORD, SCC_OPTIONS, HDTORRENTS, HDTORRENTS_USERNAME, HDTORRENTS_PASSWORD, HDTORRENTS_UID, HDTORRENTS_HASH, HDTORRENTS_OPTIONS, TORRENTDAY, TORRENTDAY_USERNAME, TORRENTDAY_PASSWORD, TORRENTDAY_UID, TORRENTDAY_HASH, TORRENTDAY_FREELEECH, TORRENTDAY_OPTIONS, \
HDBITS, HDBITS_USERNAME, HDBITS_PASSKEY, HDBITS_OPTIONS, TORRENT_DIR, USENET_RETENTION, SOCKET_TIMEOUT, RSSUPDATE_FREQUENCY, DEFAULT_SEARCH_FREQUENCY, BACKLOG_FREQUENCY, BACKLOG_STARTUP, INDEXER_DEFAULT, \ HDBITS, HDBITS_USERNAME, HDBITS_PASSKEY, HDBITS_OPTIONS, TORRENT_DIR, USENET_RETENTION, SOCKET_TIMEOUT, RSSUPDATE_FREQUENCY, DEFAULT_SEARCH_FREQUENCY, BACKLOG_FREQUENCY, BACKLOG_STARTUP, INDEXER_DEFAULT, RSSUPDATE_STARTUP, \
NEXTGEN, NEXTGEN_USERNAME, NEXTGEN_PASSWORD, NEXTGEN_FREELEECH, NEXTGEN_OPTIONS, SPEEDCD, SPEEDCD_USERNAME, SPEEDCD_PASSWORD, SPEEDCD_FREELEECH,\ NEXTGEN, NEXTGEN_USERNAME, NEXTGEN_PASSWORD, NEXTGEN_FREELEECH, NEXTGEN_OPTIONS, SPEEDCD, SPEEDCD_USERNAME, SPEEDCD_PASSWORD, SPEEDCD_FREELEECH, \
EZRSS_RATIO, TVTORRENTS_RATIO, BTN_RATIO, THEPIRATEBAY_RATIO, TORRENTLEECH_RATIO, IPTORRENTS_RATIO, KAT_RATIO, PUBLICHD_RATIO, TORRENTDAY_RATIO, SCC_RATIO, HDTORRENTS_RATIO, HDBITS_RATIO, NEXTGEN_RATIO, SPEEDCD_RATIO, \ EZRSS_RATIO, TVTORRENTS_RATIO, BTN_RATIO, THEPIRATEBAY_RATIO, TORRENTLEECH_RATIO, IPTORRENTS_RATIO, KAT_RATIO, PUBLICHD_RATIO, TORRENTDAY_RATIO, SCC_RATIO, HDTORRENTS_RATIO, HDBITS_RATIO, NEXTGEN_RATIO, SPEEDCD_RATIO, \
QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, \ QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, \
GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, GROWL_NOTIFY_ONSUBTITLEDOWNLOAD, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD, \ GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, GROWL_NOTIFY_ONSUBTITLEDOWNLOAD, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD, \
@ -507,7 +508,7 @@ def initialize(consoleLogging=True):
USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \ USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \
USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_API, PUSHBULLET_DEVICE, \ USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_API, PUSHBULLET_DEVICE, \
versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, \ versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, \
KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_SEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY,MIN_UPDATE_FREQUENCY,UPDATE_FREQUENCY,\ KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_SEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \
showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, \ showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, \
NAMING_PATTERN, NAMING_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_STRIP_YEAR, \ NAMING_PATTERN, NAMING_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_STRIP_YEAR, \
RENAME_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \ RENAME_EPISODES, properFinderScheduler, PROVIDER_ORDER, autoPostProcesserScheduler, \
@ -638,7 +639,8 @@ def initialize(consoleLogging=True):
NAMING_PATTERN = check_setting_str(CFG, 'General', 'naming_pattern', 'Season %0S/%SN - S%0SE%0E - %EN') NAMING_PATTERN = check_setting_str(CFG, 'General', 'naming_pattern', 'Season %0S/%SN - S%0SE%0E - %EN')
NAMING_ABD_PATTERN = check_setting_str(CFG, 'General', 'naming_abd_pattern', '%Y/%0M/%SN - %A.D - %EN') NAMING_ABD_PATTERN = check_setting_str(CFG, 'General', 'naming_abd_pattern', '%Y/%0M/%SN - %A.D - %EN')
NAMING_CUSTOM_ABD = check_setting_int(CFG, 'General', 'naming_custom_abd', 0) NAMING_CUSTOM_ABD = check_setting_int(CFG, 'General', 'naming_custom_abd', 0)
NAMING_SPORTS_PATTERN = check_setting_str(CFG, 'General', 'naming_sports_pattern', 'Season %0S/%SN - S%0SE%0E - %EN') NAMING_SPORTS_PATTERN = check_setting_str(CFG, 'General', 'naming_sports_pattern',
'Season %0S/%SN - S%0SE%0E - %EN')
NAMING_CUSTOM_SPORTS = check_setting_int(CFG, 'General', 'naming_custom_sports', 0) NAMING_CUSTOM_SPORTS = check_setting_int(CFG, 'General', 'naming_custom_sports', 0)
NAMING_MULTI_EP = check_setting_int(CFG, 'General', 'naming_multi_ep', 1) NAMING_MULTI_EP = check_setting_int(CFG, 'General', 'naming_multi_ep', 1)
NAMING_FORCE_FOLDERS = naming.check_force_season_folders() NAMING_FORCE_FOLDERS = naming.check_force_season_folders()
@ -661,6 +663,7 @@ def initialize(consoleLogging=True):
ALLOW_HIGH_PRIORITY = bool(check_setting_int(CFG, 'General', 'allow_high_priority', 1)) ALLOW_HIGH_PRIORITY = bool(check_setting_int(CFG, 'General', 'allow_high_priority', 1))
RSSUPDATE_STARTUP = bool(check_setting_int(CFG, 'General', 'rssupdate_startup', 1))
BACKLOG_STARTUP = bool(check_setting_int(CFG, 'General', 'backlog_startup', 1)) BACKLOG_STARTUP = bool(check_setting_int(CFG, 'General', 'backlog_startup', 1))
USENET_RETENTION = check_setting_int(CFG, 'General', 'usenet_retention', 500) USENET_RETENTION = check_setting_int(CFG, 'General', 'usenet_retention', 500)
@ -864,7 +867,8 @@ def initialize(consoleLogging=True):
USE_BOXCAR2 = bool(check_setting_int(CFG, 'Boxcar2', 'use_boxcar2', 0)) USE_BOXCAR2 = bool(check_setting_int(CFG, 'Boxcar2', 'use_boxcar2', 0))
BOXCAR2_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsnatch', 0)) BOXCAR2_NOTIFY_ONSNATCH = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsnatch', 0))
BOXCAR2_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_ondownload', 0)) BOXCAR2_NOTIFY_ONDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_ondownload', 0))
BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD = bool(check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsubtitledownload', 0)) BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD = bool(
check_setting_int(CFG, 'Boxcar2', 'boxcar2_notify_onsubtitledownload', 0))
BOXCAR2_ACCESSTOKEN = check_setting_str(CFG, 'Boxcar2', 'boxcar2_accesstoken', '') BOXCAR2_ACCESSTOKEN = check_setting_str(CFG, 'Boxcar2', 'boxcar2_accesstoken', '')
USE_PUSHOVER = bool(check_setting_int(CFG, 'Pushover', 'use_pushover', 0)) USE_PUSHOVER = bool(check_setting_int(CFG, 'Pushover', 'use_pushover', 0))
@ -1065,7 +1069,7 @@ def initialize(consoleLogging=True):
cycleTime=datetime.timedelta(minutes=RSSUPDATE_FREQUENCY), cycleTime=datetime.timedelta(minutes=RSSUPDATE_FREQUENCY),
threadName="RSSUPDATER", threadName="RSSUPDATER",
silent=True, silent=True,
runImmediately=True) runImmediately=RSSUPDATE_STARTUP)
showQueueScheduler = scheduler.Scheduler(show_queue.ShowQueue(), showQueueScheduler = scheduler.Scheduler(show_queue.ShowQueue(),
cycleTime=datetime.timedelta(seconds=3), cycleTime=datetime.timedelta(seconds=3),
@ -1103,7 +1107,7 @@ def initialize(consoleLogging=True):
backlogSearchScheduler = searchBacklog.BacklogSearchScheduler(searchBacklog.BacklogSearcher(), backlogSearchScheduler = searchBacklog.BacklogSearchScheduler(searchBacklog.BacklogSearcher(),
cycleTime=datetime.timedelta( cycleTime=datetime.timedelta(
minutes=BACKLOG_FREQUENCY), minutes=BACKLOG_FREQUENCY),
threadName="BACKLOG", threadName="BACKLOG",
silent=True, silent=True,
runImmediately=BACKLOG_STARTUP) runImmediately=BACKLOG_STARTUP)
@ -1255,12 +1259,21 @@ def halt():
__INITIALIZED__ = False __INITIALIZED__ = False
def remove_pid_file(PIDFILE):
try:
if os.path.exists(PIDFILE):
os.remove(PIDFILE)
except (IOError, OSError):
return False
return True
def sig_handler(signum=None, frame=None): def sig_handler(signum=None, frame=None):
if type(signum) != type(None): if type(signum) != type(None):
logger.log(u"Signal %i caught, saving and exiting..." % int(signum)) logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
saveAndShutdown() saveAndShutdown()
def saveAll(): def saveAll():
global showList global showList
@ -1284,7 +1297,7 @@ def saveAndShutdown(restart=False):
if CREATEPID: if CREATEPID:
logger.log(u"Removing pidfile " + str(PIDFILE)) logger.log(u"Removing pidfile " + str(PIDFILE))
os.remove(PIDFILE) remove_pid_file(PIDFILE)
if restart: if restart:
install_type = versionCheckScheduler.action.install_type install_type = versionCheckScheduler.action.install_type
@ -1306,7 +1319,7 @@ def saveAndShutdown(restart=False):
popen_list += MY_ARGS popen_list += MY_ARGS
if '--nolaunch' not in popen_list: if '--nolaunch' not in popen_list:
popen_list += ['--nolaunch'] popen_list += ['--nolaunch']
logger.log(u"Restarting Sick Beard with " + str(popen_list)) logger.log(u"Restarting SickRage with " + str(popen_list))
logger.close() logger.close()
subprocess.Popen(popen_list, cwd=os.getcwd()) subprocess.Popen(popen_list, cwd=os.getcwd())
@ -1382,6 +1395,7 @@ def save_config():
new_config['General']['download_propers'] = int(DOWNLOAD_PROPERS) new_config['General']['download_propers'] = int(DOWNLOAD_PROPERS)
new_config['General']['prefer_episode_releases'] = int(PREFER_EPISODE_RELEASES) new_config['General']['prefer_episode_releases'] = int(PREFER_EPISODE_RELEASES)
new_config['General']['allow_high_priority'] = int(ALLOW_HIGH_PRIORITY) new_config['General']['allow_high_priority'] = int(ALLOW_HIGH_PRIORITY)
new_config['General']['rssupdate_startup'] = int(RSSUPDATE_STARTUP)
new_config['General']['backlog_startup'] = int(BACKLOG_STARTUP) new_config['General']['backlog_startup'] = int(BACKLOG_STARTUP)
new_config['General']['quality_default'] = int(QUALITY_DEFAULT) new_config['General']['quality_default'] = int(QUALITY_DEFAULT)
new_config['General']['status_default'] = int(STATUS_DEFAULT) new_config['General']['status_default'] = int(STATUS_DEFAULT)

View File

@ -22,17 +22,12 @@ import datetime
from sickbeard import db from sickbeard import db
from sickbeard import logger from sickbeard import logger
from sickbeard import exceptions from sickbeard.exceptions import ex, EpisodeNotFoundException
from sickbeard.history import dateFormat from sickbeard.history import dateFormat
from sickbeard.common import Quality from sickbeard.common import Quality
from sickbeard.common import WANTED, FAILED from sickbeard.common import WANTED, FAILED
def _log_helper(message, level=logger.MESSAGE):
logger.log(message, level)
return message + u"\n"
def prepareFailedName(release): def prepareFailedName(release):
"""Standardizes release name for failed DB""" """Standardizes release name for failed DB"""
@ -41,6 +36,10 @@ def prepareFailedName(release):
fixed = fixed.rpartition(".")[0] fixed = fixed.rpartition(".")[0]
fixed = re.sub("[\.\-\+\ ]", "_", fixed) fixed = re.sub("[\.\-\+\ ]", "_", fixed)
if not isinstance(fixed, unicode):
fixed = unicode(fixed, 'utf-8')
return fixed return fixed
@ -55,26 +54,26 @@ def logFailed(release):
sql_results = myDB.select("SELECT * FROM history WHERE release=?", [release]) sql_results = myDB.select("SELECT * FROM history WHERE release=?", [release])
if len(sql_results) == 0: if len(sql_results) == 0:
log_str += _log_helper( logger.log(
u"Release not found in snatch history. Recording it as bad with no size and no proivder.", logger.WARNING) u"Release not found in snatch history. Recording it as bad with no size and no proivder.", logger.WARNING)
log_str += _log_helper( logger.log(
u"Future releases of the same name from providers that don't return size will be skipped.", logger.WARNING) u"Future releases of the same name from providers that don't return size will be skipped.", logger.WARNING)
elif len(sql_results) > 1: elif len(sql_results) > 1:
log_str += _log_helper(u"Multiple logged snatches found for release", logger.WARNING) logger.log(u"Multiple logged snatches found for release", logger.WARNING)
sizes = len(set(x["size"] for x in sql_results)) sizes = len(set(x["size"] for x in sql_results))
providers = len(set(x["provider"] for x in sql_results)) providers = len(set(x["provider"] for x in sql_results))
if sizes == 1: if sizes == 1:
log_str += _log_helper(u"However, they're all the same size. Continuing with found size.", logger.WARNING) logger.log(u"However, they're all the same size. Continuing with found size.", logger.WARNING)
size = sql_results[0]["size"] size = sql_results[0]["size"]
else: else:
log_str += _log_helper( logger.log(
u"They also vary in size. Deleting the logged snatches and recording this release with no size/provider", u"They also vary in size. Deleting the logged snatches and recording this release with no size/provider",
logger.WARNING) logger.WARNING)
for result in sql_results: for result in sql_results:
deleteLoggedSnatch(result["release"], result["size"], result["provider"]) deleteLoggedSnatch(result["release"], result["size"], result["provider"])
if providers == 1: if providers == 1:
log_str += _log_helper(u"They're also from the same provider. Using it as well.") logger.log(u"They're also from the same provider. Using it as well.")
provider = sql_results[0]["provider"] provider = sql_results[0]["provider"]
else: else:
size = sql_results[0]["size"] size = sql_results[0]["size"]
@ -113,74 +112,45 @@ def hasFailed(release, size, provider="%"):
return (len(sql_results) > 0) return (len(sql_results) > 0)
def revertEpisode(show_obj, season, episode=None): def revertEpisode(epObj):
"""Restore the episodes of a failed download to their original state""" """Restore the episodes of a failed download to their original state"""
myDB = db.DBConnection("failed.db") myDB = db.DBConnection("failed.db")
log_str = u""
sql_results = myDB.select("SELECT * FROM history WHERE showid=? AND season=?", [show_obj.indexerid, season])
# {episode: result, ...} sql_results = myDB.select("SELECT * FROM history WHERE showid=? AND season=?", [epObj.show.indexerid, epObj.season])
history_eps = dict([(res["episode"], res) for res in sql_results]) history_eps = dict([(res["episode"], res) for res in sql_results])
if episode: try:
try: logger.log(u"Reverting episode (%s, %s): %s" % (epObj.season, epObj.episode, epObj.name))
ep_obj = show_obj.getEpisode(season, episode) with epObj.lock:
log_str += _log_helper(u"Reverting episode (%s, %s): %s" % (season, episode, ep_obj.name)) if epObj.episode in history_eps:
with ep_obj.lock: logger.log(u"Found in history")
if episode in history_eps: epObj.status = history_eps[epObj.episode]['old_status']
log_str += _log_helper(u"Found in history") else:
ep_obj.status = history_eps[episode]['old_status'] logger.log(u"WARNING: Episode not found in history. Setting it back to WANTED",
else: logger.WARNING)
log_str += _log_helper(u"WARNING: Episode not found in history. Setting it back to WANTED", epObj.status = WANTED
logger.WARNING)
ep_obj.status = WANTED
ep_obj.saveToDB() epObj.saveToDB()
except exceptions.EpisodeNotFoundException, e: except EpisodeNotFoundException, e:
log_str += _log_helper(u"Unable to create episode, please set its status manually: " + exceptions.ex(e), logger.log(u"Unable to create episode, please set its status manually: " + ex(e),
logger.WARNING) logger.WARNING)
else:
# Whole season
log_str += _log_helper(u"Setting season to wanted: " + str(season))
for ep_obj in show_obj.getAllEpisodes(season):
log_str += _log_helper(u"Reverting episode (%d, %d): %s" % (season, ep_obj.episode, ep_obj.name))
with ep_obj.lock:
if ep_obj in history_eps:
log_str += _log_helper(u"Found in history")
ep_obj.status = history_eps[ep_obj]['old_status']
else:
log_str += _log_helper(u"WARNING: Episode not found in history. Setting it back to WANTED",
logger.WARNING)
ep_obj.status = WANTED
ep_obj.saveToDB() return
return log_str
def markFailed(show_obj, season, episode=None): def markFailed(epObj):
log_str = u"" log_str = u""
if episode: try:
try: with epObj.lock:
ep_obj = show_obj.getEpisode(season, episode) quality = Quality.splitCompositeStatus(epObj.status)[1]
epObj.status = Quality.compositeStatus(FAILED, quality)
epObj.saveToDB()
with ep_obj.lock: except EpisodeNotFoundException, e:
quality = Quality.splitCompositeStatus(ep_obj.status)[1] logger.log(u"Unable to get episode, please set its status manually: " + ex(e), logger.WARNING)
ep_obj.status = Quality.compositeStatus(FAILED, quality)
ep_obj.saveToDB()
except exceptions.EpisodeNotFoundException, e:
log_str += _log_helper(u"Unable to get episode, please set its status manually: " + exceptions.ex(e),
logger.WARNING)
else:
# Whole season
for ep_obj in show_obj.getAllEpisodes(season):
with ep_obj.lock:
quality = Quality.splitCompositeStatus(ep_obj.status)[1]
ep_obj.status = Quality.compositeStatus(FAILED, quality)
ep_obj.saveToDB()
return log_str return log_str
@ -191,6 +161,7 @@ def logSnatch(searchResult):
logDate = datetime.datetime.today().strftime(dateFormat) logDate = datetime.datetime.today().strftime(dateFormat)
release = prepareFailedName(searchResult.name) release = prepareFailedName(searchResult.name)
providerClass = searchResult.provider providerClass = searchResult.provider
if providerClass is not None: if providerClass is not None:
provider = providerClass.name provider = providerClass.name
@ -200,13 +171,11 @@ def logSnatch(searchResult):
show_obj = searchResult.episodes[0].show show_obj = searchResult.episodes[0].show
for episode in searchResult.episodes: for episode in searchResult.episodes:
old_status = show_obj.getEpisode(episode.season, episode.episode).status
myDB.action( myDB.action(
"INSERT INTO history (date, size, release, provider, showid, season, episode, old_status)" "INSERT INTO history (date, size, release, provider, showid, season, episode, old_status)"
"VALUES (?, ?, ?, ?, ?, ?, ?, ?)", "VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
[logDate, searchResult.size, release, provider, show_obj.indexerid, episode.season, episode.episode, [logDate, searchResult.size, release, provider, show_obj.indexerid, episode.season, episode.episode,
old_status]) episode.status])
def deleteLoggedSnatch(release, size, provider): def deleteLoggedSnatch(release, size, provider):
@ -224,13 +193,11 @@ def trimHistory():
(datetime.datetime.today() - datetime.timedelta(days=30)).strftime(dateFormat))) (datetime.datetime.today() - datetime.timedelta(days=30)).strftime(dateFormat)))
def findRelease(show, season, episode): def findRelease(epObj):
""" """
Find releases in history by show ID and season. Find releases in history by show ID and season.
Return None for release if multiple found or no release found. Return None for release if multiple found or no release found.
""" """
if not show: return (None, None, None)
if not season: return (None, None, None)
release = None release = None
provider = None provider = None
@ -238,13 +205,13 @@ def findRelease(show, season, episode):
myDB = db.DBConnection("failed.db") myDB = db.DBConnection("failed.db")
# Clear old snatches for this release if any exist # Clear old snatches for this release if any exist
myDB.action("DELETE FROM history WHERE showid=" + str(show.indexerid) + " AND season=" + str( myDB.action("DELETE FROM history WHERE showid=" + str(epObj.show.indexerid) + " AND season=" + str(
season) + " AND episode=" + str(episode) + " AND date < (SELECT max(date) FROM history WHERE showid=" + str( epObj.season) + " AND episode=" + str(epObj.episode) + " AND date < (SELECT max(date) FROM history WHERE showid=" + str(
show.indexerid) + " AND season=" + str(season) + " AND episode=" + str(episode) + ")") epObj.show.indexerid) + " AND season=" + str(epObj.season) + " AND episode=" + str(epObj.episode) + ")")
# Search for release in snatch history # Search for release in snatch history
results = myDB.select("SELECT release, provider, date FROM history WHERE showid=? AND season=? AND episode=?", results = myDB.select("SELECT release, provider, date FROM history WHERE showid=? AND season=? AND episode=?",
[show.indexerid, season, episode]) [epObj.show.indexerid, epObj.season, epObj.episode])
for result in results: for result in results:
release = str(result["release"]) release = str(result["release"])
@ -255,9 +222,9 @@ def findRelease(show, season, episode):
myDB.action("DELETE FROM history WHERE release=? AND date!=?", [release, date]) myDB.action("DELETE FROM history WHERE release=? AND date!=?", [release, date])
# Found a previously failed release # Found a previously failed release
logger.log(u"Failed release found for season (%s): (%s)" % (season, result["release"]), logger.DEBUG) logger.log(u"Failed release found for season (%s): (%s)" % (epObj.season, result["release"]), logger.DEBUG)
return (release, provider) return (release, provider)
# Release was not found # Release was not found
logger.log(u"No releases found for season (%s) of (%s)" % (season, show.indexerid), logger.DEBUG) logger.log(u"No releases found for season (%s) of (%s)" % (epObj.season, epObj.show.indexerid), logger.DEBUG)
return (release, provider) return (release, provider)

View File

@ -85,11 +85,11 @@ def logSubtitle(showid, season, episode, status, subtitleResult):
_logHistoryItem(action, showid, season, episode, quality, resource, provider) _logHistoryItem(action, showid, season, episode, quality, resource, provider)
def logFailed(indexerid, season, episode, status, release, provider=None): def logFailed(epObj, release, provider=None):
showid = int(indexerid) showid = int(epObj.show.indexerid)
season = int(season) season = int(epObj.season)
epNum = int(episode) epNum = int(epObj.episode)
status, quality = Quality.splitCompositeStatus(status) status, quality = Quality.splitCompositeStatus(epObj.status)
action = Quality.compositeStatus(FAILED, quality) action = Quality.compositeStatus(FAILED, quality)
_logHistoryItem(action, showid, season, epNum, quality, release, provider) _logHistoryItem(action, showid, season, epNum, quality, release, provider)

View File

@ -625,7 +625,6 @@ class PostProcessor(object):
# detect and convert scene numbered releases # detect and convert scene numbered releases
season, cur_episode = sickbeard.scene_numbering.get_indexer_numbering(indexer_id,indexer,season,cur_episode) season, cur_episode = sickbeard.scene_numbering.get_indexer_numbering(indexer_id,indexer,season,cur_episode)
self._log(u"Episode object has been scene converted to " + str(season) + "x" + str(cur_episode), logger.DEBUG)
# now that we've figured out which episode this file is just load it manually # now that we've figured out which episode this file is just load it manually
try: try:
@ -634,6 +633,9 @@ class PostProcessor(object):
self._log(u"Unable to create episode: " + ex(e), logger.DEBUG) self._log(u"Unable to create episode: " + ex(e), logger.DEBUG)
raise exceptions.PostProcessingFailed() raise exceptions.PostProcessingFailed()
self._log(u"Episode object has been converted from Scene numbering " + str(curEp.scene_season) + "x" + str(
curEp.scene_episode) + " to Indexer numbering" + str(curEp.season) + "x" + str(curEp.episode))
# associate all the episodes together under a single root episode # associate all the episodes together under a single root episode
if root_ep == None: if root_ep == None:
root_ep = curEp root_ep = curEp

View File

@ -27,7 +27,7 @@ from sickbeard.exceptions import ex
class Scheduler: class Scheduler:
def __init__(self, action, cycleTime=datetime.timedelta(minutes=10), runImmediately=True, def __init__(self, action, cycleTime=datetime.timedelta(minutes=10), runImmediately=True,
threadName="ScheduledThread", silent=False, runOnce=False): threadName="ScheduledThread", silent=False):
if runImmediately: if runImmediately:
self.lastRun = datetime.datetime.fromordinal(1) self.lastRun = datetime.datetime.fromordinal(1)
@ -44,7 +44,6 @@ class Scheduler:
self.initThread() self.initThread()
self.abort = False self.abort = False
self.runOnce = runOnce
def initThread(self): def initThread(self):
if self.thread == None or not self.thread.isAlive(): if self.thread == None or not self.thread.isAlive():
@ -76,7 +75,7 @@ class Scheduler:
logger.log(u"Exception generated in thread " + self.threadName + ": " + ex(e), logger.ERROR) logger.log(u"Exception generated in thread " + self.threadName + ": " + ex(e), logger.ERROR)
logger.log(repr(traceback.format_exc()), logger.DEBUG) logger.log(repr(traceback.format_exc()), logger.DEBUG)
if self.abort or self.runOnce: if self.abort:
self.abort = False self.abort = False
self.thread = None self.thread = None
return return

View File

@ -233,7 +233,6 @@ def pickBestResult(results, show, quality_list=None):
return bestResult return bestResult
def isFinalResult(result): def isFinalResult(result):
""" """
Checks if the given result is good enough quality that we can stop searching for other ones. Checks if the given result is good enough quality that we can stop searching for other ones.

View File

@ -257,22 +257,22 @@ class FailedQueueItem(generic_queue.QueueItem):
def execute(self): def execute(self):
generic_queue.QueueItem.execute(self) generic_queue.QueueItem.execute(self)
failed_episodes = []
for i, epObj in enumerate(self.episodes): for i, epObj in enumerate(self.episodes):
with epObj.lock: (release, provider) = failed_history.findRelease(epObj)
(release, provider) = failed_history.findRelease(self.show, epObj.season, epObj.episode) if release:
if release: logger.log(u"Marking release as bad: " + release)
logger.log(u"Marking release as bad: " + release) failed_history.markFailed(epObj)
failed_history.markFailed(self.show, epObj.season, epObj.episode) failed_history.logFailed(release)
failed_history.logFailed(release) history.logFailed(epObj, release, provider)
history.logFailed(self.show.indexerid, epObj.season, epObj.episode, epObj.status, release, provider) failed_history.revertEpisode(epObj)
failed_episodes.append(epObj)
failed_history.revertEpisode(self.show, epObj.season, epObj.episode)
try: try:
logger.log( logger.log(
"Beginning failed download search for episodes from Season [" + str(self.episodes[0].season) + "]") "Beginning failed download search for episodes from Season [" + str(self.episodes[0].season) + "]")
searchResult = search.searchProviders(self, self.show, self.episodes[0].season, self.episodes, False, True) searchResult = search.searchProviders(self, self.show, failed_episodes[0].season, failed_episodes, False, True)
if searchResult: if searchResult:
self.success = SearchQueue().snatch_item(searchResult) self.success = SearchQueue().snatch_item(searchResult)

View File

@ -205,7 +205,9 @@ class TVShow(object):
if ep != None: if ep != None:
self.episodes[season][episode] = ep self.episodes[season][episode] = ep
return self.episodes[season][episode] epObj = self.episodes[season][episode]
epObj.convertToSceneNumbering()
return epObj
def should_update(self, update_date=datetime.date.today()): def should_update(self, update_date=datetime.date.today()):
@ -1158,8 +1160,6 @@ class TVEpisode(object):
self.specifyEpisode(self.season, self.episode) self.specifyEpisode(self.season, self.episode)
self.convertToSceneNumbering()
self.relatedEps = [] self.relatedEps = []
self.checkForMetaFiles() self.checkForMetaFiles()

View File

@ -245,7 +245,7 @@ class TVCache():
logger.log(u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG) logger.log(u"No series name retrieved from " + name + ", unable to cache it", logger.DEBUG)
return None return None
cacheResult = sickbeard.name_cache.retrieveNameFromCache(name) cacheResult = sickbeard.name_cache.retrieveNameFromCache(parse_result.series_name)
if cacheResult: if cacheResult:
in_cache = True in_cache = True
indexerid = int(cacheResult) indexerid = int(cacheResult)
@ -255,11 +255,12 @@ class TVCache():
if showResult: if showResult:
indexerid = int(showResult[0]) indexerid = int(showResult[0])
if not indexerid: # if not indexerid:
for curShow in sickbeard.showList: # for curShow in sickbeard.showList:
if show_name_helpers.isGoodResult(name, curShow, False): # if curShow.name == parse_result.series_name:
indexerid = int(curShow.indexerid) # if show_name_helpers.isGoodResult(name, curShow, False):
break # indexerid = int(curShow.indexerid)
# break
showObj = None showObj = None
if indexerid: if indexerid:
@ -281,7 +282,7 @@ class TVCache():
season = int(sql_results[0]["season"]) season = int(sql_results[0]["season"])
episodes = [int(sql_results[0]["episode"])] episodes = [int(sql_results[0]["episode"])]
else: else:
season = parse_result.season_number season = parse_result.season_number if parse_result.season_number != None else 1
episodes = parse_result.episode_numbers episodes = parse_result.episode_numbers
if season and episodes: if season and episodes:
@ -301,7 +302,7 @@ class TVCache():
logger.log(u"Added RSS item: [" + name + "] to cache: [" + self.providerID + "]", logger.DEBUG) logger.log(u"Added RSS item: [" + name + "] to cache: [" + self.providerID + "]", logger.DEBUG)
if not in_cache: if not in_cache:
sickbeard.name_cache.addNameToCache(name, indexerid) sickbeard.name_cache.addNameToCache(parse_result.series_name, indexerid)
return [ return [
"INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)", "INSERT INTO [" + self.providerID + "] (name, season, episodes, indexerid, url, time, quality) VALUES (?,?,?,?,?,?,?)",

View File

@ -27,6 +27,7 @@ import tarfile
import stat import stat
import traceback import traceback
import gh_api as github import gh_api as github
import threading
import sickbeard import sickbeard
from sickbeard import helpers from sickbeard import helpers
@ -57,23 +58,27 @@ class CheckVersion():
self.updater = None self.updater = None
def run(self): def run(self):
updated = None
if self.check_for_new_version(): if self.check_for_new_version():
if sickbeard.AUTO_UPDATE: if sickbeard.AUTO_UPDATE:
logger.log(u"New update found for SickRage, starting auto-updater ...") logger.log(u"New update found for SickRage, starting auto-updater ...")
updated = sickbeard.versionCheckScheduler.action.update() updated = sickbeard.versionCheckScheduler.action.update()
if updated: if updated:
logger.log(u"Update was successfull, restarting SickRage ...") logger.log(u"Update was successfull, restarting SickRage ...")
sickbeard.restart(False)
# refresh scene exceptions too # do a soft restart
scene_exceptions.retrieve_exceptions() threading.Timer(2, sickbeard.invoke_restart, [False]).start()
# refresh network timezones if not updated:
network_timezones.update_network_dict() # refresh scene exceptions too
scene_exceptions.retrieve_exceptions()
# sure, why not? # refresh network timezones
if sickbeard.USE_FAILED_DOWNLOADS: network_timezones.update_network_dict()
failed_history.trimHistory()
# sure, why not?
if sickbeard.USE_FAILED_DOWNLOADS:
failed_history.trimHistory()
def find_install_type(self): def find_install_type(self):
""" """

View File

@ -1053,7 +1053,7 @@ class ConfigSearch:
nzbget_category=None, nzbget_host=None, nzbget_use_https=None, nzbget_category=None, nzbget_host=None, nzbget_use_https=None,
nzb_method=None, torrent_method=None, usenet_retention=None, rssupdate_frequency=None, backlog_frequency=None, nzb_method=None, torrent_method=None, usenet_retention=None, rssupdate_frequency=None, backlog_frequency=None,
download_propers=None, prefer_episode_releases=None, allow_high_priority=None, backlog_startup=None, download_propers=None, prefer_episode_releases=None, allow_high_priority=None, backlog_startup=None,
torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None, torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None, rssupdate_startup=None,
torrent_label=None, torrent_path=None, torrent_verify_cert=None, torrent_label=None, torrent_path=None, torrent_verify_cert=None,
torrent_ratio=None, torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None, ignore_words=None): torrent_ratio=None, torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None, ignore_words=None):
@ -1086,6 +1086,7 @@ class ConfigSearch:
sickbeard.ALLOW_HIGH_PRIORITY = config.checkbox_to_value(allow_high_priority) sickbeard.ALLOW_HIGH_PRIORITY = config.checkbox_to_value(allow_high_priority)
config.change_BACKLOG_FREQUENCY(backlog_frequency) config.change_BACKLOG_FREQUENCY(backlog_frequency)
sickbeard.RSSUPDATE_STARTUP = config.checkbox_to_value(rssupdate_startup)
sickbeard.BACKLOG_STARTUP = config.checkbox_to_value(backlog_startup) sickbeard.BACKLOG_STARTUP = config.checkbox_to_value(backlog_startup)
sickbeard.SAB_USERNAME = sab_username sickbeard.SAB_USERNAME = sab_username