def GetXBMCItem(self): """ Creates an Xbmc ListItem object for this channel """ name = HtmlEntityHelper.ConvertHTMLEntities(self.channelName) description = HtmlEntityHelper.ConvertHTMLEntities(self.channelDescription) self.icon = self.__GetImagePath(self.icon) item = xbmcgui.ListItem(name, description) try: item.setIconImage(self.icon) except: # it was deprecated pass item.setArt({'thumb': self.icon, 'icon': self.icon}) # http://mirrors.kodi.tv/docs/python-docs/14.x-helix/xbmcgui.html#ListItem-setInfo item.setInfo("video", {"Title": name, # "Count": self.sortOrderPerCountry, # "TrackNumber": self.sortOrder, "Genre": LanguageHelper.GetFullLanguage(self.language), # "Tagline": description, "Plot": description}) if AddonSettings.HideFanart(): return item if self.fanart is not None: self.fanart = self.__GetImagePath(self.fanart) else: self.fanart = os.path.join(Config.rootDir, "fanart.jpg") item.setArt({'fanart': self.fanart}) return item
def CreateEpisodeItem(self, resultSet): """Creates a new MediaItem for an episode Arguments: resultSet : list[string] - the resultSet of the self.episodeItemRegex Returns: A new MediaItem of type 'folder' This method creates a new MediaItem from the Regular Expression results <resultSet>. The method should be implemented by derived classes and are specific to the channel. """ Logger.Trace(resultSet) url = resultSet[0] if "&" in url: url = HtmlEntityHelper.ConvertHTMLEntities(url) if not url.startswith("http:"): url = "%s%s" % (self.baseUrl, url) # get the ajax page for less bandwidth url = "%s?sida=1&sort=tid_stigande&embed=true" % (url, ) item = mediaitem.MediaItem(resultSet[1], url) item.icon = self.icon item.thumb = self.noImage item.complete = True return item
def CreateEpisodeItem(self, resultSet): """ Accepts an arraylist of results. It returns an item. """ url = urlparse.urljoin( self.baseUrl, HtmlEntityHelper.ConvertHTMLEntities(resultSet[0])) name = resultSet[1] if name == "Tags": return None if name == "Authors": return None if name == "Most Viewed": return None if name == "Top Rated": name = "Recent" url = "http://channel9.msdn.com/Feeds/RSS" else: url = "%s?sort=atoz" % (url, ) item = mediaitem.MediaItem(name, url) item.icon = self.icon item.complete = True return item
def UpdateVideoItem(self, item): """ Accepts an item. It returns an updated item. Usually retrieves the MediaURL and the Thumb! It should return a completed item. """ Logger.Debug('Starting UpdateVideoItem for %s (%s)', item.name, self.channelName) # now the mediaurl is derived. First we try WMV data = UriHandler.Open(item.url) urls = Regexer.DoRegex( '<a href="([^"]+.(?:wmv|mp4))">(High|Medium|Mid|Low|MP4)', data) mediaPart = mediaitem.MediaItemPart(item.name) for url in urls: if url[1].lower() == "high": bitrate = 2000 elif url[1].lower() == "medium" or url[1].lower() == "mid": bitrate = 1200 elif url[1].lower() == "low" or url[1].lower() == "mp4": bitrate = 200 else: bitrate = 0 mediaPart.AppendMediaStream( HtmlEntityHelper.ConvertHTMLEntities(url[0]), bitrate) item.MediaItemParts.append(mediaPart) #images = Regexer.DoRegex('<link type="image/jpeg" rel="videothumbnail" href="([^"]+)"/>', data) #for image in images: # thumbUrl = htmlentityhelper.HtmlEntityHelper.ConvertHTMLEntities(image) # break item.complete = True return item
def CreatePageItem(self, resultSet): """Creates a MediaItem of type 'page' using the resultSet from the regex. Arguments: resultSet : tuple(string) - the resultSet of the self.pageNavigationRegex Returns: A new MediaItem of type 'page' This method creates a new MediaItem from the Regular Expression results <resultSet>. The method should be implemented by derived classes and are specific to the channel. """ url = urlparse.urljoin( self.baseUrl, HtmlEntityHelper.ConvertHTMLEntities(resultSet[0])) item = mediaitem.MediaItem(resultSet[self.pageNavigationRegexIndex], url) item.type = "page" item.complete = True item.SetDate(2022, 1, 1, text="") Logger.Trace("Created '%s' for url %s", item.name, item.url) return item
def UpdateVideoItem(self, item): data = UriHandler.Open(item.url, proxy=self.proxy, additionalHeaders=item.HttpHeaders) mediaRegex = 'data-media="([^"]+)"' mediaInfo = Regexer.DoRegex(mediaRegex, data)[0] mediaInfo = HtmlEntityHelper.ConvertHTMLEntities(mediaInfo) mediaInfo = JsonHelper(mediaInfo) Logger.Trace(mediaInfo) # sources part = item.CreateNewEmptyMediaPart() # high, web, mobile, url mediaSources = mediaInfo.json.get("sources", {}) for quality in mediaSources: url = mediaSources[quality] if quality == "high": bitrate = 2000 elif quality == "web": bitrate = 800 elif quality == "mobile": bitrate = 400 else: bitrate = 0 part.AppendMediaStream(url, bitrate) # geoLocRestriction item.isGeoLocked = not mediaInfo.GetValue("geoLocRestriction", fallback="world") == "world" item.complete = True return item
def __ConvertJsonSubtitleToSrt(jsonSubtitle): """Converts Json Subtitle format into SRT format: Arguments: jsonSubtitle : string - Json Subtitle subtitle format Returns: SRT formatted subtitle: Example: {"startMillis":80,"endMillis":4170,"text":"Ett Kanal 5:\nAlla gonblick i \"100 jdare!!!\"?","posX":0.5,"posY":0.9,"colorR":220,"colorG":220,"colorB":220} Returns 1 00:00:20,000 --> 00:00:24,400 text The format of the timecode is Hours:Minutes:Seconds:Ticks where a "Tick" is a value of between 0 and 249 and lasts 4 milliseconds. """ regex = '"startMillis":(\d+),"endMillis":(\d+),"text":"(.+?)(?=["] *,)' subs = Regexer.DoRegex(regex, jsonSubtitle) # Init some stuff srt = "" i = 1 for sub in subs: try: # print sub start = SubtitleHelper.__ConvertToTime(sub[0]) end = SubtitleHelper.__ConvertToTime(sub[1]) text = sub[2].replace('\"', '"') text = JsonHelper.ConvertSpecialChars(text) text = HtmlEntityHelper.ConvertHTMLEntities(text) srt = "%s\n%s\n%s --> %s\n%s\n" % (srt, i, start, end, text.strip()) i += 1 except: Logger.Error("Error parsing subtitle: %s", sub, exc_info=True) return srt
def UpdateLiveItem(self, item): data = UriHandler.Open(item.url, proxy=self.proxy, additionalHeaders=item.HttpHeaders) mediaRegex = 'data-media="([^"]+)"' mediaInfo = Regexer.DoRegex(mediaRegex, data)[0] mediaInfo = HtmlEntityHelper.ConvertHTMLEntities(mediaInfo) mediaInfo = JsonHelper(mediaInfo) Logger.Trace(mediaInfo) part = item.CreateNewEmptyMediaPart() hlsUrl = mediaInfo.GetValue("streamUrl") if hlsUrl is not None and "m3u8" in hlsUrl: Logger.Debug("Found HLS url for %s: %s", mediaInfo.json["streamName"], hlsUrl) # from debug.router import Router # data = Router.GetVia("be", hlsUrl, proxy=self.proxy) for s, b in M3u8.GetStreamsFromM3u8(hlsUrl, self.proxy): part.AppendMediaStream(s, b) item.complete = True else: Logger.Debug("No HLS url found for %s. Fetching RTMP Token.", mediaInfo.json["streamName"]) # fetch the token: tokenUrl = "%s/api/media/streaming?streamname=%s" % ( self.baseUrl, mediaInfo.json["streamName"]) tokenData = UriHandler.Open(tokenUrl, proxy=self.proxy, additionalHeaders=item.HttpHeaders, noCache=True) tokenData = JsonHelper(tokenData) token = tokenData.GetValue("token") Logger.Debug("Found token '%s' for '%s'", token, mediaInfo.json["streamName"]) rtmpUrl = "rtmp://rtmp.rtbf.be/livecast/%s?%s pageUrl=%s tcUrl=rtmp://rtmp.rtbf.be/livecast" % ( mediaInfo.json["streamName"], token, self.baseUrl) rtmpUrl = self.GetVerifiableVideoUrl(rtmpUrl) part.AppendMediaStream(rtmpUrl, 0) item.complete = True item.isGeoLocked = not mediaInfo.GetValue("geoLocRestriction", fallback="world") == "world" return item
def ShowChannelSettings(channel): """ Show the add-on settings and pre-selects the channel settings tab with the correct channel selected. @param channel: The channel to display settings for. """ channelName = channel.safeName # remove some HTML chars channelName = HtmlEntityHelper.ConvertHTMLEntities(channelName) Logger.Debug("Showing channel settings for channel: %s (%s)", channelName, channel.channelName) # Set the channel to be the preselected one AddonSettings.SetSetting("config_channel", channelName) # show settings and focus on the channel settings tab return AddonSettings.ShowSettings(102)
def __ConvertSamiToSrt(sami): """Converts sami format into SRT format: Arguments: sami : string - SAMI subtitle format Returns: SRT formatted subtitle: Example: 1 00:00:20,000 --> 00:00:24,400 text """ parsRegex = '<sync start="(\d+)"><p[^>]+>([^<]+)</p></sync>\W+<sync start="(\d+)">' subs = Regexer.DoRegex(parsRegex, sami) if len(subs) == 0: parsRegex2 = '<sync start=(\d+)>\W+<p[^>]+>([^\n]+)\W+<sync start=(\d+)>' subs = Regexer.DoRegex(parsRegex2, sami) srt = "" i = 1 for sub in subs: try: # print sub start = SubtitleHelper.__ConvertToTime(sub[0]) end = SubtitleHelper.__ConvertToTime(sub[2]) text = sub[1] text = HtmlEntityHelper.ConvertHTMLEntities(text) # text = sub[1] srt = "%s\n%s\n%s --> %s\n%s\n" % (srt, i, start, end, text) i += 1 except: Logger.Error("Error parsing subtitle: %s", sub[1], exc_info=True) # re-encode to be able to write it return srt
def ShowChannelSettings(channel): """ Show the add-on settings and pre-selects the channel settings tab with the correct channel selected. @param channel: The channel to display settings for. """ channelName = channel.safeName # remove some HTML chars channelName = HtmlEntityHelper.ConvertHTMLEntities(channelName) Logger.Debug("Showing channel settings for channel: %s (%s)", channelName, channel.channelName) # Set the channel to be the preselected one AddonSettings.__settings.setSetting("config_channel", channelName) # show settings and focus on the channel settings tab xbmc.executebuiltin('Addon.OpenSettings(%s)' % (Config.addonId, )) # the 100 range are the tabs # the 200 range are the controls in a tab xbmc.executebuiltin('SetFocus(%i)' % 102)
def __FullDecodeText(self, stringValue): """ Decodes a byte encoded string with HTML content into Unicode String Arguments: stringValue : string - The byte encoded string to decode Returns: An Unicode String with all HTML entities replaced by their UTF8 characters The decoding is done by first decode the string to UTF8 and then replace the HTML entities to their UTF8 characters. """ if stringValue is None: return None if stringValue == "": return "" # then get rid of the HTML entities stringValue = HtmlEntityHelper.ConvertHTMLEntities(stringValue) return stringValue
def __ConvertTtmlToSrt(ttml): """Converts sami format into SRT format: Arguments: ttml : string - TTML (Timed Text Markup Language) subtitle format Returns: SRT formatted subtitle: Example: 1 00:00:20,000 --> 00:00:24,400 text """ parsRegex = '<p[^>]+begin="([^"]+)\.(\d+)"[^>]+end="([^"]+)\.(\d+)"[^>]*>([\w\W]+?)</p>' subs = Regexer.DoRegex(parsRegex, ttml) srt = "" i = 1 for sub in subs: try: # print sub start = "%s,%03d" % (sub[0], int(sub[1])) end = "%s,%03d" % (sub[2], int(sub[3])) text = sub[4].replace("<br />", "\n") # text = sub[4].replace("<br />", "\n") text = HtmlEntityHelper.ConvertHTMLEntities(text) text = text.replace("\r\n", "") srt = "%s\n%s\n%s --> %s\n%s\n" % (srt, i, start, end, text.strip()) i += 1 except: Logger.Error("Error parsing subtitle: %s", sub[1], exc_info=True) return srt
def __RegisterHit(category, action, label, value=None, referer=None): """ Register an event with Google Analytics @param category: String - Name of category to register @param action: String - Name of action to register @param value: String - Value of action to register @param label: String - The label for the event @param value: int - The value for the event (Defaults to None) @param referer: String - The referer (Defaults to None) See: https://ga-dev-tools.appspot.com/hit-builder/ v=1&t=event&tid=UA-3902785-1&cid=3c8961be-6a53-48f6-bded-d136760ab55f&ec=Test&ea=Test%20Action&el=Test%20%5Blabel)&ev=100 """ try: if not AddonSettings.SendUsageStatistics(): Logger.Debug( "Not sending statistics because the configuration does not allow this." ) return postData = { "v": 1, "t": "event", "tid": Config.googleAnalyticsId, "cid": AddonSettings.GetClientId(), "ec": HtmlEntityHelper.UrlEncode(category), # "ec": HtmlEntityHelper.UrlEncode("Test"), "ea": HtmlEntityHelper.UrlEncode( HtmlEntityHelper.ConvertHTMLEntities(action)), "el": HtmlEntityHelper.UrlEncode( HtmlEntityHelper.ConvertHTMLEntities(label)), } if value is not None: postData["ev"] = value if referer is not None: if "://" not in referer: referer = "http://%s" % (referer, ) postData["dr"] = HtmlEntityHelper.UrlEncode(referer) url = "http://www.google-analytics.com/collect" data = "" for k, v in postData.iteritems(): data += "%s=%s&" % (k, v) data = data.rstrip("&") # url = "http://www.rieter.net/net.rieter.xot.usage/%s/%s/?rnd=%s" % (action, value, rnd) Logger.Debug("Sending statistics: %s", data) # now we need something async without caching userAgent = AddonSettings.GetUserAgent() if userAgent: result = UriHandler.Open( url, additionalHeaders={"User-Agent": userAgent}, params=data, noCache=True) else: result = UriHandler.Open(url, params=data, noCache=True) if len(result) > 0: Logger.Debug( "Statistics were successfully sent. Content Length: %d", len(result)) else: Logger.Warning("Statistics were not successfully sent") except: # we should never ever fail here Logger.Warning("Cannot send statistics", exc_info=True) return
def __ConvertDCSubtitleToSrt(dcSubtitle): """Converts DC Subtitle format into SRT format: Arguments: dcSubtitle : string - DC Subtitle subtitle format Returns: SRT formatted subtitle: Example: <Subtitle SpotNumber="1" TimeIn="00:00:01:220" TimeOut="00:00:04:001" FadeUpTime="20" FadeDownTime="20"> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="6.0">Line 1</Text> </Subtitle> <Subtitle SpotNumber="2" TimeIn="00:02:07:180" TimeOut="00:02:10:040" FadeUpTime="20" FadeDownTime="20"> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="6.0">Line 1</Text> </Subtitle> <Subtitle SpotNumber="3" TimeIn="00:02:15:190" TimeOut="00:02:17:190" FadeUpTime="20" FadeDownTime="20"> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="14.0">Line 1</Text> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="6.0">Line 2</Text> </Subtitle> <Subtitle SpotNumber="4" TimeIn="00:03:23:140" TimeOut="00:03:30:120" FadeUpTime="20" FadeDownTime="20"> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="14.0">Line 1</Text> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="14.0">Line 2</Text> <Text Direction="horizontal" HAlign="center" HPosition="0.0" VAlign="bottom" VPosition="14.0">Line 3</Text> </Subtitle> Returns 1 00:00:20,000 --> 00:00:24,400 text The format of the timecode is Hours:Minutes:Seconds:Ticks where a "Tick" is a value of between 0 and 249 and lasts 4 milliseconds. """ # parseRegex = '<subtitle[^>]+spotnumber="(\d+)" timein="(\d+:\d+:\d+):(\d+)" timeout="(\d+:\d+:\d+):(\d+)"[^>]+>\W+<text[^>]+>([^<]+)</text>\W+(?:<text[^>]+>([^<]+)</text>)*\W+</subtitle>' parseRegex = '<subtitle[^>]+spotnumber="(\d+)" timein="(\d+:\d+:\d+):(\d+)" timeout="(\d+:\d+:\d+):(\d+)"[^>]+>|<text[^>]+>([^<]+)</text>' parseRegex = parseRegex.replace('"', '["\']') subs = Regexer.DoRegex(parseRegex, dcSubtitle) srt = "" i = 1 text = "" start = "" end = "" for sub in subs: #Logger.Trace(sub) try: if sub[0]: # new start of a sub if text and start and end: # if we have a complete old one, save it text = HtmlEntityHelper.ConvertHTMLEntities(text) srt = "%s\n%s\n%s --> %s\n%s\n" % (srt, i, start, end, text.strip()) i += 1 start = "%s,%03d" % (sub[1], int(sub[2])) end = "%s,%03d" % (sub[3], int(sub[4])) text = "" else: text = "%s\n%s" % (text, sub[5].replace("<br />", "\n")) except: Logger.Error("Error parsing subtitle: %s", sub, exc_info=True) return srt
def CreateFolderItem(self, resultSet): """Creates a MediaItem of type 'folder' using the resultSet from the regex. Arguments: resultSet : tuple(strig) - the resultSet of the self.folderItemRegex Returns: A new MediaItem of type 'folder' This method creates a new MediaItem from the Regular Expression or Json results <resultSet>. The method should be implemented by derived classes and are specific to the channel. """ if len(resultSet) > 3 and resultSet[3] != "": Logger.Debug("Sub category folder found.") url = urlparse.urljoin( self.baseUrl, HtmlEntityHelper.ConvertHTMLEntities(resultSet[3])) name = "\a.: %s :." % (resultSet[4], ) item = mediaitem.MediaItem(name, url) item.thumb = self.noImage item.complete = True item.type = "folder" return item url = urlparse.urljoin( self.baseUrl, HtmlEntityHelper.ConvertHTMLEntities(resultSet[0])) name = HtmlEntityHelper.ConvertHTMLEntities(resultSet[1]) helper = HtmlHelper(resultSet[2]) description = helper.GetTagContent("div", {'class': 'description'}) item = mediaitem.MediaItem(name, "%s/RSS" % (url, )) item.thumb = self.noImage item.type = 'folder' item.description = description.strip() date = helper.GetTagContent("div", {'class': 'date'}) if date == "": date = helper.GetTagContent("span", {'class': 'lastPublishedDate'}) if not date == "": dateParts = Regexer.DoRegex("(\w+) (\d+)[^<]+, (\d+)", date) if len(dateParts) > 0: dateParts = dateParts[0] monthPart = dateParts[0].lower() dayPart = dateParts[1] yearPart = dateParts[2] try: month = DateHelper.GetMonthFromName(monthPart, "en") item.SetDate(yearPart, month, dayPart) except: Logger.Error("Error matching month: %s", monthPart, exc_info=True) item.complete = True return item