def addMultipleSeasonToMediaList(params): name = name_orig = params.get('name') url = params.get('url') selectAction = ['Continue with original Title: {0}'.format(name_orig), 'Rename Title', 'Get Title from Medialist'] if not fileSys.writeTutList('select:Rename'): tutWin = ['Adding content to your library', 'You can rename your Movie, TV-Show or Music title.', 'To make your scraper recognize the content, some times it is necessary to rename the title.', 'Be careful, wrong title can also cause that your scraper can\'t recognize your content.'] xbmcgui.Dialog().ok(tutWin[0], tutWin[1], tutWin[2], tutWin[3]) choice = guiTools.selectDialog('Title for MediaList entry: {0}'.format(name_orig), selectAction) if choice != -1: cType = None if name: name = stringUtils.cleanLabels(name) if choice == 1 or name == None or name == '': name = guiTools.editDialog(name).strip() name = '{0}++RenamedTitle++'.format(name) if name else name if choice == 2: item = guiTools.mediaListDialog(False, False, header_prefix='Get Title from Medialist for {0}'.format(name_orig), preselect_name=name, cTypeFilter='TV-Shows') splits = item.get('entry').split('|') if item else None name = splits[1] if splits else None cType = splits[0] if splits else None utils.addon_log_notice('addMultipleSeasonToMediaList: name = {0}, cType = {1}'.format(name, cType)) if name: if not cType: cType = guiTools.getTypeLangOnly('TV-Shows') if cType != -1: details = jsonUtils.requestList(url, 'video').get('files', []) retry_count = 1 while len(details) == 0 and retry_count <= 3: utils.addon_log('requestList: try={0} data = {1})'.format(retry_count, details)) details = jsonUtils.requestList(url, 'video').get('files', []) retry_count = retry_count + 1 seasonList = [] for detail in details: file = detail['file'].replace('\\\\', '\\') filetype = detail['filetype'] label = detail['label'] if label.find('COLOR') != -1: label = stringUtils.cleanLabels(label) + ' (*)' showtitle = detail['showtitle'] name_orig = '{0} - {1}'.format(showtitle, label) if filetype == 'directory': seasonList.append({'label': label, 'name': name, 'name_orig': name_orig, 'url': file, 'cType': cType, 'noninteractive': True}) sItems = sorted([item.get('label') for item in seasonList], key=lambda k: utils.key_natural_sort(k.lower())) preselect = [i for i, item in enumerate(sItems) if item.find(' (*)') == -1] selectedItemsIndex = guiTools.selectDialog('Select Seasons to add for {0}'.format(showtitle), sItems, multiselect=True, preselect=preselect) seasonList = [item for item in seasonList for index in selectedItemsIndex if item.get('label') == sItems[index]] if selectedItemsIndex and len(selectedItemsIndex) > 0 else None utils.addon_log_notice('addMultipleSeasonToMediaList: seasonList = {0}'.format(seasonList)) if seasonList and len(seasonList) > 0: for season in seasonList: addToMedialist(season)
def getEpisodeDataFromTVDB(showid, lang): utils.addon_log_notice( 'getEpisodeDataFromTVDB: showid = {0}, lang = {1}'.format( showid, lang)) page = 1 maxpages = 1 json_data = [] while page and maxpages and page <= maxpages: params = {'page': page} path = 'series/{0}/episodes/query'.format(showid) res_ep = getJsonFromTVDB(api_baseurl.format(path), lang, params) json_ep = res_ep.json() if res_ep.status_code == 200 and len(json_ep.get('data', {})) > 0: page = json_ep.get('links').get('next') maxpages = json_ep.get('links').get('last') json_data = json_data + json_ep.get('data') else: break return json_data
def renameMediaListEntry(selectedItems): for item in selectedItems: splits = item.get('entry').split('|') cType = splits[0] name_old = stringUtils.getStrmname(splits[1]) choice = 1 if cType.find('TV-Shows') != -1: selectAction = ['Get Title from TVDB', 'Enter new Title'] choice = guiTools.selectDialog('Rename MediaList entry: {0}'.format(name_old), selectAction) if choice != -1: if choice == 1: name = guiTools.editDialog(name_old).strip() name = '{0}++RenamedTitle++'.format(name) if name else name elif choice == 0: show_data = tvdb.getShowByName(name_old, re.sub('TV-Shows\((.*)\)', r'\g<1>', cType)) if show_data: name = show_data.get('seriesName', name_old) if name and name_old != name: utils.addon_log_notice('renameMediaListEntry: Use new name \'{0}\' for \'{1}\''.format(name, name_old)) item['name_new'] = name removeAndReadMedialistEntry([item])
def removeShowsFromTVDBCache(selectedItems=None): if not selectedItems and not xbmcgui.Dialog().yesno( 'Remove all Shows from TVDB cache', 'Are you sure to delete all shows from cache?'): return delete_type = xbmcgui.Dialog( ).select('Which data should be deleted from cache?', [ 'all cached data for show (includes automatched and user entries for episodes)', 'automatched entries for episodes', 'user entries for episode', 'automatched and user entries for episodes', ], preselect=1) if xbmcvfs.exists(MediaList_LOC): thelist = fileSys.readMediaList() items = selectedItems if selectedItems else [{ 'entry': item } for item in thelist] if len(items) > 0: splittedEntries = [] if not selectedItems: for item in items: splits = item.get('entry').split('|') splittedEntries.append(splits) else: splittedEntries = [ item.get('entry').split('|') for item in selectedItems ] for splittedEntry in splittedEntries: cType, name = splittedEntry[0], stringUtils.getStrmname( splittedEntry[1]) if re.findall('TV-Shows', cType): show_data = getTVShowFromCache(name) if show_data: tvdb_id = show_data.get('id') if delete_type in [0, 1, 3]: utils.addon_log_notice( 'tvdb: Delete automatched episode entries from cache for \'{0}\'' .format(name)) deleteEpisodeFromCache('%', '%', tvdb_id, user_entry=False) if delete_type in [0, 2, 3]: utils.addon_log_notice( 'tvdb: Delete user episode entries from cache for \'{0}\'' .format(name)) deleteEpisodeFromCache('%', '%', tvdb_id, user_entry=True) if delete_type == 0: utils.addon_log_notice( 'tvdb: Delete TVDB data from cache for \'{0}\'' .format(name)) deleteTVShowFromCache(name)
def findEpisodeByName(show_data, episodeSeason, episodeNr, episodeName, lang, silent=False, fallback_en=False): utils.addon_log( 'tvdb findEpisodeByName: show_data = {0}'.format(show_data)) showid = show_data.get('id') showname = show_data.get('seriesName') utils.addon_log_notice( 'tvdb findEpisodeByName: \'{0}\'; showname = \'{1}\', showid = {2}, lang = {3}' .format(episodeName, showname, showid, lang)) episode_data = getEpisodeFromCache(episodeSeason, episodeName, showid) if episode_data and episode_data.get( 'user_entry') == True and CONFIRM_USER_ENTRIES == 'true': if silent == False and fallback_en == False: confirmed = xbmcgui.Dialog().yesno( 'Confirm user entry for {0} is correct?'.format(showname), 'S{0:02d}E{1:02d} - {2}'.format(episodeSeason, episodeNr, episodeName), 'User Entry: S{0:02d}E{1:02d} - {2}'.format( episode_data.get('season'), episode_data.get('episode'), episode_data.get('episodeName', None)), autoclose=dialog_autoclose_time * 1000) if confirmed == False: episode_data = None else: episode_data = None if episode_data is None: ratio_max = 0 ratio_max2 = 100 ratio_max_season = -1 ratio_max_episode = -1 episodeListData = [] episodeListDialog = [] episodecount = 0 episodecountcurrentseason = 0 preselected = None json_data = cache.getTvdbDataCache().cacheFunction( getEpisodeDataFromTVDB, showid, lang) json_data = sorted( json_data, key=lambda x: (x['airedSeason'] == 0, x['airedSeason'] != episodeSeason or x[ 'airedEpisodeNumber'] != episodeNr, x['airedSeason'] != episodeSeason, x['airedSeason'], x['airedEpisodeNumber'])) dictresubList = [] regex_match_start = '([ \.,:;\(]+|^)' regex_match_end = '(?=[ \.,:;\)]+|$)' dictresubList.append({ ' *(?:-|\(|:)* *(?:[tT]eil|[pP]art|[pP]t\.) (\d+|\w+)\)*': r' (\g<1>)', ' *(?:-|\(|:)* *(?:[tT]eil 1 und 2|[pP]art[s]* 1 (&|and) 2)': ' (1)', }) dictresubList.append({ ' *(?:-|\(|:)* *(?:[tT]eil|[pP]art|[pP]t\.) (\d+|\w+)\)*': r' (\g<1>)', ' *(?:-|\(|:)* *(?:[tT]eil 1 und 2|[pP]art[s]* 1 (&|and) 2)': ' (1)', '[\s:;\.]\([\w\d\. ]*\)[\s:;\.]': ' ', }) dictresubList.append({ ' *(?:-|\(|:)* *(?:[tT]eil|[pP]art|[pP]t\.) (\d+|\w+)\)*': r' (\g<1>)', ' *(?:-|\(|:)* *(?:[tT]eil 1 und 2|[pP]art[s]* 1 (&|and) 2)': ' (1)', '[\s:;\.]\([\w\d\. ]*\)$': ' ', }) dictresubList.append({ ' *(?:-|\(|:)* *(?:[tT]eil|[pP]art|[pP]t\.) (\d+|\w+)\)*': r' (\g<1>)', ' *(?:-|\(|:)* *(?:[tT]eil 1 und 2|[pP]art[s]* 1 (&|and) 2)': ' (1)', '[\w\s\']{8,}\Z[:;] ([\w\s\']{8,}\Z)': '\g<1>', }) dictresubList.append({ '[pP]art [oO]ne': 'Part (1)', '[pP]art [tT]wo': 'Part (2)', }) dictresubList.append({ '[pP]art [oO]ne': '(1)', '[pP]art [tT]wo': '(2)', }) dictresubList.append({ '[pP]art 1': 'part one', '[pP]art 2': 'part two', }) dictresubList.append({ '{0}[eE]ins{1}'.format(regex_match_start, regex_match_end): r'\g<1>1', '{0}[zW]wei{1}'.format(regex_match_start, regex_match_end): r'\g<1>2', '{0}[dD]drei{1}'.format(regex_match_start, regex_match_end): r'\g<1>3', }) dictresubList.append({ '{0}[oO]ne{1}'.format(regex_match_start, regex_match_end): '\g<1>1', '{0}[tT]wo{1}'.format(regex_match_start, regex_match_end): '\g<1>2', '{0}[tT]hree{1}'.format(regex_match_start, regex_match_end): '\g<1>3', }) dictresubList.append({ '{0}1{1}'.format(regex_match_start, regex_match_end): r'\g<1>eins', '{0}2{1}'.format(regex_match_start, regex_match_end): r'\g<1>zwei', '{0}3{1}'.format(regex_match_start, regex_match_end): r'\g<1>drei', }) dictresubList.append({ '{0}1{1}'.format(regex_match_start, regex_match_end): r'\g<1>one', '{0}2{1}'.format(regex_match_start, regex_match_end): r'\g<1>two', '{0}3{1}'.format(regex_match_start, regex_match_end): r'\g<1>thre', }) epNames = {episodeName} for dictresub in dictresubList: utils.addon_log('dictresub = {0}'.format(dictresub)) epNames.add(utils.multiple_reSub(episodeName, dictresub)) epNames_split = list(filter(None, re.split(' / | , ', episodeName))) if epNames_split[0] != episodeName: epNames.add(epNames_split[0]) utils.addon_log( 'tvdb findEpisodeByName: epNames = {0}'.format(epNames)) delta_selected = 2 ListItem = xbmcgui.ListItem() ListItem.setLabel('Ignore') ListItem.setLabel2('This episode will not be exported') episodeListDialog.append(ListItem) ListItem = xbmcgui.ListItem() ListItem.setLabel('Enter manually') ListItem.setLabel2('Enter season and episode number') episodeListDialog.append(ListItem) if lang != 'en': ListItem = xbmcgui.ListItem() ListItem.setLabel('Try english') ListItem.setLabel2( 'Search TVDB again with language set to english') episodeListDialog.append(ListItem) delta_selected = 3 for episode in json_data: utils.addon_log( 'tvdb findEpisodeByName: episode = {0}'.format(episode)) ListItem = xbmcgui.ListItem() ListItem.setLabel('S{0:02d}E{1:02d} - {2}'.format( episode.get('airedSeason'), episode.get('airedEpisodeNumber'), episode.get('episodeName', episodeName))) ListItem.setLabel2(episode.get('overview')) episodeListDialog.append(ListItem) episodeListData.append({ 'season': episode.get('airedSeason'), 'episode': episode.get('airedEpisodeNumber'), 'episodeName': episode.get('episodeName'), 'match_ratio': -1 }) if episode.get('airedEpisodeNumber') == episodeNr and episode.get( 'airedSeason') == episodeSeason: preselected = episodecount episodecount = episodecount + 1 for epName in epNames: if use_fuzzy_matching == True: if episode.get('episodeName', None): episodeNameTVDB = episode.get('episodeName').lower() epNameL = epName.lower() if re.sub('( |:|,|\.)', '', episodeNameTVDB) == re.sub( '( |:|,|\.)', '', epNameL): ratio1 = 100 ratio2 = 100 ratio3 = 100 ratio4 = 100 else: ratio1 = fuzz.token_sort_ratio( re.sub('(:|,|\.)', '', episodeNameTVDB), re.sub('(:|,|\.)', '', epNameL)) ratio2 = fuzz.token_sort_ratio( re.sub('( |:|,|\.)', '', episodeNameTVDB), re.sub('( |:|,|\.)', '', epNameL)) ratio3 = fuzz.token_set_ratio( episodeNameTVDB, epNameL) ratio4 = fuzz.partial_ratio( re.sub('(:|,|\.)', '', episodeNameTVDB), re.sub('(:|,|\.)', '', epNameL)) if min(len(episodeNameTVDB), len(epNameL)) < 6: ratio = (ratio1 + ratio2) / 2.0 else: ratio = (ratio1 + ratio2 + ratio3 + ratio4) / 4.0 if episodeSeason != episode.get('airedSeason'): if episode.get('airedSeason') == 0: ratio = 0.72 * ratio else: ratio = 0.80 * ratio utils.addon_log( 'tvdb ratio: \'{0}\'; \'{1}\' (TVDB); ratio={2:0.1f} ({3:0.1f} {4:0.1f} {5:0.1f} {6:%0.1f})' .format(epName, episode.get('episodeName'), ratio, ratio1, ratio2, ratio3, ratio4)) if ratio > ratio_max: if ratio_max > 0 and not ( ratio_max_season == episode.get('airedSeason') and ratio_max_episode == episode.get('airedEpisodeNumber')): ratio_max2 = ratio_max ratio_max = ratio ratio_max_season = episode.get('airedSeason') ratio_max_episode = episode.get( 'airedEpisodeNumber') episode_data = { 'season': episode.get('airedSeason'), 'episode': episode.get('airedEpisodeNumber'), 'episodeName': episode.get('episodeName'), 'match_ratio': ratio } else: if (ratio_max2 == 100 or ratio_max2 < ratio) and not ( ratio_max_season == episode.get('airedSeason') and ratio_max_episode == episode.get('airedEpisodeNumber')): ratio_max2 = max(ratio, 0.1) if ratio_max > 99.0: break else: if episode.get('episodeName', None) and ( episode.get('episodeName').lower().replace( ' ', '').find(epName.lower().replace(' ', '')) >= 0 or epName.lower().replace(' ', '').find( episode.get('episodeName').lower().replace( ' ', '')) >= 0): if episodeSeason == episode.get('airedSeason'): ratio_max = 99.5 else: ratio_max = 80 episode_data = { 'season': episode.get('airedSeason'), 'episode': episode.get('airedEpisodeNumber'), 'episodeName': episode.get('episodeName'), 'match_ratio': ratio_max } setEpisodeCache(episodeSeason, episodeName, showid, episode_data, user_entry=False) if ratio_max > 99.0: break match_found = False match_userentry = False if ratio_max >= 95 or (use_fuzzy_matching == False and ratio_max >= 80): match_found = True elif ((ratio_max >= 85 and ratio_max / ratio_max2 >= 1.05) or (ratio_max >= 75 and ratio_max / ratio_max2 >= 1.15) or (ratio_max >= 68 and ratio_max / ratio_max2 >= 1.48)): match_found = True else: utils.addon_log( 'tvdb \'{0}\' \'{1}\'; ratio={2:0.1f} (ratio2={3:0.1f}) [{4:0.1f}]' .format(showname, episodeName, ratio_max, ratio_max2, ratio_max / ratio_max2)) match_found_fallback_en = False if match_found == False and lang != 'en': episode_data_en = findEpisodeByName(show_data, episodeSeason, episodeNr, episodeName, 'en', silent=True, fallback_en=True) if episode_data_en: episode_data = episode_data_en match_found = True match_found_fallback_en = True # if match_found == False and silent == False and ratio_max >= 60 and ratio_max/ratio_max2 > 1.05: # match_found = xbmcgui.Dialog().yesno('Match for {0}?'.format(showname), # 'from Addon: \'S{0:02d}E{1:02d} - {2}\''.format( episodeSeason, episodeNr, episodeName), # 'TVDB: \'S{0:02d}E{1:02d} - {2}\''.format(episode_data.get('season'), episode_data.get('episode'), episode_data.get('episodeName')), # 'ratio = {0:0.1f} ({1:0.1f}) [{2:0.1f}]'.format(ratio_max, ratio_max2, ratio_max/ratio_max2), # autoclose = dialog_autoclose_time*1000 ) if match_found == True: match_userentry = True if match_found == False and silent == False: dialog = xbmcgui.Dialog() time1 = time.time() selected = dialog.select( 'No match found for {0}: \'S{1:02d}E{2:02d} - {3}\''.format( showname, episodeSeason, episodeNr, episodeName), episodeListDialog, useDetails=True, autoclose=dialog_autoclose_time * 1000, preselect=int(0 if preselected is None else preselected + delta_selected)) time2 = time.time() if dialog_autoclose_time > 0 and int( time2 - time1) >= dialog_autoclose_time: selected = -1 if selected >= delta_selected and selected < episodecount + delta_selected: episode_data = episodeListData[selected - delta_selected] match_found = True match_userentry = True elif selected == 1: try: season_input = int( dialog.numeric( 0, 'Season for \'{0}\': \'S{1:02d}E{2:02d} - {3}\''. format(showname, episodeSeason, episodeNr, episodeName), str(episodeSeason))) episode_input = int( dialog.numeric( 0, 'Episode for \'{0}\': \'S{1:02d}E{2:02d} - {3}\''. format(showname, episodeSeason, episodeNr, episodeName), str(episodeNr))) episode_data = { 'season': season_input, 'episode': episode_input, 'episodeName': episodeName, 'match_ratio': -1 } setEpisodeCache(episodeSeason, episodeName, showid, episode_data, user_entry=True) match_found = True match_userentry = True except: pass elif lang != 'en' and selected == 2: episode_data_en = findEpisodeByName(show_data, episodeSeason, episodeNr, episodeName, 'en', fallback_en=True) if episode_data_en: episode_data = episode_data_en match_found = True match_found_fallback_en = True elif selected == 0: episode_data = { 'season': episodeSeason, 'episode': episodeNr, 'episodeName': episodeName, 'ignore': True } setEpisodeCache(episodeSeason, episodeName, showid, episode_data, user_entry=True) utils.addon_log_notice( 'tvdb findEpisodeByName: ignore episodeName = \'{0}\'; lang = {1}' .format(episodeName, lang)) if match_found == True: if match_found_fallback_en != True: setEpisodeCache(episodeSeason, episodeName, showid, episode_data, user_entry=match_userentry) utils.addon_log_notice( 'tvdb findEpisodeByName: \'{0}\' <-> \'{1}\' (TVDB); lang={2}; ratio={3:0.2f}' .format(episodeName, episode_data.get('episodeName'), lang, episode_data.get('match_ratio'))) else: episode_data = None utils.addon_log_notice( 'tvdb findEpisodeByName: could not match episodeName = \'{0}\'; lang = {1}' .format(episodeName, lang)) if episode_data and episode_data.get('ignore', False): return None return episode_data
def getTVShowFromList(showList, strm_name='', strm_type='Other', pagesDone=0, name_orig=None): dirList = [] episodesList = [] lang = None if strm_type.lower().find('other') == -1: lang = strm_type[strm_type.find('(') + 1:strm_type.find(')')] showtitle = stringUtils.getStrmname(strm_name) while pagesDone < int(PAGINGTVshows): strm_type = strm_type.replace('Shows-Collection', 'TV-Shows') for detailInfo in showList: filetype = detailInfo.get('filetype', None) file = detailInfo.get('file', None) if filetype: if filetype == 'directory': retry_count = 1 json_reply = jsonUtils.requestList(file, 'video').get('files', []) while len(json_reply) == 0 and retry_count <= 3: utils.addon_log('requestList: try={0} data = {1})'.format(retry_count, json_reply)) json_reply = jsonUtils.requestList(file, 'video').get('files', []) retry_count = retry_count + 1 dirList.append(json_reply) continue elif filetype == 'file': episodetitle = detailInfo.get('title') episodeseason = detailInfo.get('season', -1) episode = detailInfo.get('episode', -1) if (SEARCH_THETVDB == 2 or (SEARCH_THETVDB == 1 and (episodeseason == -1 or episode == -1))): if showtitle and showtitle != '' and episodetitle and episodetitle != '': eptitle = episodetitle eptitle = eptitle.replace('\u201e', '\'') eptitle = eptitle.replace('\u201c', '\'') eptitle = eptitle.replace('\u2013', '-') utils.addon_log_notice('search tvdb for \'{0}\': \'S{1:02d}E{2:02d} - {3}\' (lang={4})'.format(showtitle, episodeseason, episode, eptitle, lang)) data = tvdb.getEpisodeByName(showtitle, episodeseason, episode, eptitle, lang) if data: detailInfo['season'] = data.get('season') detailInfo['episode'] = data.get('episode') detailInfo['episodeName'] = data.get('episodeName', None) utils.addon_log_notice('found tvdb entry for \'{0}\': \'S{1:02d}E{2:02d} - {3}\' matched to \'S{4:02d}E{5:02d} - {6}\'' .format(showtitle, episodeseason, episode, episodetitle, detailInfo['season'], detailInfo['episode'], detailInfo['episodeName'])) else: detailInfo['season'] = -1 detailInfo['episode'] = -1 utils.addon_log_notice('no tvdb entry found for \'{0}\': \'S{1:02d}E{2:02d} - {3}\'' .format(showtitle, episodeseason, episode, episodetitle)) get_title_with_OV = True if HIDE_title_in_OV == 'true': label = detailInfo.get('label').strip() if detailInfo.get('label', None) else None label = stringUtils.cleanLabels(label) if re.search('(\WOV\W)', label): get_title_with_OV = False if detailInfo.get('season', -1) > -1 and detailInfo.get('episode', -1) > -1: if NOE0_STRMS_EXPORT == 'false' or detailInfo.get('episode') > 0 and get_title_with_OV == True: if episodetitle.find('Teil 1 und 2') >= 0 or episodetitle.find('Parts 1 & 2') >= 0 : utils.addon_log_notice('found tvdb entry for \'{0}\': \'S{1:02d}E{2:02d} - {3}\' (multi) matched to \'S{4:02d}E{5:02d} - {6}\'' .format(showtitle, episodeseason, episode, episodetitle, detailInfo['season'], detailInfo['episode'], detailInfo['episodeName'])) data = tvdb.getEpisodeByName(showtitle, episodeseason, episode + 1, re.sub('(Teil 1 und 2|Parts 1 & 2)', '(2)', eptitle), lang) if data: utils.addon_log_notice('found tvdb entry for \'{0}\': \'S{1:02d}E{2:02d} - {3}\' (multi) matched to \'S{4:02d}E{5:02d} - {6}\'' .format(showtitle, episodeseason, episode, episodetitle, detailInfo['season'], detailInfo['episode'] + 1, data.get('episodeName', None))) detailInfo['multi_episode'] = True detailInfo['episode'] = [detailInfo['episode'], detailInfo['episode'] + 1] episodetitles = list(filter(None, re.split(' / | , ', episodetitle))) if episodetitles[0] != episodetitle and not re.search(' *(-|\(|:)* *([tT]eil|[pP]art|[pP]t\.) (\d+|\w+)\)*', episodetitle): utils.addon_log_notice('check multi episode \'{0}\': \'S{1:02d}E{2:02d} - {3}\''.format(showtitle, episodeseason, episode, episodetitle)) seasonm = [] episodem = [] episodeNamem = [] for e, eptitle in enumerate(episodetitles): data = tvdb.getEpisodeByName(showtitle, episodeseason, episode, eptitle, lang) if data: seasonm.append(data.get('season')) episodem.append(data.get('episode')) episodeNamem.append(data.get('episodeName')) if all(x == seasonm[0] for x in seasonm) and len(set(episodem)) == len(episodetitles): detailInfo['multi_episode'] = True detailInfo['episode'] = episodem for e, ep in enumerate(episodem): utils.addon_log_notice('found tvdb entry for \'{0}\': \'S{1:02d}E{2:02d} - {3}\' (multi) matched to \'S{4:02d}E{5:02d} - {6}\'' .format(showtitle, episodeseason, episode, episodetitle, detailInfo['season'], episodem[e], episodeNamem[e])) episodesList.append(detailInfo) step = float(100.0 / len(episodesList) if len(episodesList) > 0 else 1) if pagesDone == 0: thisDialog.dialogeBG.update(int(step), 'Initialisation of TV-Shows: {0}'.format(stringUtils.getStrmname(strm_name))) else: thisDialog.dialogeBG.update(int(step), 'Page: {0} {1}'.format(pagesDone, stringUtils.getStrmname(strm_name))) split_episode = 0 for index, episode in enumerate(episodesList): if index > 0: if season_prev == episode.get('season') and episode_prev == episode.get('episode'): episodesList[index - 1]['split_episode'] = split_episode + 1 episodesList[index]['split_episode'] = split_episode + 2 split_episode = split_episode + 1 else: if split_episode > 0: split_episode_names = [] for s in range(0, split_episode + 1): split_episode_names.insert(0, episodesList[index - s - 1]['title']) utils.addon_log_notice('Split Episode for {0}: \'{1}\' matched to \'S{2:02d}E{3:02d} - {4}\'' .format(showtitle, ', '.join(split_episode_names), episodesList[index - split_episode].get('season', None), episodesList[index - split_episode].get('episode', None), episodesList[index - split_episode].get('episodeName', None))) split_episode = 0 episodesList[index]['showtitle'] = showtitle season_prev = episode.get('season') episode_prev = episode.get('episode') for index, episode in enumerate(episodesList): pagesDone = getEpisode(episode, strm_name, strm_type, pagesDone=pagesDone, name_orig=name_orig) thisDialog.dialogeBG.update(int(step * (index + 1))) pagesDone += 1 episodesList = [] showList = [] if pagesDone < int(PAGINGTVshows) and len(dirList) > 0: showList = [item for sublist in dirList for item in sublist] dirList = []
def addToMedialist(params): name = name_orig = params.get('name') # A dialog to rename the Change Title for Folder and MediaList entry: if params.get('noninteractive', False) == False: name = re.sub('( - |, )*([sS](taffel|eason|erie[s]{0,1})|[pP]art|[tT]eil) \d+', '', name_orig) if name != name_orig: tvshow_detected = True else: tvshow_detected = False if name == '': name = params.get('name_parent') name_orig = '{0} - {1}'.format(name, name_orig) if params.get('type') == 'movie' and params.get('year'): name = '{0} ({1})'.format(name, params.get('year')) selectAction = ['Continue with original Title: {0}'.format(name), 'Rename Title', 'Get Title from Medialist'] if not fileSys.writeTutList('select:Rename'): tutWin = ['Adding content to your library', 'You can rename your Movie, TV-Show or Music title.', 'To make your scraper recognize the content, some times it is necessary to rename the title.', 'Be careful, wrong title can also cause that your scraper can\'t recognize your content.'] xbmcgui.Dialog().ok(tutWin[0], tutWin[1], tutWin[2], tutWin[3]) choice = guiTools.selectDialog('Title for MediaList entry: {0}'.format(name_orig), selectAction) else: choice = params.get('choice', 0) name = params.get('name') name_orig = params.get('name_orig') if choice != -1: cType = params.get('cType', None) if name: name = stringUtils.cleanLabels(name) if choice == 1 or name == None or name == '': name = guiTools.editDialog(name).strip() name = '{0}++RenamedTitle++'.format(name) if name else name if choice == 2: cTypeFilter = None if tvshow_detected or params.get('type', None) == 'tvshow': cTypeFilter = 'TV-Shows' elif params.get('type', None) == 'movie': cTypeFilter = 'Movies' item = guiTools.mediaListDialog(False, False, header_prefix='Get Title from Medialist for {0}'.format(name_orig), cTypeFilter=cTypeFilter, preselect_name=name) splits = item.get('entry').split('|') if item else None name = splits[1] if splits else None cType = splits[0] if splits else None if name: url = params.get('url') if not cType: if not fileSys.writeTutList('select:ContentTypeLang'): tutWin = ['Adding content to your library', 'Now select your content type.', 'Select language or YouTube type.', 'Wait for done message.'] xbmcgui.Dialog().ok(tutWin[0], tutWin[1], tutWin[2], tutWin[3]) if tvshow_detected or params.get('type', None) == 'tvshow': cType = guiTools.getTypeLangOnly('TV-Shows') elif params.get('type', None) == 'movie': cType = guiTools.getTypeLangOnly('Movies') else: cType = guiTools.getType(url) if cType != -1: if params.get('filetype', 'directory') == 'file': url += '&playMode=play' if (SEARCH_THETVDB == 2 and cType.find('TV-Shows') != -1 and choice == 0): show_data = tvdb.getShowByName(name, re.sub('TV-Shows\((.*)\)', r'\g<1>', cType)) if show_data: showtitle_tvdb = show_data.get('seriesName', name) if showtitle_tvdb != name: utils.addon_log_notice('addToMedialist: Use TVDB name \'{0}\' for \'{1}\''.format(showtitle_tvdb, name)) name = showtitle_tvdb fileSys.writeMediaList('name_orig={0};{1}'.format(name_orig, url), name, cType) xbmcgui.Dialog().notification(cType, name_orig, xbmcgui.NOTIFICATION_INFO, 5000, False) try: plugin_id = re.search('{0}([^\/\?]*)'.format('plugin:\/\/'), url) if plugin_id: module = moduleUtil.getModule(plugin_id.group(1)) if module and hasattr(module, 'create'): url = module.create(name, url, 'video') except: pass fillPluginItems(url, strm=True, strm_name=name, strm_type=cType, name_orig=name_orig) xbmcgui.Dialog().notification('Writing items...', 'Done', xbmcgui.NOTIFICATION_INFO, 5000, False)
def delNotInMediaList(delList): for item in delList: try: splits = item.get('entry').split('|') type = splits[0] isAudio = True if type.lower().find('audio') > -1 else False if type.lower().find('movies') > -1: path = xbmc.translatePath( os.path.join(STRM_LOC, stringUtils.getMovieStrmPath(type, splits[1]))) else: path = os.path.join(STRM_LOC, type) if isAudio and len(splits) > 3: path = os.path.join( path, stringUtils.cleanByDictReplacements(splits[3])) itemPath = stringUtils.getStrmname(splits[1]) path = xbmc.translatePath( os.path.join(path, stringUtils.cleanStrmFilesys(itemPath))) path = stringUtils.completePath(py2_decode(path)) utils.addon_log('remove: {0}'.format(path)) deleteFromFileSystem = True for split2 in splits[2].split('<next>'): streams = None if type.lower().find('tv-shows') > -1 or type.lower().find( 'movies') > -1: deleteFromFileSystem = False streams = [ py2_decode(stream[0]) for stream in kodiDB.delStream( path[len(STRM_LOC) + 1:len(path)], stringUtils.getProviderId(item.get('url')).get( 'providerId'), type.lower().find('tv-shows') > -1) ] if len(streams) > 0: dirs, files = xbmcvfs.listdir(path) for file in files: if py2_decode(file).replace('.strm', '') in streams: filePath = os.path.join(py2_encode(path), file) utils.addon_log_notice( 'delNotInMediaList: delete file = \'{0}\''. format(py2_decode(filePath))) xbmcvfs.delete(xbmc.translatePath(filePath)) dirs, files = xbmcvfs.listdir(path) if not files and not dirs: deleteFromFileSystem = True utils.addon_log_notice( 'delNotInMediaList: delete empty directory = {0}'. format(path)) if deleteFromFileSystem: xbmcvfs.rmdir(path, force=True) if isAudio: jsonUtils.jsonrpc('AudioLibrary.Clean') except OSError: print('Unable to remove: {0}'.format(path))
def writeMediaList(url, name, cType='Other', cleanName=True, albumartist=None): utils.addon_log('writeMediaList') existInList = False if not xbmcvfs.exists(profile): xbmcvfs.mkdirs(profile) if not xbmcvfs.exists(MediaList_LOC): xbmcvfs.File(MediaList_LOC, 'w').close() thelist = readMediaList() thelist = [x for x in thelist if x != ''] if len(thelist) > 0: for entry in thelist: splits = entry.strip().split('|') if stringUtils.getStrmname( splits[1]).lower() == stringUtils.getStrmname( name).lower(): existInList = True splits[0] = cType splits[1] = name plugin = re.sub('.*(plugin:\/\/[^<]*)', '\g<1>', url) name_orig = re.sub('(?:name_orig=([^;]*);)(plugin:\/\/[^<]*)', '\g<1>', url) replaced = False splits2 = filter(None, splits[2].split('<next>')) for s, split2 in enumerate(splits2): split2_plugin = re.sub('.*(plugin:\/\/[^<]*)', '\g<1>', split2) split2_name_orig = re.sub( '(?:name_orig=([^;]*);)(plugin:\/\/[^<]*)', '\g<1>', split2) if re.sub('%26OfferGroups%3DB0043YVHMY', '', split2_plugin) == re.sub( '%26OfferGroups%3DB0043YVHMY', '', plugin) or split2_name_orig == name_orig: splits2[s] = url replaced = True if replaced == True: splits[2] = '<next>'.join(set(splits2)) utils.addon_log_notice( 'writeMediaList: replace {0} in {1}'.format( name_orig, name)) else: splits[2] = '{0}<next>{1}'.format( splits[2], url) if splits[2].strip() != '' else '{0}'.format(url) utils.addon_log_notice( 'writeMediaList: append {0} to {1}'.format( name_orig, name)) if albumartist: if len(splits) == 5: splits[4] = albumartist else: splits.append(albumartist) newentry = '|'.join(splits) xbmcgui.Dialog().notification( entry, 'Adding to MediaList', os.path.join(ADDON_PATH, 'resources/media/representerIcon.png'), 5000) thelist = stringUtils.replaceStringElem( thelist, entry, newentry) if existInList != True: newentry = [cType, name, url] if albumartist: newentry.append(albumartist) newentry = ('|'.join(newentry)) thelist.append(newentry) output_file = xbmcvfs.File(MediaList_LOC, 'w') for index, linje in enumerate(thelist): entry = ('{0}\n' if index < len(thelist) - 1 else '{0}').format( linje.strip()) output_file.write(py2_encode(entry))