mirror of
https://github.com/moparisthebest/SickRage
synced 2024-12-04 07:02:26 -05:00
Fixes sickragetv/sickrage-issues#101 - Added code to mainDB to correct malformed episode statues, converted column default_ep_status field type from TEXT to NUMERIC, default to ep status UNKNOWN when loading from DB incase of exception errors.
Added git branch reset option to general settings github to help fix git update related issues. Added github username/password options to general settings github as a requirement for submitting issue tickets from app. Fixed issue with default ep status not showing correct value. Added ability to submit issue reports via errorlogs menu. Added errorlogs view button to error message displayed for webui errors.
This commit is contained in:
parent
170d50c279
commit
6713ce0981
@ -37,7 +37,6 @@
|
||||
#else
|
||||
You don't have version checking turned on. Please turn on "Check for Update" in Config > General.<br />
|
||||
#end if
|
||||
<font color="red">You are using BETA software</font>
|
||||
</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>
|
||||
|
@ -438,48 +438,14 @@
|
||||
|
||||
<div id="core-component-group3" class="component-group">
|
||||
|
||||
<div class="component-group">
|
||||
|
||||
<div class="component-group-desc">
|
||||
<h3>Advanced Settings</h3>
|
||||
|
||||
</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_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">
|
||||
<label>
|
||||
<span class="component-title">CPU throttling:</span>
|
||||
@ -548,6 +514,86 @@
|
||||
|
||||
<input type="submit" class="btn config_submitter" value="Save Changes" />
|
||||
</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 //-->
|
||||
|
||||
<br/>
|
||||
|
@ -106,7 +106,7 @@
|
||||
(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">
|
||||
#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
|
||||
</select><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('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/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('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');
|
||||
|
@ -115,6 +115,8 @@ GIT_REMOTE_URL = ''
|
||||
CUR_COMMIT_BRANCH = ''
|
||||
GIT_ORG = 'SiCKRAGETV'
|
||||
GIT_REPO = 'SickRage'
|
||||
GIT_USERNAME = None
|
||||
GIT_PASSWORD = None
|
||||
GIT_PATH = None
|
||||
|
||||
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, \
|
||||
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
||||
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__:
|
||||
return False
|
||||
@ -558,14 +560,20 @@ def initialize(consoleLogging=True):
|
||||
fileLogging = True
|
||||
if not helpers.makeDir(LOG_DIR):
|
||||
sys.stderr.write("!!! No log folder, logging to screen only!\n")
|
||||
fileLogging=False
|
||||
fileLogging = False
|
||||
|
||||
# init logging
|
||||
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
|
||||
try:gh = Github().get_organization(GIT_ORG).get_repo(GIT_REPO)
|
||||
except:gh = None
|
||||
try:
|
||||
gh = Github(user_agent="SiCKRAGE").get_organization(GIT_ORG).get_repo(GIT_REPO)
|
||||
except:
|
||||
gh = None
|
||||
|
||||
# git reset on update
|
||||
GIT_RESET = bool(check_setting_int(CFG, 'General', 'git_reset', 0))
|
||||
@ -1131,7 +1139,7 @@ def initialize(consoleLogging=True):
|
||||
(METADATA_WDTV, metadata.wdtv),
|
||||
(METADATA_TIVO, metadata.tivo),
|
||||
(METADATA_MEDE8ER, metadata.mede8er),
|
||||
]:
|
||||
]:
|
||||
(cur_metadata_config, cur_metadata_class) = cur_metadata_tuple
|
||||
tmp_provider = cur_metadata_class.metadata_class()
|
||||
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()
|
||||
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']['branch'] = BRANCH
|
||||
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
|
||||
# along with SickRage. If not, see <http://www.gnu.org/licenses/>.
|
||||
import re
|
||||
import sys
|
||||
|
||||
import sickbeard
|
||||
|
||||
@ -261,6 +262,9 @@ class ErrorViewer():
|
||||
def clear():
|
||||
ErrorViewer.errors = []
|
||||
|
||||
@staticmethod
|
||||
def get():
|
||||
return ErrorViewer.errors
|
||||
|
||||
class UIError():
|
||||
"""
|
||||
@ -268,5 +272,7 @@ class UIError():
|
||||
"""
|
||||
|
||||
def __init__(self, message):
|
||||
self.title = sys.exc_info()[1].message or None
|
||||
self.message = message
|
||||
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):
|
||||
if name.lower().endswith((".avi", ".mp4")):
|
||||
return Quality.SDTV
|
||||
# elif name.lower().endswith(".mkv"):
|
||||
# return Quality.HDTV
|
||||
elif name.lower().endswith(".ts"):
|
||||
return Quality.RAWHDTV
|
||||
else:
|
||||
|
@ -27,7 +27,7 @@ from sickbeard import encodingKludge as ek
|
||||
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
||||
|
||||
MIN_DB_VERSION = 9 # oldest db version we support migrating from
|
||||
MAX_DB_VERSION = 41
|
||||
MAX_DB_VERSION = 42
|
||||
|
||||
class MainSanityCheck(db.DBSanityCheck):
|
||||
def check(self):
|
||||
@ -37,6 +37,7 @@ class MainSanityCheck(db.DBSanityCheck):
|
||||
self.fix_orphan_episodes()
|
||||
self.fix_unaired_episodes()
|
||||
self.fix_tvrage_show_statues()
|
||||
self.fix_episode_statuses()
|
||||
|
||||
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')"):
|
||||
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')"):
|
||||
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')"):
|
||||
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')"):
|
||||
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')"):
|
||||
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):
|
||||
|
||||
@ -163,6 +164,19 @@ class MainSanityCheck(db.DBSanityCheck):
|
||||
for old_status, new_status in status_map.items():
|
||||
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):
|
||||
logger.log(u"Backing up database before upgrade")
|
||||
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 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 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 UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)",
|
||||
"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(
|
||||
"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)
|
||||
|
||||
# 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("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)")
|
||||
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("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("DROP TABLE tmp_tv_shows")
|
||||
|
||||
self.connection.action("CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id);")
|
||||
@ -647,7 +659,7 @@ class ConvertTVEpisodesToIndexerScheme(ConvertTVShowsToIndexerScheme):
|
||||
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)")
|
||||
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("CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate);")
|
||||
@ -678,7 +690,7 @@ class ConvertIMDBInfoToIndexerScheme(ConvertTVEpisodesToIndexerScheme):
|
||||
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)")
|
||||
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.incDBVersion()
|
||||
@ -701,7 +713,7 @@ class ConvertInfoToIndexerScheme(ConvertIMDBInfoToIndexerScheme):
|
||||
self.connection.action(
|
||||
"CREATE TABLE info (last_backlog NUMERIC, last_indexer NUMERIC, last_proper_search NUMERIC)")
|
||||
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.incDBVersion()
|
||||
@ -944,6 +956,21 @@ class AddDefaultEpStatusToTvShows(AddVersionToTvEpisodes):
|
||||
backupDatabase(41)
|
||||
|
||||
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()
|
||||
|
@ -240,7 +240,7 @@ class TVShow(object):
|
||||
# if we get an anime get the real season and episode
|
||||
if self.is_anime and absolute_number and not season and not episode:
|
||||
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])
|
||||
|
||||
if len(sqlResults) == 1:
|
||||
@ -282,7 +282,7 @@ class TVShow(object):
|
||||
def should_update(self, update_date=datetime.date.today()):
|
||||
|
||||
# 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
|
||||
|
||||
# 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:
|
||||
curEp = self.getEpisode(curSeason, curEpisode)
|
||||
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 deleteEp:
|
||||
@ -957,7 +957,7 @@ class TVShow(object):
|
||||
if not self.nextaired or self.nextaired and curDate > self.nextaired:
|
||||
myDB = db.DBConnection()
|
||||
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])
|
||||
|
||||
if sqlResults == None or len(sqlResults) == 0:
|
||||
@ -1526,7 +1526,7 @@ class TVEpisode(object):
|
||||
self.subtitles_lastsearch = sqlResults[0]["subtitles_lastsearch"]
|
||||
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)
|
||||
self.status = int(sqlResults[0]["status"])
|
||||
self.status = int(sqlResults[0]["status"] or -1)
|
||||
|
||||
# don't overwrite my location
|
||||
if sqlResults[0]["location"] and sqlResults[0]["location"]:
|
||||
@ -1684,8 +1684,8 @@ class TVEpisode(object):
|
||||
try:
|
||||
self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2])
|
||||
except (ValueError, IndexError):
|
||||
logger.log(u"Malformed air date retrieved from " + sickbeard.indexerApi(
|
||||
self.indexer).name + " (" + self.show.name + " - " + str(season) + "x" + str(episode) + ")",
|
||||
logger.log(u"Malformed air date of " + str(firstaired) + " retrieved from " + sickbeard.indexerApi(
|
||||
self.indexer).name + " for (" + self.show.name + " - " + str(season) + "x" + str(episode) + ")",
|
||||
logger.ERROR)
|
||||
# if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now
|
||||
if self.indexerid != -1:
|
||||
|
@ -24,8 +24,11 @@ import time
|
||||
import urllib
|
||||
import re
|
||||
import datetime
|
||||
import sys
|
||||
import platform
|
||||
|
||||
import sickbeard
|
||||
from github import Github
|
||||
from sickbeard import config, sab
|
||||
from sickbeard import clients
|
||||
from sickbeard import history, notifiers, processTV
|
||||
@ -180,9 +183,9 @@ class BaseHandler(RequestHandler):
|
||||
<p>%s</p>
|
||||
<h2>Request Info</h2>
|
||||
<p>%s</p>
|
||||
<button onclick="window.location='%s/errorlogs/';">View Log(Errors)</button>
|
||||
</body>
|
||||
</html>""" % (error, error,
|
||||
trace_info, request_info))
|
||||
</html>""" % (error, error, trace_info, request_info, sickbeard.WEB_ROOT))
|
||||
|
||||
def redirect(self, url, permanent=False, status=None):
|
||||
if not url.startswith(sickbeard.WEB_ROOT):
|
||||
@ -3437,7 +3440,8 @@ class ConfigGeneral(Config):
|
||||
proxy_setting=None, proxy_indexers=None, anon_redirect=None, git_path=None, git_remote=None,
|
||||
calendar_unprotected=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 = []
|
||||
|
||||
@ -3459,6 +3463,9 @@ class ConfigGeneral(Config):
|
||||
sickbeard.ANON_REDIRECT = anon_redirect
|
||||
sickbeard.PROXY_SETTING = proxy_setting
|
||||
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_REMOTE = git_remote
|
||||
sickbeard.CALENDAR_UNPROTECTED = config.checkbox_to_value(calendar_unprotected)
|
||||
@ -4637,7 +4644,7 @@ class ErrorLogs(WebRoot):
|
||||
def ErrorLogsMenu(self):
|
||||
menu = [
|
||||
{'title': 'Clear Errors', 'path': 'errorlogs/clearerrors/'},
|
||||
# { 'title': 'View Log', 'path': 'errorlogs/viewlog' },
|
||||
{'title': 'Submit Errors', 'path': 'errorlogs/submit_errors/', 'requires': self.haveGitHub},
|
||||
]
|
||||
|
||||
return menu
|
||||
@ -4649,12 +4656,14 @@ class ErrorLogs(WebRoot):
|
||||
|
||||
return t.respond()
|
||||
|
||||
def haveGitHub(self):
|
||||
if sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD:
|
||||
return True
|
||||
|
||||
def clearerrors(self):
|
||||
classes.ErrorViewer.clear()
|
||||
return self.redirect("/errorlogs/")
|
||||
|
||||
|
||||
def viewlog(self, minLevel=logger.INFO, maxLines=500):
|
||||
|
||||
t = PageTemplate(rh=self, file="viewlogs.tmpl")
|
||||
@ -4706,4 +4715,37 @@ class ErrorLogs(WebRoot):
|
||||
t.logLines = result
|
||||
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)
|
||||
except Exception as e:
|
||||
logger.log(ex(e), logger.ERROR)
|
||||
|
||||
return self.redirect("/errorlogs/")
|
Loading…
Reference in New Issue
Block a user