mirror of
https://github.com/moparisthebest/SickRage
synced 2024-11-17 06:45:05 -05:00
Merge branch 'release/v4.0.2'
This commit is contained in:
commit
514e9d848f
@ -37,7 +37,6 @@
|
|||||||
#else
|
#else
|
||||||
You don't have version checking turned on. Please turn on "Check for Update" in Config > General.<br />
|
You don't have version checking turned on. Please turn on "Check for Update" in Config > General.<br />
|
||||||
#end if
|
#end if
|
||||||
<font color="red">You are using BETA software</font>
|
|
||||||
</td></tr>
|
</td></tr>
|
||||||
<tr><td class="infoTableHeader">SR Config file:</td><td class="infoTableCell">$sickbeard.CONFIG_FILE</td></tr>
|
<tr><td class="infoTableHeader">SR Config file:</td><td class="infoTableCell">$sickbeard.CONFIG_FILE</td></tr>
|
||||||
<tr><td class="infoTableHeader">SR Database file:</td><td class="infoTableCell">$db.dbFilename()</td></tr>
|
<tr><td class="infoTableHeader">SR Database file:</td><td class="infoTableCell">$db.dbFilename()</td></tr>
|
||||||
|
@ -438,48 +438,14 @@
|
|||||||
|
|
||||||
<div id="core-component-group3" class="component-group">
|
<div id="core-component-group3" class="component-group">
|
||||||
|
|
||||||
|
<div class="component-group">
|
||||||
|
|
||||||
<div class="component-group-desc">
|
<div class="component-group-desc">
|
||||||
<h3>Advanced Settings</h3>
|
<h3>Advanced Settings</h3>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<fieldset class="component-group-list">
|
<fieldset class="component-group-list">
|
||||||
|
|
||||||
<div class="field-pair">
|
|
||||||
<label>
|
|
||||||
<span class="component-title">Branch version:</span>
|
|
||||||
<span class="component-desc">
|
|
||||||
<select id="branchVersion" class="form-control form-control-inline input-sm pull-left">
|
|
||||||
#for $cur_branch in $sickbeard.versionCheckScheduler.action.list_remote_branches():
|
|
||||||
<option value="$cur_branch" #if $cur_branch == $sickbeard.BRANCH then 'selected="selected"' else ''#>$cur_branch</option>
|
|
||||||
#end for
|
|
||||||
</select>
|
|
||||||
<input class="btn btn-inline" style="margin-left: 6px;" type="button" id="branchCheckout" value="Checkout Branch">
|
|
||||||
<div class="clear-left"><p>select branch to use (restart required)</p></div>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-pair">
|
|
||||||
<label for="git_remote">
|
|
||||||
<span class="component-title">Git remote for branch</span>
|
|
||||||
<span class="component-desc">
|
|
||||||
<input type="text" name="git_remote" id="git_remote" value="$sickbeard.GIT_REMOTE" class="form-control input-sm input300" />
|
|
||||||
<div class="clear-left"><p>default:origin. Access repo configured remotes (save then refresh browser)</p></div>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-pair">
|
|
||||||
<label>
|
|
||||||
<span class="component-title">Git executable path</span>
|
|
||||||
<span class="component-desc">
|
|
||||||
<input type="text" name="git_path" value="$sickbeard.GIT_PATH" class="form-control input-sm input300" />
|
|
||||||
<div class="clear-left"><p>only needed if OS is unable to locate git from env</p></div>
|
|
||||||
</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-pair">
|
<div class="field-pair">
|
||||||
<label>
|
<label>
|
||||||
<span class="component-title">CPU throttling:</span>
|
<span class="component-title">CPU throttling:</span>
|
||||||
@ -548,6 +514,86 @@
|
|||||||
|
|
||||||
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="component-group">
|
||||||
|
|
||||||
|
<div class="component-group-desc">
|
||||||
|
<h3>GitHub</h3>
|
||||||
|
<p>Options for github related features.</p>
|
||||||
|
</div>
|
||||||
|
<fieldset class="component-group-list">
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label>
|
||||||
|
<span class="component-title">Branch version:</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<select id="branchVersion" class="form-control form-control-inline input-sm pull-left">
|
||||||
|
#for $cur_branch in $sickbeard.versionCheckScheduler.action.list_remote_branches():
|
||||||
|
<option value="$cur_branch" #if $cur_branch == $sickbeard.BRANCH then 'selected="selected"' else ''#>$cur_branch</option>
|
||||||
|
#end for
|
||||||
|
</select>
|
||||||
|
<input class="btn btn-inline" style="margin-left: 6px;" type="button" id="branchCheckout" value="Checkout Branch">
|
||||||
|
<div class="clear-left"><p>select branch to use (restart required)</p></div>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label for="git_username">
|
||||||
|
<span class="component-title">GitHub username</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="text" name="git_username" id="git_username" value="$sickbeard.GIT_USERNAME" class="form-control input-sm input300" />
|
||||||
|
<div class="clear-left"><p>*** (REQUIRED FOR SUBMITTING ISSUES) ***</p></div>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label for="git_password">
|
||||||
|
<span class="component-title">GitHub password</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="password" name="git_password" id="git_password" value="$sickbeard.GIT_PASSWORD" class="form-control input-sm input300" />
|
||||||
|
<div class="clear-left"><p>*** (REQUIRED FOR SUBMITTING ISSUES) ***</p></div>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label for="git_remote">
|
||||||
|
<span class="component-title">GitHub remote for branch</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="text" name="git_remote" id="git_remote" value="$sickbeard.GIT_REMOTE" class="form-control input-sm input300" />
|
||||||
|
<div class="clear-left"><p>default:origin. Access repo configured remotes (save then refresh browser)</p></div>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label>
|
||||||
|
<span class="component-title">Git executable path</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="text" name="git_path" value="$sickbeard.GIT_PATH" class="form-control input-sm input300" />
|
||||||
|
<div class="clear-left"><p>only needed if OS is unable to locate git from env</p></div>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-pair">
|
||||||
|
<label for="git_reset">
|
||||||
|
<span class="component-title">Git branch reset</span>
|
||||||
|
<span class="component-desc">
|
||||||
|
<input type="checkbox" name="git_reset" id="git_reset" #if True == $sickbeard.GIT_RESET then 'checked="checked"' else ''#/>
|
||||||
|
<p>reset git branch automatically to help resolve update issues</p>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</div><!-- /component-group3 //-->
|
</div><!-- /component-group3 //-->
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
(this will set a default status to be applied to any newly added episodes)<br />
|
(this will set a default status to be applied to any newly added episodes)<br />
|
||||||
<select name="defaultEpStatus" id="defaultEpStatusSelect" class="form-control form-control-inline input-sm">
|
<select name="defaultEpStatus" id="defaultEpStatusSelect" class="form-control form-control-inline input-sm">
|
||||||
#for $curStatus in [$WANTED, $SKIPPED, $ARCHIVED, $IGNORED]:
|
#for $curStatus in [$WANTED, $SKIPPED, $ARCHIVED, $IGNORED]:
|
||||||
<option value="$curStatus">$statusStrings[$curStatus]</option>
|
<option value="$curStatus" #if $curStatus == $show.default_ep_status then 'selected="selected"' else ''#>$statusStrings[$curStatus]</option>
|
||||||
#end for
|
#end for
|
||||||
</select><br />
|
</select><br />
|
||||||
<br />
|
<br />
|
||||||
|
@ -89,6 +89,7 @@
|
|||||||
\$("#SubMenu a:contains('Clear History')").addClass('btn clearhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History');
|
\$("#SubMenu a:contains('Clear History')").addClass('btn clearhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear History');
|
||||||
\$("#SubMenu a:contains('Trim History')").addClass('btn trimhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History');
|
\$("#SubMenu a:contains('Trim History')").addClass('btn trimhistory').html('<span class="ui-icon ui-icon-trash pull-left"></span> Trim History');
|
||||||
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors');
|
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html('<span class="ui-icon ui-icon-trash pull-left"></span> Clear Errors');
|
||||||
|
\$("#SubMenu a[href$='/errorlogs/submit_errors/']").addClass('btn').html('<span class="ui-icon ui-icon-arrowreturnthick-1-n pull-left"></span> Submit Errors');
|
||||||
\$("#SubMenu a:contains('Re-scan')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Re-scan');
|
\$("#SubMenu a:contains('Re-scan')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Re-scan');
|
||||||
\$("#SubMenu a:contains('Backlog Overview')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Backlog Overview');
|
\$("#SubMenu a:contains('Backlog Overview')").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Backlog Overview');
|
||||||
\$("#SubMenu a[href$='/home/updatePLEX/']").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Update PLEX');
|
\$("#SubMenu a[href$='/home/updatePLEX/']").addClass('btn').html('<span class="ui-icon ui-icon-refresh pull-left"></span> Update PLEX');
|
||||||
|
@ -3,7 +3,7 @@ SickRage
|
|||||||
Video File Manager for TV Shows, It watches for new episodes of your favorite shows and when they are posted it does its magic.
|
Video File Manager for TV Shows, It watches for new episodes of your favorite shows and when they are posted it does its magic.
|
||||||
|
|
||||||
## Branch Build Status
|
## Branch Build Status
|
||||||
[![Build Status](https://travis-ci.org/SiCKRAGETV/SickRage.svg?branch=develop)](https://travis-ci.org/SiCKRAGETV/SickRage)
|
[![Build Status](https://travis-ci.org/SiCKRAGETV/SickRage.svg?branch=nightly)](https://travis-ci.org/SiCKRAGETV/SickRage)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- XBMC library updates, poster/fanart downloads, and NFO/TBN generation
|
- XBMC library updates, poster/fanart downloads, and NFO/TBN generation
|
||||||
|
@ -115,6 +115,8 @@ GIT_REMOTE_URL = ''
|
|||||||
CUR_COMMIT_BRANCH = ''
|
CUR_COMMIT_BRANCH = ''
|
||||||
GIT_ORG = 'SiCKRAGETV'
|
GIT_ORG = 'SiCKRAGETV'
|
||||||
GIT_REPO = 'SickRage'
|
GIT_REPO = 'SickRage'
|
||||||
|
GIT_USERNAME = None
|
||||||
|
GIT_PASSWORD = None
|
||||||
GIT_PATH = None
|
GIT_PATH = None
|
||||||
|
|
||||||
INIT_LOCK = Lock()
|
INIT_LOCK = Lock()
|
||||||
@ -522,7 +524,7 @@ def initialize(consoleLogging=True):
|
|||||||
USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, PROXY_INDEXERS, \
|
USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, LOCALHOST_IP, TMDB_API_KEY, DEBUG, PROXY_SETTING, PROXY_INDEXERS, \
|
||||||
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
||||||
ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
|
ANIME_DEFAULT, NAMING_ANIME, ANIMESUPPORT, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
|
||||||
ANIME_SPLIT_HOME, SCENE_DEFAULT, PLAY_VIDEOS, BACKLOG_DAYS, GIT_ORG, GIT_REPO, gh
|
ANIME_SPLIT_HOME, SCENE_DEFAULT, PLAY_VIDEOS, BACKLOG_DAYS, GIT_ORG, GIT_REPO, GIT_USERNAME, GIT_PASSWORD, gh
|
||||||
|
|
||||||
if __INITIALIZED__:
|
if __INITIALIZED__:
|
||||||
return False
|
return False
|
||||||
@ -558,14 +560,20 @@ def initialize(consoleLogging=True):
|
|||||||
fileLogging = True
|
fileLogging = True
|
||||||
if not helpers.makeDir(LOG_DIR):
|
if not helpers.makeDir(LOG_DIR):
|
||||||
sys.stderr.write("!!! No log folder, logging to screen only!\n")
|
sys.stderr.write("!!! No log folder, logging to screen only!\n")
|
||||||
fileLogging=False
|
fileLogging = False
|
||||||
|
|
||||||
# init logging
|
# init logging
|
||||||
logger.initLogging(consoleLogging=consoleLogging, fileLogging=fileLogging, debugLogging=DEBUG)
|
logger.initLogging(consoleLogging=consoleLogging, fileLogging=fileLogging, debugLogging=DEBUG)
|
||||||
|
|
||||||
|
# git login info
|
||||||
|
GIT_USERNAME = check_setting_str(CFG, 'General', 'git_username', '')
|
||||||
|
GIT_PASSWORD = check_setting_str(CFG, 'General', 'git_password', '', censor_log=True)
|
||||||
|
|
||||||
# github api
|
# github api
|
||||||
try:gh = Github().get_organization(GIT_ORG).get_repo(GIT_REPO)
|
try:
|
||||||
except:gh = None
|
gh = Github(user_agent="SiCKRAGE").get_organization(GIT_ORG).get_repo(GIT_REPO)
|
||||||
|
except:
|
||||||
|
gh = None
|
||||||
|
|
||||||
# git reset on update
|
# git reset on update
|
||||||
GIT_RESET = bool(check_setting_int(CFG, 'General', 'git_reset', 0))
|
GIT_RESET = bool(check_setting_int(CFG, 'General', 'git_reset', 0))
|
||||||
@ -1131,7 +1139,7 @@ def initialize(consoleLogging=True):
|
|||||||
(METADATA_WDTV, metadata.wdtv),
|
(METADATA_WDTV, metadata.wdtv),
|
||||||
(METADATA_TIVO, metadata.tivo),
|
(METADATA_TIVO, metadata.tivo),
|
||||||
(METADATA_MEDE8ER, metadata.mede8er),
|
(METADATA_MEDE8ER, metadata.mede8er),
|
||||||
]:
|
]:
|
||||||
(cur_metadata_config, cur_metadata_class) = cur_metadata_tuple
|
(cur_metadata_config, cur_metadata_class) = cur_metadata_tuple
|
||||||
tmp_provider = cur_metadata_class.metadata_class()
|
tmp_provider = cur_metadata_class.metadata_class()
|
||||||
tmp_provider.set_config(cur_metadata_config)
|
tmp_provider.set_config(cur_metadata_config)
|
||||||
@ -1401,6 +1409,8 @@ def save_config():
|
|||||||
|
|
||||||
# For passwords you must include the word `password` in the item_name and add `helpers.encrypt(ITEM_NAME, ENCRYPTION_VERSION)` in save_config()
|
# For passwords you must include the word `password` in the item_name and add `helpers.encrypt(ITEM_NAME, ENCRYPTION_VERSION)` in save_config()
|
||||||
new_config['General'] = {}
|
new_config['General'] = {}
|
||||||
|
new_config['General']['git_username'] = GIT_USERNAME
|
||||||
|
new_config['General']['git_password'] = GIT_PASSWORD
|
||||||
new_config['General']['git_reset'] = int(GIT_RESET)
|
new_config['General']['git_reset'] = int(GIT_RESET)
|
||||||
new_config['General']['branch'] = BRANCH
|
new_config['General']['branch'] = BRANCH
|
||||||
new_config['General']['git_remote'] = GIT_REMOTE
|
new_config['General']['git_remote'] = GIT_REMOTE
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
import sickbeard
|
|
||||||
|
|
||||||
class BugTracker:
|
|
||||||
def submit_bug(self, title, error):
|
|
||||||
return sickbeard.gh.create_issue(title, error, labels=[sickbeard.gh().get_label(sickbeard.BRANCH)])
|
|
@ -16,6 +16,7 @@
|
|||||||
# 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 SickRage. If not, see <http://www.gnu.org/licenses/>.
|
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
import sickbeard
|
import sickbeard
|
||||||
|
|
||||||
@ -261,6 +262,9 @@ class ErrorViewer():
|
|||||||
def clear():
|
def clear():
|
||||||
ErrorViewer.errors = []
|
ErrorViewer.errors = []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get():
|
||||||
|
return ErrorViewer.errors
|
||||||
|
|
||||||
class UIError():
|
class UIError():
|
||||||
"""
|
"""
|
||||||
@ -268,5 +272,7 @@ class UIError():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
|
self.title = sys.exc_info()[1].message or None
|
||||||
self.message = message
|
self.message = message
|
||||||
self.time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
self.time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
|
self.exc_info = sys.exc_info() or None
|
||||||
|
@ -236,8 +236,6 @@ class Quality:
|
|||||||
def assumeQuality(name):
|
def assumeQuality(name):
|
||||||
if name.lower().endswith((".avi", ".mp4")):
|
if name.lower().endswith((".avi", ".mp4")):
|
||||||
return Quality.SDTV
|
return Quality.SDTV
|
||||||
# elif name.lower().endswith(".mkv"):
|
|
||||||
# return Quality.HDTV
|
|
||||||
elif name.lower().endswith(".ts"):
|
elif name.lower().endswith(".ts"):
|
||||||
return Quality.RAWHDTV
|
return Quality.RAWHDTV
|
||||||
else:
|
else:
|
||||||
|
@ -27,7 +27,7 @@ from sickbeard import encodingKludge as ek
|
|||||||
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
||||||
|
|
||||||
MIN_DB_VERSION = 9 # oldest db version we support migrating from
|
MIN_DB_VERSION = 9 # oldest db version we support migrating from
|
||||||
MAX_DB_VERSION = 41
|
MAX_DB_VERSION = 42
|
||||||
|
|
||||||
class MainSanityCheck(db.DBSanityCheck):
|
class MainSanityCheck(db.DBSanityCheck):
|
||||||
def check(self):
|
def check(self):
|
||||||
@ -37,6 +37,7 @@ class MainSanityCheck(db.DBSanityCheck):
|
|||||||
self.fix_orphan_episodes()
|
self.fix_orphan_episodes()
|
||||||
self.fix_unaired_episodes()
|
self.fix_unaired_episodes()
|
||||||
self.fix_tvrage_show_statues()
|
self.fix_tvrage_show_statues()
|
||||||
|
self.fix_episode_statuses()
|
||||||
|
|
||||||
def fix_duplicate_shows(self, column='indexer_id'):
|
def fix_duplicate_shows(self, column='indexer_id'):
|
||||||
|
|
||||||
@ -107,7 +108,7 @@ class MainSanityCheck(db.DBSanityCheck):
|
|||||||
|
|
||||||
if not self.connection.select("PRAGMA index_info('idx_tv_episodes_showid_airdate')"):
|
if not self.connection.select("PRAGMA index_info('idx_tv_episodes_showid_airdate')"):
|
||||||
logger.log(u"Missing idx_tv_episodes_showid_airdate for TV Episodes table detected!, fixing...")
|
logger.log(u"Missing idx_tv_episodes_showid_airdate for TV Episodes table detected!, fixing...")
|
||||||
self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);")
|
self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid, airdate);")
|
||||||
|
|
||||||
if not self.connection.select("PRAGMA index_info('idx_showid')"):
|
if not self.connection.select("PRAGMA index_info('idx_showid')"):
|
||||||
logger.log(u"Missing idx_showid for TV Episodes table detected!, fixing...")
|
logger.log(u"Missing idx_showid for TV Episodes table detected!, fixing...")
|
||||||
@ -115,15 +116,15 @@ class MainSanityCheck(db.DBSanityCheck):
|
|||||||
|
|
||||||
if not self.connection.select("PRAGMA index_info('idx_status')"):
|
if not self.connection.select("PRAGMA index_info('idx_status')"):
|
||||||
logger.log(u"Missing idx_status for TV Episodes table detected!, fixing...")
|
logger.log(u"Missing idx_status for TV Episodes table detected!, fixing...")
|
||||||
self.connection.action("CREATE INDEX idx_status ON tv_episodes (status,season,episode,airdate)")
|
self.connection.action("CREATE INDEX idx_status ON tv_episodes (status, season, episode, airdate)")
|
||||||
|
|
||||||
if not self.connection.select("PRAGMA index_info('idx_sta_epi_air')"):
|
if not self.connection.select("PRAGMA index_info('idx_sta_epi_air')"):
|
||||||
logger.log(u"Missing idx_sta_epi_air for TV Episodes table detected!, fixing...")
|
logger.log(u"Missing idx_sta_epi_air for TV Episodes table detected!, fixing...")
|
||||||
self.connection.action("CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate)")
|
self.connection.action("CREATE INDEX idx_sta_epi_air ON tv_episodes (status, episode, airdate)")
|
||||||
|
|
||||||
if not self.connection.select("PRAGMA index_info('idx_sta_epi_sta_air')"):
|
if not self.connection.select("PRAGMA index_info('idx_sta_epi_sta_air')"):
|
||||||
logger.log(u"Missing idx_sta_epi_sta_air for TV Episodes table detected!, fixing...")
|
logger.log(u"Missing idx_sta_epi_sta_air for TV Episodes table detected!, fixing...")
|
||||||
self.connection.action("CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate)")
|
self.connection.action("CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season, episode, status, airdate)")
|
||||||
|
|
||||||
def fix_unaired_episodes(self):
|
def fix_unaired_episodes(self):
|
||||||
|
|
||||||
@ -163,6 +164,19 @@ class MainSanityCheck(db.DBSanityCheck):
|
|||||||
for old_status, new_status in status_map.items():
|
for old_status, new_status in status_map.items():
|
||||||
self.connection.action("UPDATE tv_shows SET status = ? WHERE LOWER(status) = ?", [new_status, old_status])
|
self.connection.action("UPDATE tv_shows SET status = ? WHERE LOWER(status) = ?", [new_status, old_status])
|
||||||
|
|
||||||
|
def fix_episode_statuses(self):
|
||||||
|
sqlResults = self.connection.select("SELECT episode_id, showid FROM tv_episodes WHERE status IS NULL")
|
||||||
|
|
||||||
|
for cur_ep in sqlResults:
|
||||||
|
logger.log(u"MALFORMED episode status detected! episode_id: " + str(cur_ep["episode_id"]) + " showid: " + str(
|
||||||
|
cur_ep["showid"]), logger.DEBUG)
|
||||||
|
logger.log(u"Fixing malformed episode status with episode_id: " + str(cur_ep["episode_id"]))
|
||||||
|
self.connection.action("UPDATE tv_episodes SET status = ? WHERE episode_id = ?",
|
||||||
|
[common.UNKNOWN, cur_ep["episode_id"]])
|
||||||
|
else:
|
||||||
|
logger.log(u"No MALFORMED episode statuses, check passed")
|
||||||
|
|
||||||
|
|
||||||
def backupDatabase(version):
|
def backupDatabase(version):
|
||||||
logger.log(u"Backing up database before upgrade")
|
logger.log(u"Backing up database before upgrade")
|
||||||
if not helpers.backupVersionedFile(db.dbFilename(), version):
|
if not helpers.backupVersionedFile(db.dbFilename(), version):
|
||||||
@ -187,7 +201,7 @@ class InitialSchema(db.SchemaUpgrade):
|
|||||||
"CREATE TABLE imdb_info (indexer_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)",
|
"CREATE TABLE imdb_info (indexer_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)",
|
||||||
"CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)",
|
"CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)",
|
||||||
"CREATE TABLE scene_numbering(indexer TEXT, indexer_id INTEGER, season INTEGER, episode INTEGER,scene_season INTEGER, scene_episode INTEGER, PRIMARY KEY(indexer_id, season, episode))",
|
"CREATE TABLE scene_numbering(indexer TEXT, indexer_id INTEGER, season INTEGER, episode INTEGER,scene_season INTEGER, scene_episode INTEGER, PRIMARY KEY(indexer_id, season, episode))",
|
||||||
"CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer TEXT, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC);",
|
"CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC);",
|
||||||
"CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer TEXT, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC, scene_season NUMERIC, scene_episode NUMERIC);",
|
"CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer TEXT, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC, scene_season NUMERIC, scene_episode NUMERIC);",
|
||||||
"CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)",
|
"CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)",
|
||||||
"CREATE INDEX idx_showid ON tv_episodes (showid);",
|
"CREATE INDEX idx_showid ON tv_episodes (showid);",
|
||||||
@ -339,7 +353,7 @@ class RenameSeasonFolders(AddSizeAndSceneNameFields):
|
|||||||
self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")
|
self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")
|
||||||
self.connection.action(
|
self.connection.action(
|
||||||
"CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, location TEXT, show_name TEXT, tvdb_id NUMERIC, network TEXT, genre TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, tvr_id NUMERIC, tvr_name TEXT, air_by_date NUMERIC, lang TEXT)")
|
"CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, location TEXT, show_name TEXT, tvdb_id NUMERIC, network TEXT, genre TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, tvr_id NUMERIC, tvr_name TEXT, air_by_date NUMERIC, lang TEXT)")
|
||||||
sql = "INSERT INTO tv_shows(show_id, location, show_name, tvdb_id, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, tvr_id, tvr_name, air_by_date, lang) SELECT show_id, location, show_name, tvdb_id, network, genre, runtime, quality, airs, status, seasonfolders, paused, startyear, tvr_id, tvr_name, air_by_date, lang FROM tmp_tv_shows"
|
sql = "INSERT INTO tv_shows SELECT * FROM tmp_tv_shows"
|
||||||
self.connection.action(sql)
|
self.connection.action(sql)
|
||||||
|
|
||||||
# flip the values to be opposite of what they were before
|
# flip the values to be opposite of what they were before
|
||||||
@ -616,10 +630,8 @@ class ConvertTVShowsToIndexerScheme(AddSubtitlesSupport):
|
|||||||
self.connection.action("DROP TABLE tmp_tv_shows")
|
self.connection.action("DROP TABLE tmp_tv_shows")
|
||||||
|
|
||||||
self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")
|
self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")
|
||||||
self.connection.action(
|
self.connection.action("CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC)")
|
||||||
"CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC)")
|
self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows")
|
||||||
self.connection.action(
|
|
||||||
"INSERT INTO tv_shows(show_id, indexer_id, show_name, location, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, air_by_date, lang, subtitles, notify_list, imdb_id, last_update_indexer, dvdorder) SELECT show_id, tvdb_id, show_name, location, network, genre, runtime, quality, airs, status, flatten_folders, paused, startyear, air_by_date, lang, subtitles, notify_list, imdb_id, last_update_tvdb, dvdorder FROM tmp_tv_shows")
|
|
||||||
self.connection.action("DROP TABLE tmp_tv_shows")
|
self.connection.action("DROP TABLE tmp_tv_shows")
|
||||||
|
|
||||||
self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);")
|
self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);")
|
||||||
@ -647,7 +659,7 @@ class ConvertTVEpisodesToIndexerScheme(ConvertTVShowsToIndexerScheme):
|
|||||||
self.connection.action(
|
self.connection.action(
|
||||||
"CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer NUMERIC, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC)")
|
"CREATE TABLE tv_episodes (episode_id INTEGER PRIMARY KEY, showid NUMERIC, indexerid NUMERIC, indexer NUMERIC, name TEXT, season NUMERIC, episode NUMERIC, description TEXT, airdate NUMERIC, hasnfo NUMERIC, hastbn NUMERIC, status NUMERIC, location TEXT, file_size NUMERIC, release_name TEXT, subtitles TEXT, subtitles_searchcount NUMERIC, subtitles_lastsearch TIMESTAMP, is_proper NUMERIC)")
|
||||||
self.connection.action(
|
self.connection.action(
|
||||||
"INSERT INTO tv_episodes(episode_id, showid, indexerid, name, season, episode, description, airdate, hasnfo, hastbn, status, location, file_size, release_name, subtitles, subtitles_searchcount, subtitles_lastsearch, is_proper) SELECT episode_id, showid, tvdbid, name, season, episode, description, airdate, hasnfo, hastbn, status, location, file_size, release_name, subtitles, subtitles_searchcount, subtitles_lastsearch, is_proper FROM tmp_tv_episodes")
|
"INSERT INTO tv_episodes SELECT * FROM tmp_tv_episodes")
|
||||||
self.connection.action("DROP TABLE tmp_tv_episodes")
|
self.connection.action("DROP TABLE tmp_tv_episodes")
|
||||||
|
|
||||||
self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);")
|
self.connection.action("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);")
|
||||||
@ -678,7 +690,7 @@ class ConvertIMDBInfoToIndexerScheme(ConvertTVEpisodesToIndexerScheme):
|
|||||||
self.connection.action(
|
self.connection.action(
|
||||||
"CREATE TABLE imdb_info (indexer_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)")
|
"CREATE TABLE imdb_info (indexer_id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, year NUMERIC, akas TEXT, runtimes NUMERIC, genres TEXT, countries TEXT, country_codes TEXT, certificates TEXT, rating TEXT, votes INTEGER, last_update NUMERIC)")
|
||||||
self.connection.action(
|
self.connection.action(
|
||||||
"INSERT INTO imdb_info(indexer_id, imdb_id, title, year, akas, runtimes, genres, countries, country_codes, certificates, rating, votes, last_update) SELECT tvdb_id, imdb_id, title, year, akas, runtimes, genres, countries, country_codes, certificates, rating, votes, last_update FROM tmp_imdb_info")
|
"INSERT INTO imdb_info SELECT * FROM tmp_imdb_info")
|
||||||
self.connection.action("DROP TABLE tmp_imdb_info")
|
self.connection.action("DROP TABLE tmp_imdb_info")
|
||||||
|
|
||||||
self.incDBVersion()
|
self.incDBVersion()
|
||||||
@ -701,7 +713,7 @@ class ConvertInfoToIndexerScheme(ConvertIMDBInfoToIndexerScheme):
|
|||||||
self.connection.action(
|
self.connection.action(
|
||||||
"CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)")
|
"CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)")
|
||||||
self.connection.action(
|
self.connection.action(
|
||||||
"INSERT INTO info(last_backlog, last_indexer, last_proper_search) SELECT last_backlog, last_tvdb, last_proper_search FROM tmp_info")
|
"INSERT INTO info SELECT * FROM tmp_info")
|
||||||
self.connection.action("DROP TABLE tmp_info")
|
self.connection.action("DROP TABLE tmp_info")
|
||||||
|
|
||||||
self.incDBVersion()
|
self.incDBVersion()
|
||||||
@ -944,6 +956,21 @@ class AddDefaultEpStatusToTvShows(AddVersionToTvEpisodes):
|
|||||||
backupDatabase(41)
|
backupDatabase(41)
|
||||||
|
|
||||||
logger.log(u"Adding column default_ep_status to tv_shows")
|
logger.log(u"Adding column default_ep_status to tv_shows")
|
||||||
self.addColumn("tv_shows", "default_ep_status", "TEXT", "")
|
self.addColumn("tv_shows", "default_ep_status", "NUMERIC", "-1")
|
||||||
|
|
||||||
|
self.incDBVersion()
|
||||||
|
|
||||||
|
class AlterTVShowsFieldTypes(AddDefaultEpStatusToTvShows):
|
||||||
|
def test(self):
|
||||||
|
return self.checkDBVersion() >= 42
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
backupDatabase(42)
|
||||||
|
|
||||||
|
logger.log(u"Converting column indexer and default_ep_status field types to numeric")
|
||||||
|
self.connection.action("ALTER TABLE tv_shows RENAME TO tmp_tv_shows")
|
||||||
|
self.connection.action("CREATE TABLE tv_shows (show_id INTEGER PRIMARY KEY, indexer_id NUMERIC, indexer NUMERIC, show_name TEXT, location TEXT, network TEXT, genre TEXT, classification TEXT, runtime NUMERIC, quality NUMERIC, airs TEXT, status TEXT, flatten_folders NUMERIC, paused NUMERIC, startyear NUMERIC, air_by_date NUMERIC, lang TEXT, subtitles NUMERIC, notify_list TEXT, imdb_id TEXT, last_update_indexer NUMERIC, dvdorder NUMERIC, archive_firstmatch NUMERIC, rls_require_words TEXT, rls_ignore_words TEXT, sports NUMERIC, anime NUMERIC, scene NUMERIC, default_ep_status NUMERIC)")
|
||||||
|
self.connection.action("INSERT INTO tv_shows SELECT * FROM tmp_tv_shows")
|
||||||
|
self.connection.action("DROP TABLE tmp_tv_shows")
|
||||||
|
|
||||||
self.incDBVersion()
|
self.incDBVersion()
|
||||||
|
@ -240,7 +240,7 @@ class TVShow(object):
|
|||||||
# if we get an anime get the real season and episode
|
# if we get an anime get the real season and episode
|
||||||
if self.is_anime and absolute_number and not season and not episode:
|
if self.is_anime and absolute_number and not season and not episode:
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
sql = "SELECT * FROM tv_episodes WHERE showid = ? and absolute_number = ? and season != 0"
|
sql = "SELECT * FROM tv_episodes WHERE showid = ? AND absolute_number = ? AND season != 0"
|
||||||
sqlResults = myDB.select(sql, [self.indexerid, absolute_number])
|
sqlResults = myDB.select(sql, [self.indexerid, absolute_number])
|
||||||
|
|
||||||
if len(sqlResults) == 1:
|
if len(sqlResults) == 1:
|
||||||
@ -282,7 +282,7 @@ class TVShow(object):
|
|||||||
def should_update(self, update_date=datetime.date.today()):
|
def should_update(self, update_date=datetime.date.today()):
|
||||||
|
|
||||||
# if show is not 'Ended' always update (status 'Continuing')
|
# if show is not 'Ended' always update (status 'Continuing')
|
||||||
if 'Unknown' not in self.status and 'Ended' not in self.status:
|
if self.status == 'Continuing':
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# run logic against the current show latest aired and next unaired data to see if we should bypass 'Ended' status
|
# run logic against the current show latest aired and next unaired data to see if we should bypass 'Ended' status
|
||||||
@ -500,7 +500,7 @@ class TVShow(object):
|
|||||||
try:
|
try:
|
||||||
curEp = self.getEpisode(curSeason, curEpisode)
|
curEp = self.getEpisode(curSeason, curEpisode)
|
||||||
if not curEp:
|
if not curEp:
|
||||||
raise exceptions.EpisodeNotFoundException
|
raise exceptions.EpisodeNotFoundException
|
||||||
|
|
||||||
# if we found out that the ep is no longer on TVDB then delete it from our database too
|
# if we found out that the ep is no longer on TVDB then delete it from our database too
|
||||||
if deleteEp:
|
if deleteEp:
|
||||||
@ -957,7 +957,7 @@ class TVShow(object):
|
|||||||
if not self.nextaired or self.nextaired and curDate > self.nextaired:
|
if not self.nextaired or self.nextaired and curDate > self.nextaired:
|
||||||
myDB = db.DBConnection()
|
myDB = db.DBConnection()
|
||||||
sqlResults = myDB.select(
|
sqlResults = myDB.select(
|
||||||
"SELECT airdate, season, episode FROM tv_episodes WHERE showid = ? AND airdate >= ? AND status in (?,?) ORDER BY airdate ASC LIMIT 1",
|
"SELECT airdate, season, episode FROM tv_episodes WHERE showid = ? AND airdate >= ? AND status IN (?,?) ORDER BY airdate ASC LIMIT 1",
|
||||||
[self.indexerid, datetime.date.today().toordinal(), UNAIRED, WANTED])
|
[self.indexerid, datetime.date.today().toordinal(), UNAIRED, WANTED])
|
||||||
|
|
||||||
if sqlResults == None or len(sqlResults) == 0:
|
if sqlResults == None or len(sqlResults) == 0:
|
||||||
@ -1526,7 +1526,7 @@ class TVEpisode(object):
|
|||||||
self.subtitles_lastsearch = sqlResults[0]["subtitles_lastsearch"]
|
self.subtitles_lastsearch = sqlResults[0]["subtitles_lastsearch"]
|
||||||
self.airdate = datetime.date.fromordinal(int(sqlResults[0]["airdate"]))
|
self.airdate = datetime.date.fromordinal(int(sqlResults[0]["airdate"]))
|
||||||
# logger.log(u"1 Status changes from " + str(self.status) + " to " + str(sqlResults[0]["status"]), logger.DEBUG)
|
# logger.log(u"1 Status changes from " + str(self.status) + " to " + str(sqlResults[0]["status"]), logger.DEBUG)
|
||||||
self.status = int(sqlResults[0]["status"])
|
self.status = int(sqlResults[0]["status"] or -1)
|
||||||
|
|
||||||
# don't overwrite my location
|
# don't overwrite my location
|
||||||
if sqlResults[0]["location"] and sqlResults[0]["location"]:
|
if sqlResults[0]["location"] and sqlResults[0]["location"]:
|
||||||
@ -1677,15 +1677,15 @@ class TVEpisode(object):
|
|||||||
self.description = getattr(myEp, 'overview', "")
|
self.description = getattr(myEp, 'overview', "")
|
||||||
|
|
||||||
firstaired = getattr(myEp, 'firstaired', None)
|
firstaired = getattr(myEp, 'firstaired', None)
|
||||||
if firstaired is None or firstaired in "0000-00-00":
|
if not firstaired or firstaired == "0000-00-00":
|
||||||
firstaired = str(datetime.date.fromordinal(1))
|
firstaired = str(datetime.date.fromordinal(1))
|
||||||
rawAirdate = [int(x) for x in firstaired.split("-")]
|
rawAirdate = [int(x) for x in firstaired.split("-")]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])
|
self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
logger.log(u"Malformed air date retrieved from " + sickbeard.indexerApi(
|
logger.log(u"Malformed air date of " + str(firstaired) + " retrieved from " + sickbeard.indexerApi(
|
||||||
self.indexer).name + " (" + self.show.name + " - " + str(season) + "x" + str(episode) + ")",
|
self.indexer).name + " for (" + self.show.name + " - " + str(season) + "x" + str(episode) + ")",
|
||||||
logger.ERROR)
|
logger.ERROR)
|
||||||
# if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now
|
# if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now
|
||||||
if self.indexerid != -1:
|
if self.indexerid != -1:
|
||||||
|
@ -24,8 +24,11 @@ import time
|
|||||||
import urllib
|
import urllib
|
||||||
import re
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
|
import sys
|
||||||
|
import platform
|
||||||
|
|
||||||
import sickbeard
|
import sickbeard
|
||||||
|
from github import Github
|
||||||
from sickbeard import config, sab
|
from sickbeard import config, sab
|
||||||
from sickbeard import clients
|
from sickbeard import clients
|
||||||
from sickbeard import history, notifiers, processTV
|
from sickbeard import history, notifiers, processTV
|
||||||
@ -180,9 +183,9 @@ class BaseHandler(RequestHandler):
|
|||||||
<p>%s</p>
|
<p>%s</p>
|
||||||
<h2>Request Info</h2>
|
<h2>Request Info</h2>
|
||||||
<p>%s</p>
|
<p>%s</p>
|
||||||
|
<button onclick="window.location='%s/errorlogs/';">View Log(Errors)</button>
|
||||||
</body>
|
</body>
|
||||||
</html>""" % (error, error,
|
</html>""" % (error, error, trace_info, request_info, sickbeard.WEB_ROOT))
|
||||||
trace_info, request_info))
|
|
||||||
|
|
||||||
def redirect(self, url, permanent=False, status=None):
|
def redirect(self, url, permanent=False, status=None):
|
||||||
if not url.startswith(sickbeard.WEB_ROOT):
|
if not url.startswith(sickbeard.WEB_ROOT):
|
||||||
@ -200,9 +203,8 @@ class BaseHandler(RequestHandler):
|
|||||||
class WebHandler(BaseHandler):
|
class WebHandler(BaseHandler):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(WebHandler, self).__init__(*args, **kwargs)
|
super(WebHandler, self).__init__(*args, **kwargs)
|
||||||
|
self.io_loop = IOLoop.current()
|
||||||
io_loop = IOLoop.current()
|
self.executor = ThreadPoolExecutor(50)
|
||||||
executor = ThreadPoolExecutor(50)
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
@asynchronous
|
@asynchronous
|
||||||
@ -3437,7 +3439,8 @@ class ConfigGeneral(Config):
|
|||||||
proxy_setting=None, proxy_indexers=None, anon_redirect=None, git_path=None, git_remote=None,
|
proxy_setting=None, proxy_indexers=None, anon_redirect=None, git_path=None, git_remote=None,
|
||||||
calendar_unprotected=None,
|
calendar_unprotected=None,
|
||||||
fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None,
|
fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None,
|
||||||
indexer_timeout=None, play_videos=None, rootDir=None, theme_name=None):
|
indexer_timeout=None, play_videos=None, rootDir=None, theme_name=None,
|
||||||
|
git_reset=None, git_username=None, git_password=None):
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
|
|
||||||
@ -3459,6 +3462,9 @@ class ConfigGeneral(Config):
|
|||||||
sickbeard.ANON_REDIRECT = anon_redirect
|
sickbeard.ANON_REDIRECT = anon_redirect
|
||||||
sickbeard.PROXY_SETTING = proxy_setting
|
sickbeard.PROXY_SETTING = proxy_setting
|
||||||
sickbeard.PROXY_INDEXERS = config.checkbox_to_value(proxy_indexers)
|
sickbeard.PROXY_INDEXERS = config.checkbox_to_value(proxy_indexers)
|
||||||
|
sickbeard.GIT_USERNAME = git_username
|
||||||
|
sickbeard.GIT_PASSWORD = git_password
|
||||||
|
sickbeard.GIT_RESET = config.checkbox_to_value(git_reset)
|
||||||
sickbeard.GIT_PATH = git_path
|
sickbeard.GIT_PATH = git_path
|
||||||
sickbeard.GIT_REMOTE = git_remote
|
sickbeard.GIT_REMOTE = git_remote
|
||||||
sickbeard.CALENDAR_UNPROTECTED = config.checkbox_to_value(calendar_unprotected)
|
sickbeard.CALENDAR_UNPROTECTED = config.checkbox_to_value(calendar_unprotected)
|
||||||
@ -4637,7 +4643,7 @@ class ErrorLogs(WebRoot):
|
|||||||
def ErrorLogsMenu(self):
|
def ErrorLogsMenu(self):
|
||||||
menu = [
|
menu = [
|
||||||
{'title': 'Clear Errors', 'path': 'errorlogs/clearerrors/'},
|
{'title': 'Clear Errors', 'path': 'errorlogs/clearerrors/'},
|
||||||
# { 'title': 'View Log', 'path': 'errorlogs/viewlog' },
|
{'title': 'Submit Errors', 'path': 'errorlogs/submit_errors/', 'requires': self.haveGitHub},
|
||||||
]
|
]
|
||||||
|
|
||||||
return menu
|
return menu
|
||||||
@ -4649,12 +4655,14 @@ class ErrorLogs(WebRoot):
|
|||||||
|
|
||||||
return t.respond()
|
return t.respond()
|
||||||
|
|
||||||
|
def haveGitHub(self):
|
||||||
|
if sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD:
|
||||||
|
return True
|
||||||
|
|
||||||
def clearerrors(self):
|
def clearerrors(self):
|
||||||
classes.ErrorViewer.clear()
|
classes.ErrorViewer.clear()
|
||||||
return self.redirect("/errorlogs/")
|
return self.redirect("/errorlogs/")
|
||||||
|
|
||||||
|
|
||||||
def viewlog(self, minLevel=logger.INFO, maxLines=500):
|
def viewlog(self, minLevel=logger.INFO, maxLines=500):
|
||||||
|
|
||||||
t = PageTemplate(rh=self, file="viewlogs.tmpl")
|
t = PageTemplate(rh=self, file="viewlogs.tmpl")
|
||||||
@ -4706,4 +4714,39 @@ class ErrorLogs(WebRoot):
|
|||||||
t.logLines = result
|
t.logLines = result
|
||||||
t.minLevel = minLevel
|
t.minLevel = minLevel
|
||||||
|
|
||||||
return t.respond()
|
return t.respond()
|
||||||
|
|
||||||
|
def submit_errors(self):
|
||||||
|
title = "[APP SUBMITTED]: "
|
||||||
|
|
||||||
|
gh_org = sickbeard.GIT_ORG or 'SiCKRAGETV'
|
||||||
|
gh_repo = 'sickrage-issues'
|
||||||
|
|
||||||
|
self.gh_issues = Github(login_or_token=sickbeard.GIT_USERNAME, password=sickbeard.GIT_PASSWORD,
|
||||||
|
user_agent="SiCKRAGE").get_organization(gh_org).get_repo(gh_repo)
|
||||||
|
|
||||||
|
try:
|
||||||
|
for curError in sorted(classes.ErrorViewer.errors, key=lambda error: error.time, reverse=True)[:500]:
|
||||||
|
title = title + curError.title
|
||||||
|
|
||||||
|
message = u"### INFO\n"
|
||||||
|
message += u"Python Version: **" + sys.version[:120] + "**\n"
|
||||||
|
message += u"Operating System: **" + platform.platform() + "**\n"
|
||||||
|
message += u"Branch: **" + sickbeard.BRANCH + "**\n"
|
||||||
|
message += u"Commit: SiCKRAGETV/SickRage@" + sickbeard.CUR_COMMIT_HASH + "\n"
|
||||||
|
message += u"### ERROR\n"
|
||||||
|
message += u"```\n"
|
||||||
|
message += curError.message
|
||||||
|
message += u"```\n"
|
||||||
|
message += u"---\n"
|
||||||
|
message += u"_STAFF NOTIFIED_: @SiCKRAGETV/owners @SiCKRAGETV/moderators"
|
||||||
|
|
||||||
|
issue = self.gh_issues.create_issue(title, message)
|
||||||
|
if issue:
|
||||||
|
ui.notifications.message('Your issue ticket #%s was submitted successfully!' % issue.number)
|
||||||
|
classes.ErrorViewer.clear()
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.log(ex(e), logger.ERROR)
|
||||||
|
|
||||||
|
return self.redirect("/errorlogs/")
|
@ -7,7 +7,7 @@ from sickbeard.webserve import LoginHandler, LogoutHandler, KeyHandler
|
|||||||
from sickbeard.webapi import ApiHandler
|
from sickbeard.webapi import ApiHandler
|
||||||
from sickbeard import logger
|
from sickbeard import logger
|
||||||
from sickbeard.helpers import create_https_certificates, generateApiKey
|
from sickbeard.helpers import create_https_certificates, generateApiKey
|
||||||
from tornado.web import Application, StaticFileHandler, HTTPError, RedirectHandler
|
from tornado.web import Application, StaticFileHandler, RedirectHandler
|
||||||
from tornado.httpserver import HTTPServer
|
from tornado.httpserver import HTTPServer
|
||||||
from tornado.ioloop import IOLoop
|
from tornado.ioloop import IOLoop
|
||||||
from tornado.routes import route
|
from tornado.routes import route
|
||||||
|
Loading…
Reference in New Issue
Block a user