diff --git a/data/interfaces/default/comingEpisodes.tmpl b/data/interfaces/default/comingEpisodes.tmpl index 40396d4b223f5ef20bbcd32a12a9468995fe656e..e2a1561746d0980311481d76a71cbb3d52dd2751 100644 --- a/data/interfaces/default/comingEpisodes.tmpl +++ b/data/interfaces/default/comingEpisodes.tmpl @@ -132,7 +132,7 @@ <span class="quality Custom">Custom</span> #end if </td> - <td align="center"><a href="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[info]" height="16" width="16" src="$sbRoot/images/thetvdb16.png" /></a></td> + <td align="center"><a href="http://thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[info]" height="16" width="16" src="$sbRoot/images/thetvdb16.png" /></a></td> <td align="center"> <a href="$sbRoot/home/searchEpisode?show=${cur_result["showid"]}&season=$cur_result["season"]&episode=$cur_result["episode"]" title="Manual Search" id="forceUpdate-${cur_result["showid"]}" class="forceUpdate epSearch"><img alt="[search]" height="16" width="16" src="$sbRoot/images/search16.png" id="forceUpdateImage-${cur_result["showid"]}" /></a> </td> @@ -228,7 +228,7 @@ #end if </a></span> <span class="tvshowTitleIcons"> - <a href="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://www.thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[tvdb]" height="16" width="16" src="$sbRoot/images/thetvdb16.png" /></a> + <a href="http://thetvdb.com/?tab=series&id=${cur_result["showid"]}" onclick="window.open(this.href, '_blank'); return false;" title="http://thetvdb.com/?tab=series&id=${cur_result["showid"]}"><img alt="[tvdb]" height="16" width="16" src="$sbRoot/images/thetvdb16.png" /></a> <span><a href="$sbRoot/home/searchEpisode?show=${cur_result["showid"]}&season=$cur_result["season"]&episode=$cur_result["episode"]" title="Manual Search" id="forceUpdate-${cur_result["showid"]}" class="epSearch forceUpdate"><img alt="[search]" height="16" width="16" src="$sbRoot/images/search16.png" id="forceUpdateImage-${cur_result["showid"]}" /></a></span> </span> </th> diff --git a/lib/tvdb_api/tests/test_tvdb_api.py b/lib/tvdb_api/tests/test_tvdb_api.py index 59824b596737e01380f930cf2071484ebff50030..2401143f3db176061ff4e4a1b8553815cad486cb 100755 --- a/lib/tvdb_api/tests/test_tvdb_api.py +++ b/lib/tvdb_api/tests/test_tvdb_api.py @@ -229,7 +229,7 @@ class test_tvdb_misc(unittest.TestCase): """Check valid_languages is up-to-date (compared to languages.xml) """ et = self.t._getetsrc( - "http://www.thetvdb.com/api/%s/languages.xml" % ( + "http://thetvdb.com/api/%s/languages.xml" % ( self.t.config['apikey'] ) ) diff --git a/lib/tvdb_api/tvdb_api.py b/lib/tvdb_api/tvdb_api.py index b8c0d4503edebadd8f2b80275884acbef9e726ed..4211a4225ad9259e69839ca5c2f28522ceced848 100755 --- a/lib/tvdb_api/tvdb_api.py +++ b/lib/tvdb_api/tvdb_api.py @@ -477,7 +477,7 @@ class Tvdb: # The following url_ configs are based of the # http://thetvdb.com/wiki/index.php/Programmers_API - self.config['base_url'] = "http://www.thetvdb.com" + self.config['base_url'] = "http://thetvdb.com" if self.config['search_all_languages']: self.config['url_getSeries'] = u"%(base_url)s/api/GetSeries.php?seriesname=%%s&language=all" % self.config diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py index 8b7847231dfd1a1aab2c1f1d4b93b4609f257ab3..93900b76bd3c8f4a6550c3ead9a082bbd0f4fa9f 100755 --- a/sickbeard/__init__.py +++ b/sickbeard/__init__.py @@ -470,7 +470,7 @@ def initialize(consoleLogging=True): if CACHE_DIR: TVDB_API_PARMS['cache'] = os.path.join(CACHE_DIR, 'tvdb') - TVDB_BASE_URL = 'http://www.thetvdb.com/api/' + TVDB_API_KEY + TVDB_BASE_URL = 'http://thetvdb.com/api/' + TVDB_API_KEY QUALITY_DEFAULT = check_setting_int(CFG, 'General', 'quality_default', SD) STATUS_DEFAULT = check_setting_int(CFG, 'General', 'status_default', SKIPPED) diff --git a/sickbeard/databases/mainDB.py b/sickbeard/databases/mainDB.py index a6506957586ab20c6452a42af90e813dbca522b6..3dc8d4b4c26f8f41971c68b514e24ce3edee1ce7 100644 --- a/sickbeard/databases/mainDB.py +++ b/sickbeard/databases/mainDB.py @@ -27,6 +27,7 @@ from sickbeard.name_parser.parser import NameParser, InvalidNameException MAX_DB_VERSION = 13 + class MainSanityCheck(db.DBSanityCheck): def check(self): self.fix_duplicate_shows() @@ -522,7 +523,7 @@ class AddSizeAndSceneNameFields(AddShowLangsToEpisode): ep_file_name = ek.ek(os.path.basename, cur_result["location"]) ep_file_name = os.path.splitext(ep_file_name)[0] - # I only want to find real scene names here so anything with a space in it is out + # only want to find real scene names here so anything with a space in it is out if ' ' in ep_file_name: continue @@ -560,6 +561,7 @@ class RenameSeasonFolders(AddSizeAndSceneNameFields): self.incDBVersion() + class Add1080pAndRawHDQualities(RenameSeasonFolders): """Add support for 1080p related qualities along with RawHD @@ -639,6 +641,8 @@ class Add1080pAndRawHDQualities(RenameSeasonFolders): new_any = common.Quality.combineQualities([common.Quality.SDTV, common.Quality.SDDVD, common.Quality.HDTV, common.Quality.FULLHDTV, common.Quality.HDWEBDL, common.Quality.FULLHDWEBDL, common.Quality.HDBLURAY, common.Quality.FULLHDBLURAY, common.Quality.UNKNOWN], []) # update qualities (including templates) + logger.log(u"[1/4] Updating pre-defined templates and the quality for each show...", logger.MESSAGE) + ql = [] shows = self.connection.select("SELECT * FROM tv_shows") for cur_show in shows: if cur_show["quality"] == old_hd: @@ -647,26 +651,40 @@ class Add1080pAndRawHDQualities(RenameSeasonFolders): new_quality = new_any else: new_quality = self._update_composite_qualities(cur_show["quality"]) - self.connection.action("UPDATE tv_shows SET quality = ? WHERE tvdb_id = ?", [new_quality, cur_show["tvdb_id"]]) + ql.append(["UPDATE tv_shows SET quality = ? WHERE show_id = ?", [new_quality, cur_show["show_id"]]]) + self.connection.mass_action(ql) # update status that are are within the old hdwebdl (1<<3 which is 8) and better -- exclude unknown (1<<15 which is 32768) - episodes = self.connection.select("SELECT * FROM tv_episodes WHERE status/100 < 32768 AND status/100 >= 8") + logger.log(u"[2/4] Updating the status for the episodes within each show...", logger.MESSAGE) + ql = [] + episodes = self.connection.select("SELECT * FROM tv_episodes WHERE status < 3276800 AND status >= 800") for cur_episode in episodes: - self.connection.action("UPDATE tv_episodes SET status = ? WHERE episode_id = ?", [self._update_status(cur_episode["status"]), cur_episode["episode_id"]]) + ql.append(["UPDATE tv_episodes SET status = ? WHERE episode_id = ?", [self._update_status(cur_episode["status"]), cur_episode["episode_id"]]]) + self.connection.mass_action(ql) # make two seperate passes through the history since snatched and downloaded (action & quality) may not always coordinate together # update previous history so it shows the correct action - historyAction = self.connection.select("SELECT * FROM history WHERE action/100 < 32768 AND action/100 >= 8") + logger.log(u"[3/4] Updating history to reflect the correct action...", logger.MESSAGE) + ql = [] + historyAction = self.connection.select("SELECT * FROM history WHERE action < 3276800 AND action >= 800") for cur_entry in historyAction: - self.connection.action("UPDATE history SET action = ? WHERE showid = ? AND date = ?", [self._update_status(cur_entry["action"]), cur_entry["showid"], cur_entry["date"]]) + ql.append(["UPDATE history SET action = ? WHERE showid = ? AND date = ?", [self._update_status(cur_entry["action"]), cur_entry["showid"], cur_entry["date"]]]) + self.connection.mass_action(ql) # update previous history so it shows the correct quality + logger.log(u"[4/4] Updating history to reflect the correct quality...", logger.MESSAGE) + ql = [] historyQuality = self.connection.select("SELECT * FROM history WHERE quality < 32768 AND quality >= 8") for cur_entry in historyQuality: - self.connection.action("UPDATE history SET quality = ? WHERE showid = ? AND date = ?", [self._update_quality(cur_entry["quality"]), cur_entry["showid"], cur_entry["date"]]) + ql.append(["UPDATE history SET quality = ? WHERE showid = ? AND date = ?", [self._update_quality(cur_entry["quality"]), cur_entry["showid"], cur_entry["date"]]]) + self.connection.mass_action(ql) self.incDBVersion() + + # cleanup and reduce db if any previous data was removed + logger.log(u"Performing a vacuum on the database.", logger.DEBUG) + self.connection.action("VACUUM") class AddSubtitlesSupport(Add1080pAndRawHDQualities): def test(self): diff --git a/sickbeard/db.py b/sickbeard/db.py index 057ccc97d3b805e54300f41b465533af4b65b2fc..34a9b4111bcfdf3aa4fec72ee8af64b3931fa014 100644 --- a/sickbeard/db.py +++ b/sickbeard/db.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with Sick Beard. If not, see <http://www.gnu.org/licenses/>. -from __future__ import with_statement +from __future__ import with_statement import os.path import re @@ -66,6 +66,50 @@ class DBConnection: else: return 0 + def mass_action(self, querylist, logTransaction=False): + + with db_lock: + + if querylist == None: + return + + sqlResult = [] + attempt = 0 + + while attempt < 5: + try: + for qu in querylist: + if len(qu) == 1: + if logTransaction: + logger.log(qu[0], logger.DEBUG) + sqlResult.append(self.connection.execute(qu[0])) + elif len(qu) > 1: + if logTransaction: + logger.log(qu[0] + " with args " + str(qu[1]), logger.DEBUG) + sqlResult.append(self.connection.execute(qu[0], qu[1])) + self.connection.commit() + logger.log(u"Transaction with " + str(len(querylist)) + u" query's executed", logger.DEBUG) + return sqlResult + except sqlite3.OperationalError, e: + sqlResult = [] + if self.connection: + self.connection.rollback() + if "unable to open database file" in e.message or "database is locked" in e.message: + logger.log(u"DB error: " + ex(e), logger.WARNING) + attempt += 1 + time.sleep(1) + else: + logger.log(u"DB error: " + ex(e), logger.ERROR) + raise + except sqlite3.DatabaseError, e: + sqlResult = [] + if self.connection: + self.connection.rollback() + logger.log(u"Fatal error executing query: " + ex(e), logger.ERROR) + raise + + return sqlResult + def action(self, query, args=None): with db_lock: diff --git a/sickbeard/notifiers/xbmc.py b/sickbeard/notifiers/xbmc.py index 6774191140779066f2ccfe576933f69d25564edf..064142af1856757b69c8dc2b1a83a1af2f029e36 100644 --- a/sickbeard/notifiers/xbmc.py +++ b/sickbeard/notifiers/xbmc.py @@ -414,7 +414,7 @@ class XBMCNotifier: return False logger.log(u"XBMC Updating " + showName + " on " + host + " at " + path, logger.DEBUG) - updateCommand = '{"jsonrpc":"2.0","method":"VideoLibrary.Scan","params":{"directory":%s},"id":1}' % (json.dumps("\"" + path + "\"")) # yes we really have to wrap the path in escaped " + updateCommand = '{"jsonrpc":"2.0","method":"VideoLibrary.Scan","params":{"directory":%s},"id":1}' % (json.dumps(path)) request = self._send_to_xbmc_json(updateCommand, host) if not request: logger.log(u"Update of show directory failed on " + showName + " on " + host + " at " + path, logger.ERROR) diff --git a/sickbeard/providers/__init__.py b/sickbeard/providers/__init__.py index 7747743d769fb469bb511bc51eb034de16f8b9e7..be102576e9cb8152702bfd4115021ec8e9d3ab55 100755 --- a/sickbeard/providers/__init__.py +++ b/sickbeard/providers/__init__.py @@ -104,7 +104,7 @@ def makeNewznabProvider(configString): def getDefaultNewznabProviders(): - return 'Sick Beard Index|http://lolo.sickbeard.com/|0|0!!!NZBs.org|http://nzbs.org/||0!!!NZBGeek|https://index.nzbgeek.info/||0!!!NZBFinder|http://www.nzbfinder.ws/||0!!!Usenet-Crawler|http://www.usenet-crawler.com/||0' + return 'Sick Beard Index|http://lolo.sickbeard.com/|0|0!!!NZBs.org|http://nzbs.org/||0!!!Usenet-Crawler|http://www.usenet-crawler.com/||0' def getProviderModule(name): diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 091a51b4c17267ca08b98cf4d37222c2ec5cf69d..fb0d22af80dc42405099308b58a5ab587ccaec9e 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -1469,7 +1469,7 @@ class CMD_SickBeardSearchTVDB(ApiCall): def run(self): """ search for show at tvdb with a given string and language """ if self.name and not self.tvdbid: # only name was given - baseURL = "http://www.thetvdb.com/api/GetSeries.php?" + baseURL = "http://thetvdb.com/api/GetSeries.php?" params = {"seriesname": str(self.name).encode('utf-8'), 'language': self.lang} finalURL = baseURL + urllib.urlencode(params) urlData = sickbeard.helpers.getURL(finalURL) diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py index 87cc3d8b0fba3ee81e23b7cdfe2315709a06f59f..fc91934ce4b18bfcde79ee3fcb226062f11ba582 100644 --- a/sickbeard/webserve.py +++ b/sickbeard/webserve.py @@ -1892,7 +1892,7 @@ class NewHomeAddShows: if not lang or lang == 'null': lang = "fr" - baseURL = "http://www.thetvdb.com/api/GetSeries.php?" + baseURL = "http://thetvdb.com/api/GetSeries.php?" nameUTF8 = name.encode('utf-8') logger.log(u"Trying to find Show on thetvdb.com with: " + nameUTF8.decode('utf-8'), logger.DEBUG)