diff --git a/gui/slick/interfaces/default/config.tmpl b/gui/slick/interfaces/default/config.tmpl
index 9f3897c5..99265456 100644
--- a/gui/slick/interfaces/default/config.tmpl
+++ b/gui/slick/interfaces/default/config.tmpl
@@ -37,7 +37,6 @@
#else
You don't have version checking turned on. Please turn on "Check for Update" in Config > General.
#end if
- You are using BETA software
diff --git a/gui/slick/interfaces/default/editShow.tmpl b/gui/slick/interfaces/default/editShow.tmpl
index f7f7fbc6..c031ec13 100644
--- a/gui/slick/interfaces/default/editShow.tmpl
+++ b/gui/slick/interfaces/default/editShow.tmpl
@@ -106,7 +106,7 @@
(this will set a default status to be applied to any newly added episodes)
diff --git a/gui/slick/interfaces/default/inc_top.tmpl b/gui/slick/interfaces/default/inc_top.tmpl
index 93a9057b..857874a3 100644
--- a/gui/slick/interfaces/default/inc_top.tmpl
+++ b/gui/slick/interfaces/default/inc_top.tmpl
@@ -89,6 +89,7 @@
\$("#SubMenu a:contains('Clear History')").addClass('btn clearhistory').html(' Clear History');
\$("#SubMenu a:contains('Trim History')").addClass('btn trimhistory').html(' Trim History');
\$("#SubMenu a[href$='/errorlogs/clearerrors/']").addClass('btn').html(' Clear Errors');
+ \$("#SubMenu a[href$='/errorlogs/submit_errors/']").addClass('btn').html(' Submit Errors');
\$("#SubMenu a:contains('Re-scan')").addClass('btn').html(' Re-scan');
\$("#SubMenu a:contains('Backlog Overview')").addClass('btn').html(' Backlog Overview');
\$("#SubMenu a[href$='/home/updatePLEX/']").addClass('btn').html(' Update PLEX');
diff --git a/readme.md b/readme.md
index 69bff7c3..9c72cad1 100644
--- a/readme.md
+++ b/readme.md
@@ -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.
## 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
- XBMC library updates, poster/fanart downloads, and NFO/TBN generation
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 25406c00..95dfbe8c 100755
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -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
diff --git a/sickbeard/bug_tracker.py b/sickbeard/bug_tracker.py
deleted file mode 100644
index 0c4f303e..00000000
--- a/sickbeard/bug_tracker.py
+++ /dev/null
@@ -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)])
\ No newline at end of file
diff --git a/sickbeard/classes.py b/sickbeard/classes.py
index 7036b0ee..6b70edce 100644
--- a/sickbeard/classes.py
+++ b/sickbeard/classes.py
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License
# along with SickRage. If not, see .
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
diff --git a/sickbeard/common.py b/sickbeard/common.py
index 24a31cc8..bc8e9cd7 100644
--- a/sickbeard/common.py
+++ b/sickbeard/common.py
@@ -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:
diff --git a/sickbeard/databases/mainDB.py b/sickbeard/databases/mainDB.py
index 66ba94bd..7de47c45 100644
--- a/sickbeard/databases/mainDB.py
+++ b/sickbeard/databases/mainDB.py
@@ -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()
diff --git a/sickbeard/tv.py b/sickbeard/tv.py
index 0efde9bb..a149b99a 100644
--- a/sickbeard/tv.py
+++ b/sickbeard/tv.py
@@ -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"]:
@@ -1677,15 +1677,15 @@ class TVEpisode(object):
self.description = getattr(myEp, 'overview', "")
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))
rawAirdate = [int(x) for x in firstaired.split("-")]
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:
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 2f991009..12916106 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -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):