def __init__(self, addon_id, fileName, addonADG, modSourceCode=None): self._fileId = addon_id self._fileName = fileName self._location = "" self._isEditable = True self.parser = CoderParser() self.addonADG = addonADG self.addon_id = addon_id self.modSourceCode = modSourceCode or {}
def __init__(self, addon_id, fileName, addonADG, modSourceCode = None): self._fileId = addon_id self._fileName = fileName self._location = "" self._isEditable = True self.parser = CoderParser() self.addonADG = addonADG self.addon_id = addon_id self.modSourceCode = modSourceCode or {}
class InitModule: HEADER = '\nimport os, sys\nimport xbmcaddon\nimport xbmc\nimport xbmcplugin\nimport xbmcgui\nimport urlparse\nimport urllib\nimport re\n\n_settings = xbmcaddon.Addon()\n_path = xbmc.translatePath(_settings.getAddonInfo(\'path\')).decode(\'utf-8\')\n_lib = xbmc.translatePath(os.path.join(_path, \'resources\', \'lib\'))\n_media = xbmc.translatePath(os.path.join(_path, \'resources\', \'media\'))\nsys.path.append(_lib)\n\nEMPTYCONTENT = [[{}, {"isFolder": True, "label": ""}, None]]\n\nfrom basicFunc import openUrl, parseUrlContent, makeXbmcMenu, getMenu, LISTITEM_KEYS, INFOLABELS_KEYS\n' FOOTER = '\nbase_url = sys.argv[0]\naddon_handle = int(sys.argv[1])\nargs = urlparse.parse_qs(sys.argv[2][1:])\nxbmcplugin.setContent(addon_handle, \'movies\')\n\nmenu = args.get(\'menu\', None)\n\nmenuFunc = menu[0] if menu else \'rootmenu\'\nmenuItems = eval(menuFunc + \'()\')\nif menuItems: makeXbmcMenu(addon_handle, base_url, menuItems) \n' ERRORS = '' def __init__(self, addon_id, fileName, addonADG, modSourceCode = None): self._fileId = addon_id self._fileName = fileName self._location = "" self._isEditable = True self.parser = CoderParser() self.addonADG = addonADG self.addon_id = addon_id self.modSourceCode = modSourceCode or {} def getFileMetaData(self): return (self._fileId, self._fileName, self._location, self._isEditable) def getSource(self): return self.addonScripSource() def setSource(self, content, isPartialMod = False): self.saveCode(content, isPartialMod) def __getattr__(self, name): return getattr(self.addonADG, name) def getActiveNode(self): return self.addonADG.threadDef def addonScripSource(self): self.ERRORS = '' if self.modSourceCode.has_key('_codeframe_'): codeStr = self.modSourceCode['_codeframe_'] codeStr = codeStr.replace('<header>', self.HEADER) codeStr = codeStr.replace('<footer>', self.FOOTER) pos = 0 for nodeId, isReverse in [('rootmenu', False), ('media', True)]: fncList = self.addonADG.getSameTypeNodes(nodeId) if isReverse: fncList = list(reversed(fncList)) for node in fncList: if node.endswith('_lnk'): continue placeHolder = '<' + node + '>' nodeCode = self.knothCode(node) posIni = codeStr.find(placeHolder) if posIni != -1: codeStr = codeStr.replace(placeHolder, nodeCode) pos = posIni + len(nodeCode + '\n') else: codeStr = codeStr[:pos]+ '\n' + nodeCode + '\n' + codeStr[pos:] pos += len('\n' + nodeCode + '\n') else: codeStr = self.HEADER codeStr += self.scriptSource('rootmenu') codeStr += self.scriptSource('media', reverse = True) codeStr += self.FOOTER self.ERRORS = self.ERRORS or 'no ERRORS, no WARNINGS' return codeStr def scriptSource(self, threadId, reverse = False): fncList = self.addonADG.getSameTypeNodes(threadId) if reverse: fncList = list(reversed(fncList)) sourceCode = '' for node in fncList: if self.addonADG.getThreadAttr(node, 'type') == 'link': continue sourceCode += '\n' + self.knothCode(node) + '\n' return sourceCode def knothCode(self, node): if self.modSourceCode.has_key(node): return self.modSourceCode[node].replace(node + '():', node + '():' + ' # Modified code') sourceCode = '' threadType = self.addonADG.getThreadAttr(node, 'type') if threadType != -1: if threadType == 'list': sourceCode = self.listSource(node) elif threadType == 'thread': sourceCode = self.threadSource(node) else: pass return sourceCode.expandtabs(4) def listSource(self, threadId): children = self.addonADG.getChildren(threadId) if threadId != 'rootmenu' and not children: self.ERRORS += 'WARNING: ' + threadId + ' not implemented' + '\n' return self.parser.handle(ntype.NOTIMPLEMENTED, threadId) if threadId == 'rootmenu': testFunc = lambda x: self.addonADG.getThreadParam(x, 'source') fncList = [elem for elem in self.addonADG.getSameTypeNodes('media') if not elem.endswith("_lnk")] for node in fncList: dwnNode = self.addonADG.getThreadAttr(node, 'down') if not dwnNode or all(map(testFunc, self.addonADG.getChildren(node))): children.append(node) if len(children) == 1 and (threadId == 'rootmenu' or self.addonADG.getThreadAttr(children[0], 'type') == 'link'): nodeId = children[0] if self.addonADG.getThreadAttr(children[0], 'type') != 'link' else self.addonADG.getThreadAttr(children[0], 'name') url = self.addonADG.getThreadParam(nodeId, 'url') option = self.addonADG.getThreadParam(threadId,'option') return self.parser.handle(ntype.ONECHILD, threadId, nodeId, url, option) menuElem=[] for elem in children: paramDict = {} nodeType = self.addonADG.getThreadAttr(elem, 'type') nodeId = elem if nodeType != "link" else self.addonADG.getThreadAttr(elem, 'name') if nodeType != "list": params = self.addonADG.getThreadAttr(elem, 'params') paramDict.update({key:value for key, value in params.items() if key in ['url', 'searchkeys']}) if paramDict.has_key('searchkeys'): paramDict.pop('url') if params.get("plainnode"): paramDict["nxtmenu"] = nodeId paramDict['menu'] = nodeId node = self.addonADG.parseThreads[nodeId] itemParam = {'isFolder':True} itemParam['label'] = node['name'] menuElem.append((paramDict, itemParam)) menuIcons = None if self.addonADG.getThreadParam(threadId, 'iconflag'): params = self.addonADG.getThreadAttr(threadId, 'params') iconList = [icon.strip() for icon in params['iconimage'].split(',')] kMax = min(len(menuElem), len(iconList)) if kMax != len(menuElem): self.ERRORS += '\n' + 'WARNING: in ' + threadId + ' not enough icons were provided' menuIcons = iconList[:kMax] return self.parser.handle(ntype.MENU, threadId, menuElem, menuIcons) def getMediaCode(self): keyValues = set(['url', 'videoUrl', 'videoId']) def getRegexKey(regexp, keySet): posFin = 0 while True: posIni = regexp.find('(?P<', posFin) if posIni == -1: break posIni += len('(?P<') posFin = regexp.find('>', posIni) if posFin == -1: break keySet.add(regexp[posIni:posFin]) return keySet.intersection(keyValues) lista = [(elem, self.addonADG.getThreadParam(elem, 'regexp')) for elem in self.addonADG.getChildren('media') if self.addonADG.getThreadAttr(elem, 'type') == 'thread'] keySet = set() for elem in lista: keyElem = getRegexKey(elem[1], set()) if keyElem: keySet.update(keyElem) else: self.ERRORS += 'ERROR: ' + elem[0] + ' not send any of ' + str(keyValues) + ' to media' + '\n' regexp = self.addonADG.getThreadParam('media', 'regexp') compflags = self.addonADG.getThreadParam('media', 'compflags') return self.parser.handle(ntype.MEDIA, keySet, regexp, compflags) def threadSource(self, threadId): if threadId == 'media': return self.getMediaCode() # nodeId = self.addonADG.getThreadAttr(threadId, 'up') node = self.addonADG.parseThreads[threadId] paramDict = dict(node['params']) paramDict['menu'] = node['up'] regexp = paramDict.get('regexp', None) # ** En proceso SEARCH if regexp and regexp.startswith('(?#<SEARCH>)'): regexp = regexp[len('(?#<SEARCH>)'):] menuId = node['up'] searchKeys = paramDict.get('searchkeys', None) return self.parser.handle(ntype.SEARCH, threadId, menuId, self.addon_id, regexp, searchKeys) searchFlag = False spanFlag = False menuId = self.addonADG.getThreadAttr(threadId, 'down') if menuId: lista = [self.addonADG.getThreadParam(elem, 'regexp') for elem in self.addonADG.getChildren(threadId) if self.addonADG.getThreadAttr(elem, 'type') == 'thread'] spanFlag = any(map(lambda x: x.find('?#<SPAN') != -1, lista)) searchFlag = any(map(lambda x: x.find('?#<SEARCH>') != -1, lista)) menuIcons = None if not self.addonADG.getThreadParam(threadId, 'nextregexp') and self.addonADG.getThreadParam(threadId, 'iconflag'): menuIcons = [icon.strip() for icon in self.addonADG.getThreadParam(threadId, 'iconimage').split(',')] if self.addonADG.getThreadParam(threadId, 'discrim'): discrim = self.addonADG.getThreadParam(threadId, 'discrim') listaMenu = [self.addonADG.getThreadAttr(elem, 'name') for elem in self.addonADG.getChildren(threadId) if self.addonADG.getThreadAttr(elem, 'type') == 'link'] listaDisc = [] for elem in listaMenu: params = self.addonADG.parseThreads[elem]['params'] listaDisc.extend([(disc, elem) for key, disc in params.items() if key.startswith(discrim)]) discrimDict = dict(listaDisc) if not discrimDict: self.ERRORS += 'WARNING: ' + threadId + ' not define alternative menus' + '\n' if self.addonADG.getThreadParam(threadId, 'discrim').startswith('urldata'): return self.parser.handle(ntype.MULTIPLEXOR, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag, discrimDict) return self.parser.handle(ntype.APICATEGORY, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag, discrimDict) if paramDict.has_key('nextregexp'): return self.parser.handle(ntype.PAGE, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag) return self.parser.handle(ntype.APIMENU, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag) def modifyCode(self, modType, *args): if modType == 'delete': for node in args: if self.modSourceCode.has_key(node): self.modSourceCode.pop(node) if self.modSourceCode.has_key('_codeframe_'): codeStr = self.modSourceCode['_codeframe_'] self.modSourceCode['_codeframe_'] = codeStr.replace('<' + node + '>', '# Deleted node ' + node) elif modType == 'rename': oldName, newName = args[0:2] if self.modSourceCode.has_key(oldName): self.modSourceCode[newName] = self.modSourceCode.pop(oldName) if self.modSourceCode.has_key('_codeframe_'): codeStr = self.modSourceCode['_codeframe_'] self.modSourceCode['_codeframe_'] = codeStr.replace('<' + oldName + '>', '<' + newName + '>') def saveCode(self, content): import re for key in self.modSourceCode.keys(): if self.addonADG.existsThread(key): params = self.addonADG.parseThreads[key]['params'] if params.has_key('enabled'): params.pop('enabled') self.modSourceCode = {} if content.startswith(self.HEADER): content = '<header>' + content[len(self.HEADER):] if content.endswith(self.FOOTER): content = content[: -len(self.FOOTER)] + '<footer>' pos = 0 reg = re.compile('def (?P<name>[^\(]+?)\([^\)]*?\):(?:.+?)\n {4}return (?P<return>.+?)\n', re.DOTALL) while 1: match = reg.search(content, pos) if not match: break knotId = match.group(1) genCode = self.knothCode(knotId) pos = match.end(0) if not genCode: continue placeHolder = '<' + knotId + '>' params = self.addonADG.parseThreads[knotId]['params'] if genCode != match.group(0)[:-1]: nodeCode = match.group(0).replace(' # Modified code', '') self.modSourceCode[knotId] = nodeCode params['enabled'] = False pos = match.start(0) content = content[:pos] + placeHolder + content[match.end(0)-1:] pos += len(placeHolder) if content.strip('\t\n\x0b\x0c\r '): self.modSourceCode['_codeframe_'] = content.strip('\t\n\x0b\x0c\r ') + '\n'
class InitModule: HEADER = '\nimport os, sys\nimport xbmcaddon\nimport xbmc\nimport xbmcplugin\nimport xbmcgui\nimport urlparse\nimport urllib\nimport re\n\n_settings = xbmcaddon.Addon()\n_path = xbmc.translatePath(_settings.getAddonInfo(\'path\')).decode(\'utf-8\')\n_lib = xbmc.translatePath(os.path.join(_path, \'resources\', \'lib\'))\n_media = xbmc.translatePath(os.path.join(_path, \'resources\', \'media\'))\nsys.path.append(_lib)\n\nEMPTYCONTENT = [[{}, {"isFolder": True, "label": ""}, None]]\n\nfrom basicFunc import openUrl, parseUrlContent, makeXbmcMenu, getMenu, LISTITEM_KEYS, INFOLABELS_KEYS\n' FOOTER = '\nbase_url = sys.argv[0]\naddon_handle = int(sys.argv[1])\nargs = urlparse.parse_qs(sys.argv[2][1:])\nxbmcplugin.setContent(addon_handle, \'movies\')\n\nmenu = args.get(\'menu\', None)\n\nmenuFunc = menu[0] if menu else \'rootmenu\'\nmenuItems = eval(menuFunc + \'()\')\nif menuItems: makeXbmcMenu(addon_handle, base_url, menuItems) \n' ERRORS = '' def __init__(self, addon_id, fileName, addonADG, modSourceCode=None): self._fileId = addon_id self._fileName = fileName self._location = "" self._isEditable = True self.parser = CoderParser() self.addonADG = addonADG self.addon_id = addon_id self.modSourceCode = modSourceCode or {} def getFileMetaData(self): return (self._fileId, self._fileName, self._location, self._isEditable) def getSource(self): return self.addonScripSource() def setSource(self, content, isPartialMod=False): self.saveCode(content, isPartialMod) def __getattr__(self, name): return getattr(self.addonADG, name) def getActiveNode(self): return self.addonADG.threadDef def addonScripSource(self): self.ERRORS = '' if self.modSourceCode.has_key('_codeframe_'): codeStr = self.modSourceCode['_codeframe_'] codeStr = codeStr.replace('<header>', self.HEADER) codeStr = codeStr.replace('<footer>', self.FOOTER) pos = 0 for nodeId, isReverse in [('rootmenu', False), ('media', True)]: fncList = self.addonADG.getSameTypeNodes(nodeId) if isReverse: fncList = list(reversed(fncList)) for node in fncList: if node.endswith('_lnk'): continue placeHolder = '<' + node + '>' nodeCode = self.knothCode(node) posIni = codeStr.find(placeHolder) if posIni != -1: codeStr = codeStr.replace(placeHolder, nodeCode) pos = posIni + len(nodeCode + '\n') else: codeStr = codeStr[: pos] + '\n' + nodeCode + '\n' + codeStr[ pos:] pos += len('\n' + nodeCode + '\n') else: codeStr = self.HEADER codeStr += self.scriptSource('rootmenu') codeStr += self.scriptSource('media', reverse=True) codeStr += self.FOOTER self.ERRORS = self.ERRORS or 'no ERRORS, no WARNINGS' return codeStr def scriptSource(self, threadId, reverse=False): fncList = self.addonADG.getSameTypeNodes(threadId) if reverse: fncList = list(reversed(fncList)) sourceCode = '' for node in fncList: if self.addonADG.getThreadAttr(node, 'type') == 'link': continue sourceCode += '\n' + self.knothCode(node) + '\n' return sourceCode def knothCode(self, node): if self.modSourceCode.has_key(node): return self.modSourceCode[node].replace( node + '():', node + '():' + ' # Modified code') sourceCode = '' threadType = self.addonADG.getThreadAttr(node, 'type') if threadType != -1: if threadType == 'list': sourceCode = self.listSource(node) elif threadType == 'thread': sourceCode = self.threadSource(node) else: pass return sourceCode.expandtabs(4) def listSource(self, threadId): children = self.addonADG.getChildren(threadId) if threadId != 'rootmenu' and not children: self.ERRORS += 'WARNING: ' + threadId + ' not implemented' + '\n' return self.parser.handle(ntype.NOTIMPLEMENTED, threadId) if threadId == 'rootmenu': testFunc = lambda x: self.addonADG.getThreadParam(x, 'source') fncList = [ elem for elem in self.addonADG.getSameTypeNodes('media') if not elem.endswith("_lnk") ] for node in fncList: dwnNode = self.addonADG.getThreadAttr(node, 'down') if not dwnNode or all( map(testFunc, self.addonADG.getChildren(node))): children.append(node) if len(children) == 1 and (threadId == 'rootmenu' or self.addonADG.getThreadAttr( children[0], 'type') == 'link'): nodeId = children[0] if self.addonADG.getThreadAttr( children[0], 'type') != 'link' else self.addonADG.getThreadAttr( children[0], 'name') url = self.addonADG.getThreadParam(nodeId, 'url') option = self.addonADG.getThreadParam(threadId, 'option') return self.parser.handle(ntype.ONECHILD, threadId, nodeId, url, option) menuElem = [] for elem in children: paramDict = {} nodeType = self.addonADG.getThreadAttr(elem, 'type') nodeId = elem if nodeType != "link" else self.addonADG.getThreadAttr( elem, 'name') if nodeType != "list": params = self.addonADG.getThreadAttr(elem, 'params') paramDict.update({ key: value for key, value in params.items() if key in ['url', 'searchkeys'] }) if paramDict.has_key('searchkeys'): paramDict.pop('url') if params.get("plainnode"): paramDict["nxtmenu"] = nodeId paramDict['menu'] = nodeId node = self.addonADG.parseThreads[nodeId] itemParam = {'isFolder': True} itemParam['label'] = node['name'] menuElem.append((paramDict, itemParam)) menuIcons = None if self.addonADG.getThreadParam(threadId, 'iconflag'): params = self.addonADG.getThreadAttr(threadId, 'params') iconList = [ icon.strip() for icon in params['iconimage'].split(',') ] kMax = min(len(menuElem), len(iconList)) if kMax != len(menuElem): self.ERRORS += '\n' + 'WARNING: in ' + threadId + ' not enough icons were provided' menuIcons = iconList[:kMax] return self.parser.handle(ntype.MENU, threadId, menuElem, menuIcons) def getMediaCode(self): keyValues = set(['url', 'videoUrl', 'videoId']) def getRegexKey(regexp, keySet): posFin = 0 while True: posIni = regexp.find('(?P<', posFin) if posIni == -1: break posIni += len('(?P<') posFin = regexp.find('>', posIni) if posFin == -1: break keySet.add(regexp[posIni:posFin]) return keySet.intersection(keyValues) lista = [(elem, self.addonADG.getThreadParam(elem, 'regexp')) for elem in self.addonADG.getChildren('media') if self.addonADG.getThreadAttr(elem, 'type') == 'thread'] keySet = set() for elem in lista: keyElem = getRegexKey(elem[1], set()) if keyElem: keySet.update(keyElem) else: self.ERRORS += 'ERROR: ' + elem[0] + ' not send any of ' + str( keyValues) + ' to media' + '\n' regexp = self.addonADG.getThreadParam('media', 'regexp') compflags = self.addonADG.getThreadParam('media', 'compflags') return self.parser.handle(ntype.MEDIA, keySet, regexp, compflags) def threadSource(self, threadId): if threadId == 'media': return self.getMediaCode() # nodeId = self.addonADG.getThreadAttr(threadId, 'up') node = self.addonADG.parseThreads[threadId] paramDict = dict(node['params']) paramDict['menu'] = node['up'] regexp = paramDict.get('regexp', None) # ** En proceso SEARCH if regexp and regexp.startswith('(?#<SEARCH>)'): regexp = regexp[len('(?#<SEARCH>)'):] menuId = node['up'] searchKeys = paramDict.get('searchkeys', None) return self.parser.handle(ntype.SEARCH, threadId, menuId, self.addon_id, regexp, searchKeys) searchFlag = False spanFlag = False menuId = self.addonADG.getThreadAttr(threadId, 'down') if menuId: lista = [ self.addonADG.getThreadParam(elem, 'regexp') for elem in self.addonADG.getChildren(threadId) if self.addonADG.getThreadAttr(elem, 'type') == 'thread' ] spanFlag = any(map(lambda x: x.find('?#<SPAN') != -1, lista)) searchFlag = any(map(lambda x: x.find('?#<SEARCH>') != -1, lista)) menuIcons = None if not self.addonADG.getThreadParam( threadId, 'nextregexp') and self.addonADG.getThreadParam( threadId, 'iconflag'): menuIcons = [ icon.strip() for icon in self.addonADG.getThreadParam( threadId, 'iconimage').split(',') ] if self.addonADG.getThreadParam(threadId, 'discrim'): discrim = self.addonADG.getThreadParam(threadId, 'discrim') listaMenu = [ self.addonADG.getThreadAttr(elem, 'name') for elem in self.addonADG.getChildren(threadId) if self.addonADG.getThreadAttr(elem, 'type') == 'link' ] listaDisc = [] for elem in listaMenu: params = self.addonADG.parseThreads[elem]['params'] listaDisc.extend([(disc, elem) for key, disc in params.items() if key.startswith(discrim)]) discrimDict = dict(listaDisc) if not discrimDict: self.ERRORS += 'WARNING: ' + threadId + ' not define alternative menus' + '\n' if self.addonADG.getThreadParam(threadId, 'discrim').startswith('urldata'): return self.parser.handle(ntype.MULTIPLEXOR, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag, discrimDict) return self.parser.handle(ntype.APICATEGORY, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag, discrimDict) if paramDict.has_key('nextregexp'): return self.parser.handle(ntype.PAGE, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag) return self.parser.handle(ntype.APIMENU, threadId, menuId, paramDict, menuIcons, searchFlag, spanFlag) def modifyCode(self, modType, *args): if modType == 'delete': for node in args: if self.modSourceCode.has_key(node): self.modSourceCode.pop(node) if self.modSourceCode.has_key('_codeframe_'): codeStr = self.modSourceCode['_codeframe_'] self.modSourceCode['_codeframe_'] = codeStr.replace( '<' + node + '>', '# Deleted node ' + node) elif modType == 'rename': oldName, newName = args[0:2] if self.modSourceCode.has_key(oldName): self.modSourceCode[newName] = self.modSourceCode.pop(oldName) if self.modSourceCode.has_key('_codeframe_'): codeStr = self.modSourceCode['_codeframe_'] self.modSourceCode['_codeframe_'] = codeStr.replace( '<' + oldName + '>', '<' + newName + '>') def saveCode(self, content): import re for key in self.modSourceCode.keys(): if self.addonADG.existsThread(key): params = self.addonADG.parseThreads[key]['params'] if params.has_key('enabled'): params.pop('enabled') self.modSourceCode = {} if content.startswith(self.HEADER): content = '<header>' + content[len(self.HEADER):] if content.endswith(self.FOOTER): content = content[:-len(self.FOOTER)] + '<footer>' pos = 0 reg = re.compile( 'def (?P<name>[^\(]+?)\([^\)]*?\):(?:.+?)\n {4}return (?P<return>.+?)\n', re.DOTALL) while 1: match = reg.search(content, pos) if not match: break knotId = match.group(1) genCode = self.knothCode(knotId) pos = match.end(0) if not genCode: continue placeHolder = '<' + knotId + '>' params = self.addonADG.parseThreads[knotId]['params'] if genCode != match.group(0)[:-1]: nodeCode = match.group(0).replace(' # Modified code', '') self.modSourceCode[knotId] = nodeCode params['enabled'] = False pos = match.start(0) content = content[:pos] + placeHolder + content[match.end(0) - 1:] pos += len(placeHolder) if content.strip('\t\n\x0b\x0c\r '): self.modSourceCode['_codeframe_'] = content.strip( '\t\n\x0b\x0c\r ') + '\n'