def get_series(sonarr_series_id): data = TableShows.select(TableShows.title, TableShows.year)\ .where(TableShows.sonarrSeriesId == sonarr_series_id)\ .dicts()\ .get() return {'title': data['title'], 'year': data['year']}
def get(self): query = request.args.get('query') search_list = [] if query: if settings.general.getboolean('use_sonarr'): # Get matching series series = TableShows.select(TableShows.title, TableShows.sonarrSeriesId, TableShows.year)\ .where(TableShows.title.contains(query))\ .order_by(TableShows.title)\ .dicts() series = list(series) search_list += series if settings.general.getboolean('use_radarr'): # Get matching movies movies = TableMovies.select(TableMovies.title, TableMovies.radarrId, TableMovies.year) \ .where(TableMovies.title.contains(query)) \ .order_by(TableMovies.title) \ .dicts() movies = list(movies) search_list += movies return jsonify(search_list)
def get(self): start = request.args.get('start') or 0 length = request.args.get('length') or -1 seriesId = request.args.getlist('seriesid[]') count = TableShows.select().count() if len(seriesId) != 0: result = TableShows.select() \ .where(TableShows.sonarrSeriesId.in_(seriesId)) \ .order_by(TableShows.sortTitle).dicts() else: result = TableShows.select().order_by(TableShows.sortTitle).limit(length).offset(start).dicts() result = list(result) for item in result: postprocessSeries(item) # Add missing subtitles episode count episodes_missing_conditions = [(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']), (TableEpisodes.missing_subtitles != '[]')] episodes_missing_conditions += get_exclusion_clause('series') episodeMissingCount = TableEpisodes.select(TableShows.tags, TableEpisodes.monitored, TableShows.seriesType) \ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \ .where(reduce(operator.and_, episodes_missing_conditions)) \ .count() item.update({"episodeMissingCount": episodeMissingCount}) # Add episode count episodeFileCount = TableEpisodes.select(TableShows.tags, TableEpisodes.monitored, TableShows.seriesType) \ .join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \ .where(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']) \ .count() item.update({"episodeFileCount": episodeFileCount}) return jsonify(data=result, total=count)
def post(self): seriesIdList = request.form.getlist('seriesid') profileIdList = request.form.getlist('profileid') for idx in range(len(seriesIdList)): seriesId = seriesIdList[idx] profileId = profileIdList[idx] if profileId in None_Keys: profileId = None else: try: profileId = int(profileId) except Exception: return '', 400 TableShows.update({ TableShows.profileId: profileId }) \ .where(TableShows.sonarrSeriesId == seriesId) \ .execute() list_missing_subtitles(no=seriesId, send_event=False) event_stream(type='series', payload=seriesId) episode_id_list = TableEpisodes \ .select(TableEpisodes.sonarrEpisodeId) \ .where(TableEpisodes.sonarrSeriesId == seriesId) \ .dicts() for item in episode_id_list: event_stream(type='episode-wanted', payload=item['sonarrEpisodeId']) event_stream(type='badges') return '', 204
def get_sonarr_rootfolder(): apikey_sonarr = settings.sonarr.apikey sonarr_rootfolder = [] # Get root folder data from Sonarr if get_sonarr_info.is_legacy(): url_sonarr_api_rootfolder = url_sonarr() + "/api/rootfolder?apikey=" + apikey_sonarr else: url_sonarr_api_rootfolder = url_sonarr() + "/api/v3/rootfolder?apikey=" + apikey_sonarr try: rootfolder = requests.get(url_sonarr_api_rootfolder, timeout=60, verify=False, headers=headers) except requests.exceptions.ConnectionError: logging.exception("BAZARR Error trying to get rootfolder from Sonarr. Connection Error.") return [] except requests.exceptions.Timeout: logging.exception("BAZARR Error trying to get rootfolder from Sonarr. Timeout Error.") return [] except requests.exceptions.RequestException: logging.exception("BAZARR Error trying to get rootfolder from Sonarr.") return [] else: sonarr_movies_paths = list(TableShows.select(TableShows.path).dicts()) for folder in rootfolder.json(): if any(item['path'].startswith(folder['path']) for item in sonarr_movies_paths): sonarr_rootfolder.append({'id': folder['id'], 'path': folder['path']}) db_rootfolder = TableShowsRootfolder.select(TableShowsRootfolder.id, TableShowsRootfolder.path).dicts() rootfolder_to_remove = [x for x in db_rootfolder if not next((item for item in sonarr_rootfolder if item['id'] == x['id']), False)] rootfolder_to_update = [x for x in sonarr_rootfolder if next((item for item in db_rootfolder if item['id'] == x['id']), False)] rootfolder_to_insert = [x for x in sonarr_rootfolder if not next((item for item in db_rootfolder if item['id'] == x['id']), False)] for item in rootfolder_to_remove: TableShowsRootfolder.delete().where(TableShowsRootfolder.id == item['id']).execute() for item in rootfolder_to_update: TableShowsRootfolder.update({TableShowsRootfolder.path: item['path']})\ .where(TableShowsRootfolder.id == item['id'])\ .execute() for item in rootfolder_to_insert: TableShowsRootfolder.insert({TableShowsRootfolder.id: item['id'], TableShowsRootfolder.path: item['path']})\ .execute()
def post(self): enabled_languages = request.form.getlist('languages-enabled') if len(enabled_languages) != 0: TableSettingsLanguages.update({ TableSettingsLanguages.enabled: 0 }).execute() for code in enabled_languages: TableSettingsLanguages.update({ TableSettingsLanguages.enabled: 1 })\ .where(TableSettingsLanguages.code2 == code)\ .execute() event_stream("languages") languages_profiles = request.form.get('languages-profiles') if languages_profiles: existing_ids = TableLanguagesProfiles.select(TableLanguagesProfiles.profileId).dicts() existing_ids = list(existing_ids) existing = [x['profileId'] for x in existing_ids] for item in json.loads(languages_profiles): if item['profileId'] in existing: # Update existing profiles TableLanguagesProfiles.update({ TableLanguagesProfiles.name: item['name'], TableLanguagesProfiles.cutoff: item['cutoff'] if item['cutoff'] != 'null' else None, TableLanguagesProfiles.items: json.dumps(item['items']), TableLanguagesProfiles.mustContain: item['mustContain'], TableLanguagesProfiles.mustNotContain: item['mustNotContain'], })\ .where(TableLanguagesProfiles.profileId == item['profileId'])\ .execute() existing.remove(item['profileId']) else: # Add new profiles TableLanguagesProfiles.insert({ TableLanguagesProfiles.profileId: item['profileId'], TableLanguagesProfiles.name: item['name'], TableLanguagesProfiles.cutoff: item['cutoff'] if item['cutoff'] != 'null' else None, TableLanguagesProfiles.items: json.dumps(item['items']), TableLanguagesProfiles.mustContain: item['mustContain'], TableLanguagesProfiles.mustNotContain: item['mustNotContain'], }).execute() for profileId in existing: # Unassign this profileId from series and movies TableShows.update({ TableShows.profileId: None }).where(TableShows.profileId == profileId).execute() TableMovies.update({ TableMovies.profileId: None }).where(TableMovies.profileId == profileId).execute() # Remove deleted profiles TableLanguagesProfiles.delete().where(TableLanguagesProfiles.profileId == profileId).execute() update_profile_id_list() event_stream("languages") if settings.general.getboolean('use_sonarr'): scheduler.add_job(list_missing_subtitles, kwargs={'send_event': False}) if settings.general.getboolean('use_radarr'): scheduler.add_job(list_missing_subtitles_movies, kwargs={'send_event': False}) # Update Notification notifications = request.form.getlist('notifications-providers') for item in notifications: item = json.loads(item) TableSettingsNotifier.update({ TableSettingsNotifier.enabled: item['enabled'], TableSettingsNotifier.url: item['url'] }).where(TableSettingsNotifier.name == item['name']).execute() save_settings(zip(request.form.keys(), request.form.listvalues())) event_stream("settings") return '', 204
def update_series(send_event=True): check_sonarr_rootfolder() apikey_sonarr = settings.sonarr.apikey if apikey_sonarr is None: return serie_default_enabled = settings.general.getboolean('serie_default_enabled') if serie_default_enabled is True: serie_default_profile = settings.general.serie_default_profile if serie_default_profile == '': serie_default_profile = None else: serie_default_profile = None audio_profiles = get_profile_list() tagsDict = get_tags() # Get shows data from Sonarr series = get_series_from_sonarr_api(url=url_sonarr(), apikey_sonarr=apikey_sonarr) if not series: return else: # Get current shows in DB current_shows_db = TableShows.select(TableShows.sonarrSeriesId).dicts() current_shows_db_list = [x['sonarrSeriesId'] for x in current_shows_db] current_shows_sonarr = [] series_to_update = [] series_to_add = [] series_count = len(series) for i, show in enumerate(series): if send_event: show_progress(id='series_progress', header='Syncing series...', name=show['title'], value=i, count=series_count) # Add shows in Sonarr to current shows list current_shows_sonarr.append(show['id']) if show['id'] in current_shows_db_list: series_to_update.append(seriesParser(show, action='update', tags_dict=tagsDict, serie_default_profile=serie_default_profile, audio_profiles=audio_profiles)) else: series_to_add.append(seriesParser(show, action='insert', tags_dict=tagsDict, serie_default_profile=serie_default_profile, audio_profiles=audio_profiles)) if send_event: hide_progress(id='series_progress') # Remove old series from DB removed_series = list(set(current_shows_db_list) - set(current_shows_sonarr)) for series in removed_series: try: TableShows.delete().where(TableShows.sonarrSeriesId == series).execute() except Exception as e: logging.error(f"BAZARR cannot delete series with sonarrSeriesId {series} because of {e}") continue else: if send_event: event_stream(type='series', action='delete', payload=series) # Update existing series in DB series_in_db_list = [] series_in_db = TableShows.select(TableShows.title, TableShows.path, TableShows.tvdbId, TableShows.sonarrSeriesId, TableShows.overview, TableShows.poster, TableShows.fanart, TableShows.audio_language, TableShows.sortTitle, TableShows.year, TableShows.alternateTitles, TableShows.tags, TableShows.seriesType, TableShows.imdbId).dicts() for item in series_in_db: series_in_db_list.append(item) series_to_update_list = [i for i in series_to_update if i not in series_in_db_list] for updated_series in series_to_update_list: try: TableShows.update(updated_series).where(TableShows.sonarrSeriesId == updated_series['sonarrSeriesId']).execute() except IntegrityError as e: logging.error(f"BAZARR cannot update series {updated_series['path']} because of {e}") continue else: if send_event: event_stream(type='series', payload=updated_series['sonarrSeriesId']) # Insert new series in DB for added_series in series_to_add: try: result = TableShows.insert(added_series).on_conflict(action='IGNORE').execute() except IntegrityError as e: logging.error(f"BAZARR cannot insert series {added_series['path']} because of {e}") continue else: if result: list_missing_subtitles(no=added_series['sonarrSeriesId']) else: logging.debug('BAZARR unable to insert this series into the database:', path_mappings.path_replace(added_series['path'])) if send_event: event_stream(type='series', action='update', payload=added_series['sonarrSeriesId']) logging.debug('BAZARR All series synced from Sonarr into database.')
def update_one_series(series_id, action): logging.debug('BAZARR syncing this specific series from Sonarr: {}'.format(series_id)) # Check if there's a row in database for this series ID existing_series = TableShows.select(TableShows.path)\ .where(TableShows.sonarrSeriesId == series_id)\ .dicts()\ .get_or_none() # Delete series from DB if action == 'deleted' and existing_series: try: TableShows.delete().where(TableShows.sonarrSeriesId == int(series_id)).execute() except Exception as e: logging.error(f"BAZARR cannot delete series with sonarrSeriesId {series_id} because of {e}") else: TableEpisodes.delete().where(TableEpisodes.sonarrSeriesId == int(series_id)).execute() event_stream(type='series', action='delete', payload=int(series_id)) return serie_default_enabled = settings.general.getboolean('serie_default_enabled') if serie_default_enabled is True: serie_default_profile = settings.general.serie_default_profile if serie_default_profile == '': serie_default_profile = None else: serie_default_profile = None audio_profiles = get_profile_list() tagsDict = get_tags() try: # Get series data from sonarr api series = None series_data = get_series_from_sonarr_api(url=url_sonarr(), apikey_sonarr=settings.sonarr.apikey, sonarr_series_id=int(series_id)) if not series_data: return else: if action == 'updated' and existing_series: series = seriesParser(series_data, action='update', tags_dict=tagsDict, serie_default_profile=serie_default_profile, audio_profiles=audio_profiles) elif action == 'updated' and not existing_series: series = seriesParser(series_data, action='insert', tags_dict=tagsDict, serie_default_profile=serie_default_profile, audio_profiles=audio_profiles) except Exception: logging.debug('BAZARR cannot parse series returned by SignalR feed.') return # Update existing series in DB if action == 'updated' and existing_series: try: TableShows.update(series).where(TableShows.sonarrSeriesId == series['sonarrSeriesId']).execute() except IntegrityError as e: logging.error(f"BAZARR cannot update series {series['path']} because of {e}") else: sync_episodes(series_id=int(series_id), send_event=True) event_stream(type='series', action='update', payload=int(series_id)) logging.debug('BAZARR updated this series into the database:{}'.format(path_mappings.path_replace( series['path']))) # Insert new series in DB elif action == 'updated' and not existing_series: try: TableShows.insert(series).on_conflict(action='IGNORE').execute() except IntegrityError as e: logging.error(f"BAZARR cannot insert series {series['path']} because of {e}") else: event_stream(type='series', action='update', payload=int(series_id)) logging.debug('BAZARR inserted this series into the database:{}'.format(path_mappings.path_replace( series['path'])))
def episodeParser(episode): if 'hasFile' in episode: if episode['hasFile'] is True: if 'episodeFile' in episode: if episode['episodeFile']['size'] > 20480: if 'sceneName' in episode['episodeFile']: sceneName = episode['episodeFile']['sceneName'] else: sceneName = None audio_language = [] if 'language' in episode['episodeFile'] and len( episode['episodeFile']['language']): item = episode['episodeFile']['language'] if isinstance(item, dict): if 'name' in item: audio_language.append(item['name']) else: audio_language = TableShows.get( TableShows.sonarrSeriesId == episode['seriesId']).audio_language if 'mediaInfo' in episode['episodeFile']: if 'videoCodec' in episode['episodeFile']['mediaInfo']: videoCodec = episode['episodeFile']['mediaInfo'][ 'videoCodec'] videoCodec = SonarrFormatVideoCodec(videoCodec) else: videoCodec = None if 'audioCodec' in episode['episodeFile']['mediaInfo']: audioCodec = episode['episodeFile']['mediaInfo'][ 'audioCodec'] audioCodec = SonarrFormatAudioCodec(audioCodec) else: audioCodec = None else: videoCodec = None audioCodec = None try: video_format, video_resolution = episode[ 'episodeFile']['quality']['quality']['name'].split( '-') except: video_format = episode['episodeFile']['quality'][ 'quality']['name'] try: video_resolution = str( episode['episodeFile']['quality']['quality'] ['resolution']) + 'p' except: video_resolution = None return { 'sonarrSeriesId': episode['seriesId'], 'sonarrEpisodeId': episode['id'], 'title': episode['title'], 'path': episode['episodeFile']['path'], 'season': episode['seasonNumber'], 'episode': episode['episodeNumber'], 'scene_name': sceneName, 'monitored': str(bool(episode['monitored'])), 'format': video_format, 'resolution': video_resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, 'episode_file_id': episode['episodeFile']['id'], 'audio_language': str(audio_language), 'file_size': episode['episodeFile']['size'] }
def sync_episodes(): notifications.write(msg='Episodes sync from Sonarr started...', queue='get_episodes') logging.debug('BAZARR Starting episodes sync from Sonarr.') apikey_sonarr = settings.sonarr.apikey # Get current episodes id in DB current_episodes_db = TableEpisodes.select(TableEpisodes.sonarr_episode_id, TableEpisodes.path, TableEpisodes.sonarr_series_id) current_episodes_db_list = [ x.sonarr_episode_id for x in current_episodes_db ] current_episodes_sonarr = [] episodes_to_update = [] episodes_to_add = [] altered_episodes = [] # Get sonarrId for each series from database seriesIdList = TableShows.select(TableShows.sonarr_series_id, TableShows.title) seriesIdListLength = seriesIdList.count() for i, seriesId in enumerate(seriesIdList, 1): notifications.write(msg='Getting episodes data from Sonarr...', queue='get_episodes', item=i, length=seriesIdListLength) # Get episodes data for a series from Sonarr url_sonarr_api_episode = url_sonarr + "/api/episode?seriesId=" + str( seriesId.sonarr_series_id) + "&apikey=" + apikey_sonarr try: r = requests.get(url_sonarr_api_episode, timeout=60, verify=False) r.raise_for_status() except requests.exceptions.HTTPError as errh: logging.exception( "BAZARR Error trying to get episodes from Sonarr. Http error.") return except requests.exceptions.ConnectionError as errc: logging.exception( "BAZARR Error trying to get episodes from Sonarr. Connection Error." ) return except requests.exceptions.Timeout as errt: logging.exception( "BAZARR Error trying to get episodes from Sonarr. Timeout Error." ) return except requests.exceptions.RequestException as err: logging.exception( "BAZARR Error trying to get episodes from Sonarr.") return else: for episode in r.json(): if 'hasFile' in episode: if episode['hasFile'] is True: if 'episodeFile' in episode: if episode['episodeFile']['size'] > 20480: # Add shows in Sonarr to current shows list if 'sceneName' in episode['episodeFile']: sceneName = episode['episodeFile'][ 'sceneName'] else: sceneName = None try: format, resolution = episode[ 'episodeFile']['quality']['quality'][ 'name'].split('-') except: format = episode['episodeFile']['quality'][ 'quality']['name'] try: resolution = str( episode['episodeFile']['quality'] ['quality']['resolution']) + 'p' except: resolution = None if 'mediaInfo' in episode['episodeFile']: if 'videoCodec' in episode['episodeFile'][ 'mediaInfo']: videoCodec = episode['episodeFile'][ 'mediaInfo']['videoCodec'] videoCodec = SonarrFormatVideoCodec( videoCodec) else: videoCodec = None if 'audioCodec' in episode['episodeFile'][ 'mediaInfo']: audioCodec = episode['episodeFile'][ 'mediaInfo']['audioCodec'] audioCodec = SonarrFormatAudioCodec( audioCodec) else: audioCodec = None else: videoCodec = None audioCodec = None # Add episodes in sonarr to current episode list current_episodes_sonarr.append(episode['id']) if episode['id'] in current_episodes_db_list: episodes_to_update.append({ 'sonarr_series_id': episode['seriesId'], 'sonarr_episode_id': episode['id'], 'title': episode['title'], 'path': episode['episodeFile']['path'], 'season': episode['seasonNumber'], 'episode': episode['episodeNumber'], 'scene_name': sceneName, 'monitored': str(bool(episode['monitored'])), 'format': format, 'resolution': resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, 'episode_file_id': episode['episodeFile']['id'] }) else: episodes_to_add.append({ 'sonarr_series_id': episode['seriesId'], 'sonarr_episode_id': episode['id'], 'title': episode['title'], 'path': episode['episodeFile']['path'], 'season': episode['seasonNumber'], 'episode': episode['episodeNumber'], 'scene_name': sceneName, 'monitored': str(bool(episode['monitored'])), 'format': format, 'resolution': resolution, 'video_codec': videoCodec, 'audio_codec': audioCodec, 'episode_file_id': episode['episodeFile']['id'] }) # Update existing episodes in DB episode_in_db_list = [] episodes_in_db = TableEpisodes.select( TableEpisodes.sonarr_series_id, TableEpisodes.sonarr_episode_id, TableEpisodes.title, TableEpisodes.path, TableEpisodes.season, TableEpisodes.episode, TableEpisodes.scene_name, TableEpisodes.monitored, TableEpisodes.format, TableEpisodes.resolution, TableEpisodes.video_codec, TableEpisodes.audio_codec, TableEpisodes.episode_file_id).dicts() for item in episodes_in_db: episode_in_db_list.append(item) episodes_to_update_list = [ i for i in episodes_to_update if i not in episode_in_db_list ] for updated_episode in episodes_to_update_list: TableEpisodes.update(updated_episode).where( TableEpisodes.sonarr_episode_id == updated_episode['sonarr_episode_id']).execute() altered_episodes.append([ updated_episode['sonarr_episode_id'], updated_episode['path'], updated_episode['sonarr_series_id'] ]) # Insert new episodes in DB for added_episode in episodes_to_add: TableEpisodes.insert(added_episode).on_conflict_ignore().execute() altered_episodes.append([ added_episode['sonarr_episode_id'], added_episode['path'], added_episode['sonarr_series_id'] ]) # Remove old episodes from DB removed_episodes = list( set(current_episodes_db_list) - set(current_episodes_sonarr)) for removed_episode in removed_episodes: TableEpisodes.delete().where( TableEpisodes.sonarr_episode_id == removed_episode).execute() # Store subtitles for added or modified episodes for i, altered_episode in enumerate(altered_episodes, 1): notifications.write(msg='Indexing episodes embedded subtitles...', queue='get_episodes', item=i, length=len(altered_episodes)) store_subtitles(path_replace(altered_episode[1])) list_missing_subtitles(altered_episode[2]) logging.debug('BAZARR All episodes synced from Sonarr into database.') # Search for desired subtitles if no more than 5 episodes have been added. if len(altered_episodes) <= 5: logging.debug( "BAZARR No more than 5 episodes were added during this sync then we'll search for subtitles." ) for altered_episode in altered_episodes: episode_download_subtitles(altered_episode[0]) else: logging.debug( "BAZARR More than 5 episodes were added during this sync then we wont search for subtitles right now." )
def get_series_name(sonarrSeriesId): data = TableShows.select(TableShows.title).where( TableShows.sonarr_series_id == sonarrSeriesId).first() return data.title
def update_series(): notifications.write(msg="Update series list from Sonarr is running...", queue='get_series') apikey_sonarr = settings.sonarr.apikey sonarr_version = get_sonarr_version() serie_default_enabled = settings.general.getboolean('serie_default_enabled') serie_default_language = settings.general.serie_default_language serie_default_hi = settings.general.serie_default_hi serie_default_forced = settings.general.serie_default_forced if apikey_sonarr is None: pass else: audio_profiles = get_profile_list() # Get shows data from Sonarr url_sonarr_api_series = url_sonarr + "/api/series?apikey=" + apikey_sonarr try: r = requests.get(url_sonarr_api_series, timeout=60, verify=False) r.raise_for_status() except requests.exceptions.HTTPError as errh: logging.exception("BAZARR Error trying to get series from Sonarr. Http error.") return except requests.exceptions.ConnectionError as errc: logging.exception("BAZARR Error trying to get series from Sonarr. Connection Error.") return except requests.exceptions.Timeout as errt: logging.exception("BAZARR Error trying to get series from Sonarr. Timeout Error.") return except requests.exceptions.RequestException as err: logging.exception("BAZARR Error trying to get series from Sonarr.") return else: # Get current shows in DB current_shows_db = TableShows.select( TableShows.tvdb_id ) current_shows_db_list = [x.tvdb_id for x in current_shows_db] current_shows_sonarr = [] series_to_update = [] series_to_add = [] altered_series = [] seriesListLength = len(r.json()) for i, show in enumerate(r.json(), 1): notifications.write(msg="Getting series data from Sonarr...", queue='get_series', item=i, length=seriesListLength) try: overview = unicode(show['overview']) except: overview = "" try: poster_big = show['images'][2]['url'].split('?')[0] poster = os.path.splitext(poster_big)[0] + '-250' + os.path.splitext(poster_big)[1] except: poster = "" try: fanart = show['images'][0]['url'].split('?')[0] except: fanart = "" if show['alternateTitles'] != None: alternateTitles = str([item['title'] for item in show['alternateTitles']]) else: alternateTitles = None # Add shows in Sonarr to current shows list current_shows_sonarr.append(show['tvdbId']) if show['tvdbId'] in current_shows_db_list: series_to_update.append({'title': unicode(show["title"]), 'path': unicode(show["path"]), 'tvdb_id': int(show["tvdbId"]), 'sonarr_series_id': int(show["id"]), 'overview': unicode(overview), 'poster': unicode(poster), 'fanart': unicode(fanart), 'audio_language': unicode(profile_id_to_language((show['qualityProfileId'] if sonarr_version.startswith('2') else show['languageProfileId']), audio_profiles)), 'sort_title': unicode(show['sortTitle']), 'year': unicode(show['year']), 'alternate_titles': unicode(alternateTitles)}) else: if serie_default_enabled is True: series_to_add.append({'title': show["title"], 'path': show["path"], 'tvdb_id': show["tvdbId"], 'languages': serie_default_language, 'hearing_impaired': serie_default_hi, 'sonarr_series_id': show["id"], 'overview': overview, 'poster': poster, 'fanart': fanart, 'audio_language': profile_id_to_language((show['qualityProfileId'] if sonarr_version.startswith('2') else show['languageProfileId']), audio_profiles), 'sort_title': show['sortTitle'], 'year': show['year'], 'alternate_titles': alternateTitles, 'forced': serie_default_forced}) else: series_to_add.append({'title': show["title"], 'path': show["path"], 'tvdb_id': show["tvdbId"], 'sonarr_series_id': show["id"], 'overview': overview, 'poster': poster, 'fanart': fanart, 'audio_language': profile_id_to_language((show['qualityProfileId'] if sonarr_version.startswith('2') else show['languageProfileId']), audio_profiles), 'sort_title': show['sortTitle'], 'year': show['year'], 'alternate_titles': alternateTitles}) # Update existing series in DB series_in_db_list = [] series_in_db = TableShows.select( TableShows.title, TableShows.path, TableShows.tvdb_id, TableShows.sonarr_series_id, TableShows.overview, TableShows.poster, TableShows.fanart, TableShows.audio_language, TableShows.sort_title, TableShows.year, TableShows.alternate_titles ).dicts() for item in series_in_db: series_in_db_list.append(item) series_to_update_list = [i for i in series_to_update if i not in series_in_db_list] for updated_series in series_to_update_list: TableShows.update( updated_series ).where( TableShows.sonarr_series_id == updated_series['sonarr_series_id'] ).execute() # Insert new series in DB for added_series in series_to_add: TableShows.insert( added_series ).on_conflict_ignore().execute() list_missing_subtitles(added_series['sonarr_series_id']) # Remove old series from DB removed_series = list(set(current_shows_db_list) - set(current_shows_sonarr)) for series in removed_series: TableShows.delete().where( TableShows.tvdb_id == series ).execute() logging.debug('BAZARR All series synced from Sonarr into database.')