def ParseCommand(self, mycgi): (category, search, allShows, calendar, date, page, thumbnail, resume) = mycgi.Params(u'category', u'search', u'allShows', u'calendar', u'date', u'page', u'thumbnail', u'resume') self.log( u"category: %s, search: %s, allShows: %s, calendar: %s, date: %s, page: %s, thumbnail: %s, resume: %s" % (category, str(search), str(allShows), calendar, date, page, thumbnail, str(resume)), xbmc.LOGDEBUG) if search <> u'': return self.DoSearch() if category <> u'': return self.ShowCategory(category) if allShows <> u'': if thumbnail <> u'': return self.ListAToZ(thumbnail) else: return self.ListAToZ() if calendar <> u'': return self.ListCalendar() if date <> u'': return self.ListByDate(date) if page == u'': # "Can't find 'page' parameter " logException = LoggingException(logMessage=self.language(30030)) # 'Cannot proceed', Error processing command logException.process(self.language(30755), self.language(30780), self.logLevel(xbmc.LOGERROR)) return False self.log(u"page = %s" % page, xbmc.LOGDEBUG) page = mycgi.URLUnescape(page) self.log(u"mycgi.URLUnescape(page) = %s" % page, xbmc.LOGDEBUG) if u' ' in page: page = page.replace(u' ', u'%20') resumeFlag = False if resume <> u'': resumeFlag = True try: return self.PlayVideoWithDialog(self.PlayEpisode, (page, resumeFlag)) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # "Error playing or downloading episode %s" exception.addLogMessage(self.language(30051) % u"") # "Error processing video" exception.process(severity=self.logLevel(xbmc.LOGERROR)) return False
def DoSearchQuery(self, query): self.log(u"query: %s" % query, xbmc.LOGDEBUG) values = {u'queryString': query, u'limit': 20} # headers = {'DNT':'1', 'X-Requested-With':'XMLHttpRequest' } headers = {} headers[u'DNT'] = u'1' headers[u'Referer'] = u'http://www.tv3.ie/3player/' headers[ u'Content-Type'] = u'application/x-www-form-urlencoded; charset=UTF-8' html = self.httpManager.GetWebPage(searchUrl, 1800, values=values, headers=headers) if html is None or html == u'': # Data returned from web page: %s, is: '%s' logException = LoggingException(logMessage=self.language(30060) % (searchUrl, html)) # Error getting web page logException.process(self.language(30050), u'', self.logLevel(xbmc.LOGERROR)) return False # Fix fcuked up TV3 HTML formatting html = html.replace(u"<h3 id='search_heading'>Videos</h2>", "<h3 id='search_heading'>Videos</h3>") self.ListSearchShows(html) return True
def DoSearchQuery( self, query = None, queryUrl = None): if query is not None: queryUrl = urlRoot + self.GetSearchURL() + mycgi.URLEscape(query) self.log(u"queryUrl: %s" % queryUrl, xbmc.LOGDEBUG) try: html = None html = self.httpManager.GetWebPage( queryUrl, 1800 ) if html is None or html == '': # Data returned from web page: %s, is: '%s' logException = LoggingException(logMessage = self.language(30060) % ( __SEARCH__ + mycgi.URLEscape(query), html)) # Error getting web page logException.process(self.language(30050), u'', severity = self.logLevel(xbmc.LOGWARNING)) return False self.ListSearchShows(html) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error performing query %s exception.addLogMessage(self.language(30052) % query) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def DoSearchQuery(self, query=None, queryUrl=None): if query is not None: queryUrl = urlRoot + self.GetSearchURL() + mycgi.URLEscape(query) self.log(u"queryUrl: %s" % queryUrl, xbmc.LOGDEBUG) try: html = None html = self.httpManager.GetWebPage(queryUrl, 1800) if html is None or html == '': # Data returned from web page: %s, is: '%s' logException = LoggingException( logMessage=self.language(30060) % (__SEARCH__ + mycgi.URLEscape(query), html)) # Error getting web page logException.process(self.language(30050), u'', severity=self.logLevel(xbmc.LOGWARNING)) return False self.ListSearchShows(html) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error performing query %s exception.addLogMessage(self.language(30052) % query) exception.process(severity=self.logLevel(xbmc.LOGERROR)) return False
def PlayEpisode(self, page, resumeFlag): self.log(u"", xbmc.LOGDEBUG) try: html = None self.log(u"urlRoot: " + urlRoot + u", page: " + page ) html = self.httpManager.GetWebPage( urlRoot + page, 1800 ) #raise Exception("test1", "test2") except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = u"html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting web page exception.addLogMessage(self.language(30050)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False soup = BeautifulSoup(html) ageCheck = soup.find(u'div', {u'id':u'age_check_form_row'}) if ageCheck is not None: if self.dialog.iscanceled(): return False # "Getting episode info" self.dialog.update(25, self.language(30084)) try: html = None html = self.httpManager.GetWebPage( urlRoot + page, 1800, values = {u'age_ok':'1'} ) soup = BeautifulSoup(html) except (Exception) as exception: exception = LoggingException.fromException(exception) if html is not None: msg = u"html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting web page: %s exception.addLogMessage(self.language(30050) + u": " + ( urlRoot + page ) ) # Error getting web page exception.process(self.language(30050), u'', severity = self.logLevel(xbmc.LOGERROR)) return False rtmpVar = self.InitialiseRTMP(soup) infoLabels = self.GetEpisodeInfo(soup) thumbnail = soup.find(u'meta', {u'property' : u'og:image'})[u'content'] defaultFilename = infoLabels[u'Title'] resumeKey = unicode(zlib.crc32(page)) return self.PlayOrDownloadEpisode(infoLabels, thumbnail, rtmpVar, defaultFilename, url = None, subtitles = None, resumeKey = resumeKey, resumeFlag = resumeFlag)
def ShowCategory(self, category, label, order, page): self.log(unicode((category, label, order, page)), xbmc.LOGDEBUG) pageInt = int(page) listItems = [] try: pattern = u"\((\d+)\)" match = re.search(pattern, label, re.DOTALL | re.IGNORECASE) count = int(match.group(1)) except: count = None if pageInt == 1 and (count is None or count > 10): try: self.AddExtraLinks(category, label, order, listItems) except (Exception) as exception: exception = LoggingException.fromException(exception) # 'Error processing web page', 'Cannot show Category' exception.addLogMessage(self.language(30785)) exception.process(self.language(30780), self.language(30785), severity=xbmc.LOGWARNING) if pageInt > 1: self.AddPageLink(category, label, order, True, unicode(pageInt - 1), listItems) try: moreShows = self.AddPageToListItems(category, label, order, page, listItems) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # 'Error processing web page', 'Cannot show Most Popular/A-Z/Latest' exception.addLogMessage(self.language(30780)) exception.process(self.language(30785), self.language(30780), severity=xbmc.LOGWARNING) return False if moreShows: nextPage = unicode(pageInt + 1) self.AddPageLink(category, label, order, False, nextPage, listItems) xbmcplugin.addDirectoryItems(handle=self.pluginHandle, items=listItems) xbmcplugin.setContent(handle=self.pluginHandle, content=u'tvshows') xbmcplugin.endOfDirectory(handle=self.pluginHandle, succeeded=True) return True
def ListByDate(self, date): values = {u'queryString' : date} html = None html = self.httpManager.GetWebPage( calendarUrl, 3600, values = values) if html is None or html == u'': # Data returned from web page: %s, is: '%s' logException = LoggingException(logMessage = self.language(30060) % ( searchUrl, html )) # Error getting web page logException.process(self.language(30050), u'', self.logLevel(xbmc.LOGERROR)) return False soup = BeautifulSoup(html) listItems = [] htmlparser = HTMLParser.HTMLParser() videos = soup.findAll(u'div', {u'id':u'tooltip_showvideo_cal'}) if len(videos) == 1 and len(videos[0].findAll(u'a')) == 0: # No videos broadcast on this date. xbmc.executebuiltin(u'XBMC.Notification(IrishTV, %s)' % (videos[0].text)) return True for video in videos: try: anchors = video.findAll(u'a') time = anchors[2].small.text title = self.fullDecode( anchors[1].b.text + u", " + time ) description = self.fullDecode( anchors[3].text ) infoLabels = {u'Title': title, u'Plot': description, u'PlotOutline': description} page = anchors[0][u'href'] thumbnail = anchors[0].img[u'src'] self.AddEpisodeItem(title, thumbnail, infoLabels, page, listItems) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if video is not None: msg = u"video:\n\n%s\n\n" % video exception.addLogMessage(msg) # "Error processing video" exception.addLogMessage(logMessage = self.language(30063) % u"video\n" + repr(video)) # "Error processing video" exception.process(self.language(30063) % programme % u"video\n", u"", xbmc.LOGWARNING) continue xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True
def AttemptLogin(self, values, logUrl = False): self.log(u"", xbmc.LOGDEBUG) try: loginJSONText = None loginJSON = None url = self.GetAPIUrl(values) loginJSONText = self.httpManager.GetWebPageDirect(url, logUrl = logUrl) loginJSON = _json.loads(loginJSONText) for key in loginJSON: self.log(u"loginJSON['%s'] exists" % key, xbmc.LOGDEBUG) if u'user' in loginJSON: self.log(u"loginJSON['user']", xbmc.LOGDEBUG) for key in loginJSON[u'user']: if key == u'fname' or key == u'lname' or key == 'email': self.log(u"loginJSON['user']['%s'] exists" % key, xbmc.LOGDEBUG) else: self.log(u"loginJSON['user']['%s'] = %s" % (key, utils.drepr(loginJSON[u'user'][key])), xbmc.LOGDEBUG) # Check for failed login if loginJSON[u'user'][u'login'] != True: # Show error message if u'status' in loginJSON[u'user']: statusMessage = loginJSON[u'user'][u'status'] else: statusMessage = u"None" # 'AerTV login failed', logException = LoggingException(self.language(30101)) # "Status Message: %s logException.process(self.language(30102) % statusMessage, u"", xbmc.LOGDEBUG) return None self.log(u"AerTV successful login", xbmc.LOGDEBUG) return loginJSON except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if loginJSONText is not None: msg = u"loginJSONText:\n\n%s\n\n" % loginJSONText exception.addLogMessage(msg) if loginJSON is not None: msg = u"epgJSON:\n\n%s\n\n" % utils.drepr(loginJSON) exception.addLogMessage(msg) raise exception
def executeCommand(): pluginHandle = int(sys.argv[1]) success = False if (mycgi.EmptyQS()): success = ShowProviders() else: (providerName, clearCache, testForwardedIP) = mycgi.Params(u'provider', u'clearcache', u'testforwardedip') if clearCache != u'': httpManager.ClearCache() return True elif testForwardedIP != u'': provider = Provider() provider.addon = addon httpManager.SetDefaultHeaders(provider.GetHeaders()) forwardedIP = provider.CreateForwardedForIP('0.0.0.0') return TestForwardedIP(forwardedIP) elif providerName != u'': log(u"providerName: " + providerName, xbmc.LOGDEBUG) if providerName <> u'': provider = providerfactory.getProvider(providerName) if provider is None: # ProviderFactory return none for providerName: %s logException = LoggingException( language(30000) % providerName) # 'Cannot proceed', Error processing provider name logException.process(language(30755), language(30020), xbmc.LOGERROR) return False if provider.initialise(httpManager, sys.argv[0], pluginHandle, addon, language, PROFILE_DATA_FOLDER, RESOURCE_PATH): success = provider.ExecuteCommand(mycgi) log(u"executeCommand done", xbmc.LOGDEBUG) """ print cookiejar print 'These are the cookies we have received so far :' for index, cookie in enumerate(cookiejar): print index, ' : ', cookie cookiejar.save() """ return success
def ParseCommand(self, mycgi): (category, search, allShows, calendar, date, page, thumbnail, resume) = mycgi.Params( u'category', u'search', u'allShows', u'calendar', u'date', u'page', u'thumbnail', u'resume' ) self.log(u"category: %s, search: %s, allShows: %s, calendar: %s, date: %s, page: %s, thumbnail: %s, resume: %s" % (category, str(search), str(allShows), calendar, date, page, thumbnail, str(resume)), xbmc.LOGDEBUG) if search <> u'': return self.DoSearch() if category <> u'': return self.ShowCategory(category) if allShows <> u'': if thumbnail <> u'': return self.ListAToZ(thumbnail) else: return self.ListAToZ() if calendar <> u'': return self.ListCalendar() if date <> u'': return self.ListByDate(date) if page == u'': # "Can't find 'page' parameter " logException = LoggingException(logMessage = self.language(30030)) # 'Cannot proceed', Error processing command logException.process(self.language(30755), self.language(30780), self.logLevel(xbmc.LOGERROR)) return False self.log(u"page = %s" % page, xbmc.LOGDEBUG) page = mycgi.URLUnescape(page) self.log(u"mycgi.URLUnescape(page) = %s" % page, xbmc.LOGDEBUG) if u' ' in page: page = page.replace(u' ', u'%20') resumeFlag = False if resume <> u'': resumeFlag = True try: return self.PlayVideoWithDialog(self.PlayEpisode, (page, resumeFlag)) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # "Error playing or downloading episode %s" exception.addLogMessage(self.language(30051) % u"") # "Error processing video" exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def findString(method, pattern, string, flags = (re.DOTALL | re.IGNORECASE)): try: match = re.search( pattern, string, flags ) if match is not None: return match.group(1) except (Exception) as exception: raise LoggingException.fromException(exception) # Limit logging of string to 1000 chars limit = 1000 messageLog = u"\nPattern - \n%s\n\nString - \n%s\n\n" % (pattern, string[0:limit]) logException = LoggingException(u"utils.findString", "Can't find pattern in string\n\n" + messageLog) raise logException
def executeCommand(): pluginHandle = int(sys.argv[1]) success = False if ( mycgi.EmptyQS() ): success = ShowProviders() else: (providerName, clearCache, testForwardedIP) = mycgi.Params( u'provider', u'clearcache', u'testforwardedip' ) if clearCache != u'': httpManager.ClearCache() return True elif testForwardedIP != u'': provider = Provider() provider.addon = addon httpManager.SetDefaultHeaders( provider.GetHeaders() ) forwardedIP = provider.CreateForwardedForIP('0.0.0.0') return TestForwardedIP(forwardedIP) elif providerName != u'': log(u"providerName: " + providerName, xbmc.LOGDEBUG) if providerName <> u'': provider = providerfactory.getProvider(providerName) if provider is None: # ProviderFactory return none for providerName: %s logException = LoggingException(language(30000) % providerName) # 'Cannot proceed', Error processing provider name logException.process(language(30755), language(30020), xbmc.LOGERROR) return False if provider.initialise(httpManager, sys.argv[0], pluginHandle, addon, language, PROFILE_DATA_FOLDER, RESOURCE_PATH): success = provider.ExecuteCommand(mycgi) log (u"executeCommand done", xbmc.LOGDEBUG) """ print cookiejar print 'These are the cookies we have received so far :' for index, cookie in enumerate(cookiejar): print index, ' : ', cookie cookiejar.save() """ return success
def InitialiseRTMP(self, soup): self.log(u"", xbmc.LOGDEBUG) try: flowPlayerScript = unicode( soup.find(u'div', { u'id': u'flowPlayer' }).findNextSibling(u'script').text) rtmpStr = utils.findString(u"TV3Provider::InitialiseRTMP()", u"netConnectionUrl: \"(.+?)\"", flowPlayerScript) rootIndex = rtmpStr[8:].index(u'/') + 9 app = rtmpStr[rootIndex:] swfUrl = self.GetSWFPlayer(flowPlayerScript) playPath = utils.findString( u"TV3Provider::InitialiseRTMP()", u"playlist:\s+\[\s+{\s+url:\s+\"(.+?)\"", flowPlayerScript) rtmpVar = rtmp.RTMP(rtmp=rtmpStr, app=app, swfVfy=swfUrl, playPath=playPath) self.AddSocksToRTMP(rtmpVar) return rtmpVar except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Error getting RTMP data exception.addLogMessage(self.language(30057)) raise exception
def AddLiveMenuItem(self, listItems, labelEN, labelIE, urlFragment): try: if self.languageCode == u'en': newLabel = labelEN else: newLabel = labelIE thumbnailPath = self.GetThumbnailPath(newLabel) schedule = self.GetLiveSchedule() newLabel = newLabel + " [" + schedule + "]" newListItem = xbmcgui.ListItem( label=newLabel ) newListItem.setThumbnailImage(thumbnailPath) newListItem.setProperty("Video", "true") #newListItem.setProperty('IsPlayable', 'true') url = self.GetURLStart() + urlFragment listItems.append( (url, newListItem, False) ) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Not fatal, just means that we don't have the news option exception.process(severity = xbmc.LOGWARNING)
def GetSearchURL(self): try: rootMenuHtml = None html = None rootMenuHtml = self.httpManager.GetWebPage(rootMenuUrl, 60) playerJSUrl = self.GetPlayerJSURL(rootMenuHtml) html = self.httpManager.GetWebPage(playerJSUrl, 20000) programmeSearchIndex = html.find('Programme Search') match=re.search("window.location.href = \'(.*?)\'", html[programmeSearchIndex:]) searchURL = match.group(1) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if rootMenuHtml is not None: msg = "rootMenuHtml:\n\n%s\n\n" % rootMenuHtml exception.addLogMessage(msg) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting search url: Using default %s exception.addLogMessage(self.language(30054) + searchUrlDefault) exception.process(severity = self.logLevel(xbmc.LOGWARNING)) searchURL = searchUrlDefault return searchURL
def GetLiveVideoParams(self, js): self.log(u"", xbmc.LOGDEBUG) try: pattern = u"function (getLivePlayer.+?)^}" match=re.search(pattern, js, re.MULTILINE | re.DOTALL) getLivePlayer = match.group(1) pattern = u'} else {\s+id\s*=\s*[\'"](\d+?)[\'"]' videoId = re.search(pattern, getLivePlayer, re.DOTALL).group(1) pattern='progTitle\s*=\s*"(.+?)"' progTitle = re.search(pattern, getLivePlayer, re.DOTALL).group(1) return (videoId, progTitle) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if playerFunctionsJs is not None: msg = u"playerFunctionsJs:\n\n%s\n\n" % playerFunctionsJs exception.addLogMessage(msg) # Unable to determine live video parameters. Using default values. exception.addLogMessage(self.language(30022)) exception.process(severity = xbmc.LOGWARNING) return (defaultLiveVideoId, defaultLiveProgTitle)
def GetThumbnailFromEpisode(self, episodeId, soup=None): self.log(u"", xbmc.LOGDEBUG) try: html = None if soup is None: html = self.httpManager.GetWebPage(showUrl % episodeId, 20000) soup = BeautifulSoup(html, selfClosingTags=[u'img']) image = soup.find(u'meta', {u'property': u"og:image"})[u'content'] return image except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error processing web page exception.addLogMessage( self.language(30780) + ": " + (showUrl % episodeId)) exception.process(u"Error getting thumbnail", "", self.logLevel(xbmc.LOGWARNING)) raise exception
def ListAvailable(self, html): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: soup = BeautifulSoup(html, selfClosingTags=[u'img']) count = int(soup.find(u'meta', { u'name' : u"episodes_available"} )[u'content']) availableEpisodes = soup.findAll(u'a', u"thumbnail-programme-link") for index in range ( 0, count ): self.AddEpisodeToList(listItems, availableEpisodes[index]) xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting count of available episodes exception.addLogMessage(self.language(30045)) exception.process(self.language(30046), self.language(30045), self.logLevel(xbmc.LOGERROR)) return False
def ListShows(self, html): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: soup = BeautifulSoup(html, selfClosingTags=[u'img']) episodes = soup.findAll(u'a', u"thumbnail-programme-link") for episode in episodes: self.AddEpisodeToList(listItems, episode) xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting list of shows exception.addLogMessage(self.language(30049)) # Error getting list of shows exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def initialise(self, showId, showTitle, season, dataFolder): method = u"EpisodeList.initialise" self.log( u"initialise showId: %s, showTitle: %s, season: %s " % (showId, showTitle, season), xbmc.LOGDEBUG) try: self.html = None self.dataFolder = dataFolder url = None url = self.showUrl % (showId, season) self.html = self.cache.GetWebPage(url, 600) # 10 minutes self.log(u"page: %s\n\n%s\n\n" % (url, self.html), xbmc.LOGDEBUG) self.showId = showId self.showTitle = showTitle self.currentSeason = season return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = u"html:\n\n%s\n\n" % html exception.addLogMessage(msg) # 'Error getting episode list' exception.addLogMessage(__language__(30790)) raise exception
def logException(self, exception, detailName): if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # 'Error getting episode data "%s"' exception.addLogMessage(__language__(30960) % detailName) exception.printLogMessages(severity=xbmc.LOGWARNING)
def PlayOrDownloadEpisode(self, infoLabels, thumbnail, rtmpVar = None, defaultFilename = u'', url = None, subtitles = None, resumeKey = None, resumeFlag = False): try: action = self.GetAction(infoLabels[u'Title']) if self.dialog.iscanceled(): return False if ( action == 1 ): # Play # "Preparing to play video" self.dialog.update(50, self.language(30085)) self.Play(infoLabels, thumbnail, rtmpVar, url, subtitles, resumeKey, resumeFlag) elif ( action == 0 ): # Download # "Preparing to download video" self.dialog.update(50, self.language(30086)) self.Download(rtmpVar, defaultFilename, subtitles) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Error playing or downloading episode %s exception.process(self.language(30051) % u'', u'', self.logLevel(xbmc.LOGERROR)) return False
def GetQSData(self, vidId, bitlyUrl, js): self.log("", xbmc.LOGDEBUG) try: pattern = u"function (createPlayerHtml.+?)^}" match=re.search(pattern, js, re.MULTILINE | re.DOTALL) createPlayerHtml = match.group(1) bc_params = {} pattern = u"[^/][^/]\s+(bc_params\s*\[.+?\]\s*=.+?);" paramAppends = re.findall(pattern, createPlayerHtml) for paramAppend in paramAppends: paramAppend = paramAppend.replace(u'true', u'True') paramAppend = paramAppend.replace(u'["', u'[u"') paramAppend = paramAppend.replace(u'= "', u'= u"') self.log(u"paramAppend: %s" % paramAppend, xbmc.LOGDEBUG) exec(paramAppend) if bc_params < 10: self.log(self.language(30036), xbmc.LOGWARNING) self.log(utils.drepr(bc_params), xbmc.LOGDEBUG) return self.GetDefaultQSData(vidId, bitlyUrl) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Unable to determine qsdata. Using default values. exception.addLogMessage(self.language(40600)) exception.process(severity = xbmc.LOGWARNING) return self.GetDefaultQSData(vidId, bitlyUrl) return bc_params
def GetFullLink(self, episodeId, series, js): self.log("", xbmc.LOGDEBUG) try: pattern = u"function (loadPlayer.+?)^}" match=re.search(pattern, js, re.MULTILINE | re.DOTALL) loadPlayer = match.group(1) pattern = u"linkUrl\s*=\s*[\"'](http://.+?)[\"']" linkUrl = re.search(pattern, loadPlayer, re.DOTALL).group(1) linkUrl.replace(u'/ie/', u'/%s/' % self.languageCode) pattern = u"(fullLinkUrl\s*=\s*linkUrl.*?);" fullLinkUrlCode = re.search(pattern, loadPlayer, re.DOTALL).group(1) vidId = episodeId progTitle = series fullLinkUrl = "" exec(fullLinkUrlCode) if fullLinkUrl != "": return fullLinkUrl except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Error getting player url. Using default. exception.addLogMessage(self.language(30039)) exception.process(severity = xbmc.LOGWARNING) return self.GetDefaultFullLink(episodeId, series)
def AddAllLinks(self, listItems, html, listshows = False, autoThumbnails = False): htmlparser = HTMLParser.HTMLParser() try: for link in html.findAll(u'a'): page = link[u'href'] newLabel = htmlparser.unescape(link.contents[0]) thumbnailPath = self.GetThumbnailPath(newLabel.replace(u' ', u'')) newListItem = xbmcgui.ListItem( label=newLabel) newListItem.setThumbnailImage(thumbnailPath) url = self.GetURLStart() + u'&page=' + mycgi.URLEscape(page) # "Most Popular" does not need a submenu, go straight to episode listing if listshows or u"Popular" in newLabel: url = url + u'&listshows=1' self.log(u"url: %s" % url, xbmc.LOGDEBUG) listItems.append( (url,newListItem,True) ) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error adding links exception.addLogMessage(self.language(30047)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def logException(self, exception, detailName): if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # 'Error getting episode data "%s"' exception.addLogMessage(__language__(30960) % detailName) exception.printLogMessages(severity = xbmc.LOGWARNING)
def CallBitlyApi(self, username, key, apiUrl, longUrl, dataType, episodeId, series ): self.log("longUrl: %s", xbmc.LOGDEBUG) try: values = { u'callback': '%s%d' % (dataType, int(round(time.time() * 1000.0))), #u'longUrl': (longUrl + u"id=%s&title=%s" % (episodeId, series)).encode(u'latin1'), u'longUrl': (longUrl).encode(u'latin1'), u'apiKey': key, u'login': username } jsonData = self.httpManager.GetWebPage(apiUrl, 20000, values = values) jsonText = utils.extractJSON (jsonData) bitlyJSON = _json.loads(jsonText) return bitlyJSON[u'data'][u'url'] except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Error calling bit.ly API exception.addLogMessage(self.language(30038)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) raise exception
def initialise(self, showId, showTitle, season, dataFolder): method = u"EpisodeList.initialise" self.log (u"initialise showId: %s, showTitle: %s, season: %s " % ( showId, showTitle, season ), xbmc.LOGDEBUG) try: self.html = None self.dataFolder = dataFolder url = None url = self.showUrl % (showId, season) self.html = self.cache.GetWebPage( url, 600 ) # 10 minutes self.log (u"page: %s\n\n%s\n\n" % ( url, self.html ), xbmc.LOGDEBUG) self.showId = showId self.showTitle = showTitle self.currentSeason = season return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = u"html:\n\n%s\n\n" % html exception.addLogMessage(msg) # 'Error getting episode list' exception.addLogMessage(__language__(30790)) raise exception
def TestForwardedIP(forwardedIP): try: html = None logger.info(u"TestForwardedIP: " + forwardedIP) httpManager.EnableForwardedForIP() httpManager.SetForwardedForIP( forwardedIP ) html = httpManager.GetWebPageDirect( xhausUrl ) soup = BeautifulSoup(html) xForwardedForString = soup.find(text='X-Forwarded-For') if xForwardedForString is None: logger.error("Test failed: X-Forwarded-For header not received by website") else: forwardedForIP = xForwardedForString.parent.findNextSibling('td').text logger.info("Test passed: X-Forwarded-For header received as %s" % forwardedForIP) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) logger.warning("Test inconclusive: Error processing web page") # Error getting web page exception.addLogMessage("Error getting web page") exception.printLogMessages(logging.ERROR) return False
def GetSWFPlayer(self): self.log(u"", xbmc.LOGDEBUG) try: xml = self.httpManager.GetWebPage(configUrl, 20000) soup = BeautifulStoneSoup(xml) swfPlayer = soup.find("player")['url'] if swfPlayer.find('.swf') > 0: swfPlayer = re.search("(.*\.swf)", swfPlayer).groups()[0] if swfPlayer.find('http') == 0: # It's an absolute URL, do nothing. pass elif swfPlayer.find('/') == 0: # If it's a root URL, append it to the base URL: swfPlayer = urljoin(urlRoot, swfPlayer) else: # URL is relative to config.xml swfPlayer = urljoin(configUrl, swfPlayer) return swfPlayer except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Unable to determine swfPlayer URL. Using default: %s exception.addLogMessage(self.language(30520) % swfDefault) exception.process(severity=self.logLevel(xbmc.LOGWARNING)) return swfDefault
def GetSWFPlayer(self): self.log(u"", xbmc.LOGDEBUG) try: xml = self.httpManager.GetWebPage(configUrl, 20000) soup = BeautifulStoneSoup(xml) swfPlayer = soup.find("player")['url'] if swfPlayer.find('.swf') > 0: swfPlayer=re.search("(.*\.swf)", swfPlayer).groups()[0] if swfPlayer.find('http') == 0: # It's an absolute URL, do nothing. pass elif swfPlayer.find('/') == 0: # If it's a root URL, append it to the base URL: swfPlayer = urljoin(urlRoot, swfPlayer) else: # URL is relative to config.xml swfPlayer = urljoin(configUrl, swfPlayer) return swfPlayer except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Unable to determine swfPlayer URL. Using default: %s exception.addLogMessage(self.language(30520) % swfDefault) exception.process(severity = self.logLevel(xbmc.LOGWARNING)) return swfDefault
def AddEpisodeToList(self, listItems, episode): self.log(u"", xbmc.LOGDEBUG) try: htmlparser = HTMLParser.HTMLParser() href = episode[u'href'] title = htmlparser.unescape( episode.find(u'span', u"thumbnail-title").contents[0] ) date = episode.find(u'span', u"thumbnail-date").contents[0] #description = ... thumbnail = episode.find(u'img', u'thumbnail')[u'src'] newLabel = title + u", " + date newListItem = xbmcgui.ListItem( label=newLabel ) newListItem.setThumbnailImage(thumbnail) if self.addon.getSetting( u'RTE_descriptions' ) == u'true': infoLabels = self.GetEpisodeInfo(self.GetEpisodeIdFromURL(href)) else: infoLabels = {u'Title': title, u'Plot': title} newListItem.setInfo(u'video', infoLabels) newListItem.setProperty(u"Video", u"true") #newListItem.setProperty('IsPlayable', 'true') self.log(u"label == " + newLabel, xbmc.LOGDEBUG) if u"episodes available" in date: url = self.GetURLStart() + u'&listavailable=1' + u'&page=' + mycgi.URLEscape(href) folder = True else: newListItem.setProperty("Video", "true") #newListItem.setProperty('IsPlayable', 'true') folder = False match = re.search( u"/player/[^/]+/show/([0-9]+)/", href ) if match is None: self.log(u"No show id found in page href: '%s'" % href, xbmc.LOGWARNING) return episodeId = match.group(1) url = self.GetURLStart() + u'&episodeId=' + mycgi.URLEscape(episodeId) if self.resumeEnabled: resumeKey = episodeId self.ResumeListItem(url, newLabel, newListItem, resumeKey) listItems.append( (url, newListItem, folder) ) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) msg = u"episode:\n\n%s\n\n" % utils.drepr(episode) exception.addLogMessage(msg) # Error getting episode details exception.addLogMessage(self.language(30099)) exception.process(self.logLevel(xbmc.LOGWARNING))
def ListAvailable(self, html): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: soup = BeautifulSoup(html, selfClosingTags=[u'img']) count = int( soup.find(u'meta', {u'name': u"episodes_available"})[u'content']) availableEpisodes = soup.findAll(u'a', u"thumbnail-programme-link") for index in range(0, count): self.AddEpisodeToList(listItems, availableEpisodes[index]) xbmcplugin.addDirectoryItems(handle=self.pluginHandle, items=listItems) xbmcplugin.endOfDirectory(handle=self.pluginHandle, succeeded=True) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting count of available episodes exception.addLogMessage(self.language(30045)) exception.process(self.language(30046), self.language(30045), self.logLevel(xbmc.LOGERROR)) return False
def ShowRootMenu(self): self.log(u"", xbmc.LOGDEBUG) try: listItems = [] liveItemTuple = None searchItemTuple = None self.AddMenuItem(listItems, u"Search", u'Cuardaigh', u'&search=1') self.AddMenuItem(listItems, u"Latest", u"Is Déanaí", u'&latest=1') self.AddMenuItem(listItems, u"Categories", u'Catag\u00f3ir\u00ed', u'&categories=1') self.AddMenuItem(listItems, u"Popular", u"Is Coitianta", u'&popular=1') # TODO Fix live TV ##self.AddLiveMenuItem(listItems, u"Live", u"Beo", u'&live=1') xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if xml is not None: msg = u"xml:\n\n%s\n\n" % xml exception.addLogMessage(msg) # Cannot show root menu exception.addLogMessage(self.language(30010)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def ShowLiveMenu(self): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: html = None page = self.GetLivePageUrl() html = self.httpManager.GetWebPage(urlRoot + page, 60) soup = BeautifulSoup(html, selfClosingTags=['img']) schedule = soup.find('div', 'live-schedule-strap clearfix') liList = schedule.findAll('li') for li in liList: logoName = li.find('span', {'class': re.compile('live-logo')}) channel = logoName.text thumbnailPath = self.GetThumbnailPath( (channel.replace(u'RT\xc9 ', '')).replace(' ', '')) page = li.a['href'] infoList = li.findAll('span', "live-channel-info") programme = "" for info in infoList: text = info.text.replace(" ", "") if len(text) == 0: continue comma = "" if len(programme) == 0: programme = info.text else: programme = programme + ", " + info.text programme = programme.replace(''', "'") newListItem = xbmcgui.ListItem(label=programme) newListItem.setThumbnailImage(thumbnailPath) newListItem.setProperty("Video", "true") #newListItem.setProperty('IsPlayable', 'true') url = self.GetURLStart( ) + u'&live=1' + u'&page=' + mycgi.URLEscape(page) listItems.append((url, newListItem, False)) xbmcplugin.addDirectoryItems(handle=self.pluginHandle, items=listItems) xbmcplugin.endOfDirectory(handle=self.pluginHandle, succeeded=True) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting Live TV information exception.addLogMessage(self.language(30047)) exception.process(severity=self.logLevel(xbmc.LOGERROR)) return False
def ListShows(self, html): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: soup = BeautifulSoup(html, selfClosingTags=[u'img']) episodes = soup.findAll(u'a', u"thumbnail-programme-link") for episode in episodes: self.AddEpisodeToList(listItems, episode) xbmcplugin.addDirectoryItems(handle=self.pluginHandle, items=listItems) xbmcplugin.endOfDirectory(handle=self.pluginHandle, succeeded=True) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting list of shows exception.addLogMessage(self.language(30049)) # Error getting list of shows exception.process(severity=self.logLevel(xbmc.LOGERROR)) return False
def GetSearchURL(self): try: rootMenuHtml = None html = None rootMenuHtml = self.httpManager.GetWebPage(rootMenuUrl, 60) playerJSUrl = self.GetPlayerJSURL(rootMenuHtml) html = self.httpManager.GetWebPage(playerJSUrl, 20000) programmeSearchIndex = html.find('Programme Search') match = re.search("window.location.href = \'(.*?)\'", html[programmeSearchIndex:]) searchURL = match.group(1) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if rootMenuHtml is not None: msg = "rootMenuHtml:\n\n%s\n\n" % rootMenuHtml exception.addLogMessage(msg) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting search url: Using default %s exception.addLogMessage(self.language(30054) + searchUrlDefault) exception.process(severity=self.logLevel(xbmc.LOGWARNING)) searchURL = searchUrlDefault return searchURL
def initialise(self, showId, showTitle): method = u"EpisodeList.initialise" self.log( u"initialise showId: %s, showTitle: %s " % (showId, showTitle), xbmc.LOGDEBUG) try: jsonText = None url = None url = ps3ShowUrl % (showId, int(time.time() * 1000)) jsonText = self.cache.GetWebPage(url, 600) # 10 minutes jsonData = simplejson.loads(jsonText) if isinstance(jsonData[u'feed'][u'entry'], list): self.entries = jsonData[u'feed'][u'entry'] else: # Single entry, put in a list self.entries = [jsonData[u'feed'][u'entry']] self.showId = showId self.showTitle = showTitle return True except (Exception), exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if jsonText is not None: msg = u"jsonText:\n\n%s\n\n" % jsonText exception.addLogMessage(msg) # 'Error getting episode list' exception.addLogMessage(__language__(30790)) raise exception
def GetSwfPlayer(self): try: jsHtml = None jsHtml = self.httpManager.GetWebPage(javascriptUrl, 30001) pattern = u"options.swfPath = \"(/swf/mobileplayer-10.2.0-1.43.swf)\";" match = re.search(pattern, jsHtml, re.DOTALL | re.IGNORECASE) swfPlayer = urlRoot + match.group(1) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if jsHtml is not None: msg = u"jsHtml:\n\n%s\n\n" % jsHtml exception.addLogMessage(msg) # Unable to determine swfPlayer URL. Using default: exception.addLogMessage(self.language(30520) % swfDefault) exception.process(u'', u'', severity=xbmc.LOGWARNING) swfPlayer = swfDefault return swfPlayer
def GetStreamInfo(self, assetUrl): try: xml = None xml = self.httpManager.GetWebPageDirect(assetUrl) self.log(u"assetUrl: %s\n\n%s\n\n" % (assetUrl, xml), xbmc.LOGDEBUG) soup = BeautifulStoneSoup(xml) uriData = soup.find(u'uridata') streamURI = uriData.find(u'streamuri').text auth = self.GetAuthentication(uriData) return (streamURI, auth) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if xml is not None: msg = u"xml:\n\n%s\n\n" % xml exception.addLogMessage(msg) # Error processing asset data exception.addLogMessage(self.language(30504) + swfDefault) exception.process(u'', u'', severity=xbmc.LOGDEBUG) raise exception
def ShowEpisodes(self, showId, showTitle, season): self.log(unicode((showId, showTitle)), xbmc.LOGDEBUG) episodeList = EpisodeList(self.GetURLStart(), showUrl, self.httpManager, self.watchedEnabled) try: episodeList.initialise(showId, showTitle, season, self.dataFolder) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # 'Error processing web page', 'Cannot show Most Popular/A-Z/Latest' exception.addLogMessage(self.language(30740)) exception.process(self.language(30735), self.language(30740), severity=self.logLevel(xbmc.LOGERROR)) return False listItems = episodeList.createListItems(mycgi, self.resumeEnabled, self) xbmcplugin.addDirectoryItems(handle=self.pluginHandle, items=listItems) xbmcplugin.setContent(handle=self.pluginHandle, content=u'episodes') xbmcplugin.endOfDirectory(handle=self.pluginHandle, succeeded=True) return True
def ListSearchShows(self, html): logger.debug(u"") listItems = [] soup = BeautifulSoup(html) videos = soup.findAll(u'li', u'unselected_video') for video in videos: try: self.AddEpisodeToSearchList(listItems, video) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # "Error processing search result" exception.addLogMessage( logMessage="Error processing search result" + u"\n" + repr(video)) exception.process("Error processing search result", u"", logging.WARNING) # xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) # xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) # return True return listItems
def ShowVinesByTag(self, page, label): self.log("page: " + repr(page)) url = urlRoot + page try: jsonText = None listItems = [] html = self.httpManager.GetWebPageDirect(url) pattern = "<script.*>\s*var\s*vines\s*=\s*(\[.*\])\s*;\s*</script>" match = re.search(pattern, html, re.MULTILINE | re.DOTALL) jsonText = match.group(1) jsonData = _json.loads(jsonText) soup = BeautifulSoup(html) previous = soup.find('li', 'previous') next = soup.find('li', 'next') if previous: listItem = xbmcgui.ListItem("<< " + previous.text) url = self.GetURLStart() + u'&page=' + previous.a['href'] listItems.append((url, listItem, True)) else: self.AddOrderLinks(soup, listItems) for vineData in jsonData: url = vineData['vineVideoURL'] icon = vineData['vineImageURL'] infoLabels = {u'Title': vineData['vineDescription'], u'Plot': vineData['vineDescription']} self.log("infoLabels: " + utils.drepr(infoLabels)) listItem = xbmcgui.ListItem(vineData['vineDescription'], iconImage = icon ) listItem.setInfo(u'video', infoLabels) listItems.append((url, listItem)) if next: listItem = xbmcgui.ListItem(">> " + next.text) url = self.GetURLStart() + u'&page=' + next.a['href'] listItems.append((url, listItem, True)) xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) self.log( "listItems: " + repr(listItems)) except (Exception) as exception: exception = LoggingException.fromException(exception) if jsonText is not None: msg = u"jsonText:\n\n%s\n\n" % jsonText exception.addLogMessage(msg) # Error processing web page exception.addLogMessage(self.language(30780)) exception.process(self.language(30280), self.language(30780), severity = self.logLevel( xbmc.LOGERROR ))
def Play(self, infoLabels, thumbnail, rtmpVar = None, url = None, subtitles = None, resumeKey = None, resumeFlag = False): if url is None: url = rtmpVar.getPlayUrl() if thumbnail is not None: listItem = xbmcgui.ListItem(label=infoLabels[u'Title'], iconImage=thumbnail, thumbnailImage=thumbnail, path=url) infoLabels[u'thumbnail'] = thumbnail else: listItem = xbmcgui.ListItem(label=infoLabels[u'Title'], path=url) infoLabels[u'video_url'] = url listItem.setInfo(type=u'Video', infoLabels=infoLabels) if self.dialog.iscanceled(): return False try: player = self.GetPlayer() except PlayerLockException: exception_dialog = xbmcgui.Dialog() exception_dialog.ok("Stream Already Playing", "Unable to open stream", " - To continue, stop all other streams (try pressing 'x')[CR] - If you are sure there are no other streams [CR]playing, remove the resume lock (check addon settings -> advanced)") return playList=xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playList.clear() playList.add(url, listItem) player = self.GetPlayer() player.play(playList) self.dialog.close() #xbmcplugin.setResolvedUrl(handle=self.pluginHandle, succeeded=True, listitem=listItem) if subtitles is not None: try: self.log (u"Subtitle processing", xbmc.LOGDEBUG) subtitleFile = subtitles.GetSubtitleFile() player.setSubtitles(subtitleFile) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Error getting subtitles exception.addLogMessage(self.language(30970)) exception.process('', '', severity = xbmc.LOGWARNING) #self.log (u"AddSegments(playList)", xbmc.LOGDEBUG) #self.AddSegments(player.get_playlist()) #self.log (u"Post AddSegments(playList)", xbmc.LOGDEBUG) if os.environ.get( "OS" ) != "xbox": while player.isPlaying() and not xbmc.abortRequested: xbmc.sleep(500) self.log("Exiting playback loop... (isPlaying %s, abortRequested %s)" % (player.isPlaying(), xbmc.abortRequested), level=xbmc.LOGDEBUG) #player.set_cancelled() """
def ShowRootMenu(self): self.log(u"", xbmc.LOGDEBUG) warningFilePath = self.GetWarningFile() if not os.path.exists(warningFilePath): dialog = xbmcgui.Dialog() # WARNING: These videos are not moderated. By using this plugin you are accepting sole responsibility for any and all consequences of said use. action = dialog.yesno(self.GetProviderId(), self.language(30240), self.language(30241), self.language(30242), self.language(30260), self.language(30250) ) # 1=Continue; 0=Cancel if action == 0: return True f = open(warningFilePath, u"w") f.write('') f.close() try: listItems = [] # Search by #tag label = self.language(30210) thumbnailPath = self.GetThumbnailPath(label) newListItem = xbmcgui.ListItem( label=self.language(30210) ) newListItem.setThumbnailImage(thumbnailPath) url = self.GetURLStart() + u'&search=1' listItems.append((url, newListItem, True)) # Popular hashtags thumbnailPath = self.GetThumbnailPath(label) newListItem = xbmcgui.ListItem( label=self.language(30001) ) newListItem.setThumbnailImage(thumbnailPath) url = self.GetURLStart() + u'&popular=1' listItems.append((url, newListItem, True)) # Trending hashtags thumbnailPath = self.GetThumbnailPath(label) newListItem = xbmcgui.ListItem( label=self.language(30002) ) newListItem.setThumbnailImage(thumbnailPath) url = self.GetURLStart() + u'&trending=1' listItems.append((url, newListItem, True)) xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True except (Exception) as exception: exception = LoggingException.fromException(exception) #TODO Change text # Error processing categories exception.addLogMessage(self.language(30795)) exception.process(self.language(30765), self.language(30795), severity = xbmc.LOGWARNING) return False
def PlayLiveTV(self, html, dummy): """ <li class="first-live-channel selected-channel"> <a href="/player/ie/live/8/" class="live-channel-container"> <span class="sprite live-logo-rte-one">RTÉ One</span> <span class="sprite live-channel-now-playing">Playing</span> <span class="live-channel-info"><span class="live-time">Now:</span>The Works</span> <span class="live-channel-info"><span class="live-time">Next:</span>RTÉ News: Nine O'Clock and Weather (21:00)</span></a> </li> """ self.log(u"", xbmc.LOGDEBUG) swfPlayer = self.GetLiveSWFPlayer() liveChannels = { u'RT\xc9 One' : u'rte1', u'RT\xc9 Two' : u'rte2', u'RT\xc9jr': u'rtejr', u'RT\xc9 News Now' : u'newsnow' } try: soup = BeautifulSoup(html, selfClosingTags=[u'img']) #liveTVInfo = soup.find('span', 'sprite live-channel-now-playing').parent liveTVInfo = soup.find('li', 'selected-channel') channel = liveTVInfo.find('span').string programme = liveTVInfo.find('span', 'live-channel-info').next.nextSibling programme = self.fullDecode(programme).replace(''', "'") infoLabels = {u'Title': channel + u": " + programme } thumbnailPath = self.GetThumbnailPath((channel.replace(u'RT\xc9 ', '')).replace(' ', '')) rtmpStr = u"rtmp://fmsod.rte.ie/live/" app = u"live" swfVfy = swfPlayer playPath = liveChannels[channel] rtmpVar = rtmp.RTMP(rtmp = rtmpStr, app = app, swfVfy = swfVfy, playPath = playPath, live = True) self.AddSocksToRTMP(rtmpVar) self.Play(infoLabels, thumbnailPath, rtmpVar) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error playing live TV exception.addLogMessage(self.language(30053)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def ShowLiveMenu(self): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: html = None page = self.GetLivePageUrl() html = self.httpManager.GetWebPage(urlRoot + page, 60) soup = BeautifulSoup(html, selfClosingTags=['img']) schedule = soup.find('div', 'live-schedule-strap clearfix') liList = schedule.findAll('li') for li in liList: logoName = li.find('span', {'class':re.compile('live-logo')}) channel = logoName.text thumbnailPath = self.GetThumbnailPath((channel.replace(u'RT\xc9 ', '')).replace(' ', '')) page = li.a['href'] infoList=li.findAll('span', "live-channel-info") programme = "" for info in infoList: text = info.text.replace(" ", "") if len(text) == 0: continue comma = "" if len(programme) == 0: programme = info.text else: programme = programme + ", " + info.text programme = programme.replace(''', "'") newListItem = xbmcgui.ListItem( label=programme ) newListItem.setThumbnailImage(thumbnailPath) newListItem.setProperty("Video", "true") #newListItem.setProperty('IsPlayable', 'true') url = self.GetURLStart() + u'&live=1' + u'&page=' + mycgi.URLEscape(page) listItems.append( (url, newListItem, False) ) xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting Live TV information exception.addLogMessage(self.language(30047)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def Download(self, rtmpVar, defaultFilename, subtitles = None): (rtmpdumpPath, downloadFolder, filename) = self.GetDownloadSettings(defaultFilename) savePath = os.path.join( downloadFolder, filename ) rtmpVar.setDownloadDetails(rtmpdumpPath, savePath) parameters = rtmpVar.getParameters() if subtitles is not None: self.log (u"Getting subtitles") if subtitles is not None: try: # Replace '.flv' or other 3 character extension with '.smi' subtitleFile = subtitles.GetSubtitleFile(savePath[0:-4] + u'.smi') except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Error getting subtitles exception.addLogMessage(self.language(30970)) exception.process(u'', u'', severity = xbmc.LOGWARNING) if self.dialog.iscanceled(): return False self.dialog.close() # Starting downloads self.log (u"Starting download: " + rtmpdumpPath + u" " + parameters) xbmc.executebuiltin((u'XBMC.Notification(%s, %s, 5000, %s)' % ( self.language(30610), filename, self.addon.getAddonInfo('icon'))).encode(u'utf8')) self.log(u'"%s" %s' % (rtmpdumpPath, parameters)) if sys.modules[u"__main__"].get_system_platform() == u'windows': p = Popen( parameters, executable=rtmpdumpPath, shell=True, stdout=PIPE, stderr=PIPE ) else: cmdline = u'"%s" %s' % (rtmpdumpPath, parameters) p = Popen( cmdline, shell=True, stdout=PIPE, stderr=PIPE ) self.log (u"rtmpdump has started executing", xbmc.LOGDEBUG) (stdout, stderr) = p.communicate() self.log (u"rtmpdump has stopped executing", xbmc.LOGDEBUG) stderr = utils.normalize(stderr) if u'Download complete' in stderr: # Download Finished! self.log (u'stdout: ' + str(stdout), xbmc.LOGDEBUG) self.log (u'stderr: ' + str(stderr), xbmc.LOGDEBUG) self.log (u"Download Finished!") xbmc.executebuiltin((u'XBMC.Notification(%s,%s,2000, %s)' % ( self.language(30620), filename, self.addon.getAddonInfo('icon'))).encode(u'utf8')) else: # Download Failed! self.log (u'stdout: ' + str(stdout), xbmc.LOGERROR) self.log (u'stderr: ' + str(stderr), xbmc.LOGERROR) self.log (u"Download Failed!") xbmc.executebuiltin((u'XBMC.Notification(%s,%s,2000)' % ( u"Download Failed! See log for details", filename)).encode(u'utf8'))
def ListSearchShows(self, html): self.log(u"", xbmc.LOGDEBUG) listItems = [] try: soup = BeautifulSoup(html, selfClosingTags=[u'img']) articles = soup.findAll(u"article", u"search-result clearfix") if len(articles) > 0: for article in articles: self.AddEpisodeToSearchList(listItems, article) current = soup.find('li', 'dot-current') if current is not None: moreResults = current.findNextSibling('li', 'dot') if moreResults is not None: try: listItems.append( self.CreateSearchItem(moreResults.a['href']) ) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) # Not fatal, just means that we don't have the search option exception.process(severity = self.logLevel(xbmc.LOGWARNING)) xbmcplugin.addDirectoryItems( handle=self.pluginHandle, items=listItems ) xbmcplugin.endOfDirectory( handle=self.pluginHandle, succeeded=True ) return True except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if html is not None: msg = "html:\n\n%s\n\n" % html exception.addLogMessage(msg) # Error getting list of shows exception.addLogMessage(self.language(30049)) exception.process(severity = self.logLevel(xbmc.LOGERROR)) return False
def ShowEpisode(self, episodeId, series, appFormat, live = False): self.log(u"episodeId: %s, series: %s, live: %s" % (episodeId, series, live), xbmc.LOGDEBUG) # "Getting player functions" self.dialog.update(5, self.language(30092)) try: playerFunctionsJs = None playerFunctionsJs = self.httpManager.GetWebPage(playerFunctionsUrl, 20000) fullLLinkUrl = self.GetFullLink(episodeId, series, playerFunctionsJs) playerUrl = fullLLinkUrl.split('?')[0] bitUrl = self.GetBitUrl(episodeId, series, fullLLinkUrl, playerFunctionsJs) qsData = self.GetQSData(episodeId, bitUrl, playerFunctionsJs) if self.dialog.iscanceled(): return False # "Getting SWF url" self.dialog.update(15, self.language(30089)) self.swfUrl = self.GetSwfUrl(qsData) self.playerId = qsData[u'playerId'] self.playerKey = qsData[u'playerKey'] if self.dialog.iscanceled(): return False # "Getting stream url" self.dialog.update(30, self.language(30087)) rtmpUrl = self.GetStreamUrl(self.playerKey, playerUrl, self.playerId, contentId = episodeId) self.publisherId = unicode(int(float(self.amfResponse[u'publisherId']))) self.episodeId = episodeId self.totalParts = 0 mediaDTO = self.amfResponse[u'programmedContent'][u'videoPlayer'][u'mediaDTO'] (infoLabels, logo, rtmpVar, defaultFilename) = self.GetPlayListDetailsFromAMF(mediaDTO, appFormat, episodeId, live) if live: return self.Play(infoLabels, logo, rtmpVar) else: return self.PlayOrDownloadEpisode(infoLabels, logo, rtmpVar, defaultFilename) except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if playerFunctionsJs is not None: msg = u"playerFunctionsJs:\n\n%s\n\n" % playerFunctionsJs exception.addLogMessage(msg) # Error playing or downloading episode %s exception.addLogMessage(self.language(30051) % (episodeId + ", " + series)) # Error playing or downloading episode %s exception.process(self.language(30051) % ' ' , '', self.logLevel(xbmc.LOGERROR)) return False
def GetStreamUrl(self, key, url, playerId, contentRefId = None, contentId = None, streamType = "RTMP"): self.log("", xbmc.LOGDEBUG) try: self.amfResponse = None self.amfResponse = self.GetEpisodeInfo(key, url, playerId, contentRefId = contentRefId, contentId = contentId) name = self.amfResponse[u'name'] self.log(u"Name field: " + name) preferredRate = self.GetBitRateSetting() defaultStreamUrl = self.amfResponse[u'programmedContent'][u'videoPlayer'][u'mediaDTO'][u'FLVFullLengthURL'] self.log(u"defaultStreamUrl: %s" % defaultStreamUrl) if preferredRate is None and defaultStreamUrl.upper().startswith(streamType): return defaultStreamUrl originalRenditions = self.amfResponse[u'programmedContent'][u'videoPlayer'][u'mediaDTO'][u'renditions'] self.log(u"renditions:\n\n%s\n\n" % pformat(originalRenditions)) renditions = [] renditionsOther = [] for rendition in originalRenditions: ### TODO Check if this upsets aertv/tg4... ###if rendition[u'encodingRate'] == 0: ### continue if rendition['defaultURL'].upper().startswith(streamType): renditions.append(rendition) else: renditionsOther.append(rendition) if len(renditions) == 0: self.log(u"Unable to find stream of type '%s'" % streamType, xbmc.LOGWARNING) renditions = renditionsOther self.log(u"renditions: %s" % utils.drepr(renditions)) bitrate = self.ChooseBitRate(preferredRate, renditions) if bitrate == None: return defaultStreamUrl return bitrate except (Exception) as exception: if not isinstance(exception, LoggingException): exception = LoggingException.fromException(exception) if self.amfResponse is not None: msg = "self.amfResponse:\n\n%s\n\n" % utils.drepr(self.amfResponse) exception.addLogMessage(msg) raise exception