def _get_profile_name(profile): """ Get a descriptive string of the profile. :type profile: resources.lib.streamz.Profile """ title = profile.name # Convert the Streamz Profile color to a matching Kodi color color_map = { '#F20D3A': 'red', '#FF0A5A': 'crimson', '#FF4B00': 'darkorange', '#FED71F': 'gold', '#5EFF74': 'palegreen', '#0DF2E8': 'turquoise', '#226DFF': 'dodgerblue', '#6900CC': 'blueviolet', } if color_map.get(profile.color.upper()): title = '[COLOR %s]%s[/COLOR]' % (color_map.get( profile.color.upper()), kodiutils.to_unicode(title)) # Append (Kids) if profile.product == PRODUCT_STREAMZ_KIDS: title = "%s (Kids)" % title return title
def _get_profile_name(profile): """ Get a descriptive string of the profile :type profile: resources.lib.vtmgo.vtmgo.Profile """ title = profile.name # Convert the VTM GO Profile color to a matching Kodi color color_map = { '#64D8E3': 'skyblue', '#4DFF76': 'mediumspringgreen', '#0243FF': 'blue', '#831CFA': 'blueviolet', '#FFB24D': 'khaki', '#FF4DD5': 'violet', '#FFB002': 'gold', '#FF0257': 'crimson', } if color_map.get(profile.color.upper()): title = '[COLOR %s]%s[/COLOR]' % (color_map.get( profile.color), kodiutils.to_unicode(title)) # Append (Kids) if profile.product == 'VTM_GO_KIDS': title = "%s (Kids)" % title return title
def get_selection(cls): """Retrieve information about the selected ListItem.""" # The selected ListItem is available in sys.listitem, but there is not enough data that we can use to know what # exact item was selected. Therefore, we use xbmc.getInfoLabel(ListItem.xxx), that references the currently # selected ListItem. This is not always the same as the item where the Context Menu was opened on when the # selection was moved really quick before the Python code was started. This often happens when using the mouse, # but should not happen when using the keyboard or a remote control. Therefore, we do a check to see if the # sys.listitem.getPath is the same as xbmc.getInfoLabel(ListItem.FolderPath) before continuing. # For now, this is the best we can do. # # The sys.listitem.getPath() returns a string like "pvr://guide/0016/2020-05-28 09:24:47.epg". We could use the # date to find out what item was selected, but we can't match the channel with something that makes sense. It's # not the same ID as the ID in the JSON-RPC "PVR.GetChannels" or "PVR.GetChannelDetails" commands. # # The available fields are: # * sys.listitem.getLabel() # Universiteit van Vlaanderen # * sys.listitem.getPath() # pvr://guide/0016/2020-05-28 09:24:47.epg # # I would have preferred to use the Channel ID we use for for the epg (like een.be), but that isn't available. # We only have a name (ListItem.ChannelName), or the channel number (ListItem.ChannelNumberLabel). # Check if the selected item is also the intended item if sys.listitem.getPath() != kodiutils.get_info_label('ListItem.FolderPath'): # pylint: disable=no-member # We are in trouble. We know that the data we want to use is invalid, but there is nothing we can do. kodiutils.ok_dialog(message=kodiutils.localize(30712)) # Could not determine the selected program... return None # Load information from the ListItem date = kodiutils.get_info_label('ListItem.Date') duration = kodiutils.get_info_label('ListItem.Duration') channel = kodiutils.to_unicode(kodiutils.get_info_label('ListItem.ChannelName')) # Parse begin to a datetime. The ListItem.Date doesn't contain seconds date_format = kodiutils.get_region('dateshort') + ' ' + kodiutils.get_region('time').replace(':%S', '') try: start = datetime.strptime(date, date_format) except TypeError: start = datetime(*(time.strptime(date, date_format)[0:6])) # Parse duration to seconds splitted = duration.split(':') if len(splitted) == 1: # %S seconds = int(splitted[0]) elif len(splitted) == 2: # %M:%S seconds = int(splitted[0]) * 60 + int(splitted[1]) elif len(splitted) == 3: # %H:%M:%S seconds = int(splitted[0]) * 3600 + int(splitted[1]) * 60 + int(splitted[2]) else: raise Exception('Unknown duration %s' % duration) return dict( start=start, duration=seconds, channel=channel, )
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 send_upnext(upnext_info): """ Send a message to Up Next with information about the next Episode. :type upnext_info: object """ from base64 import b64encode from json import dumps data = [kodiutils.to_unicode(b64encode(dumps(upnext_info).encode()))] sender = '{addon_id}.SIGNAL'.format(addon_id='plugin.video.vtm.go') kodiutils.notify(sender=sender, message='upnext_data', data=data)
def __get_subtitle_paths(): """ Get the external subtitles path """ temp_path = kodiutils.addon_profile() + 'temp/' files = None if kodiutils.exists(temp_path): _, files = kodiutils.listdir(temp_path) if files and len(files) >= 1: return [temp_path + kodiutils.to_unicode(filename) for filename in files] _LOGGER.debug('Player: No subtitle path') return None
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, profile=self._tokens.profile) 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
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