def first_run(): if settings[SETTINGS.UUID] == '': settings[SETTINGS.UUID] = uuid.uuid4() DialogRenderer.ok(get_string(LANG.NEWS_TITLE), get_string(LANG.NEWS_TEXT)) if settings[SETTINGS.INSTALLATION_DATE] == '': set_settings(SETTINGS.INSTALLATION_DATE, get_current_datetime_str()) if settings[SETTINGS.VERSION] == '': set_settings(SETTINGS.VERSION, get_info('version')) if settings[SETTINGS.PROVIDER_USERNAME] == '': settings[SETTINGS.PROVIDER_TOKEN] = '' # fix plain stored password on first run if settings[SETTINGS.PROVIDER_USERNAME] and len( settings[SETTINGS.PROVIDER_PASSWORD]) != 40: salt = provider.get_salt(settings[SETTINGS.PROVIDER_USERNAME]) if salt is not None: settings[SETTINGS.PROVIDER_PASSWORD] = hash_password( settings[SETTINGS.PROVIDER_PASSWORD], salt) if get_plugin_route( ) != ROUTE.CHECK_PROVIDER_CREDENTIALS or not storage.get( STORAGE.IS_OLD_KODI_SESSION): settings.load_to_cache(SETTINGS.PROVIDER_USERNAME, SETTINGS.PROVIDER_PASSWORD, SETTINGS.PROVIDER_TOKEN) if not storage.get(STORAGE.IS_OLD_KODI_SESSION): storage[STORAGE.IS_OLD_KODI_SESSION] = True
def show_search_results(self, collection, media_list): if media_list: num_media = media_list.get('totalCount') if num_media == 0: InfoDialog(get_string(30302)).notify() # if collection == COLLECTION.TV_SHOWS: # self.router.back(steps=1, skip_search=True) else: if not settings.as_bool(SETTINGS.EXPLICIT_CONTENT): self.vulgar_filter(media_list) self.render_media_list(collection, media_list) if not self.renderers[collection].is_same_list(): InfoDialog(get_string(30303).format(number=str(num_media))).notify()
def media_menu(self, collection): with self.start_directory(self.handle): SearchItem(url=self._router.url_for(self.search, collection))( self.handle) DirectoryItem(title=get_string(30211), url=router_url_from_string(ROUTE.POPULAR, collection))(self.handle) DirectoryItem(title=get_string(30210), url=self._url_for(self.a_to_z_menu, collection))(self.handle) DirectoryItem(title=get_string(30209), url=self._url_for(self.genre_menu, collection))(self.handle)
def vip_remains(self): if time_limit_expired(SETTINGS.LAST_VIP_CHECK, GENERAL.VIP_CHECK_INTERVAL): settings[SETTINGS.LAST_VIP_CHECK] = datetime.now() valid_token, user_data = self._check_token_and_return_user_data() if valid_token: if self._check_vip(user_data): days_to = self._provider.vip_remains(user_data) if days_to <= GENERAL.VIP_REMAINING_DAYS_WARN: DialogRenderer.ok( get_string(LANG.VIP_REMAINS).format( provider=self._provider), STRINGS.PAIR_BOLD.format(get_string(LANG.DAYS), str(days_to)))
def _check_vip(self, user_data): logger.debug('Checking VIP') is_vip = self._provider.is_vip(user_data) if not is_vip: logger.debug('VIP is not active') InfoDialog(get_string(LANG.ACTIVATE_VIP), sound=True).notify() vip_string = get_string(LANG.NOT_ACTIVE) else: logger.debug('VIP is active') vip_string = STRINGS.VIP_INFO.format( self._provider.vip_until(user_data), get_string(LANG.DAYS), self._provider.vip_remains(user_data)) settings[SETTINGS.VIP_DURATION] = vip_string return is_vip
def _check_provider(self): if self._provider.username == '' or self._provider.username == '': InfoDialog(get_string(LANG.MISSING_PROVIDER_CREDENTIALS), sound=True).notify() settings.show() return False return True
def genre_menu(self, collection): genres = [ LANG.ACTION, LANG.ANIMATED, LANG.ADVENTURE, LANG.DOCUMENTARY, LANG.DRAMA, LANG.FANTASY, LANG.HISTORICAL, LANG.HORROR, LANG.MUSIC, LANG.IMAX, LANG.CATASTROPHIC, LANG.COMEDY, LANG.SHORT, LANG.CRIME, LANG.MUSICAL, LANG.MYSTERIOUS, LANG.EDUCATIONAL, LANG.FAIRYTALE, LANG.PSYCHOLOGICAL, LANG.JOURNALISTIC, LANG.REALITY, LANG.TRAVEL, LANG.FAMILY, LANG.ROMANTIC, LANG.SCI_FI, LANG.COMPETITION, LANG.SPORTS, LANG.STAND_UP, LANG.TALK_SHOW, LANG.TELENOVELA, LANG.THRILLER, LANG.MILITARY, LANG.WESTERN, LANG.BIOGRAPHICAL ] if settings.as_bool(SETTINGS.EXPLICIT_CONTENT): genres = genres + explicit_genres genre_pairs = {} lang_genres = [] for genre in genres: lang_genre = get_string(genre) api_genre = api_genres[genre] genre_pairs[lang_genre] = api_genre lang_genres.append(lang_genre) lang_genres.sort() with self.start_directory(self.handle): for lang_genre in lang_genres: DirectoryItem(title=lang_genre, url=router_url_from_string( ROUTE.FILTER, collection, FILTER_TYPE.GENRE, genre_pairs[lang_genre]))(self.handle)
def genre_menu(self, collection): genres = [ LANG.ACTION, LANG.ANIMATED, LANG.ADVENTURE, LANG.DOCUMENTARY, LANG.DRAMA, LANG.FANTASY, LANG.HISTORICAL, LANG.HORROR, LANG.MUSIC, LANG.IMAX, LANG.CATASTROPHIC, LANG.COMEDY, LANG.SHORT, LANG.CRIME, LANG.MUSICAL, LANG.MYSTERIOUS, LANG.EDUCATIONAL, LANG.FAIRYTALE, LANG.PSYCHOLOGICAL, LANG.JOURNALISTIC, LANG.REALITY, LANG.TRAVEL, LANG.FAMILY, LANG.ROMANTIC, LANG.SCI_FI, LANG.COMPETITION, LANG.SPORTS, LANG.STAND_UP, LANG.TALK_SHOW, LANG.TELENOVELA, LANG.THRILLER, LANG.MILITARY, LANG.WESTERN, LANG.BIOGRAPHICAL ] if settings.as_bool(SETTINGS.EXPLICIT_CONTENT): genres = genres + explicit_genres genres = [{ 'lang_id': genre, 'string': get_string(genre) } for genre in genres] genres.sort(key=operator.itemgetter('string')) with self.start_directory(self.handle): for genre in genres: DirectoryItem(title=genre.get('string'), url=router_url_from_string( ROUTE.FILTER, collection, FILTER_TYPE.GENRE, Url.encode_param( [api_genres[genre.get('lang_id')]]), ORDER.DESCENDING))(self.handle)
def add_to_library(): logger.debug("add to lib called") # DialogRenderer.ok('Info', 'OK') # Check settings, whether library paths are set up corretly if dbtype == 'movie': mf = settings[SETTINGS.MOVIE_LIBRARY_FOLDER] if mf != '': add_movie(mf) # k tomuto else by nemalo prist, kedze sa robi check pred contextMenu # else: # notification('Unknown library folder', "Please set up movie library folder in settings") # show_settings() # ToDo: if (dbtype == 'tvshow' or dbtype == 'episode'): DialogRenderer.ok(get_string(30351), get_string(30352))
def api_response_handler(response): try: response.raise_for_status() return response except requests.exceptions.HTTPError as e: InfoDialog(get_string(30301), icon=InfoDialogType.ERROR).notify() logger.error(e) return None
def check_version(): if time_limit_expired(SETTINGS.LAST_VERSION_CHECK, GENERAL.VERSION_CHECK_INTERVAL) or settings[ SETTINGS.LAST_VERSION_AVAILABLE] == '': settings[SETTINGS.LAST_VERSION_CHECK] = datetime.now() tag_name = get_latest_release_tag_name() if tag_name: settings[SETTINGS.LAST_VERSION_AVAILABLE] = tag_name current_version = settings[SETTINGS.VERSION] if current_version != tag_name: settings[SETTINGS.IS_OUTDATED] = True clear_kodi_addon_cache() DialogRenderer.ok( get_string(LANG.NEW_VERSION_TITLE), get_string(LANG.NEW_VERSION_TEXT).format(version=tag_name)) else: settings[SETTINGS.IS_OUTDATED] = False
def build_season_list_gui(self, season_list, media_id): gui_season_list = [] for i, season in enumerate(season_list, start=1): title = STRINGS.SEASON_TITLE.format(get_string(30920), str(i)) url = self._router.url_for(self.select_episode, media_id, i - 1) item = DirectoryItem(title, url) gui_season_list.append(item) return gui_season_list
def ensure_provider_token(self): token = self._provider.get_token() if token: settings.set_cache(SETTINGS.PROVIDER_TOKEN, token) return True InfoDialog(get_string(LANG.INCORRECT_PROVIDER_CREDENTIALS), sound=True).notify() return False
def vulgar_filter(media_list): filtered_list = [] explicit_genres_str = [get_string(i) for i in explicit_genres] for media in media_list.get('data'): genres = media.get('info_labels').get('genre') is_blocked = bool(set(genres).intersection(explicit_genres_str)) if is_blocked: continue filtered_list.append(media) media_list.update({'data': filtered_list})
def run(): first_run() setup_root_logger() on_clear_cache_redirect() set_settings(SETTINGS.VERSION, get_info('version')) logger.debug('Entry point ------- ' + str(sys.argv)) try: stream_cinema.vip_remains() # settings.load_to_cache(SETTINGS.PROVIDER_USERNAME, SETTINGS.PROVIDER_PASSWORD, SETTINGS.PROVIDER_TOKEN) check_version() plugin_url_history.add(get_plugin_url()) return router.run() except requests.exceptions.ConnectionError as e: logger.error(e) if _can_connect_google(): Dialog().ok(get_string(LANG.CONNECTION_ERROR), get_string(LANG.SERVER_ERROR_HELP)) else: Dialog().ok(get_string(LANG.CONNECTION_ERROR), get_string(LANG.NO_CONNECTION_HELP))
def media_menu(self, collection): with self.start_directory(self.handle): DirectoryItem(title=get_string(LANG.POPULAR), url=router_url_from_string(ROUTE.POPULAR, collection))(self.handle) DirectoryItem(title=get_string(LANG.NEWS), url=router_url_from_string( ROUTE.SORT, collection, SORT_TYPE.AIRED, ORDER.DESCENDING))(self.handle) DirectoryItem(title=get_string(LANG.LAST_ADDED), url=router_url_from_string( ROUTE.SORT, collection, SORT_TYPE.DATE_ADDED, ORDER.DESCENDING))(self.handle) DirectoryItem(title=get_string(LANG.A_Z), url=self._url_for(self.a_to_z_menu, collection))(self.handle) DirectoryItem(title=get_string(LANG.GENRE), url=self._url_for(self.genre_menu, collection))(self.handle) self.add_extra_items(collection)
def show_search_results(self, media_list, callback, *args): if media_list: num_media = media_list.get('totalCount') if num_media == 0: InfoDialog(get_string(30302)).notify() # if collection == COLLECTION.TV_SHOWS: # self.router.back(steps=1, skip_search=True) else: if not settings.as_bool(SETTINGS.EXPLICIT_CONTENT): MediaListRenderer.explicit_filter(media_list) if settings.as_bool( SETTINGS.SHOW_RESULTS_COUNT ) and not MediaListRenderer.is_same_list(self.router): pagination = media_list.get('pagination') first_page = pagination.get( 'page') == 1 if pagination else True if first_page: InfoDialog( get_string(30303).format( number=str(num_media))).notify() return callback(media_list, *args)
def build(self): """Creates the ListItem together with metadata.""" item = xbmcgui.ListItem( label=self._title, path=self._url, ) menu = [] if self._art: # Without this it clutters the logs with: # CreateLoader - unsupported protocol(plugin) in plugin://plugin.video.stream-cinema-2/select_stream/5eb4691439a9578cbf25d7f4 # InputStream: Error opening, plugin://plugin.video.stream-cinema-2/select_stream/5eb4691439a9578cbf25d7f4 # Kodi for some reason tries to load the Art from the movie. # We have to set only some attributes of the Art. item.setArt({ 'fanart': self._art.get('fanart'), 'poster': self._art.get('poster'), }) if self._info_labels: item.setInfo('video', self._info_labels) if self._stream_info: menu.append((get_string(30404), 'PlayMedia({}?force=true)'.format(self._url))) for key, value in self._stream_info.items(): item.addStreamInfo(key, value) if self._services: item.setUniqueIDs({'imdb': 'tt' + str(self._services.get('imdb'))}, 'imdb') item.setProperty('IsPlayable', 'true') logger.debug(router_url_from_string(ROUTE.ADD_TO_LIBRARY)) if settings[SETTINGS.MOVIE_LIBRARY_FOLDER] != '': menu.append((get_string(LANG.ADD_TO_LIBRARY), "RunPlugin(%s)" % router_url_from_string(ROUTE.ADD_TO_LIBRARY))) item.addContextMenuItems(menu) return self._url, item, self.DIRECTORY,
def build_episode_list_gui(self, media_id, episode_list, season_id): gui_list = [] for episode_id, episode in enumerate(episode_list): title = episode.get('info_labels').get('title') title = title if title else STRINGS.EPISODE_TITLE.format( get_string(LANG.EPISODE), str(season_id), str(episode_id)) gui_list.append( self.build_media_item_gui(TvShowItem, episode, self.stream_url_builder( media_id, season_id, episode_id), title=title)) return gui_list
def a_to_z_menu(self, collection): import string filter_type = FILTER_TYPE.STARTS_WITH_LETTER with self.start_directory(self.handle): DirectoryItem(title=get_string(30251), url=router_url_from_string(ROUTE.FILTER, collection, filter_type, '0-9'))(self.handle) for c in string.ascii_uppercase: DirectoryItem(title=c, url=router_url_from_string( ROUTE.FILTER, collection, filter_type, c))(self.handle)
def search_for_csfd_item(self, collection, search_value): # No idea how to decode search_value to correct format. It must be decoded on the server right now. media_list = self.filter_media(collection, FILTER_TYPE.EXACT_TITLE, Url.encode_param([search_value]), ORDER.ASCENDING).get('data') num_media = len(media_list) if num_media == 1: media_id = media_list.pop().get('_id') streams = API.get_source( self.get_media_detail(collection, media_id)).get('streams') self.renderers[RENDERER.MOVIES].select_stream(media_id, streams) elif num_media == 0: InfoDialog( get_string(30303).format(number=str(num_media))).notify()
def set_provider_credentials(): username = DialogRenderer.keyboard(get_string(LANG.USERNAME)) if username is None: return else: salt = provider.get_salt(username) if salt is None: InfoDialog(get_string(LANG.INCORRECT_PROVIDER_CREDENTIALS), sound=True).notify() return password = DialogRenderer.keyboard(get_string(LANG.PASSWORD), hidden=True) if password is None: return if username: settings.set_cache(SETTINGS.PROVIDER_USERNAME, username) settings.set_cache(SETTINGS.PROVIDER_TOKEN, '') if password: hashed = hash_password(password, salt) settings.set_cache(SETTINGS.PROVIDER_PASSWORD, hashed) logger.debug('Saving credentials to cache')
def main_menu(self): logger.debug('Rendering main menu') with self.start_directory(self.handle): SearchItem(url=self._router.url_for(self.search, COLLECTION.ALL))( self.handle) DirectoryItem(title=get_string(LANG.NEWS), url=router_url_from_string( ROUTE.SORT, COLLECTION.ALL, SORT_TYPE.AIRED, ORDER.DESCENDING))(self.handle) DirectoryItem(title=get_string(LANG.LAST_ADDED), url=router_url_from_string( ROUTE.SORT, COLLECTION.ALL, SORT_TYPE.DATE_ADDED, ORDER.DESCENDING))(self.handle) MoviesItem( url=self._router.url_for(self.media_menu, COLLECTION.MOVIES))( self.handle) TvShowsItem(url=self._router.url_for( self.media_menu, COLLECTION.TV_SHOWS))(self.handle) WatchHistoryItem(url=router_url_from_string(ROUTE.WATCHED))( self.handle) SettingsItem( url=self._router.url_for(self.command, COMMAND.OPEN_SETTINGS))( self.handle) return
def a_to_z_submenu(self, collection, previous_letter, previous_letter_count): import string filter_type = FILTER_TYPE.STARTS_WITH letter_counts = self._on_a_to_z_menu( collection, filter_type, [previous_letter + c for c in string.ascii_lowercase]) with self.start_directory(self.handle): MainMenuFolderItem(url=router_url_from_string(ROUTE.CLEAR_PATH))( self.handle) SearchItem(title=self._a_to_z_title( get_string(LANG.SEARCH_FOR_LETTERS).format( letters=previous_letter.upper()), previous_letter_count), url=router_url_from_string( ROUTE.FILTER, collection, filter_type, Url.encode_param([previous_letter]), ORDER.ASCENDING))(self.handle) self._a_to_z_submenu_items(collection, filter_type, previous_letter, letter_counts, previous_letter_count)
def choose_video_stream(streams): stream_labels = [] streams.sort(key=operator.itemgetter('size'), reverse=settings.as_int(SETTINGS.FILE_SIZE_SORT)) audio_info_list = [] for stream in streams: # Fix audio string that begins with the comma. audio_info = [] for audio in stream.get('audio'): audio_info.append( STRINGS.AUDIO_INFO.format( audio.get('codec'), format(audio.get('channels'), '.1f'), audio.get('language'))) audio_info_list.append(' '.join(audio_info)) quality = STRINGS.STREAM_TITLE_BRACKETS.format( stream.get('quality')) size = STRINGS.BOLD.format(convert_size(stream.get('size'))) bitrate = STRINGS.STREAM_BITRATE_BRACKETS.format( convert_bitrate(stream.get('bitrate'))) if settings.as_bool( SETTINGS.SHOW_BITRATE) else '' codec = STRINGS.STREAM_TITLE_BRACKETS.format( codecs[stream.get('codec')]) if settings.as_bool( SETTINGS.SHOW_CODEC) else '' duration = STRINGS.BOLD.format( str(datetime.timedelta( seconds=int(stream.get('duration'))))) if settings.as_bool( SETTINGS.SHOW_DURATION) else '' stream_labels.append([quality, codec, size, duration, bitrate]) table = make_table(stream_labels) table = append_list_items_to_nested_list_items(table, audio_info_list) ret = Dialog().select( get_string(LANG.CHOOSE_STREAM), [STRINGS.TABLE_SPACES.join(item) for item in table]) if ret < 0: return None return streams[ret]
def a_to_z_menu(self, collection): import string filter_type = FILTER_TYPE.STARTS_WITH zero_nine = [i for i in range(10)] _0_9 = get_string(LANG.ZERO_NINE) letter_counts = self._on_a_to_z_menu( collection, filter_type, [c for c in string.ascii_lowercase] + zero_nine) with self.start_directory(self.handle): DirectoryItem(title=self._a_to_z_title( _0_9, sum([letter_counts[str(i)] for i in range(10)])), url=router_url_from_string( ROUTE.FILTER, collection, filter_type, Url.encode_param(zero_nine), ORDER.ASCENDING))(self.handle) for c in string.ascii_lowercase: letter_count = letter_counts.get(c) DirectoryItem(title=self._a_to_z_title(c.upper(), letter_count), url=self._url_for(self.a_to_z_submenu, collection, c, letter_count))(self.handle)
def search(): search_value = show_input(get_string(30207)) if search_value: return search_value
class SettingsItem(DirectoryItem): ICON = 'DefaultAddonService.png' TITLE = get_string(30208) DIRECTORY = False
class MainMenuFolderItem(DirectoryItem): ICON = 'DefaultFolderBack.png' TITLE = get_string(30202)
class TvShowsItem(DirectoryItem): ICON = 'DefaultTvshows.png' TITLE = get_string(30201)