def AddCategories(self, data): Logger.Info("Performing Pre-Processing") items = [] if self.parentItem and "code" in self.parentItem.metaData: self.__currentChannel = self.parentItem.metaData["code"] Logger.Info("Only showing items for channel: '%s'", self.__currentChannel) return data, items cat = mediaitem.MediaItem("\a.: Categoriën :.", "https://www.vrt.be/vrtnu/categorieen/") cat.fanart = self.fanart cat.thumb = self.noImage cat.icon = self.icon cat.dontGroup = True items.append(cat) live = mediaitem.MediaItem("\a.: Live Streams :.", "https://services.vrt.be/videoplayer/r/live.json") live.fanart = self.fanart live.thumb = self.noImage live.icon = self.icon live.dontGroup = True live.isLive = True items.append(live) channelText = LanguageHelper.GetLocalizedString(30010) channels = mediaitem.MediaItem(".: %s :." % (channelText, ), "#channels") channels.fanart = self.fanart channels.thumb = self.noImage channels.icon = self.icon channels.dontGroup = True items.append(channels) Logger.Debug("Pre-Processing finished") return data, items
def ShowSettings(tabId=None, settingId=None): """Shows the settings dialog @param tabId: what tab should have focus in the settings? @param settingId: what control should have focus in the settings tab? """ if tabId is None: # shows the settings and blocks: AddonSettings.__CachedSettings().openSettings( ) # this will open settings window # reload the cache because stuff might have changed AddonSettings.__LoadSettings() Logger.Info( "Clearing Settings cache because settings dialog was shown.") else: # show settings and focus on a tab xbmc.executebuiltin('Addon.OpenSettings(%s)' % (Config.addonId, )) if tabId: # the 100 range are the tabs # the 200 range are the controls in a tab xbmc.executebuiltin('SetFocus(%i)' % int(tabId)) if settingId: xbmc.executebuiltin('SetFocus(%s)' % int(settingId)) Logger.Info("Settings shown with focus on %s-%s", tabId, settingId or "<none>") return
def GetUserAgent(): """ Retrieves a user agent string for this XBMC instance. @return: a user-agent string """ if not AddonSettings.__UserAgent: # load and cache AddonSettings.__UserAgent = AddonSettings.GetSetting( AddonSettings.__USER_AGENT_SETTING) or None # double check if the version of XBMC is still OK if AddonSettings.__UserAgent: # noinspection PyNoneFunctionAssignment version = AddonSettings.GetKodiVersion() if version not in AddonSettings.__UserAgent: old = AddonSettings.__UserAgent # a new XBMC version was installed, update the User-agent AddonSettings.UpdateUserAgent() Logger.Info( "User agent updated due to Kodi version change from\n%s to\n%s", old, AddonSettings.__UserAgent) else: AddonSettings.UpdateUserAgent() Logger.Info( "Set initial User agent version because it was missing.") Logger.Debug("User agent retrieved from cache: %s", AddonSettings.__UserAgent) return AddonSettings.__UserAgent
def __ImportChannel(self, className, channelCode): """ Imports a single channel by first importing all others @param className: the class to import @param channelCode: the channel code within the class @return: a Channel object """ if not self.__enabledChannels: self.__ImportChannels() # now we filter the channels results = filter(lambda c: c.moduleName == className and ( c.channelCode == channelCode or c.channelCode is channelCode ), self.__enabledChannels) # Order them by channelName MUST Also sort the buttons Logger.Info("ImportChannel resulted in %s channel(s)", len(results)) if len(results) == 1: Logger.Info("ImportChannel found: %s", results[0]) return results[0].GetChannel() else: return None
def GetSetting(self, settingId): """ Retrieves an encrypted setting from the Kodi Add-on Settings. @param settingId: the ID for the setting to retrieve @return: the decrypted value for the setting """ Logger.Info("Decrypting value for setting '%s'", settingId) encryptedValue = AddonSettings.GetSetting(settingId) if not encryptedValue: return encryptedValue try: decryptedValue = self.__Decrypt(encryptedValue, Vault.__Key) if not decryptedValue.startswith(settingId): Logger.Error("Invalid decrypted value for setting '%s'", settingId) return None decryptedValue = decryptedValue[len(settingId) + 1:] Logger.Info("Successfully decrypted value for setting '%s'", settingId) except UnicodeDecodeError: Logger.Error("Invalid Unicode data returned from decryption. Must be wrong data") return None return decryptedValue
def InstallViaExecutable(service): conf = config.GetConfig() Logger.Info('Installing executable, follow the instructions..', end=' ') if sys.platform == "linux" or sys.platform == "linux2": if not sh.Call('sudo apt-get update'): raise Exception('Unexpected: Could not update apt') if not sh.Call('sudo apt-get install {0}'.format(service)): raise Exception('Unexpected: Could not install service: ' + service) return Logger.Info(service + " package added", 'green', attrs=['bold']) elif sys.platform == "darwin": return elif sys.platform == "win32": installpath = conf["install-root"] + '' + service installer = 'msiexec.exe /i' if service in conf['windows-service']: if conf['windows-service'][service]['strategy'] == 'msi': return sh.Call('{0} "{1}" ^ INSTALLLOCATION="{2}" /qb'.format( installer, conf['windows-service'][service], installpath)) return DownloadAndInstallWindowsService( conf['windows-service'][service], service) else: Logger.Error("Unsupported operating system") return sys.exit()
def __IsNewVersionAvailable(self): """ Verifies that there is a new version available. It compares the addons.xml.md5 with the stored one. @return: True or False """ # first check if there is a "channel" folder channelPath = os.path.join(Config.rootDir, "channels") if not os.path.isdir(channelPath): Logger.Warning( "No Channels found at '%s', skipping updates for now.", channelPath) return False onlineData = UriHandler.Open(Config.UpdateUrl) self.__NewMd5 = onlineData.strip() self.__OldMd5 = AddonSettings.GetCurrentAddonXmlMd5() updated = self.__OldMd5 != self.__NewMd5 if updated: Logger.Info("New updates are available ('%s' vs '%s')", self.__OldMd5, self.__NewMd5) else: Logger.Info("No new updates available, MD5 hashes match") return updated
def DownloadVideoItem(self, item): """Downloads an existing MediaItem with more data. Arguments: item : MediaItem - the MediaItem that should be downloaded. Returns: The original item with more data added to it's properties. Used to download an <item>. If the item is not complete, the self.UpdateVideoItem method is called to update the item. The method downloads only the MediaStream with the bitrate that was set in the addon settings. After downloading the self.downloaded property is set. """ if not item.IsPlayable(): Logger.Error("Cannot download a folder item.") return item if item.IsPlayable(): if not item.complete: Logger.Info("Fetching MediaUrl for PlayableItem[%s]", item.type) item = self.ProcessVideoItem(item) if not item.complete or not item.HasMediaItemParts(): Logger.Error("Cannot download incomplete item or item without MediaItemParts") return item i = 1 bitrate = AddonSettings.GetMaxStreamBitrate() for mediaItemPart in item.MediaItemParts: Logger.Info("Trying to download %s", mediaItemPart) stream = mediaItemPart.GetMediaStreamForBitrate(bitrate) downloadUrl = stream.Url extension = UriHandler.GetExtensionFromUrl(downloadUrl) if len(item.MediaItemParts) > 1: saveFileName = "%s-Part_%s.%s" % (item.name, i, extension) else: saveFileName = "%s.%s" % (item.name, extension) Logger.Debug(saveFileName) # headers = item.HttpHeaders + mediaItemPart.HttpHeaders headers = item.HttpHeaders.copy() headers.update(mediaItemPart.HttpHeaders) progressDialog = XbmcDialogProgressWrapper("Downloading Item", item.name, stream.Url) folderName = XbmcWrapper.ShowFolderSelection('Select download destination for "%s"' % (saveFileName, )) UriHandler.Download(downloadUrl, saveFileName, folderName, progressDialog, proxy=self.proxy, additionalHeaders=headers) i += 1 item.downloaded = True return item
def __DeployNewChannels(self): """Checks the deploy folder for new channels, if present, deploys them The last part of the folders in the deploy subfolder are considered the channel names. The other part is replaced with the <addon base name>. So if the deploy has a folder temp.channelOne and the addon is called net.rieter.xot it will be deployed to net.rieter.xot.channel.channelOne. The folders are intially removed and then re-created. If the folder in the deploy does not have a addon.xml it will not be imported. """ Logger.Debug("Checking for new channels to deploy") # location of new channels and list of subfolders deployPath = os.path.join(Config.rootDir, "deploy") toDeploy = os.listdir(deployPath) # addons folder, different for XBMC and XBMC4Xbox if envcontroller.EnvController.IsPlatform(Environments.Xbox): targetFolder = os.path.abspath( os.path.join(Config.rootDir, self.__INTERNAL_CHANNEL_PATH)) if not os.path.exists(targetFolder): os.mkdir(targetFolder) else: targetFolder = os.path.abspath(os.path.join(Config.rootDir, "..")) for deploy in toDeploy: if deploy.startswith("."): continue sourcePath = os.path.join(deployPath, deploy) # find out if the scriptname is not net.rieter.xot and update deployParts = deploy.split(".") # channels addons always end with .channel.name # if (deployParts[-1] == "autoupdate"): # destDeploy = "%s.%s" % (Config.addonDir, deployParts[-1]) # else: destDeploy = "%s.channel.%s" % (Config.addonDir, deployParts[-1]) destinationPath = os.path.join(targetFolder, destDeploy) Logger.Info("Deploying Channel Addon '%s' to '%s'", deploy, destinationPath) if os.path.exists(destinationPath): Logger.Info("Removing old channel at %s", destDeploy) shutil.rmtree(destinationPath) # only update if there was a real addon if os.path.exists(os.path.join(sourcePath, "addon.xml")): shutil.move(sourcePath, destinationPath) else: shutil.rmtree(sourcePath) return
def CreateNgApp(appName): Logger.Info("Creating {} as an angular app..".format(appName)) package = "@angular/cli" command = "ng new {}".format(appName) if not ash.IsNpmPackageInstalled(package): Logger.Info("Angular was not found, installing..") ish.NpmInstall(package, True) return sh.Call(command)
def AssertNPMInstalled(): Logger.Info("Checking npm install path..", end = ' ') if not asserter.IsCommandExists("npm"): installhelper.InstallPrompt([ "npm" ]) else: Logger.Success("OK") Logger.Info("Verifying latest version of NPM", end = ' ') installhelper.Install("npm", "npm") Logger.Success("OK")
def ChangePin(self, applicationKey=None): # type: (str) -> bool """ Stores an existing ApplicationKey using a new PIN @param applicationKey: an existing ApplicationKey that will be stored. If none specified, the existing ApplicationKey of the Vault will be used. @return: indication of success """ Logger.Info("Updating the ApplicationKey with a new PIN") if self.__newKeyGeneratedInConstructor: Logger.Info("A key was just generated, no need to change PINs.") return True if applicationKey is None: Logger.Debug("Using the ApplicationKey from the vault.") applicationKey = Vault.__Key else: Logger.Debug("Using the ApplicationKey from the input parameter.") if not applicationKey: raise ValueError("No ApplicationKey specified.") # Now we get a new PIN and (re)encrypt pin = XbmcWrapper.ShowKeyBoard( heading=LanguageHelper.GetLocalizedString(LanguageHelper.VaultNewPin), hidden=True) if not pin: XbmcWrapper.ShowNotification( "", LanguageHelper.GetLocalizedString(LanguageHelper.VaultNoPin), XbmcWrapper.Error) return False pin2 = XbmcWrapper.ShowKeyBoard( heading=LanguageHelper.GetLocalizedString(LanguageHelper.VaultRepeatPin), hidden=True) if pin != pin2: Logger.Critical("Mismatch in PINs") XbmcWrapper.ShowNotification( "", LanguageHelper.GetLocalizedString(LanguageHelper.VaultPinsDontMatch), XbmcWrapper.Error) return False encryptedKey = "%s=%s" % (self.__APPLICATION_KEY_SETTING, applicationKey) # let's generate a pin using the scrypt password-based key derivation pinKey = self.__GetPBK(pin) encryptedKey = self.__Encrypt(encryptedKey, pinKey) AddonSettings.SetSetting(Vault.__APPLICATION_KEY_SETTING, encryptedKey) Logger.Info("Successfully updated the Retrospect PIN") return True
def ShowFavourites(self, channel, replaceExisting=False): """ Show the favourites Arguments: channel : Channel - The channel to show favourites for. Might be None to show all. Keyword Arguments: replaceExisting : boolean - if True it will replace the current list """ Logger.Debug("Plugin::ShowFavourites") if channel is None: Logger.Info("Showing all favourites") else: Logger.Info("Showing favourites for: %s", channel) stopWatch = stopwatch.StopWatch("Plugin Favourites timer", Logger.Instance()) try: ok = True f = Favourites(Config.favouriteDir) favs = f.List(channel) # get (actionUrl, pickle) tuples # favs = map(lambda (a, p): (a, Pickler.DePickleMediaItem(p)), favs) if len(favs) == 0: ok = self.__ShowEmptyInformation(favs, favs=True) stopWatch.Lap("Items retrieved") # create the XBMC items xbmcItems = map(lambda item: self.__ConvertMainlistItemToXbmcItem(channel, item[1], True, item[0]), favs) stopWatch.Lap("%s items for Kodi generated" % (len(xbmcItems),)) # add them to XBMC ok = ok and xbmcplugin.addDirectoryItems(self.handle, xbmcItems, len(xbmcItems)) # add sort handle, but don't use any dates as they make no sense for favourites self.__AddSortMethodToHandle(self.handle) # set the content xbmcplugin.setContent(handle=self.handle, content=self.contentType) # make sure we do not cache this one to disc! xbmcplugin.endOfDirectory(self.handle, succeeded=ok, updateListing=replaceExisting, cacheToDisc=False) stopWatch.Lap("items send to Kodi") Logger.Debug("Plugin::Favourites completed. Returned %s item(s)", len(favs)) stopWatch.Stop() except: XbmcWrapper.ShowNotification(LanguageHelper.GetLocalizedString(LanguageHelper.ErrorId), LanguageHelper.GetLocalizedString(LanguageHelper.ErrorList), XbmcWrapper.Error, 4000) Logger.Error("Plugin::Error parsing favourites", exc_info=True) xbmcplugin.endOfDirectory(self.handle, False)
def __init__(self, channelInfo): """Initialisation of the class. Arguments: channelInfo: ChannelInfo - The channel info object to base this channel on. All class variables should be instantiated here and this method should not be overridden by any derived classes. """ chn_class.Channel.__init__(self, channelInfo) self.mainListUri = "#mainlist" self._AddDataParser(url="#mainlist", preprocessor=self.ParseRadioList) self._AddDataParser(url="*", preprocessor=self.ParseSubList) # ============== Actual channel setup STARTS here and should be overwritten from derived classes =============== self.noImage = "radionlimage.png" #=============================================================================================================== # non standard items # download the stream data dataPath = os.path.join(self.path, "data") Logger.Debug("Checking '%s' for data", dataPath) if not os.path.isdir(dataPath): Logger.Info("No data found at '%s', downloading stream data", dataPath) url = "http://www.rieter.net/net.rieter.xot.repository/net.rieter.xot.channel.streams/" \ "net.rieter.xot.channel.streams.radionl.data.zip" # give the user feedback progressDialog = XbmcDialogProgressWrapper( "Downloading Data", "net.rieter.xot.channel.streams.radionl.data.zip", url) # download the zipfile zipFile = UriHandler.Download( url, "net.rieter.xot.channel.streams.radionl.data.zip", self.GetDefaultCachePath(), progressDialog) # and unzip it ZipHelper.Unzip(zipFile, dataPath) if os.path.isdir(dataPath): Logger.Info("Data successfully downloaded to: %s", dataPath) #=============================================================================================================== # Test cases: # ====================================== Actual channel setup STOPS here ======================================= return
def __UpdateFromUrl(self, url, zipName): """ Update a channel from an URL @param url: The url to download @param zipName: The name to give the download """ Logger.Info("Going to update from %s", url) # wrapper = XbmcDialogProgressWrapper("Updating XOT", url) # destFilename = UriHandler.Download(url, zipName, Config.cacheDir, wrapper.ProgressUpdate) destFilename = UriHandler.Download(url, zipName, Config.cacheDir, self.__RetrieveProgressDummy) Logger.Debug("Download succeeded: %s", destFilename) # we extract to the deploy folder, so with the first start of XOT, the new channel is deployed deployDir = os.path.abspath(os.path.join(Config.rootDir, "deploy")) zipFile = zipfile.ZipFile(destFilename) # now extract first = True Logger.Debug("Extracting %s to %s", destFilename, deployDir) for name in zipFile.namelist(): if first: folder = os.path.split(name)[0] if os.path.exists(os.path.join(deployDir, folder)): shutil.rmtree(os.path.join(deployDir, folder)) first = False if not name.endswith("/") and not name.endswith("\\"): fileName = os.path.join(deployDir, name) path = os.path.dirname(fileName) if not os.path.exists(path): os.makedirs(path) Logger.Debug("Extracting %s", fileName) outfile = open(fileName, 'wb') outfile.write(zipFile.read(name)) outfile.close() zipFile.close() os.remove(destFilename) Logger.Info("Update completed and zip file (%s) removed", destFilename) message = LanguageHelper.GetLocalizedString( LanguageHelper.UpdateCompleteId, splitOnPipes=False) % (zipName.replace(".zip", ""), ) message = message.split("|") XbmcWrapper.ShowNotification(LanguageHelper.GetLocalizedString( LanguageHelper.RestartId), message, displayTime=5000, logger=Logger.Instance())
def AddLive(self, data): """Performs pre-process actions for data processing Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] item = mediaitem.MediaItem( "\a.: Live TV :.", "http://www.tikilive.com:8080/socket.io/" "?c=34967&n=TIKISESSID&i=fo84il3e7qs68uet2ql2eav081&EIO=3" "&transport=polling&t=1428225927102-0") item.type = 'video' items.append(item) Logger.Debug("Pre-Processing finished") return data, items
def AddLiveChannel(self, data): Logger.Info("Performing Pre-Processing") # if self.channelCode != "vtm": # return data, [] username = AddonSettings.GetSetting("mediaan_username") if not username: return data, [] items = [] if self.channelCode == "vtm": item = MediaItem("Live VTM", "#livestream") else: item = MediaItem("Live Q2", "#livestream") item.type = "video" item.isLive = True item.fanart = self.fanart item.thumb = self.noImage now = datetime.datetime.now() item.SetDate(now.year, now.month, now.day, now.hour, now.minute, now.second) items.append(item) if self.channelCode == "vtm": recent = MediaItem("\a.: Recent :.", "https://vtm.be/video/volledige-afleveringen/id") item.fanart = self.fanart item.thumb = self.noImage item.dontGroup = True items.append(recent) Logger.Debug("Pre-Processing finished") return data, items
def Extend(args): containers = args[0].split(':')[1:] switch = helper.GetSwitchFromArgs(args) ash.AssertDockerInstalled() if not containers or len(containers) == 0: return Logger.Error("Error use of " + args + " please read the manual") for container in containers: if not container: return Logger.Error("Error use of " + args + " please read the manual") if not (container in IMAGES): return Logger.Error(container + " is not supported image") Logger.Info("Creating docker initialization for: " + container) #CreateDockerContainer(container) conf['app-type'] = 'virtualized' conf['features']['virtualizer'] = 'docker' config.WriteAppiConfig({"app-type": conf['app-type']}) config.WriteAppiConfig({"fetures": conf['features']}) return
def StripNonCategories(self, data): """Performs pre-process actions for data processing/ Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] start = data.find('<div id="playJs-alphabetic-list"') end = data.find('<div id="playJs-', start + 1) if end == 0: end = -1 data = data[start:end] Logger.Debug("Pre-Processing finished") return data, items
def AddPageItems(self, data): """ Adds page items to the main listing @param data: the Parsed Data @return: a tuple of data and items """ Logger.Info("Performing Pre-Processing") items = [] json = JsonHelper(data) totalResults = json.GetValue("totalResults") fromValue = json.GetValue("from") sizeValue = json.GetValue("size") if fromValue + sizeValue < totalResults: morePages = LanguageHelper.GetLocalizedString( LanguageHelper.MorePages) url = self.parentItem.url.split('?')[0] url = "%s?size=%s&from=%s&sort=Nieuwste" % (url, sizeValue, fromValue + sizeValue) Logger.Debug("Adding next-page item from %s to %s", fromValue + sizeValue, fromValue + sizeValue + sizeValue) nextPage = mediaitem.MediaItem(morePages, url) nextPage.icon = self.parentItem.icon nextPage.fanart = self.parentItem.fanart nextPage.thumb = self.parentItem.thumb nextPage.dontGroup = True items.append(nextPage) Logger.Debug("Pre-Processing finished") return json, items
def ExtractVideoSection(self, data): """Performs pre-process actions for data processing Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] data = data[0:data.find('<div class="splitter split24">')] # data = data[0:data.find('<ul class="videoarticle-socialsharing">')] Logger.Debug("Pre-Processing finished") return data, items
def __GetApplicationKey(self): """ Gets the decrypted application key that is used for all the encryption @return: the decrypted application key that is used for all the encryption """ applicationKeyEncrypted = AddonSettings.GetSetting(Vault.__APPLICATION_KEY_SETTING) if not applicationKeyEncrypted: return None vaultIncorrectPin = LanguageHelper.GetLocalizedString(LanguageHelper.VaultIncorrectPin) pin = XbmcWrapper.ShowKeyBoard( heading=LanguageHelper.GetLocalizedString(LanguageHelper.VaultInputPin), hidden=True) if not pin: XbmcWrapper.ShowNotification("", vaultIncorrectPin, XbmcWrapper.Error) raise RuntimeError("Incorrect Retrospect PIN specified") pinKey = self.__GetPBK(pin) applicationKey = self.__Decrypt(applicationKeyEncrypted, pinKey) if not applicationKey.startswith(Vault.__APPLICATION_KEY_SETTING): Logger.Critical("Invalid Retrospect PIN") XbmcWrapper.ShowNotification("", vaultIncorrectPin, XbmcWrapper.Error) raise RuntimeError("Incorrect Retrospect PIN specified") applicationKeyValue = applicationKey[len(Vault.__APPLICATION_KEY_SETTING) + 1:] Logger.Info("Successfully decrypted the ApplicationKey.") return applicationKeyValue
def AddSearch(self, data): """Performs pre-process actions for data processing, in this case adding a search Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] searchItem = mediaitem.MediaItem("\a.: Sök :.", "searchSite") searchItem.complete = True searchItem.thumb = self.noImage searchItem.dontGroup = True searchItem.fanart = self.fanart # searchItem.SetDate(2099, 1, 1, text="") # -> No items have dates, so adding this will force a date sort in Retrospect items.append(searchItem) Logger.Debug("Pre-Processing finished") return data, items
def PreProcessFolderList(self, data): """Performs pre-process actions for data processing/ Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] if '>Populair<' in data: data = data[data.index('>Populair<'):] if '>L1-kanalen<' in data: data = data[:data.index('>L1-kanalen<')] Logger.Debug("Pre-Processing finished") return data, items
def PreProcessFolderList(self, data): """Performs pre-process actions for data processing/ Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] data = data.replace(" ", " ") pageNav = data.find('<div class="pageNav">') if pageNav > 0: data = data[0:pageNav] Logger.Debug("Pre-Processing finished") return data, items
def ExtractJsonData(self, data): """Performs pre-process actions for data processing Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") data = Regexer.DoRegex("<script>var programEpisodes = ({[^<]+})", data)[-1] items = [] Logger.Debug("Pre-Processing finished") return data, items
def LogOn(self, *args): """Logs on to a website, using an url. Arguments: userName : string - the username to use to log on passWord : string - the password to use to log on Returns: True if successful. First checks if the channel requires log on. If so and it's not already logged on, it should handle the log on. That part should be implemented by the specific channel. More arguments can be passed on, but must be handled by custom code. After a successful log on the self.loggedOn property is set to True and True is returned. """ if not self.requiresLogon: Logger.Debug("No login required of %s", self.channelName) return True if self.loggedOn: Logger.Info("Already logged in") return True return False
def __IgnoreCookieLaw(self): """ Accepts the cookies from UZG in order to have the site available """ Logger.Info("Setting the Cookie-Consent cookie for www.dumpert.nl") # Set-Cookie: cpc=10; path=/; domain=www.dumpert.nl; expires=Thu, 11-Jun-2020 18:49:38 GMT # the rfc2109 parameters is not valid in Python 2.4 (Xbox), so we ommit it. c = cookielib.Cookie(version=0, name='cpc', value='10', port=None, port_specified=False, domain='.www.dumpert.nl', domain_specified=True, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=2327431273, discard=False, comment=None, comment_url=None, rest={'HttpOnly': None}) # , rfc2109=False) UriHandler.Instance().cookieJar.set_cookie(c) return
def AddClips(self, data): Logger.Info("Adding Clips Pre-Processing") items = [] # if the main list was retrieve using json, are the current data is json, just determine # the clip URL clipUrl = None if data.lstrip().startswith("{"): if self.parentItem.url.endswith("type=program"): # http://playapi.mtgx.tv/v3/videos?format=6723&order=-airdate&type=program # http://playapi.mtgx.tv/v3/videos?format=6723&order=-updated&type=clip" % (dataId,) clipUrl = self.parentItem.url.replace("type=program", "type=clip") else: # now we determine the ID and load the json data dataId = Regexer.DoRegex('data-format-id="(\d+)"', data)[-1] Logger.Debug("Found FormatId = %s", dataId) programUrl = "http://playapi.mtgx.tv/v3/videos?format=%s&order=-airdate&type=program" % ( dataId, ) data = UriHandler.Open(programUrl, proxy=self.proxy) clipUrl = "http://playapi.mtgx.tv/v3/videos?format=%s&order=-updated&type=clip" % ( dataId, ) if clipUrl is not None: clipTitle = LanguageHelper.GetLocalizedString(LanguageHelper.Clips) clipItem = mediaitem.MediaItem("\a.: %s :." % (clipTitle, ), clipUrl) clipItem.thumb = self.noImage items.append(clipItem) Logger.Debug("Pre-Processing finished") return data, items
def AddSearch(self, data): """Performs pre-process actions for data processing/ Arguments: data : string - the retrieve data that was loaded for the current item and URL. Returns: A tuple of the data and a list of MediaItems that were generated. Accepts an data from the ProcessFolderList method, BEFORE the items are processed. Allows setting of parameters (like title etc) for the channel. Inside this method the <data> could be changed and additional items can be created. The return values should always be instantiated in at least ("", []). """ Logger.Info("Performing Pre-Processing") items = [] title = "\a.: %s :." % (self.searchInfo.get( self.language, self.searchInfo["se"])[1], ) Logger.Trace("Adding search item: %s", title) searchItem = mediaitem.MediaItem(title, "searchSite") searchItem.thumb = self.noImage searchItem.fanart = self.fanart searchItem.dontGroup = True items.append(searchItem) Logger.Debug("Pre-Processing finished") return data, items