def get_current_brasilia_utc_offset(): try: import pytz import datetime import resources.lib.modules.util as util sp_timezone = pytz.timezone('America/Sao_Paulo') return util.get_total_seconds(datetime.datetime.now(sp_timezone).utcoffset()) / 60 / 60 except Exception as ex: log("TIMEZONE ERROR: %s" % repr(ex)) return -3
def get_simulcast(): url = 'https://sexyhot.globo.com/api/v1/simulcast' simulcast = client.request(url) program_title = simulcast['nowEvent']['title'] program_start = simulcast['nowEvent']['date'] program_stop = simulcast['nextEvent']['date'] program_start_date = util.strptime_workaround(program_start, '%Y-%m-%dT%H:%M:%S-03:00') program_stop_date = util.strptime_workaround(program_stop, '%Y-%m-%dT%H:%M:%S-03:00') utc_timezone = control.get_current_brasilia_utc_offset() duration = util.get_total_seconds(program_stop_date - program_start_date) return { 'program_title': program_title, 'duration_seconds': duration, 'start_date': program_start_date - datetime.timedelta(hours=(utc_timezone)) }
def channel_directory(self, items): if items is None or len(items) == 0: control.idle() sys.exit() sysaddon = sys.argv[0] syshandle = int(sys.argv[1]) try: isOld = False control.item().getArt('type') except: isOld = True refreshMenu = control.lang(32072).encode('utf-8') list_items = [] for order, channel in enumerate(items): label = channel['name'] meta = channel meta.update({'mediatype': channel['mediatype'] if 'mediatype' in channel else 'tvshow'}) # string - "video", "movie", "tvshow", "season", "episode" or "musicvideo" meta.update({'playcount': 0, 'overlay': 6}) meta.update({'duration': channel['duration']}) if 'duration' in channel else None meta.update({'title': channel['title']}) if 'title' in channel else None meta.update({'tagline': channel['tagline']}) if 'tagline' in channel else None meta.update({'year': channel['year']}) if 'year' in channel else None meta.update({'sorttitle': meta['title']}) meta.update({'title': meta['name']}) sysmeta = urllib.quote_plus(json.dumps(meta)) id_globo_videos = channel['id'] brplayprovider = channel['brplayprovider'] if 'brplayprovider' in channel else None isFolder = channel['isFolder'] == 'true' if 'isFolder' in channel else False isPlayable = channel['playable'] == 'true' if 'playable' in channel else False url = channel['url'] if 'url' in channel else '%s?action=playlive&provider=%s&id_globo_videos=%s&isFolder=%s&meta=%s&t=%s' % (sysaddon, brplayprovider, id_globo_videos, isFolder, sysmeta, self.systime) cm = [(refreshMenu, 'RunPlugin(%s?action=refresh)' % sysaddon)] if isOld is True: cm.append((control.lang2(19033).encode('utf-8'), 'Action(Info)')) item = control.item(label=label) fanart = channel['fanart'] art = {'icon': channel['logo'], 'fanart': fanart} if 'poster' in channel: art.update({'poster': channel['poster']}) if 'banner' in channel: art.update({'banner': channel['banner']}) if 'clearart' in channel: art.update({'clearart': channel['clearart']}) if 'clearlogo' in channel: art.update({'clearlogo': channel['clearlogo']}) if 'landscape' in channel: art.update({'landscape': channel['landscape']}) if 'thumb' in channel: art.update({'thumb': channel['thumb']}) item.setArt(art) if 'logo' in channel and 'logo2' in channel: item.setProperty('Logo1', channel['logo']) item.setProperty('Logo2', channel['logo2']) item.setProperty('Initials1', channel['initials1']) item.setProperty('Initials2', channel['initials2']) if 'live' in channel: item.setProperty('Live', str(channel['live'])) if 'gamedetails' in channel: item.setProperty('GameDetails', channel['gamedetails']) item.setProperty('Fanart_Image', fanart) if 'hd' not in channel or channel['hd'] == True: video_info = {'aspect': 1.78, 'width': 1280, 'height': 720} else: video_info = {'aspect': 1.78, 'width': 720, 'height': 480} item.addStreamInfo('video', video_info) item.addContextMenuItems(cm) item.setProperty('IsPlayable', 'false' if isFolder or not isPlayable else 'true') item.setInfo(type='video', infoLabels=meta) item.setContentLookup(False) if 'duration' in channel and channel['duration'] is not None: duration = float(meta['duration']) startdate = util.strptime_workaround(channel['dateadded'], '%Y-%m-%d %H:%M:%S') if 'dateadded' in channel else None offset = float(util.get_total_seconds(datetime.datetime.now() - startdate)) if startdate else 0 item.setProperty('Progress', str((offset / duration) * 100) if duration else str(0)) item.setProperty('totaltime', str(duration)) # if not isFolder: # item.setMimeType("application/vnd.apple.mpegurl") list_items.append((url, item, isFolder)) # control.addSortMethod(int(sys.argv[1]), control.SORT_METHOD_VIDEO_SORT_TITLE) # control.addSortMethod(int(sys.argv[1]), control.SORT_METHOD_DATEADDED) # control.addSortMethod(int(sys.argv[1]), control.SORT_METHOD_LABEL_IGNORE_FOLDERS) control.addItems(syshandle, list_items) control.category(handle=syshandle, category=control.lang(32001).encode('utf-8')) content = 'LiveTV' if control.isJarvis else 'tvshows' control.content(syshandle, content) control.directory(syshandle, cacheToDisc=False)
def __get_full_day_schedule(today, affiliate='RJ'): url = "https://api.globoplay.com.br/v1/epg/%s/praca/%s?api_key=%s" % (today, affiliate, GLOBOPLAY_APIKEY) headers = {'Accept-Encoding': 'gzip'} slots = client.request(url, headers=headers)['gradeProgramacao']['slots'] result = [] for index, slot in enumerate(slots): cast = None castandrole = None if 'elenco' in slot: try: cast_raw = slot['elenco'].split('||') cast = [c.strip() for c in cast_raw[0].split(',')] if cast_raw is not None and len(cast_raw) > 0 else None if cast_raw is not None and len(cast_raw) > 1 and cast_raw[1].strip().startswith('Elenco de dublagem:'): castandrole_raw = cast_raw[1].strip().split('Elenco de dublagem:') if len(castandrole_raw) > 1: #Dubladores e seus personagens castandrole_raw = castandrole_raw[1].split('Outras Vozes:') castandrole = [(c.strip().split(':')[1].strip(), c.strip().split(':')[0].strip()) for c in castandrole_raw[0].split('/')] if len(castandrole_raw) > 1: #Outros dubladores sem papel definido castandrole = [(c.strip(), 'Outros') for c in castandrole_raw[1].split('/')] except Exception as ex: control.log("ERROR POPULATING CAST: %s" % repr(ex)) pass program_datetime_utc = util.strptime_workaround(slot['data_exibicao_e_horario']) + datetime.timedelta(hours=3) program_datetime = program_datetime_utc + util.get_utc_delta() # program_local_date_string = datetime.datetime.strftime(program_datetime, '%d/%m/%Y %H:%M') title = slot['nome_programa'] if 'nome_programa' in slot else None if slot["tipo"] == "confronto": showtitle = slot['confronto']['titulo_confronto'] + ' - ' + slot['confronto']['participantes'][0]['nome'] + ' X ' + slot['confronto']['participantes'][1]['nome'] else: showtitle = slot['nome'] if 'nome' in slot else None next_start = slots[index+1]['data_exibicao_e_horario'] if index+1 < len(slots) else None next_start = (util.strptime_workaround(next_start) + datetime.timedelta(hours=3) + util.get_utc_delta()) if next_start else datetime.datetime.now() item = { "tagline": slot['chamada'] if 'chamada' in slot else slot['nome'], "closed_caption": slot['closed_caption'], "facebook": slot['facebook'], "twitter": slot['twitter'], "hd": slot['hd'], "id": slot['id'], "id_programa": slot['id_programa'], "id_webmedia": slot['id_webmedia'], "fanart": 'https://s02.video.glbimg.com/x720/%s.jpg' % get_globo_live_id(), "thumb": slot['imagem'], "logo": slot['logo'], "clearlogo": slot['logo'], "poster": slot['poster'] if 'poster' in slot else 'None', "subtitle": slot['nome'], "title": title, "plot": slot['resumo'] if 'resumo' in slot else None, #program_local_date_string + ' - ' + (slot['resumo'] if 'resumo' in slot else showtitle.replace(' - ', '\n') if showtitle and len(showtitle) > 0 else slot['nome_programa']), "plotoutline": datetime.datetime.strftime(program_datetime, '%H:%M') + ' - ' + datetime.datetime.strftime(next_start, '%H:%M'), "mediatype": 'episode' if showtitle and len(showtitle) > 0 else 'video', "genre": slot['tipo_programa'], "datetimeutc": program_datetime_utc, "dateadded": datetime.datetime.strftime(program_datetime, '%Y-%m-%d %H:%M:%S'), # 'StartTime': datetime.datetime.strftime(program_datetime, '%H:%M:%S'), # 'EndTime': datetime.datetime.strftime(next_start, '%H:%M:%S'), 'duration': util.get_total_seconds(next_start - program_datetime) } if showtitle and len(showtitle) > 0: item.update({ 'tvshowtitle': showtitle }) if slot['tipo'] == 'filme': item.update({ "originaltitle": slot['titulo_original'] if 'titulo_original' in slot else None, 'genre': slot['genero'] if 'genero' in slot else None, 'year': slot['ano'] if 'ano' in slot else None, 'director': slot['direcao'] if 'direcao' in slot else None }) if cast: item.update({ 'cast': cast }) if castandrole: item.update({ 'castandrole': castandrole, }) result.append(item) return result
def __get_universal_epg(): utc_timezone = control.get_current_brasilia_utc_offset() utc_now = datetime.datetime.today().utcnow() now = utc_now + datetime.timedelta(hours=utc_timezone) epg_url = 'http://ancine.grade.globosat.tv/programada/01253766000140_UniversalChannel%s.csv' % datetime.datetime.strftime(now, '%Y%m%d') # '20180205' epg_csv = cache.get(client.request, 2, epg_url) epg_data = csv.reader(epg_csv.splitlines(), delimiter='\\', quotechar='"') for program in list(epg_data): p_date = program[0] p_start = program[1] p_end = program[2] original_title = program[3] director = program[4] title = program[5] tvshow = program[6] episode = program[7] country = program[8] year = program[9] rating = program[10] plot = program[11] start_time = util.strptime_workaround(p_date + ' ' + p_start, '%Y%m%d %H:%M') - datetime.timedelta(hours=(utc_timezone)) end_time = util.strptime_workaround(p_date + ' ' + p_end, '%Y%m%d %H:%M') - datetime.timedelta(hours=(utc_timezone)) start_hour = p_start.split(':')[0] end_hour = p_end.split(':')[0] if int(end_hour) < int(start_hour): end_time = end_time + datetime.timedelta(days=1) if end_time > utc_now > start_time: studio = 'Universal Channel' return { 'original_title': original_title, 'director': director, 'title': title, 'tvshowtitle': tvshow, 'episode': episode, 'country': country, 'year': year, 'rating': rating, 'plot': plot, 'duration': util.get_total_seconds(end_time - start_time), "dateadded": datetime.datetime.strftime(start_time + util.get_utc_delta(), '%Y-%m-%d %H:%M:%S'), "plotoutline": datetime.datetime.strftime(start_time + util.get_utc_delta(), '%H:%M') + ' - ' + datetime.datetime.strftime(end_time + util.get_utc_delta(), '%H:%M'), } return { 'original_title': None, 'director': None, 'title': None, 'tvshowtitle': None, 'episode': None, 'country': None, 'year': None, 'rating': None, 'plot': None, 'duration': None, "dateadded": None }
def get_videos(url): from datetime import timedelta import time html = client.request(url, headers={'Cookie': 'disclaimer-sexyhotplay=1;'}) soup = bs(html) list = soup.find('ul', attrs={'class': 'recipiente-1'}) items = list.findAll('li', recursive=False) next_page = soup.find('a', attrs={'id': 'next-page'}) if control.setting('sexy_hot_pagination') == 'false': oldUrl = url while next_page != None and next_page[ 'data-page'] != None and next_page['data-orderby'] != None: url = util.addUrlParameters( url, { 'pagina': int(next_page['data-page']) + 1, 'ordem': next_page['data-orderby'] }) control.log("URL: %s" % url) if url == oldUrl: break oldUrl = url html = client.request( url, headers={'Cookie': 'disclaimer-sexyhotplay=1;'}) soup = bs(html) list = soup.find('ul', attrs={'class': 'recipiente-1'}) items += list.findAll('li', recursive=False) next_page = soup.find('a', attrs={'id': 'next-page'}) videos = [] for item in items: div = item.find('div') if div == None: continue img = item.find('img', attrs={'class': 'imagem'}) span = item.find('span', attrs={'class': 'chapeu'}) area = div.find('div', attrs={'class': 'area'}) link = area.find('a', attrs={'class': 'subtitulo'}) t = time.strptime(span.string, '%H:%M:%S') delta = timedelta(hours=t.tm_hour, minutes=t.tm_min, seconds=t.tm_sec) duration = util.get_total_seconds(delta) id_sexyhot = re.findall(r'\d+', link['href'])[-1] title = link['title'] title = " ".join([x.capitalize() for x in title.split(" ")]) plot = area.find('div', attrs={'class': 'informacao'}).string.strip() poster = img['src'] actors_html = area.find('li', attrs={ 'class': 'metadado' }).findAll('strong') actors = [actor.string for actor in actors_html] videos.append({ 'id_sexyhot': id_sexyhot, 'mediatype': 'movie', 'overlay': 6, 'duration': duration, 'title': title, # 'tagline': plot, 'plot': plot, 'cast': actors, 'poster': poster, 'fanart': os.path.join(artPath, 'fanart_sexyhot.png'), # 'logo': os.path.join(artPath, 'logo_sexyhot.png'), # 'thumb': os.path.join(artPath, 'logo_sexyhot.png') }) next_page_url = None if control.setting('sexy_hot_pagination') == 'true': #More Videos if next_page != None and next_page['data-page'] != None and next_page[ 'data-orderby'] != None: next_page_url = util.addUrlParameters( url, { 'pagina': int(next_page['data-page']) + 1, 'ordem': next_page['data-orderby'] }) return videos, next_page_url
def download_segment_media(self, segment_uri, stream): if self.g_stopEvent and self.g_stopEvent.isSet(): return self.log("REQUESTED MEDIA: %s" % segment_uri) while not self.media_list or not self.media_list.segments or len( self.media_list.segments) == 0: self.log("WAITING FOR MEDIA LIST...") xbmc.sleep(50) if self.g_stopEvent and self.g_stopEvent.isSet(): return is_vod = (self.media_list.playlist_type or '').lower() == 'vod' if is_vod: original_segment_index = -1 media_sequence = int(self.original_media_list.media_sequence) found = False self.log("ORIGINAL MEDIA LIST: %s" % self.original_media_list.dumps()) for segment_index, segment in enumerate( self.original_media_list.segments): self.log("SEARCHING FOR SEGMENT: '%s'.endswith('%s') = %s" % (segment.uri, segment_uri, segment.uri.endswith(segment_uri))) if segment_uri.endswith(segment.uri): original_segment_index = segment_index found = True break if not found: raise Exception( "SEGMENT NOT FOUND!!! Requested URI: %s | Parsed Number: %s | Media Sequence: %s" % (segment_uri, original_segment_index, media_sequence)) segment_number = media_sequence + original_segment_index while not self.media_list or not self.media_list.segments or self.media_list.segments == 0 or media_sequence > int( self.media_list.media_sequence): xbmc.sleep(100) if self.g_stopEvent and self.g_stopEvent.isSet(): return segment_number_index = segment_number - int( self.media_list.media_sequence) self.log( "REQUESTED SEGMENT MEDIA SEQUENCE: %s | REQUESTED PARSED INDEX: %s | SELECTED SEGMENT MEDIA SEQUENCE: %s | SELECTED MEDIA NUMBER: %s | INDEX: %s | LENGTH: %s" % (media_sequence, original_segment_index, self.media_list.media_sequence, segment_number, segment_number_index, len(self.media_list.segments))) segment = self.media_list.segments[segment_number_index] else: original_date = self.original_media_list.program_date_time current_date = self.media_list.program_date_time self.log("ORIGINAL DATE/TIME: %s" % original_date) self.log("CURRENT DATE/TIME: %s" % current_date) while original_date > current_date: self.log("OLD PLAYLIST, RELOADING...") #self.__reload_segment_playlist(0, 0, 0, 0) xbmc.sleep(int(self.media_list.target_duration) * 1000 / 2) original_date = self.original_media_list.program_date_time current_date = self.media_list.program_date_time self.log("ORIGINAL DATE/TIME: %s" % original_date) self.log("CURRENT DATE/TIME: %s" % current_date) self.log("ORIGINAL PLAYLIST: %s" % self.original_media_list.dumps()) self.log("CURRENT PLAYLIST: %s" % self.media_list.dumps()) time_delta = current_date - original_date delta_seconds = util.get_total_seconds(time_delta) target_duration = int(self.media_list.target_duration) segments_delta = delta_seconds / target_duration self.log("SEGMENT DELTA: %s" % segments_delta) for segment_index, segment in enumerate( self.original_media_list.segments): self.log("SEARCHING FOR SEGMENT %s: '%s'.endswith('%s') = %s" % (segment_index, segment.uri, segment_uri, segment.uri.endswith(segment_uri))) if segment_uri.endswith(segment.uri): original_segment_index = segment_index found = True break if not found: raise Exception( "SEGMENT NOT FOUND!!! Requested URI: %s | Parsed Number: %s" % (segment_uri, original_segment_index)) segment_index = original_segment_index - segments_delta self.log("SEGMENT INDEX: %s" % segment_index) segment = self.media_list.segments[segment_index] # segment_number = self.__get_segment_number(segment_uri) # # segment_result_list = filter(lambda k: self.__get_segment_number(k.uri) == segment_number, self.media_list.segments) # # while len(segment_result_list) == 0: # self.log("WAITING FOR SEGMENT (URI: %s | Number: %s | Media List: %s)..." % (segment_uri, segment_number, self.media_list.dumps())) # xbmc.sleep(50) # if self.g_stopEvent and self.g_stopEvent.isSet(): # return # segment_result_list = filter(lambda k: self.__get_segment_number(k.uri) == segment_number, self.media_list.segments) # # segment = segment_result_list[0] self.log("REQUESTED MEDIA URI: %s | DOWNLOADING MEDIA URI: %s" % (segment_uri, segment.absolute_uri)) segment_size = 0.0 start = datetime.datetime.now() for chunk in self.__download_chunks(segment.absolute_uri): if self.g_stopEvent.isSet(): stream.flush() return segment_size += len(chunk) stream.write(chunk) stream.flush() stop = datetime.datetime.now() self.queue.put((start, stop, segment_size, segment.duration))
def __get_full_day_schedule(today, affiliate='RJ'): # utc_timezone = control.get_current_brasilia_utc_offset() url = "https://api.globoplay.com.br/v1/epg/%s/praca/%s?api_key=%s" % ( today, affiliate, GLOBOPLAY_APIKEY) headers = {'Accept-Encoding': 'gzip'} slots = (requests.get(url, headers=headers).json() or {}).get('gradeProgramacao', {}).get('slots', []) result = [] if not slots: return result for index, slot in enumerate(slots): cast = None castandrole = None if 'elenco' in slot: try: cast_raw = slot['elenco'].split('||') cast = [ c.strip() for c in cast_raw[0].split(',') ] if cast_raw is not None and len(cast_raw) > 0 else None if cast_raw is not None and len(cast_raw) > 1 and cast_raw[ 1].strip().startswith('Elenco de dublagem:'): castandrole_raw = cast_raw[1].strip().split( 'Elenco de dublagem:') if len(castandrole_raw ) > 1: #Dubladores e seus personagens castandrole_raw = castandrole_raw[1].split( 'Outras Vozes:') castandrole = [ (c.strip().split(':')[1].strip(), c.strip().split(':')[0].strip()) for c in castandrole_raw[0].split('/') ] if len(castandrole_raw[0].split('/')) > 0 else None if len(castandrole_raw ) > 1: #Outros dubladores sem papel definido castandrole = [ (c.strip(), 'Outros') for c in castandrole_raw[1].split('/') ] except Exception as ex: control.log("ERROR POPULATING CAST: %s" % repr(ex)) pass # program_datetime_utc = util.strptime_workaround(slot['data_exibicao_e_horario']) + datetime.timedelta(hours=(-utc_timezone)) # program_datetime = program_datetime_utc + util.get_utc_delta() program_datetime = datetime.datetime.utcfromtimestamp( slot.get('start_time')) program_datetime_utc = program_datetime # program_local_date_string = datetime.datetime.strftime(program_datetime, '%d/%m/%Y %H:%M') title = slot['nome_programa'] if 'nome_programa' in slot else None if "tipo_programa" in slot and slot["tipo_programa"] == "confronto": showtitle = slot['confronto']['titulo_confronto'] + ' - ' + slot[ 'confronto']['participantes'][0]['nome'] + ' X ' + slot[ 'confronto']['participantes'][1]['nome'] else: showtitle = None # next_start = slots[index+1]['data_exibicao_e_horario'] if index+1 < len(slots) else None # next_start = (util.strptime_workaround(next_start) + datetime.timedelta(hours=(-utc_timezone)) + util.get_utc_delta()) if next_start else datetime.datetime.now() next_start = datetime.datetime.utcfromtimestamp( slots[index + 1].get('start_time') ) if index + 1 < len(slots) else datetime.datetime.utcnow() program_time_desc = datetime.datetime.strftime( program_datetime, '%H:%M') + ' - ' + datetime.datetime.strftime( next_start, '%H:%M') tags = [program_time_desc] if slot.get('closed_caption'): tags.append(slot.get('closed_caption')) if slot.get('facebook'): tags.append(slot.get('facebook')) if slot.get('twitter'): tags.append(slot.get('twitter')) description = '%s | %s' % (program_time_desc, slot.get('resumo', showtitle) or showtitle) item = { "tagline": slot['chamada'] if 'chamada' in slot else slot['nome_programa'], # "closed_caption": slot['closed_caption'] if 'closed_caption' in slot else None, # "facebook": slot['facebook'] if 'facebook' in slot else None, # "twitter": slot['twitter'] if 'twitter' in slot else None, # "hd": slot['hd'] if 'hd' in slot else True, # "id": slot['id_programa'], "id_programa": slot['id_programa'], "id_webmedia": slot['id_webmedia'], "subtitle": slot['resumo'] if slot['nome_programa'] == 'Futebol' else None, "title": title, 'tvshowtitle': showtitle, "plot": description, # "plotoutline": datetime.datetime.strftime(program_datetime, '%H:%M') + ' - ' + datetime.datetime.strftime(next_start, '%H:%M'), "genre": slot['tipo_programa'], "tag": tags, "datetimeutc": program_datetime_utc, "dateadded": datetime.datetime.strftime(program_datetime, '%Y-%m-%d %H:%M:%S'), # 'StartTime': datetime.datetime.strftime(program_datetime, '%H:%M:%S'), # 'EndTime': datetime.datetime.strftime(next_start, '%H:%M:%S'), 'duration': util.get_total_seconds(next_start - program_datetime), 'art': { # "fanart": 'https://s02.video.glbimg.com/x720/%s.jpg' % get_globo_live_id(), "thumb": slot['imagem'], # "icon": slot['logo'] if 'logo' in slot else None, "clearlogo": slot['logo'] if 'logo' in slot else None, "poster": slot['poster'] if 'poster' in slot else None, } } if slot['tipo_programa'] == 'filme': item.update({ "originaltitle": slot['titulo_original'] if 'titulo_original' in slot else None, 'genre': slot['genero'] if 'genero' in slot else None, 'year': slot['ano'] if 'ano' in slot else None, 'director': slot['direcao'] if 'direcao' in slot else None }) if cast: item.update({'cast': cast}) if castandrole: item.update({ 'castandrole': castandrole, }) result.append(item) return result