def stream_info(media): streams = media.get('streams', []) if len(streams) == 0: return stream = streams.pop() stream_info = { 'video': { 'codec': stream.get('codec'), 'aspect': stream.get('aspect'), 'width': stream.get('width'), 'height': stream.get('height'), 'duration': stream.get('duration'), }, } audios = stream.get('audio') if len(audios) > 0: stream_info.update({ 'audio': audios[0] }) subtitles = stream.get('subtitles') if len(subtitles) > 0: stream_info.update({ 'subtitle': subtitles[0] }) logger.debug('Generated stream info') return stream_info
def vip_remains(self, user_data): """ Get user's ramaining days as VIP. """ vip_days = self._find(user_data, 'vip_days') logger.debug('VIP days remaining: %s', vip_days) return int(vip_days)
def _check_account(self): logger.debug('Checking account.') valid_token, user_data = self._check_token_and_return_user_data() if valid_token: logger.debug('Provider token is valid') return self._check_vip(user_data) return False
def select_season(self, media_id): logger.debug('Showing season list') season_list = self.get_cached_media_by_id(media_id).get('seasons') if season_list: list_items = [ movie.build() for movie in self.build_season_list_gui(season_list, media_id) ] self.render(list_items)
def search(self, collection): logger.debug('Search dialog opened') search_value = DialogRenderer.search() xbmcplugin.endOfDirectory(self.handle) if search_value: self._router.go_to_route(ROUTE.SEARCH_RESULT, collection, search_value) else: logger.debug('No value for search. Returning.') self._router.replace_route(ROUTE.MEDIA_MENU, collection)
def select_episode(self, media_id, season_id): logger.debug('Showing episode list') episode_list = self.get_cached_media_by_id(media_id).get('seasons')[ int(season_id)].get('episodes') if episode_list: list_items = [ movie.build() for movie in self.build_episode_list_gui( media_id, episode_list, season_id) ] self.render(list_items)
def play_stream(self, ident): logger.debug('Trying to play stream.') if self._check_account(): stream_url = self._provider.get_link_for_file_with_id(ident) logger.debug('Stream URL found. Playing %s' % stream_url) self.send_service_message(SERVICE.PLAYER_SERVICE, SERVICE_EVENT.PLAYBACK_STARTED) self.router.set_resolved_url(stream_url) else: self.router.set_resolved_url()
def select_episode(self, collection, media_id, season_id): logger.debug('Showing episode list') MainMenuFolderItem(url=router_url_from_string(ROUTE.CLEAR_PATH))( self.handle) episode_list = self.get_season(int(season_id)).get('episodes') if episode_list: list_items = [ movie.build() for movie in self.build_episode_list_gui( media_id, episode_list, season_id) ] self.render(collection, list_items)
def get_user_data(self): """ POST /api/user_data/ HTTP/1.1 Accept-Encoding: identity Host: webshare.cz Referer: https://webshare.cz/ Content-Type: application/x-www-form-urlencoded """ response = self._post('/user_data/') logger.debug('Getting user data from provider') logger.debug(response) return self._parse(response)
def _can_connect_google(): google_addr = ("www.google.com", 443) soc = None try: soc = socket.create_connection(google_addr) return True except Exception as e: logger.debug("failed to connect to %s: %s", google_addr, e) return False finally: if soc is not None: soc.close()
def _post(self, path, data=None): """ :type data: dict """ if data is None: data = {} data.setdefault('wst', self.token) logger.debug("WS token %s " % self.token) headers = common_headers() response = requests.post('https://webshare.cz/api{}'.format(path), data=data, headers=headers) logger.debug('Response from provider: %s' % response.content) return response.content
def main_menu(self): logger.debug('Rendering main menu') with self.start_directory(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) SettingsItem( url=self._router.url_for(self.command, 'open-settings'))( self.handle) return
def select_season(self, collection, media_id): logger.debug('Showing season list') MainMenuFolderItem(url=router_url_from_string(ROUTE.CLEAR_PATH))( self.handle) media = self._on_media_selected(collection, media_id) self.set_cached_media(media) season_list = API.get_source(media).get('seasons') if season_list: list_items = [ movie.build() for movie in self.build_season_list_gui( collection, media_id, season_list) ] self.render(collection, list_items)
def _autoselect_stream(streams, quality, language): """ Function takes streams to select and indexes of desired quality and language as defined in const.py. It enumerates all streams and try to find best match in this order: 1. find stream with desired language/audio 2. find stream with desired quality If both language and quality is at least in one stream use that (if more streams qualifies, use the first one) If not both satisfy the selection 1. try to find stream with language match (if more streams qualifies, use the first one) 2. try to find stream with quality match (if more streams qualifies, use the first one) If no stream qualifies, use the first avialable stream. :param list streams: list of available streams :param int quality: desired quality (index in STREAM_AUTOSELECT.QUALITIES) :param int language: language desired language (index in STREAM_AUTOSELECT.LANGUAGES) returns selected stream """ selected = streams[0] reason = 'no-match' try: with_right_audio = set([]) with_right_video = set([]) for i, stream in enumerate(streams): for audio in stream['audio']: if audio["language"] == STREAM_AUTOSELECT.LANGUAGES[language]: with_right_audio.add(i) break if stream['quality'] == STREAM_AUTOSELECT.QUALITIES[quality]: with_right_video.add(i) intersection = with_right_audio.intersection(with_right_video) intersection = list(intersection) if len(intersection) > 0: reason = 'right audio, right quality' selected = streams[intersection[0]] elif len(with_right_audio) > 0: reason = 'right audio' selected = streams[list(with_right_audio)[0]] elif len(with_right_video) > 0: reason = 'right video' selected = streams[list(with_right_video)[0]] except Exception as e: reason = 'error' logger.error("autoselect: failed to auto select stream: %s", e) logger.debug("autoselect: auto selected stream: %s (reason: %s)", selected, reason) return selected
def get_salt(self, username): """ POST /api/salt/ HTTP/1.1 Accept-Encoding: identity Host: webshare.cz Referer: https://webshare.cz/ Content-Type: application/x-www-form-urlencoded """ response = self._post('/salt/', data={'username_or_email': username}) root = self._parse(response) logger.debug('Getting user salt from provider') status = self._find(root, 'status') if status == 'OK': return self._find(root, 'salt') else: return None
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 get_token(self): """ POST /api/login/ HTTP/1.1 Accept-Encoding: identity Host: webshare.cz Referer: https://webshare.cz/ Content-Type: application/x-www-form-urlencoded """ response = self._post('/login/', data={ 'username_or_email': self.username, 'password': self.password, 'keep_logged_in': 1, }) root = self._parse(response) logger.debug('Getting user token from provider') return self._find(root, 'token')
def csfd_tips(self, collection): logger.debug('CSFD tips search opened') with DirectoryRenderer.start_directory(self.handle, as_type=collection): for tip in get_csfd_tips(): name = tip[0][:-7] name_quoted = tip[0][:-7].replace(' ', '%20') year = tip[0][-7:] year = year[2:-1] tip_joined = STRINGS.TITLE_GENRE_YEAR.format(title=name, genre=tip[1], year=year) info_labels = {'title': name, 'year': int(year)} MediaItem(title=tip_joined, url=router_url_from_string(ROUTE.SEARCH_CSFD_ITEM, collection, Url.quote(name_quoted)), info_labels=info_labels)(self.handle)
def add_movie(mf): logger.debug("---------------------------------") originalTitle = xbmc.getInfoLabel("ListItem.Originaltitle").decode('utf-8') year = xbmc.getInfoLabel("ListItem.Year").decode('utf-8') moviePath = xbmc.getInfoLabel("ListItem.FileNameAndPath") dirName = mf + originalTitle + ' (' + year + ')' if not xbmcvfs.exists(dirName): xbmcvfs.mkdir(dirName) strmFileName = join(dirName, originalTitle + ' (' + year + ')' + '.strm') logger.debug("%s %s" % (strmFileName, moviePath)) file = xbmcvfs.File(strmFileName, 'w') file.write(str(moviePath)) file.close() # eventualne hodit notifikaciu # notification('Added to library', 'Movie %s was successfully added to library' % originalTitle) # notification(get_string(30405), get_string(30406) % originalTitle) xbmc.executebuiltin('UpdateLibrary(video)')
def get_link_for_file_with_id(self, file_id, download_type=DOWNLOAD_TYPE.VIDEO_STREAM): """ POST /api/file_link/ HTTP/1.1 Accept-Encoding: identity Host: webshare.cz Referer: https://webshare.cz/ Content-Type: application/x-www-form-urlencoded """ data = { 'ident': file_id, 'download_type': download_type, 'device_uuid': settings[SETTINGS.UUID], 'device_res_x': get_screen_width(), 'device_res_y': get_screen_height(), } response = self._post('/file_link/', data=data) root = self._parse(response) link = self._find(root, 'link') logger.debug('Getting file link from provider') return link
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 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 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 _check_token_and_return_user_data(self): logger.debug('Checking token and returning user data.') if self._check_provider_settings(): user_data = self._provider.get_user_data() if not self._provider.is_valid_token(user_data): logger.debug( 'Token is not valid. Getting new one and then new user data.' ) return self.ensure_provider_token( ), self._provider.get_user_data() logger.debug('Token is valid.') return True, user_data return False, None
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 _add(self, url=None): if url is None: url = self.current() if not self.allowed(url): logger.debug('Blacklisted URL. Not adding.') return False if self.exists(url): logger.debug('Duplicate to last URL. Not adding.') return False urls = self.get_urls() if len(urls) >= self._limit: urls.pop(0) urls.append(url) logger.debug('URL added to history') self.storage[STORAGE.PLUGIN_URL_HISTORY] = urls return True
def go(self, url): xbmcplugin.endOfDirectory(self.handle, cacheToDisc=False) logger.debug('Going to url: %s' % url) go_to_plugin_url(url)
def select_tv_show_stream(self, media_id, season_id, episode_id): logger.debug('Showing stream list') media = self.get_episode(int(season_id), int(episode_id)) self.select_stream(media_id, API.get_source(media)['streams'])
def replace(self, url=None): xbmcplugin.endOfDirectory(self.handle, cacheToDisc=False) url = self._history.current() if url is None else url logger.debug('Replacing url {} with {}'.format(self._history.current(), url)) replace_plugin_url(url)