def get_token(self): """ Get a valid token """ now = int(time.time()) if self._id_token and self._expiry > now: # We have a valid id token in memory, use it _LOGGER.debug('Got an id token from memory') return self._id_token if self._refresh_token: # We have a valid refresh token, use that to refresh our id token # The refresh token is valid for 30 days. If this refresh fails, we just continue by logging in again. _LOGGER.debug('Getting an id token by refreshing') try: self._id_token = self._refresh(self._refresh_token) self._expiry = now + 3600 except (InvalidLoginException, AuthenticationException) as exc: _LOGGER.error('Error logging in: %s', str(exc)) self._id_token = None self._refresh_token = None self._expiry = 0 # We continue by logging in with username and password if not self._id_token: # We have no tokens, or they are all invalid, do a login _LOGGER.debug('Getting an id token by logging in') id_token, refresh_token = self._authenticate( self._username, self._password) self._id_token = id_token self._refresh_token = refresh_token self._expiry = now + 3600 # Store new tokens in cache if not os.path.exists(self._token_path): os.makedirs(self._token_path) with open(os.path.join(self._token_path, self.TOKEN_FILE), 'w') as fdesc: data = json.dumps( dict( id_token=self._id_token, refresh_token=self._refresh_token, expiry=self._expiry, )) fdesc.write(kodiutils.from_unicode(data)) return self._id_token
def _delay_subtitles(self, subtitles, json_manifest): """ Modify the subtitles timings to account for ad breaks. :type subtitles: list[string] :type json_manifest: dict :rtype list[str] """ # Clean up old subtitles temp_dir = os.path.join(kodiutils.addon_profile(), 'temp', '') _, files = kodiutils.listdir(temp_dir) if files: for item in files: if kodiutils.to_unicode(item).endswith('.vtt'): kodiutils.delete(temp_dir + kodiutils.to_unicode(item)) # Return if there are no subtitles available if not subtitles: return None import re if not kodiutils.exists(temp_dir): kodiutils.mkdirs(temp_dir) ad_breaks = list() delayed_subtitles = list() webvtt_timing_regex = re.compile( r'\n(\d{2}:\d{2}:\d{2}\.\d{3}) --> (\d{2}:\d{2}:\d{2}\.\d{3})\s') # Get advertising breaks info from json manifest cues = json_manifest.get('interstitials').get('cues') for cue in cues: ad_breaks.append( dict(start=cue.get('start'), duration=cue.get('break_duration'))) for subtitle in subtitles: output_file = temp_dir + subtitle.get('name') + '.' + subtitle.get( 'url').split('.')[-1] webvtt_content = util.http_get(subtitle.get('url')).text webvtt_content = webvtt_timing_regex.sub( lambda match: self._delay_webvtt_timing(match, ad_breaks), webvtt_content) with kodiutils.open_file(output_file, 'w') as webvtt_output: webvtt_output.write(kodiutils.from_unicode(webvtt_content)) delayed_subtitles.append(output_file) return delayed_subtitles
def _download_subtitles(subtitles): # Clean up old subtitles temp_dir = os.path.join(kodiutils.addon_profile(), 'temp', '') _, files = kodiutils.listdir(temp_dir) if files: for item in files: kodiutils.delete(temp_dir + kodiutils.to_unicode(item)) # Return if there are no subtitles available if not subtitles: return None if not kodiutils.exists(temp_dir): kodiutils.mkdirs(temp_dir) downloaded_subtitles = list() for subtitle in subtitles: output_file = temp_dir + subtitle.get('name') webvtt_content = util.http_get(subtitle.get('url')).text with kodiutils.open_file(output_file, 'w') as webvtt_output: webvtt_output.write(kodiutils.from_unicode(webvtt_content)) downloaded_subtitles.append(output_file) return downloaded_subtitles
def do_search(self, search): """ Do a search in the full catalog. :type search: str :rtype list[Union[Movie, Program]] """ response = util.http_get( API_ENDPOINT + '/%s/search/?query=%s' % (self._mode(), kodiutils.to_unicode(quote(kodiutils.from_unicode(search)))), token=self._tokens.jwt_token if self._tokens else None, profile=self._tokens.profile if self._tokens else None) results = json.loads(response.text) items = [] for category in results.get('results', []): for item in category.get('teasers'): if item.get('target', {}).get('type') == CONTENT_TYPE_MOVIE: items.append(self._parse_movie_teaser(item)) elif item.get('target', {}).get('type') == CONTENT_TYPE_PROGRAM: items.append(self._parse_program_teaser(item)) return items