def run_local_db_updates(current_version, upgrade_to_version): # pylint: disable=unused-argument """Perform database actions for a db version change""" # The changes must be left in sequence to allow cascade operations on non-updated databases if common.is_less_version(current_version, '0.2'): # Changes: added table 'search' import sqlite3 as sql from resources.lib.database.db_base_sqlite import CONN_ISOLATION_LEVEL from resources.lib.database import db_utils shared_db_conn = sql.connect(db_utils.get_local_db_path(db_utils.LOCAL_DB_FILENAME), isolation_level=CONN_ISOLATION_LEVEL) cur = shared_db_conn.cursor() table = str('CREATE TABLE search (' 'ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,' 'Guid TEXT NOT NULL REFERENCES profiles (Guid) ON DELETE CASCADE ON UPDATE CASCADE,' 'Type TEXT NOT NULL,' 'Value TEXT NOT NULL,' 'Parameters TEXT,' 'LastAccess TEXT);') cur.execute(table) shared_db_conn.close() if common.is_less_version(current_version, '0.3'): pass
def _perform_addon_changes(previous_ver, current_ver): """Perform actions for an version bump""" from resources.lib.common import (debug, is_less_version) debug('Initialize addon upgrade operations, from version {} to {})', previous_ver, current_ver) if previous_ver and is_less_version(previous_ver, '0.15.9'): import resources.lib.kodi.ui as ui msg = ( 'This update resets the settings to auto-update library.\r\n' 'Therefore only in case you are using auto-update must be reconfigured.' ) ui.show_ok_dialog('Netflix upgrade', msg) if previous_ver and is_less_version(previous_ver, '0.16.0'): import resources.lib.kodi.ui as ui msg = ( 'Has been introduced watched status marks for the videos separate for each profile:\r\n' '[Use new feature] watched status will be separate by profile, [B]existing watched status will be lost.[/B]\r\n' '[Leave unchanged] existing watched status will be kept, [B]but in future versions will be lost.[/B]\r\n' 'This option can be temporarily changed in expert settings') choice = ui.show_yesno_dialog('Netflix upgrade - watched status marks', msg, 'Use new feature', 'Leave unchanged') g.settings_monitor_suspend(at_first_change=True) g.ADDON.setSettingBool('watched_status_by_profile', choice) # Clear cache (prevents problems when netflix change data structures) g.CACHE.invalidate(True) # Always leave this to last - After the operations set current version g.LOCAL_DB.set_value('addon_previous_version', current_ver)
def run_local_db_updates(current_version, upgrade_to_version): # pylint: disable=unused-argument """Perform database actions for a db version change""" # The changes must be left in sequence to allow cascade operations on non-updated databases if common.is_less_version(current_version, '0.2'): pass if common.is_less_version(current_version, '0.3'): pass
def run_local_db_updates(db_version, db_new_version): """Perform database actions for a db version change""" # The changes must be left in sequence to allow cascade operations on non-updated databases if common.is_less_version(db_version, '0.2'): pass if common.is_less_version(db_version, '0.3'): pass g.LOCAL_DB.set_value('db_version', db_new_version)
def run_shared_db_updates(current_version, upgrade_to_version): # pylint: disable=unused-argument """Perform database actions for a db version change""" # The changes must be left in sequence to allow cascade operations on non-updated databases if common.is_less_version(current_version, '0.2'): # Changes: added table 'watched_status_override' # SQLite import sqlite3 as sql from resources.lib.database.db_base_sqlite import CONN_ISOLATION_LEVEL from resources.lib.database import db_utils shared_db_conn = sql.connect(db_utils.get_local_db_path(db_utils.SHARED_DB_FILENAME), isolation_level=CONN_ISOLATION_LEVEL) cur = shared_db_conn.cursor() table = str('CREATE TABLE watched_status_override (' 'ProfileGuid TEXT NOT NULL,' 'VideoID INTEGER NOT NULL,' 'Value TEXT,' 'PRIMARY KEY (ProfileGuid, VideoID ),' 'FOREIGN KEY (ProfileGuid)' 'REFERENCES Profiles (Guid) ON DELETE CASCADE ON UPDATE CASCADE);') cur.execute(table) shared_db_conn.close() # MySQL if g.ADDON.getSettingBool('use_mysql'): import mysql.connector from resources.lib.database.db_base_mysql import MySQLDatabase shared_db_conn = MySQLDatabase() shared_db_conn.conn = mysql.connector.connect(**shared_db_conn.config) cur = shared_db_conn.conn.cursor() table = ('CREATE TABLE netflix_addon.watched_status_override (' 'ProfileGuid VARCHAR(50) NOT NULL,' 'VideoID INT(11) NOT NULL,' 'Value TEXT DEFAULT NULL,' 'PRIMARY KEY (ProfileGuid, VideoID))' 'ENGINE = INNODB, CHARACTER SET utf8mb4, COLLATE utf8mb4_unicode_ci;') alter_tbl = ('ALTER TABLE netflix_addon.watched_status_override ' 'ADD CONSTRAINT FK_watchedstatusoverride_ProfileGuid FOREIGN KEY (ProfileGuid)' 'REFERENCES netflix_addon.profiles(Guid) ON DELETE CASCADE ON UPDATE CASCADE;') cur.execute(table) cur.execute(alter_tbl) shared_db_conn.conn.close() if common.is_less_version(current_version, '0.3'): pass
def set_values(self, dict_values, table=db_utils.TABLE_APP_CONF): """ Store multiple values to database :param dict_values: The key/value to store :param table: Table map """ table_name = table[0] table_columns = table[1] # Doing many sqlite operations at the same makes the performance much worse (especially on Kodi 18) # The use of 'executemany' and 'transaction' can improve performance up to about 75% !! if common.is_less_version(sql.sqlite_version, '3.24.0'): query = 'INSERT OR REPLACE INTO {} ({}, {}) VALUES (?, ?)'.format( table_name, table_columns[0], table_columns[1]) records_values = [(key, common.convert_to_string(value)) for key, value in dict_values.items()] else: # sqlite UPSERT clause exists only on sqlite >= 3.24.0 query = ( 'INSERT INTO {tbl_name} ({tbl_col1}, {tbl_col2}) VALUES (?, ?) ' 'ON CONFLICT({tbl_col1}) DO UPDATE SET {tbl_col2} = ? ' 'WHERE {tbl_col1} = ?').format(tbl_name=table_name, tbl_col1=table_columns[0], tbl_col2=table_columns[1]) records_values = [] for key, value in dict_values.items(): value_str = common.convert_to_string(value) records_values.append((key, value_str, value_str, key)) cur = self.get_cursor() cur.execute("BEGIN TRANSACTION;") self._executemany_non_query(query, records_values, cur) cur.execute("COMMIT;")
def _perform_addon_changes(previous_ver, current_ver): """Perform actions for an version bump""" from resources.lib.common import (debug, is_less_version) debug('Initialize addon upgrade operations, from version {} to {})', previous_ver, current_ver) if previous_ver and is_less_version(previous_ver, '0.15.9'): import resources.lib.kodi.ui as ui msg = ('This update resets the settings to auto-update library.\r\n' 'Therefore only in case you are using auto-update must be reconfigured.') ui.show_ok_dialog('Netflix upgrade', msg) # Clear cache (prevents problems when netflix change data structures) g.CACHE.clear() # Always leave this to last - After the operations set current version g.LOCAL_DB.set_value('addon_previous_version', current_ver)
def _convert_text_track(text_track, period, default, isa_version): if text_track.get('ttDownloadables'): # Only one subtitle representation per adaptationset downloadable = text_track['ttDownloadables'] # common.save_file('downloadable.log', str(downloadable)) if downloadable.get('simplesdh'): content_profile = 'simplesdh' else: content_profile = list(downloadable)[0] is_ios8 = content_profile == 'webvtt-lssdh-ios8' impaired = 'true' if text_track['trackType'] == 'ASSISTIVE' else 'false' forced = 'true' if text_track['isForcedNarrative'] else 'false' default = 'true' if default else 'false' adaptation_set = ET.SubElement( period, # Parent 'AdaptationSet', # Tag lang=text_track.get('language'), codecs=('stpp', 'wvtt')[is_ios8], contentType='text', mimeType=('application/ttml+xml', 'text/vtt')[is_ios8]) role = ET.SubElement( adaptation_set, # Parent 'Role', # Tag schemeIdUri='urn:mpeg:dash:role:2011') # In the future version of InputStream Adaptive, you can set the stream parameters # in the same way as the video stream if common.is_less_version(isa_version, '2.4.3'): # To be removed when the new version is released if forced == 'true': role.set('value', 'forced') else: if default == 'true': role.set('value', 'main') else: adaptation_set.set('impaired', impaired) adaptation_set.set('forced', forced) adaptation_set.set('default', default) role.set('value', 'subtitle') representation = ET.SubElement( adaptation_set, # Parent 'Representation', # Tag nflxProfile=content_profile) _add_base_url( representation, list(downloadable[content_profile]['downloadUrls'].values())[0])