mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-03 01:43:37 +00:00
Merge pull request #385 from JackDandy/feature/ChangeFirstRunDB
Change first run after install to set up the main db …
This commit is contained in:
commit
954bcb74be
4 changed files with 105 additions and 53 deletions
|
@ -21,6 +21,8 @@
|
||||||
* Add handling for CloudFlare custom HTTP response codes
|
* Add handling for CloudFlare custom HTTP response codes
|
||||||
* Fix to correctly load local libraries instead of system installed libraries
|
* Fix to correctly load local libraries instead of system installed libraries
|
||||||
* Update PyNMA to hybrid v1.0
|
* Update PyNMA to hybrid v1.0
|
||||||
|
* Change first run after install to set up the main db to the current schema instead of upgrading
|
||||||
|
* Change don't create a backup from an initial zero byte main database file, PEP8 and code tidy up
|
||||||
|
|
||||||
[develop changelog]
|
[develop changelog]
|
||||||
* Update Requests library 2.7.0 (ab1f493) to 2.7.0 (8b5e457)
|
* Update Requests library 2.7.0 (ab1f493) to 2.7.0 (8b5e457)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import datetime
|
||||||
import sickbeard
|
import sickbeard
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from sickbeard import db, common, helpers, logger
|
from sickbeard import db, common, logger
|
||||||
|
|
||||||
from sickbeard import encodingKludge as ek
|
from sickbeard import encodingKludge as ek
|
||||||
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
from sickbeard.name_parser.parser import NameParser, InvalidNameException, InvalidShowException
|
||||||
|
@ -145,34 +145,36 @@ class MainSanityCheck(db.DBSanityCheck):
|
||||||
logger.log(u'No UNAIRED episodes, check passed')
|
logger.log(u'No UNAIRED episodes, check passed')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ======================
|
# ======================
|
||||||
# = Main DB Migrations =
|
# = Main DB Migrations =
|
||||||
# ======================
|
# ======================
|
||||||
# Add new migrations at the bottom of the list; subclass the previous migration.
|
# Add new migrations at the bottom of the list; subclass the previous migration.
|
||||||
|
# 0 -> 20003
|
||||||
|
|
||||||
# 0 -> 31
|
|
||||||
class InitialSchema(db.SchemaUpgrade):
|
class InitialSchema(db.SchemaUpgrade):
|
||||||
def execute(self):
|
def execute(self):
|
||||||
db.backup_database('sickbeard.db', self.checkDBVersion())
|
db.backup_database('sickbeard.db', self.checkDBVersion())
|
||||||
|
|
||||||
if not self.hasTable('tv_shows') and not self.hasTable('db_version'):
|
if not self.hasTable('tv_shows') and not self.hasTable('db_version'):
|
||||||
queries = [
|
queries = [
|
||||||
|
# original sick beard tables
|
||||||
'CREATE TABLE db_version (db_version INTEGER);',
|
'CREATE TABLE db_version (db_version INTEGER);',
|
||||||
'CREATE TABLE history (action NUMERIC, date NUMERIC, showid NUMERIC, season NUMERIC, episode NUMERIC, quality NUMERIC, resource TEXT, provider TEXT)',
|
'CREATE TABLE history (action NUMERIC, date NUMERIC, showid NUMERIC, season NUMERIC, episode NUMERIC, quality NUMERIC, resource TEXT, provider TEXT, version 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 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, scene_season NUMERIC, scene_episode NUMERIC, absolute_number NUMERIC, scene_absolute_number NUMERIC, version NUMERIC, release_group TEXT, trakt_watched 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_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, overview TEXT, tag TEXT)',
|
||||||
'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, scene_season NUMERIC, scene_episode NUMERIC);',
|
'CREATE INDEX idx_showid ON tv_episodes (showid)',
|
||||||
'CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)',
|
|
||||||
'CREATE INDEX idx_showid ON tv_episodes (showid);',
|
|
||||||
'CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate);',
|
|
||||||
'CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate);',
|
|
||||||
'CREATE INDEX idx_status ON tv_episodes (status,season,episode,airdate);',
|
|
||||||
'CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes (showid,airdate)',
|
'CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes (showid,airdate)',
|
||||||
'INSERT INTO db_version (db_version) VALUES (31);'
|
'CREATE TABLE blacklist (show_id INTEGER, range TEXT, keyword TEXT)',
|
||||||
|
'CREATE TABLE indexer_mapping (indexer_id INTEGER, indexer NUMERIC, mindexer_id INTEGER, mindexer NUMERIC, PRIMARY KEY (indexer_id, indexer))',
|
||||||
|
'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 scene_numbering (indexer TEXT, indexer_id INTEGER, season INTEGER, episode INTEGER, scene_season INTEGER, scene_episode INTEGER, absolute_number NUMERIC, scene_absolute_number NUMERIC, PRIMARY KEY (indexer_id, season, episode))',
|
||||||
|
'CREATE TABLE whitelist (show_id INTEGER, range TEXT, keyword TEXT)',
|
||||||
|
'CREATE TABLE xem_refresh (indexer TEXT, indexer_id INTEGER PRIMARY KEY, last_refreshed INTEGER)',
|
||||||
|
'CREATE UNIQUE INDEX idx_indexer_id ON tv_shows (indexer_id)',
|
||||||
|
'CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate)',
|
||||||
|
'CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate)',
|
||||||
|
'CREATE INDEX idx_status ON tv_episodes (status,season,episode,airdate)',
|
||||||
|
'INSERT INTO db_version (db_version) VALUES (20003)'
|
||||||
]
|
]
|
||||||
for query in queries:
|
for query in queries:
|
||||||
self.connection.action(query)
|
self.connection.action(query)
|
||||||
|
@ -964,7 +966,7 @@ class BumpDatabaseVersion(db.SchemaUpgrade):
|
||||||
return self.checkDBVersion()
|
return self.checkDBVersion()
|
||||||
|
|
||||||
|
|
||||||
# 41 -> 10001
|
# 41,42 -> 10001
|
||||||
class Migrate41(db.SchemaUpgrade):
|
class Migrate41(db.SchemaUpgrade):
|
||||||
def execute(self):
|
def execute(self):
|
||||||
db.backup_database('sickbeard.db', self.checkDBVersion())
|
db.backup_database('sickbeard.db', self.checkDBVersion())
|
||||||
|
@ -1034,6 +1036,7 @@ class AddTvShowOverview(db.SchemaUpgrade):
|
||||||
self.setDBVersion(20002)
|
self.setDBVersion(20002)
|
||||||
return self.checkDBVersion()
|
return self.checkDBVersion()
|
||||||
|
|
||||||
|
|
||||||
# 20002 -> 20003
|
# 20002 -> 20003
|
||||||
class AddTvShowTags(db.SchemaUpgrade):
|
class AddTvShowTags(db.SchemaUpgrade):
|
||||||
def execute(self):
|
def execute(self):
|
||||||
|
|
|
@ -650,28 +650,28 @@ def parse_xml(data, del_xmlns=False):
|
||||||
|
|
||||||
|
|
||||||
def backupVersionedFile(old_file, version):
|
def backupVersionedFile(old_file, version):
|
||||||
numTries = 0
|
num_tries = 0
|
||||||
|
|
||||||
new_file = old_file + '.' + 'v' + str(version)
|
new_file = '%s.v%s' % (old_file, version)
|
||||||
|
|
||||||
while not ek.ek(os.path.isfile, new_file):
|
while not ek.ek(os.path.isfile, new_file):
|
||||||
if not ek.ek(os.path.isfile, old_file):
|
if not ek.ek(os.path.isfile, old_file) or 0 == get_size(old_file):
|
||||||
logger.log(u"Not creating backup, " + old_file + " doesn't exist", logger.DEBUG)
|
logger.log(u'No need to create backup', logger.DEBUG)
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.log(u"Trying to back up " + old_file + " to " + new_file, logger.DEBUG)
|
logger.log(u'Trying to back up %s to %s' % (old_file, new_file), logger.DEBUG)
|
||||||
shutil.copy(old_file, new_file)
|
shutil.copy(old_file, new_file)
|
||||||
logger.log(u"Backup done", logger.DEBUG)
|
logger.log(u'Backup done', logger.DEBUG)
|
||||||
break
|
break
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.log(u"Error while trying to back up " + old_file + " to " + new_file + " : " + ex(e), logger.WARNING)
|
logger.log(u'Error while trying to back up %s to %s : %s' % (old_file, new_file, ex(e)), logger.WARNING)
|
||||||
numTries += 1
|
num_tries += 1
|
||||||
time.sleep(1)
|
time.sleep(3)
|
||||||
logger.log(u"Trying again.", logger.DEBUG)
|
logger.log(u'Trying again.', logger.DEBUG)
|
||||||
|
|
||||||
if numTries >= 10:
|
if 3 <= num_tries:
|
||||||
logger.log(u"Unable to back up " + old_file + " to " + new_file + " please do it manually.", logger.ERROR)
|
logger.log(u'Unable to back up %s to %s please do it manually.' % (old_file, new_file), logger.ERROR)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -5,7 +5,8 @@ import unittest
|
||||||
import test_lib as test
|
import test_lib as test
|
||||||
import sickbeard
|
import sickbeard
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from sickbeard import db
|
from sickbeard import db, logger
|
||||||
|
from sickbeard.databases.mainDB import MIN_DB_VERSION, MAX_DB_VERSION
|
||||||
|
|
||||||
sys.path.insert(1, os.path.abspath('..'))
|
sys.path.insert(1, os.path.abspath('..'))
|
||||||
sys.path.insert(1, os.path.abspath('../lib'))
|
sys.path.insert(1, os.path.abspath('../lib'))
|
||||||
|
@ -21,8 +22,7 @@ class MigrationBasicTests(test.SickbeardTestDBCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_migrations(self):
|
def test_migrations(self):
|
||||||
schema = {
|
schema = {0: OldInitialSchema, # sickbeard.mainDB.InitialSchema,
|
||||||
0: sickbeard.mainDB.InitialSchema,
|
|
||||||
31: sickbeard.mainDB.AddAnimeTVShow,
|
31: sickbeard.mainDB.AddAnimeTVShow,
|
||||||
32: sickbeard.mainDB.AddAbsoluteNumbering,
|
32: sickbeard.mainDB.AddAbsoluteNumbering,
|
||||||
33: sickbeard.mainDB.AddSceneAbsoluteNumbering,
|
33: sickbeard.mainDB.AddSceneAbsoluteNumbering,
|
||||||
|
@ -32,20 +32,20 @@ class MigrationBasicTests(test.SickbeardTestDBCase):
|
||||||
37: sickbeard.mainDB.AddSceneToTvShows,
|
37: sickbeard.mainDB.AddSceneToTvShows,
|
||||||
38: sickbeard.mainDB.AddIndexerMapping,
|
38: sickbeard.mainDB.AddIndexerMapping,
|
||||||
39: sickbeard.mainDB.AddVersionToTvEpisodes,
|
39: sickbeard.mainDB.AddVersionToTvEpisodes,
|
||||||
41: AddDefaultEpStatusToTvShows,
|
41: AddDefaultEpStatusToTvShows
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 1
|
count = 1
|
||||||
while count < len(schema.keys()):
|
while count < len(schema.keys()):
|
||||||
myDB = db.DBConnection()
|
my_db = db.DBConnection()
|
||||||
|
|
||||||
for version in sorted(schema.keys())[:count]:
|
for version in sorted(schema.keys())[:count]:
|
||||||
update = schema[version](myDB)
|
update = schema[version](my_db)
|
||||||
update.execute()
|
update.execute()
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
|
|
||||||
db.MigrationCode(myDB)
|
db.MigrationCode(my_db)
|
||||||
myDB.close()
|
my_db.close()
|
||||||
for filename in glob.glob(os.path.join(test.TESTDIR, test.TESTDBNAME) + '*'):
|
for filename in glob.glob(os.path.join(test.TESTDIR, test.TESTDBNAME) + '*'):
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|
||||||
|
@ -53,16 +53,63 @@ class MigrationBasicTests(test.SickbeardTestDBCase):
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
|
||||||
|
# 0 -> 31
|
||||||
|
class OldInitialSchema(db.SchemaUpgrade):
|
||||||
|
def execute(self):
|
||||||
|
db.backup_database('sickbeard.db', self.checkDBVersion())
|
||||||
|
|
||||||
|
if not self.hasTable('tv_shows') and not self.hasTable('db_version'):
|
||||||
|
queries = [
|
||||||
|
'CREATE TABLE db_version (db_version INTEGER);',
|
||||||
|
'CREATE TABLE history (action NUMERIC, date NUMERIC, showid NUMERIC, season NUMERIC, episode NUMERIC, quality NUMERIC, resource TEXT, provider TEXT)',
|
||||||
|
'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 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 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, 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);',
|
||||||
|
'CREATE INDEX idx_sta_epi_air ON tv_episodes (status,episode, airdate);',
|
||||||
|
'CREATE INDEX idx_sta_epi_sta_air ON tv_episodes (season,episode, status, airdate);',
|
||||||
|
'CREATE INDEX idx_status ON tv_episodes (status,season,episode,airdate);',
|
||||||
|
'CREATE INDEX idx_tv_episodes_showid_airdate ON tv_episodes(showid,airdate)',
|
||||||
|
'INSERT INTO db_version (db_version) VALUES (31);'
|
||||||
|
]
|
||||||
|
for query in queries:
|
||||||
|
self.connection.action(query)
|
||||||
|
|
||||||
|
else:
|
||||||
|
cur_db_version = self.checkDBVersion()
|
||||||
|
|
||||||
|
if cur_db_version < MIN_DB_VERSION:
|
||||||
|
logger.log_error_and_exit(u'Your database version ('
|
||||||
|
+ str(cur_db_version)
|
||||||
|
+ ') is too old to migrate from what this version of SickGear supports ('
|
||||||
|
+ str(MIN_DB_VERSION) + ').' + "\n"
|
||||||
|
+ 'Upgrade using a previous version (tag) build 496 to build 501 of SickGear first or remove database file to begin fresh.'
|
||||||
|
)
|
||||||
|
|
||||||
|
if cur_db_version > MAX_DB_VERSION:
|
||||||
|
logger.log_error_and_exit(u'Your database version ('
|
||||||
|
+ str(cur_db_version)
|
||||||
|
+ ') has been incremented past what this version of SickGear supports ('
|
||||||
|
+ str(MAX_DB_VERSION) + ').' + "\n"
|
||||||
|
+ 'If you have used other forks of SickGear, your database may be unusable due to their modifications.'
|
||||||
|
)
|
||||||
|
|
||||||
|
return self.checkDBVersion()
|
||||||
|
|
||||||
|
|
||||||
class AddDefaultEpStatusToTvShows(db.SchemaUpgrade):
|
class AddDefaultEpStatusToTvShows(db.SchemaUpgrade):
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.addColumn("tv_shows", "default_ep_status", "TEXT", "")
|
self.addColumn('tv_shows', 'default_ep_status', 'TEXT', '')
|
||||||
self.setDBVersion(41)
|
self.setDBVersion(41)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print "=================="
|
print '=================='
|
||||||
print "STARTING - MIGRATION TESTS"
|
print 'Starting - Migration Tests'
|
||||||
print "=================="
|
print '=================='
|
||||||
print "######################################################################"
|
print '######################################################################'
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(MigrationBasicTests)
|
suite = unittest.TestLoader().loadTestsFromTestCase(MigrationBasicTests)
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||||
|
|
Loading…
Reference in a new issue