def write(self, data): ''' Writes a dict to the config file. :param data: dict of Section with nested dict of keys and values: {'Section': {'key': 'val', 'key2': 'val2'}, 'Section2': {'key': 'val'}} MUST contain fully populated sections or data will be lost. Only modifies supplied section. After updating config file, copies to core.CONFIG via self.stash() Does not return. ''' diff = Comparisons.compare_dict(data, core.CONFIG) core.CONFIG.update(data) with open(self.file, 'w') as f: json.dump(core.CONFIG, f, indent=4, sort_keys=True) self.stash(config=core.CONFIG) if diff: self.restart_scheduler(diff) l = diff.get('Server', {}).get('language') if l: localization.install(l) return
def write(self, data): ''' Writes a dict to the config file. :param data: dict of Section with nested dict of keys and values: {'Section': {'key': 'val', 'key2': 'val2'}, 'Section2': {'key': 'val'}} MUST contain fully populated sections or data will be lost. Only modifies supplied section. After updating config file, copies to core.CONFIG via self.stash() Does not return. ''' conf = core.CONFIG diff = Comparisons.compare_dict(data, conf) for k, v in data.items(): conf[k] = v with open(self.file, 'w') as f: json.dump(conf, f, indent=4, sort_keys=True) self.stash(config=conf) if diff: scheduler.restart_scheduler(diff) return
def save_settings(self, data): ''' Saves settings to config file :param data: dict of Section with nested dict of keys and values: {'Section': {'key': 'val', 'key2': 'val2'}, 'Section2': {'key': 'val'}} Returns json.dumps(dict) ''' logging.info(u'Saving settings.') data = json.loads(data) diff = None existing_data = {} for i in data.keys(): existing_data.update({i: core.CONFIG[i]}) for k, v in core.CONFIG[i].iteritems(): if type(v) == list: existing_data[i][k] = ','.join(v) if data == existing_data: return json.dumps({'response': 'success'}) else: diff = Comparisons.compare_dict(data, existing_data) try: self.config.write_dict(data) if diff: return json.dumps({'response': 'change', 'changes': diff}) else: return json.dumps({'response': 'success'}) except (SystemExit, KeyboardInterrupt): raise except Exception, e: # noqa logging.error(u'Writing config.', exc_info=True) return json.dumps({'response': 'fail'})
def get_list(self, list_name, min_score=0, length=10): ''' Gets list of trending movies from Trakt list_name (str): name of Trakt list. Must be one of ('trending', 'popular', 'watched', 'collected', 'anticipated', 'boxoffice') min_score (float): minimum score to accept (max 10) <optional - default 0> length (int): how many results to get from Trakt <optional - default 10> Length is applied before min_score, so actual result count can be less than length Returns list of dicts of movie info ''' logging.info('Getting Trakt list {}'.format(list_name)) headers = { 'Content-Type': 'application/json', 'trakt-api-version': '2', 'trakt-api-key': Comparisons._k(b'trakt') } if list_name not in ('trending', 'popular', 'watched', 'collected', 'anticipated', 'boxoffice'): logging.error('Invalid list_name {}'.format(list_name)) return [] url = 'https://api.trakt.tv/movies/{}/?extended=full'.format(list_name) try: r = Url.open(url, headers=headers) if r.status_code != 200: return [] m = json.loads(r.text)[:length] if list_name == 'popular': return [i for i in m if i['rating'] >= min_score] return [i['movie'] for i in m if i['movie']['rating'] >= min_score] except Exception as e: logging.error('Unable to get Trakt list.', exc_info=True) return []
def update_tables(self): existing = self._get_existing_schema() intended = self._get_intended_schema() diff = Comparisons.compare_dict(intended, existing) if not diff: return True print 'Database update required. This may take some time.' backup_dir = os.path.join(core.PROG_PATH, 'db') logging.info(u'Backing up database to {}.'.format(backup_dir)) print u'Backing up database to {}.'.format(backup_dir) try: if not os.path.isdir(backup_dir): os.mkdir(backup_dir) backup = u'{}.{}'.format(core.DB_FILE, datetime.date.today()) shutil.copyfile(core.DB_FILE, os.path.join(backup_dir, backup)) except Exception, e: # noqa print 'Error backing up database.' logging.error(u'Copying SQL DB.', exc_info=True) raise
def update_tables(self): ''' Updates database tables Adds new rows to table based on diff between intended and existing schema Returns Bool, but should crash program if an exception is thrown. DO NOT CATCH EXCEPTIONS ''' logging.info('Checking if database needs to be updated.') existing = self._get_existing_schema() intended = self._get_intended_schema() diff = Comparisons.compare_dict(intended, existing) if not diff: return True logging.debug('Modifying database tables.') print('Modifying tables.') ''' For each item in diff, create new column. Then, if the new columns name is in SQL.convert_names, copy data from old column Create the new table, then copy data from TMP table ''' for table, schema in diff.items(): if table not in existing: logging.debug('Creating table {}'.format(table)) print('Creating table {}'.format(table)) getattr(self, table).create(self.engine) continue logging.debug('Modifying table {}.'.format(table)) print('Modifying table {}'.format(table)) for name, kind in schema.items(): command = [ 'ALTER TABLE {} ADD COLUMN {} {}'.format( table, name, kind) ] self.execute(command) if table in SQL.convert_names.keys(): for pair in SQL.convert_names[table]: if pair[0] == name: command = [ 'UPDATE {} SET {} = {}'.format( table, pair[0], pair[1]) ] self.execute(command) # move TABLE to TABLE_TMP table_tmp = '{}_TMP'.format(table) logging.debug('Renaming table to {}.'.format(table_tmp)) print('Renaming table to {}'.format(table_tmp)) command = ['ALTER TABLE {} RENAME TO {}'.format(table, table_tmp)] self.execute(command) # create new table logging.debug('Creating new table {}.'.format(table)) print('Creating new table {}'.format(table)) table_meta = getattr(self, table) table_meta.create(self.engine) # copy data over logging.debug('Merging data from {} to {}.'.format( table_tmp, table)) print('Merging data from {} to {}'.format(table_tmp, table)) names = ', '.join(intended[table].keys()) command = [ 'INSERT INTO {} ({}) SELECT {} FROM {}'.format( table, names, names, table_tmp) ] self.execute(command) logging.debug('Dropping table {}.'.format(table_tmp)) print('Dropping table {}'.format(table_tmp)) command = ['DROP TABLE {}'.format(table_tmp)] self.execute(command) logging.debug('Finished updating table {}.'.format(table)) print('Finished updating table {}'.format(table)) return True
def update_tables(self): ''' Updates database tables Adds new rows to table based on diff between intended and existing schema Also includes other methods required to manipulate database on startup Returns Bool ''' for i in self.get_user_movies(): p = i['poster'] if p and 'poster/' in p: self.update('MOVIES', 'poster', p.replace('poster/', 'posters/'), 'imdbid', i['imdbid']) existing = self._get_existing_schema() intended = self._get_intended_schema() diff = Comparisons.compare_dict(intended, existing) if not diff: return True print('Database update required. This may take some time.') backup_dir = os.path.join(core.PROG_PATH, 'db') logging.debug('Backing up database to {}.'.format(backup_dir)) print('Backing up database to {}.'.format(backup_dir)) try: if not os.path.isdir(backup_dir): os.mkdir(backup_dir) backup_name = 'watcher.sqlite.{}'.format(datetime.date.today()) shutil.copyfile(core.DB_FILE, os.path.join(backup_dir, backup_name)) except Exception as e: print('Error backing up database.') logging.error('Copying SQL DB.', exc_info=True) raise logging.debug('Modifying database tables.') print('Modifying tables.') ''' For each item in diff, create new column. Then, if the new columns name is in SQL.convert_names, copy data from old column Create the new table, then copy data from TMP table ''' for table, schema in diff.items(): if table not in existing: logging.debug('Creating table {}'.format(table)) print('Creating table {}'.format(table)) getattr(self, table).create(self.engine) continue logging.debug('Modifying table {}.'.format(table)) print('Modifying table {}'.format(table)) for name, kind in schema.items(): command = [ 'ALTER TABLE {} ADD COLUMN {} {}'.format( table, name, kind) ] self.execute(command) if table in SQL.convert_names.keys(): for pair in SQL.convert_names[table]: if pair[0] == name: command = [ 'UPDATE {} SET {} = {}'.format( table, pair[0], pair[1]) ] self.execute(command) # move TABLE to TABLE_TMP table_tmp = '{}_TMP'.format(table) logging.debug('Renaming table to {}.'.format(table_tmp)) print('Renaming table to {}'.format(table_tmp)) command = ['ALTER TABLE {} RENAME TO {}'.format(table, table_tmp)] self.execute(command) # create new table logging.debug('Creating new table {}.'.format(table)) print('Creating new table {}'.format(table)) table_meta = getattr(self, table) table_meta.create(self.engine) # copy data over logging.debug('Merging data from {} to {}.'.format( table_tmp, table)) print('Merging data from {} to {}'.format(table_tmp, table)) names = ', '.join(intended[table].keys()) command = [ 'INSERT INTO {} ({}) SELECT {} FROM {}'.format( table, names, names, table_tmp) ] self.execute(command) logging.debug('Dropping table {}.'.format(table_tmp)) print('Dropping table {}'.format(table_tmp)) command = ['DROP TABLE {}'.format(table_tmp)] self.execute(command) logging.debug('Finished updating table {}.'.format(table)) print('Finished updating table {}'.format(table)) logging.debug('Database updated') print('Database updated.')
def update_tables(self): existing = self._get_existing_schema() intended = self._get_intended_schema() diff = Comparisons.compare_dict(intended, existing) if not diff: return True print('Database update required. This may take some time.') backup_dir = os.path.join(core.PROG_PATH, 'db') logging.info('Backing up database to {}.'.format(backup_dir)) print('Backing up database to {}.'.format(backup_dir)) try: if not os.path.isdir(backup_dir): os.mkdir(backup_dir) backup = '{}.{}'.format(core.DB_FILE, datetime.date.today()) shutil.copyfile(core.DB_FILE, os.path.join(backup_dir, backup)) except Exception as e: # noqa print('Error backing up database.') logging.error('Copying SQL DB.', exc_info=True) raise logging.info('Modifying database tables.') print('Modifying tables.') ''' For each item in diff, create new column. Then, if the new columns name is in self.convert_names, copy data from old column Create the new table, then copy data from TMP table ''' for table, schema in diff.items(): if table not in existing: logging.info('Creating table {}'.format(table)) print('Creating table {}'.format(table)) getattr(self, table).create(self.engine) continue logging.info('Modifying table {}.'.format(table)) print('Modifying table {}'.format(table)) for name, kind in schema.items(): command = 'ALTER TABLE {} ADD COLUMN {} {}'.format(table, name, kind) self.execute(command) if table in self.convert_names.keys(): for pair in self.convert_names[table]: if pair[0] == name: command = 'UPDATE {} SET {} = {}'.format(table, pair[0], pair[1]) self.execute(command) # move TABLE to TABLE_TMP table_tmp = '{}_TMP'.format(table) logging.info('Renaming table to {}.'.format(table_tmp)) print('Renaming table to {}'.format(table_tmp)) command = 'ALTER TABLE {} RENAME TO {}'.format(table, table_tmp) self.execute(command) # create new table logging.info('Creating new table {}.'.format(table)) print('Creating new table {}'.format(table)) table_meta = getattr(self, table) table_meta.create(self.engine) # copy data over logging.info('Merging data from {} to {}.'.format(table_tmp, table)) print('Merging data from {} to {}'.format(table_tmp, table)) names = ', '.join(intended[table].keys()) command = 'INSERT INTO {} ({}) SELECT {} FROM {}'.format(table, names, names, table_tmp) self.execute(command) logging.info('Dropping table {}.'.format(table_tmp)) print('Dropping table {}'.format(table_tmp)) command = 'DROP TABLE {}'.format(table_tmp) self.execute(command) logging.info('Finished updating table {}.'.format(table)) print('Finished updating table {}'.format(table)) logging.info('Database updated') print('Database updated.')