def merge( newpath, firstMenuFile, secondMenuFile, preloaded=True, bypassScan=False ): """Merge two RCMenuFiles, this is may be important during the step to get ALL RCMenuFiles into translation files. """ import copy totalMenus = RCMenuFile(newpath) if not preloaded: firstMenuFile.load() #load so we know we can reference ._menus secondMenuFile.load() ids = [ ] # to keep track of ones, we still need to remove. for node in firstMenuFile._menus: found = False for nodeb in secondMenuFile._menus: if node.id == nodeb.id: totalMenus._menus.append(RCMenu.mergeMenu(node, nodeb, bypassScan)) found = True break if not found: totalMenus._menus.append( copy.deepcopy(node) ) ids.append( node.id ) #Check to make sure we got all of the ids that were in secondMenuFile for nodeb in secondMenuFile._menus: if nodeb.id in ids: continue else: totalMenus._menus.append( copy.deepcopy(nodeb) ) return totalMenus
def _ReconstructMenus( data, util, seps ): """ ***DO NOT USE THIS FUNCTION DIRECTLY!*** Use `ConvertMenuCSV2XML` as it calls this function through the correct conversion process. Reconstructs a list of RCMenus based on flat CSV data in the form of XPaths and ID references. Its tougher to go from CSV back to XML than it was to get here. Returns a list of RCMenus. """ #data = { xpath-id -> RCStringValue w/ {langcode->value}} #util = { xpath-id -> (order,type)} #seps = [ xpath-id ] # xpath-id = <menu-name>.<xpath> # idn = an id of a menu node # First expand the utility information into two mappings: ordermap = {} # xpath-id -> order (int) typemap = {} # xpath-id -> RCMenuNodeType for xpathid, udata in util.items(): order, typeid = udata ordermap[ xpathid ] = int(order) typemap [ xpathid ] = RCMenuNodeType.getType(typeid) # Second, break up the datalines by menuid and by level menus = {} # { menuid -> { xpath-id -> value } } menulvls = {} # { menuid -> { lvl -> [xpath-id] } } for xpathid, value in data.items(): menuid, xpath = xpathid.split('.', 1) lvl = _determineXPathLvl(xpath) if menus.get(menuid) is None: menus[menuid] = {} if menulvls.get(menuid) is None: menulvls[menuid] = {} if menulvls[menuid].get(lvl) is None: menulvls[menuid][lvl] = [] menus[menuid][xpath] = value menulvls[menuid][lvl].append(xpath) #Third, add all the separaters to the menus and the menulvls maps. for sep in seps: menuid, xpath = sep.split('.',1) lvl = _determineXPathLvl(xpath) if menus.get(menuid) is None: menus[menuid] = {} if menulvls.get(menuid) is None: menulvls[menuid] = {} if menulvls[menuid].get(lvl) is None: menulvls[menuid][lvl] = [] menus[menuid][xpath] = None menulvls[menuid][lvl].append(xpath) # Finally, for each menu in `menus`, loop by level adding the top # level first, and by order. menulst = [] #what gets returned! for menuid in menus: menu = RCMenu(menuid) for lvl in menulvls[menuid]: lvlorder = {} # order (int) -> xpath # loops through all the xpaths at this lvl and determines # the order to add them by adding them to the lvlorder # dictionary, which auto-sorts them. for txpath in menulvls[menuid][lvl]: orderid = ordermap[ menuid+"."+txpath ] if lvlorder.get( orderid ) is None: lvlorder[ orderid ] = [txpath] else: lvlorder[ orderid ].append( txpath ) # Now that we have what order to add them to the menu. # We loop through all the items at this level, and add them # by asking the menu to find the parent based on the xpath. for orderid, txpaths in sorted(lvlorder.items(), key=lambda x: x[0]): for txpath in txpaths: idn = _determineBasename(txpath) typeid = typemap[menuid+"."+txpath] if typeid == RCMenuNodeType.POPUP: node = RCMenuNode(menu,type=typeid,idn=idn,order=orderid) node.value.combine( menus[menuid][txpath],suppressIDWarn=True ) parent = menu.findParentOfNode( txpath ) if parent is not None: parent.addChild( node ) elif typeid == RCMenuNodeType.MENUITEM: node = RCMenuNode(menu,id=idn,type=typeid,order=orderid) node.value.combine( menus[menuid][txpath],suppressIDWarn=True ) parent = menu.findParentOfNode( txpath ) if parent is not None: parent.addChild( node ) elif typeid == RCMenuNodeType.SEPARATOR: node = RCMenuNode(menu,type=typeid,idn=idn,order=orderid) parent = menu.findParentOfNode( txpath ) if parent is not None: parent.addChild( node ) else: continue #TODO: log? this is an invalid type! # Now we can add that menu to the list of menus to return. menulst.append(menu) return menulst