def callBackDialogProgressBar(function_obj, function_args, heading, failure_message=None, line1='Please wait...', line2='Retrieved $current_index of $total_it items', line3='To go back, press the Cancel button'): total_iteration = len(function_args) current_index = 0 ProgressDisplayer().end() pDialog = None if not SUPPRESS_DIALOG_MSG: pDialog = xbmcgui.DialogProgress() pDialog.create(heading, line1, line2.replace('$total_it', str(total_iteration)).replace('$current_index', str(current_index)), line3) pDialog.update(1) Logger.logDebug('Total Iterations = ' + str(total_iteration)) function_returns = [] isCanceled = False for arg in function_args: try: returnedObj = function_obj(arg) if returnedObj is not None and type(returnedObj) is list: function_returns.extend(returnedObj) elif returnedObj is not None: function_returns.append(returnedObj) if not SUPPRESS_DIALOG_MSG and pDialog is not None: current_index = current_index + 1 percent = (current_index * 100) / total_iteration pDialog.update(percent, line1, line2.replace('$total_it', str(total_iteration)).replace('$current_index', str(current_index)), line3) if (pDialog.iscanceled()): isCanceled = True break except Exception, e: if not SUPPRESS_DIALOG_MSG and pDialog is not None and failure_message is not None: pDialog.close() dialog = xbmcgui.Dialog() dialog.ok('[B][COLOR red]FAILED: [/COLOR][/B]Info Retrieval Process', failure_message, 'You may like to try again later or use other source if available') Logger.logFatal(e) raise Exception(ExceptionHandler.DONOT_DISPLAY_ERROR, '') if isCanceled: raise Exception(ExceptionHandler.PROCESS_STOPPED, 'It looks like you don\'t want wait more|Process was stopped in between')
def parseSignature(s): ''' use decryption solution by Youtube-DL project ''' if len(s) == 93: return s[86:29:-1] + s[88] + s[28:5:-1] elif len(s) == 92: return s[25] + s[3:25] + s[0] + s[26:42] + s[79] + s[43:79] + s[91] + s[80:83] elif len(s) == 91: return s[84:27:-1] + s[86] + s[26:5:-1] elif len(s) == 90: return s[25] + s[3:25] + s[2] + s[26:40] + s[77] + s[41:77] + s[89] + s[78:81] elif len(s) == 89: return s[84:78:-1] + s[87] + s[77:60:-1] + s[0] + s[59:3:-1] elif len(s) == 88: return s[7:28] + s[87] + s[29:45] + s[55] + s[46:55] + s[2] + s[56:87] + s[28] elif len(s) == 87: return s[6:27] + s[4] + s[28:39] + s[27] + s[40:59] + s[2] + s[60:] elif len(s) == 86: return s[80:72:-1] + s[16] + s[71:39:-1] + s[72] + s[38:16:-1] + s[82] + s[15::-1] elif len(s) == 85: return s[3:11] + s[0] + s[12:55] + s[84] + s[56:84] elif len(s) == 84: return s[78:70:-1] + s[14] + s[69:37:-1] + s[70] + s[36:14:-1] + s[80] + s[:14][::-1] elif len(s) == 83: return s[80:63:-1] + s[0] + s[62:0:-1] + s[63] elif len(s) == 82: return s[80:37:-1] + s[7] + s[36:7:-1] + s[0] + s[6:0:-1] + s[37] elif len(s) == 81: return s[56] + s[79:56:-1] + s[41] + s[55:41:-1] + s[80] + s[40:34:-1] + s[0] + s[33:29:-1] + s[34] + s[28:9:-1] + s[29] + s[8:0:-1] + s[9] elif len(s) == 80: return s[1:19] + s[0] + s[20:68] + s[19] + s[69:80] elif len(s) == 79: return s[54] + s[77:54:-1] + s[39] + s[53:39:-1] + s[78] + s[38:34:-1] + s[0] + s[33:29:-1] + s[34] + s[28:9:-1] + s[29] + s[8:0:-1] + s[9] else: Logger.logFatal(u'Unable to decrypt signature, key length %d not supported; retrying might work' % (len(s))) return s
def retrieveVideoLinks(request_obj, response_obj): video_source_id = 1 video_source_img = None video_source_name = None video_part_index = 0 video_playlist_items = [] ignoreAllLinks = False content = BeautifulSoup.SoupStrainer('blockquote', {'class':re.compile(r'\bpostcontent\b')}) soup = HttpClient().getBeautifulSoup(url=request_obj.get_data()['episodeUrl'], parseOnlyThese=content) for e in soup.findAll('br'): e.extract() Logger.logDebug(soup) if soup.has_key('div'): soup = soup.findChild('div', recursive=False) prevChild = '' prevAFont = None for child in soup.findChildren(): if (child.name == 'img' or child.name == 'b' or (child.name == 'font' and not child.findChild('a'))): if (child.name == 'b' and prevChild == 'a') or (child.name == 'font' and child == prevAFont): continue else: if len(video_playlist_items) > 0: response_obj.addListItem(__preparePlayListItem__(video_source_id, video_source_img, video_source_name, video_playlist_items)) if video_source_img is not None: video_source_id = video_source_id + 1 video_source_img = None video_source_name = None video_part_index = 0 video_playlist_items = [] ignoreAllLinks = False elif not ignoreAllLinks and child.name == 'a' and not re.search('multi', str(child['href']), re.IGNORECASE): video_part_index = video_part_index + 1 video_link = {} video_link['videoTitle'] = 'Source #' + str(video_source_id) + ' | ' + 'Part #' + str(video_part_index) + ' | ' + child.getText() video_link['videoLink'] = str(child['href']) try: try: __prepareVideoLink__(video_link) except Exception, e: Logger.logFatal(e) video_hosting_info = SnapVideo.findVideoHostingInfo(video_link['videoLink']) if video_hosting_info is None or video_hosting_info.get_video_hosting_name() == 'UrlResolver by t0mm0': raise video_link['videoSourceImg'] = video_hosting_info.get_video_hosting_image() video_link['videoSourceName'] = video_hosting_info.get_video_hosting_name() video_playlist_items.append(video_link) video_source_img = video_link['videoSourceImg'] video_source_name = video_link['videoSourceName'] item = ListItem() item.add_request_data('videoLink', video_link['videoLink']) item.add_request_data('videoTitle', video_link['videoTitle']) item.set_next_action_name('SnapAndPlayVideo') xbmcListItem = xbmcgui.ListItem(label='Source #' + str(video_source_id) + ' | ' + 'Part #' + str(video_part_index) , iconImage=video_source_img, thumbnailImage=video_source_img) item.set_xbmc_list_item_obj(xbmcListItem) response_obj.addListItem(item) prevAFont = child.findChild('font') except:
def retrieveReloadedPlaylistVideoItems(playlistId): Logger.logFatal('YouTube Reloaded Playlist ID = ' + playlistId) soupXml = HttpUtils.HttpClient().getBeautifulSoup('http://gdata.youtube.com/feeds/api/playlists/' + playlistId) videoItemsList = [] for media in soupXml.findChildren('track'): videoUrl = media.findChild('location').getText() videoItemsList.append(videoUrl) return videoItemsList
def retrievePlaylistVideoItems(playlistId): Logger.logFatal('YouTube Playlist ID = ' + playlistId) soupXml = HttpUtils.HttpClient().getBeautifulSoup('http://gdata.youtube.com/feeds/api/playlists/' + playlistId + '?max-results=50') videoItemsList = [] for media in soupXml.findChildren('media:player'): videoUrl = str(media['url']) videoItemsList.append(videoUrl) return videoItemsList
def retrieveReloadedPlaylistVideoItems(playlistId): Logger.logFatal('YouTube Reloaded Playlist ID = ' + playlistId) soupXml = HttpUtils.HttpClient().getBeautifulSoup( 'http://gdata.youtube.com/feeds/api/playlists/' + playlistId) videoItemsList = [] for media in soupXml.findChildren('track'): videoUrl = media.findChild('location').getText() videoItemsList.append(videoUrl) return videoItemsList
def retrievePlaylistVideoItems(playlistId): Logger.logFatal('YouTube Playlist ID = ' + playlistId) soupXml = HttpUtils.HttpClient().getBeautifulSoup( 'http://gdata.youtube.com/feeds/api/playlists/' + playlistId + '?max-results=50') videoItemsList = [] for media in soupXml.findChildren('media:player'): videoUrl = str(media['url']) videoItemsList.append(videoUrl) return videoItemsList
def addEmbeddedVideoInfoInPlayableItems(request_obj, response_obj): items = response_obj.get_item_list() playable_items = [] for item in items: if item.get_next_action_name() == 'Play': playable_items.append(item) try: XBMCInterfaceUtils.callBackDialogProgressBar(getattr(sys.modules[__name__], '__addEmbeddedVideoInfo_in_item__'), playable_items, 'Retrieving video info', 'Failed to retrieve video information, please try again later') except Exception, e: Logger.logFatal(e)
def addVideoInfoInPlayableItems(request_obj, response_obj): items = response_obj.get_item_list() playable_items = [] for item in items: if item.get_next_action_name() == 'Play': playable_items.append(item) try: XBMCInterfaceUtils.callBackDialogProgressBar(getattr(sys.modules[__name__], '__addVideoInfo_in_item'), playable_items, 'Retrieving video info', failure_message=None) except Exception, e: Logger.logFatal(e)
def __retrieveChannelTVShows__(tvChannelObj): running_tvshows = [] finished_tvshows = [] try: running_tvshows = __retrieveTVShows__(tvChannelObj["running_tvshows_url"]) if(len(running_tvshows) == 0): running_tvshows.append({"name":"ENTER TO VIEW :: This is the only easy way to view!", "url":BASE_WSITE_URL + tvChannelObj["running_tvshows_url"]}) except Exception, e: Logger.logFatal(e) Logger.logDebug('Failed to load a channel... Continue retrieval of next tv show')
def callBackDialogProgressBar( function_obj, function_args, heading, failure_message=None, line1='Please wait...', line2='Retrieved $current_index of $total_it items', line3='To go back, press the Cancel button'): total_iteration = len(function_args) current_index = 0 ProgressDisplayer().end() pDialog = None if not SUPPRESS_DIALOG_MSG: pDialog = xbmcgui.DialogProgress() pDialog.create( heading, line1, line2.replace('$total_it', str(total_iteration)).replace( '$current_index', str(current_index)), line3) pDialog.update(1) Logger.logDebug('Total Iterations = ' + str(total_iteration)) function_returns = [] isCanceled = False for arg in function_args: try: returnedObj = function_obj(arg) if returnedObj is not None and type(returnedObj) is list: function_returns.extend(returnedObj) elif returnedObj is not None: function_returns.append(returnedObj) if not SUPPRESS_DIALOG_MSG and pDialog is not None: current_index = current_index + 1 percent = (current_index * 100) / total_iteration pDialog.update( percent, line1, line2.replace('$total_it', str(total_iteration)).replace( '$current_index', str(current_index)), line3) if (pDialog.iscanceled()): isCanceled = True break except Exception, e: if not SUPPRESS_DIALOG_MSG and pDialog is not None and failure_message is not None: pDialog.close() dialog = xbmcgui.Dialog() dialog.ok( '[B][COLOR red]FAILED: [/COLOR][/B]Info Retrieval Process', failure_message, 'You may like to try again later or use other source if available' ) Logger.logFatal(e) raise Exception(ExceptionHandler.DONOT_DISPLAY_ERROR, '') if isCanceled: raise Exception( ExceptionHandler.PROCESS_STOPPED, 'It looks like you don\'t want wait more|Process was stopped in between' )
def addPlaylistVideosInfoInPlayableItems(request_obj, response_obj): items = response_obj.get_item_list() try: for item in items: if item.get_next_action_name() == 'Play': videoItems = __processPlaylistAndAddVideoItem__(item) if videoItems is not None and len(videoItems) > 0: items.remove(item) items.extend(videoItems) except Exception, e: Logger.logFatal(e)
def judgeTurtleNextAction(self, actionObj): ProgressDisplayer().displayMessage(80, line1='Preparing items for display or play', line2='Total items: ' + str(len(self.response_obj.get_item_list()))) if self.response_obj.get_redirect_action_name() is None: isAnyPlayableItem = False isItemsList = False playlist_type = None for item in self.response_obj.get_item_list(): nextActionId = actionObj.get_next_action_map()[item.get_next_action_name()] if nextActionId == '__play__': if item.get_moving_data().has_key('pluginUrl'): XBMCInterfaceUtils.executePlugin(item.get_moving_data()['pluginUrl']) else: if not isAnyPlayableItem and not XBMCInterfaceUtils.isPlaying(): XBMCInterfaceUtils.clearPlayList() # Clear playlist item only when at least one video item is found. playlist_type = XBMCInterfaceUtils.addPlayListItem(item) isAnyPlayableItem = True elif nextActionId == '__service_response__': # Do Nothing , get response object from container for parameters to be returned pass elif nextActionId == '__download__': downloadPath = self.addon_context.addon.getSetting('downloadPath') if downloadPath is None or downloadPath == '': XBMCInterfaceUtils.displayDialogMessage("Download path not provided", "Please provide download path in add-on settings.", "The download path should be a local directory.") self.addon_context.addon.openSettings(sys.argv[ 0 ]) downloadPath = self.addon_context.addon.getSetting('downloadPath') if downloadPath is not None and downloadPath != '': XBMCInterfaceUtils.downloadVideo(item, downloadPath) elif nextActionId == '__resolved__': XBMCInterfaceUtils.setResolvedMediaUrl(item) else: isItemsList = True is_Folder = self.addon_context.isNextActionFolder(actionObj.get_action_id(), item.get_next_action_name()) downloadAction = self.addon_context.getDownloadActionIfDownloadable(actionObj.get_action_id(), item.get_next_action_name()) if(downloadAction is not None): XBMCInterfaceUtils.addContextMenuItem(item, 'Download Video', downloadAction) XBMCInterfaceUtils.addFolderItem(item, nextActionId, is_Folder) del item # deletes item if isAnyPlayableItem == True: ProgressDisplayer().end() try: if playlist_type is not None: XBMCInterfaceUtils.play(list_type=playlist_type) else: XBMCInterfaceUtils.play() except Exception, e: Logger.logFatal(e) elif isItemsList: if self.response_obj.get_xbmc_sort_method() is not None: XBMCInterfaceUtils.sortMethod(self.response_obj.get_xbmc_sort_method()) if self.response_obj.get_xbmc_content_type() is not None: XBMCInterfaceUtils.setContentType(self.response_obj.get_xbmc_content_type()) XBMCInterfaceUtils.setSortMethods()
def start(addon_id, addon_ver=None): try: Logger.logDebug(sys.argv) global __addon_id__ __addon_id__ = addon_id __addon_ver__ = addon_ver containerObj = Container(addon_id=addon_id, addon_ver=addon_ver) action_id = containerObj.getTurtleRequest().get_action_id() containerObj.performAction(action_id) except urllib2.URLError, e: Logger.logFatal(e) XBMCInterfaceUtils.displayDialogMessage('Unable to connect', 'Please choose a different source if available in add-on.', 'Website used in add-on is down, try to access using web browser.', 'Please share logs with developer if problem keeps coming!')
def getInstance(cls, *args, **kargs): '''Static method to have a reference to **THE UNIQUE** instance''' if cls.__instance is None: # Critical section start # cls.__lockObj.acquire() try: if cls.__instance is None: cls.__instance = object.__new__(cls) except Exception, e: Logger.logFatal('Error occurred while creating singleton obj') Logger.logFatal(e) raise # finally: # # Exit from critical section whatever happens # #cls.__lockObj.release() # # Critical section end # pass # Initialize **the unique** instance try: if cls.__instance is not None: cls.__instance.__initialize__(**kargs) except Exception, e: Logger.logFatal('Error occurred while initialization of singleton obj') Logger.logFatal(e) raise
def start(addon_id, service_name, context_root, default_port, allowed_port_range): server = None try: sys.argv = None # To handle the situations where some library expects system arguments. Main change made for t0mm0 urlresolver library. global __addon_id__ global __registered_services__ global __context_root__ global __port__ global __port_range__ global __service_name__ __addon_id__ = addon_id __context_root__ = context_root __port__ = default_port __port_range__ = allowed_port_range __service_name__ = service_name containerObj = Container(addon_id=addon_id) iconimage = AddonUtils.getCompleteFilePath(baseDirPath=containerObj.getAddonContext().addonPath, filename='icon.png') serviceport = int(containerObj.getAddonContext().addon.getSetting('serviceport')) XBMCInterfaceUtils.setSuppressDialogMsg(True) if serviceport < __port_range__[0] or serviceport > __port_range__[1] : containerObj.getAddonContext().addon.setSetting('serviceport', str(__port__)) serviceport = __port__ XBMCInterfaceUtils.displayNotification(__service_name__ + ' Service: Port updated', 'Service port set to default value 8181', iconimage=iconimage) server = JSONRPCServer(context_root=__context_root__, server_port=serviceport) server.registerService('serviceName', serviceMethod) defined_services = containerObj.getAddonContext().getTurtleServices() if len(defined_services) == 0: Logger.logError(__service_name__ + ' Service :: There are no services defined for registration, end this service program now.') return for service in defined_services: server.registerService(service.get_service_name(), serviceMethod) __registered_services__[service.get_service_name()] = service.get_action_id() Logger.logInfo(__service_name__ + ' Service :: service registered = %s @ %s' % (service.get_service_name(), __context_root__)) server.start() # XBMCInterfaceUtils.displayNotification(__service_name__ + ' Service has started', 'Use web browser PlayIt extension to play video.', iconimage=iconimage) while not xbmc.abortRequested: time.sleep(1) Logger.logInfo(__service_name__ + ' Service :: ABORT request received from XBMC. PlayIt service will stop now.') except Exception, e: Logger.logFatal(__service_name__ + ' Service :: ERROR OCCURRED: ' + str(e)) ExceptionHandler.handle(e)
def start(addon_id, addon_ver=None): try: Logger.logDebug(sys.argv) global __addon_id__ __addon_id__ = addon_id __addon_ver__ = addon_ver containerObj = Container(addon_id=addon_id, addon_ver=addon_ver) action_id = containerObj.getTurtleRequest().get_action_id() containerObj.performAction(action_id) except urllib2.URLError, e: Logger.logFatal(e) XBMCInterfaceUtils.displayDialogMessage( 'Unable to connect', 'Please choose a different source if available in add-on.', 'Website used in add-on is down, try to access using web browser.', 'Please share logs with developer if problem keeps coming!')
def __retrieveChannels__(tvChannels, dtUrl, channelType): contentDiv = BeautifulSoup.SoupStrainer('div', {'class':re.compile(r'\bhentry\b')}) soup = HttpClient().getBeautifulSoup(url=dtUrl, parseOnlyThese=contentDiv) for tvChannelTag in soup.div.findAll('div', recursive=False): try: tvChannel = {} running_tvshows = [] finished_tvshows = [] tmp_tvshows_list = None firstRow = False for tag in tvChannelTag.findAll(re.compile('div|a'), recursive=False): if tag.name == 'div' and tag.get('class') == 'nav_up': continue if not firstRow: channelImg = '' if(tag.find('img').has_key('src')): channelImg = str(tag.find('img')['src']) else: channelImg = str(tag.find('img')['file']) channelName = re.compile(BASE_WSITE_URL + '/category/(tv-serials|pakistan-tvs)/(.+?)/').findall(str(tag.find('a')['href']))[0][1] channelName = string.upper(channelName.replace('-', ' ')) Logger.logDebug(channelName) tvChannels[channelName] = tvChannel tvChannel['iconimage'] = channelImg tvChannel['channelType'] = channelType firstRow = True else: if tag.name == 'div' and tag.get('class') == 'dtLink': txt = tag.getText() Logger.logDebug(txt) if re.search('running', txt, flags=re.IGNORECASE): tmp_tvshows_list = running_tvshows tvChannel['running_tvshows'] = running_tvshows elif re.search('finished', txt, flags=re.IGNORECASE): tmp_tvshows_list = finished_tvshows tvChannel['finished_tvshows'] = finished_tvshows else: Logger.logWarning('UNKNOWN TV SHOW CATEGORY') elif tag.name == 'a': tvshowUrl = str(tag['href']) tvshowName = tag.getText().encode('utf-8') Logger.logDebug(tvshowName) tmp_tvshows_list.append({'name':HttpUtils.unescape(tvshowName), 'url':tvshowUrl}) except Exception, e: Logger.logFatal(e) Logger.logDebug(tvChannelTag)
global __addon_id__ __addon_id__ = addon_id __addon_ver__ = addon_ver containerObj = Container(addon_id=addon_id, addon_ver=addon_ver) action_id = containerObj.getTurtleRequest().get_action_id() containerObj.performAction(action_id) except urllib2.URLError, e: Logger.logFatal(e) XBMCInterfaceUtils.displayDialogMessage( 'Unable to connect', 'Please choose a different source if available in add-on.', 'Website used in add-on is down, try to access using web browser.', 'Please share logs with developer if problem keeps coming!') except Exception, e: Logger.logFatal(e) ExceptionHandler.handle(e) cleanUp() xbmcplugin.endOfDirectory(int(sys.argv[1])) def cleanUp(): try: containerObj = Container() containerObj.cleanUp() del containerObj httpClient = HttpUtils.HttpClient() httpClient.cleanUp() del httpClient except: pass
def judgeTurtleNextAction(self, actionObj): ProgressDisplayer().displayMessage( 80, line1='Preparing items for display or play', line2='Total items: ' + str(len(self.response_obj.get_item_list()))) if self.response_obj.get_redirect_action_name() is None: isAnyPlayableItem = False isItemsList = False playlist_type = None for item in self.response_obj.get_item_list(): nextActionId = actionObj.get_next_action_map()[ item.get_next_action_name()] if nextActionId == '__play__': if item.get_moving_data().has_key('pluginUrl'): XBMCInterfaceUtils.executePlugin( item.get_moving_data()['pluginUrl']) else: if not isAnyPlayableItem and not XBMCInterfaceUtils.isPlaying( ): XBMCInterfaceUtils.clearPlayList( ) # Clear playlist item only when at least one video item is found. playlist_type = XBMCInterfaceUtils.addPlayListItem( item) isAnyPlayableItem = True elif nextActionId == '__service_response__': # Do Nothing , get response object from container for parameters to be returned pass elif nextActionId == '__download__': downloadPath = self.addon_context.addon.getSetting( 'downloadPath') if downloadPath is None or downloadPath == '': XBMCInterfaceUtils.displayDialogMessage( "Download path not provided", "Please provide download path in add-on settings.", "The download path should be a local directory.") self.addon_context.addon.openSettings(sys.argv[0]) downloadPath = self.addon_context.addon.getSetting( 'downloadPath') if downloadPath is not None and downloadPath != '': XBMCInterfaceUtils.downloadVideo(item, downloadPath) elif nextActionId == '__resolved__': XBMCInterfaceUtils.setResolvedMediaUrl(item) else: isItemsList = True is_Folder = self.addon_context.isNextActionFolder( actionObj.get_action_id(), item.get_next_action_name()) downloadAction = self.addon_context.getDownloadActionIfDownloadable( actionObj.get_action_id(), item.get_next_action_name()) if (downloadAction is not None): XBMCInterfaceUtils.addContextMenuItem( item, 'Download Video', downloadAction) XBMCInterfaceUtils.addFolderItem(item, nextActionId, is_Folder) del item # deletes item if isAnyPlayableItem == True: ProgressDisplayer().end() try: if playlist_type is not None: XBMCInterfaceUtils.play(list_type=playlist_type) else: XBMCInterfaceUtils.play() except Exception, e: Logger.logFatal(e) elif isItemsList: if self.response_obj.get_xbmc_sort_method() is not None: XBMCInterfaceUtils.sortMethod( self.response_obj.get_xbmc_sort_method()) if self.response_obj.get_xbmc_content_type() is not None: XBMCInterfaceUtils.setContentType( self.response_obj.get_xbmc_content_type()) XBMCInterfaceUtils.setSortMethods()
def retrieveVideoInfo(video_id): video_info = VideoInfo() video_info.set_video_hosting_info(getVideoHostingInfo()) video_info.set_video_id(video_id) try: HttpUtils.HttpClient().enableCookies() video_info.set_video_image('http://i.ytimg.com/vi/' + video_id + '/default.jpg') html = HttpUtils.HttpClient().getHtmlContent(url='http://www.youtube.com/get_video_info?video_id=' + video_id + '&asv=3&el=detailpage&hl=en_US') stream_map = None html = html.decode('utf8') html = html.replace('\n', '') html = html.replace('\r', '') html = unicode(html + '&').encode('utf-8') if re.search('status=fail', html): # XBMCInterfaceUtils.displayDialogMessage('Video info retrieval failed', 'Reason: ' + ((re.compile('reason\=(.+?)\.').findall(html))[0]).replace('+', ' ') + '.') Logger.logInfo('YouTube video is removed for Id = ' + video_id + ' reason = ' + html) video_info.set_video_stopped(True) return video_info title = urllib.unquote_plus(re.compile('title=(.+?)&').findall(html)[0]).replace('/\+/g', ' ') video_info.set_video_name(title) stream_info = None if not re.search('url_encoded_fmt_stream_map=&', html): stream_info = re.compile('url_encoded_fmt_stream_map=(.+?)&').findall(html) stream_map = None if (stream_info is None or len(stream_info) == 0) and re.search('fmt_stream_map": "', html): stream_map = re.compile('fmt_stream_map": "(.+?)"').findall(html)[0].replace("\\/", "/") elif stream_info is not None: stream_map = stream_info[0] if stream_map is None: params = HttpUtils.getUrlParams(html) Logger.logDebug('ENTERING live video scenario...') for key in params: Logger.logDebug(key + " : " + urllib.unquote_plus(params[key])) hlsvp = urllib.unquote_plus(params['hlsvp']) playlistItems = HttpUtils.HttpClient().getHtmlContent(url=hlsvp).splitlines() qualityIdentified = None for item in playlistItems: Logger.logDebug(item) if item.startswith('#EXT-X-STREAM-INF'): if item.endswith('1280x720'): qualityIdentified = VIDEO_QUAL_HD_720 elif item.endswith('1080'): qualityIdentified = VIDEO_QUAL_HD_1080 elif item.endswith('854x480'): qualityIdentified = VIDEO_QUAL_SD elif item.endswith('640x360'): qualityIdentified = VIDEO_QUAL_LOW elif item.startswith('http') and qualityIdentified is not None: videoUrl = HttpUtils.HttpClient().addHttpCookiesToUrl(item, extraExtraHeaders={'Referer':'https://www.youtube.com/watch?v=' + video_id}) video_info.add_video_link(qualityIdentified, videoUrl) qualityIdentified = None video_info.set_video_stopped(False) return video_info stream_map = urllib.unquote_plus(stream_map) Logger.logDebug(stream_map) formatArray = stream_map.split(',') streams = {} for formatContent in formatArray: if formatContent == '': continue formatUrl = '' try: formatUrl = urllib.unquote(re.compile("url=([^&]+)").findall(formatContent)[0]) + "&title=" + urllib.quote_plus(title) except Exception, e: Logger.logFatal(e) if re.search("rtmpe", stream_map): try: conn = urllib.unquote(re.compile("conn=([^&]+)").findall(formatContent)[0]); host = re.compile("rtmpe:\/\/([^\/]+)").findall(conn)[0]; stream = re.compile("stream=([^&]+)").findall(formatContent)[0]; path = 'videoplayback'; formatUrl = "-r %22rtmpe:\/\/" + host + "\/" + path + "%22 -V -a %22" + path + "%22 -f %22WIN 11,3,300,268%22 -W %22http:\/\/s.ytimg.com\/yt\/swfbin\/watch_as3-vfl7aCF1A.swf%22 -p %22http:\/\/www.youtube.com\/watch?v=" + video_id + "%22 -y %22" + urllib.unquote(stream) + "%22" except Exception, e: Logger.logFatal(e) if formatUrl == '': continue Logger.logDebug('************************') Logger.logDebug(formatContent) formatQual = '' if(formatUrl[0: 4] == "http" or formatUrl[0: 2] == "-r"): formatQual = re.compile("itag=([^&]+)").findall(formatContent)[0] if not re.search("signature=", formatUrl): sig = re.compile("sig=([^&]+)").findall(formatContent) if sig is not None and len(sig) == 1: formatUrl += "&signature=" + sig[0] else: sig = re.compile("s=([^&]+)").findall(formatContent) if sig is not None and len(sig) == 1: formatUrl += "&signature=" + parseSignature(sig[0]) qual = formatQual url = HttpUtils.HttpClient().addHttpCookiesToUrl(formatUrl, addHeaders=False,addCookies=False, extraExtraHeaders={'Referer':'https://www.youtube.com/watch?v=' + video_id}) streams[int(qual)] = url
def start(addon_id, addon_ver=None): try: Logger.logDebug(sys.argv) global __addon_id__ __addon_id__ = addon_id __addon_ver__ = addon_ver containerObj = Container(addon_id=addon_id, addon_ver=addon_ver) action_id = containerObj.getTurtleRequest().get_action_id() containerObj.performAction(action_id) except urllib2.URLError, e: Logger.logFatal(e) XBMCInterfaceUtils.displayDialogMessage('Unable to connect', 'Please choose a different source if available in add-on.', 'Website used in add-on is down, try to access using web browser.', 'Please share logs with developer if problem keeps coming!') except Exception, e: Logger.logFatal(e) ExceptionHandler.handle(e) cleanUp() xbmcplugin.endOfDirectory(int(sys.argv[1])) def cleanUp(): try: containerObj = Container() containerObj.cleanUp() del containerObj httpClient = HttpUtils.HttpClient() httpClient.cleanUp() del httpClient except: pass