def walk_rawfiles_into_tagnode_collection(directory, node_collection=None): """Load the graphics-relevant content of raw files into memory. * directory is a directory containing the raw files you want to load into memory. Files with duplicate names will be treated as the same file, even if they're in different sub-folders. * node_collection is an optional parameter, to let you add additional raw files to the same node_collection. It is formatted the same as the return dict. The function returns a dictionary of string:dict{string:TagNode}. The outer key is a filename which contains some graphics-relevant content. The inner key is the tag corresponding with a top-level TagNode in that file, and maps to that TagNode. This format is the expected input format of both parameters of bind_graphics_to_targets(graphics_nodes, target_nodes). """ if node_collection is None: node_collection = {} try: for root, dirs, files in os.walk(directory): for rawfile in files: # Only look at .txt files if '.txt' not in rawfile: userlog.info("Skipping file %s...", rawfile) continue userlog.info("Loading graphics tags from %s...", rawfile) global template_tree # curr_template_node keeps track of what format of tag # we've most recently seen, and thus what's valid next curr_template_node = template_tree # curr_real_node keeps track of the tag we stored that # corresponds to the most local instance of # curr_template_node. curr_real_node = None tarpath = os.path.join(root, rawfile) openfile = open(tarpath, encoding='cp437') for line in openfile: for tag in parsing.tags(line): matching_node = curr_template_node.find_match(tag) if matching_node is not None: curr_template_node = matching_node if ((curr_real_node is None or matching_node._tag in template_tree._children)): curr_real_node = TagNode( rawfile, matching_node, tag) else: while (curr_real_node is not None and matching_node._tag not in curr_real_node._template._children): curr_real_node = curr_real_node._parent curr_real_node = TagNode( rawfile, matching_node, tag, curr_real_node) if rawfile not in node_collection: node_collection[rawfile] = {} if curr_real_node._parent is None: node_collection[rawfile][ tag] = curr_real_node openfile.close() userlog.info("Finished processing %s .", rawfile) except: userlog.error("Exception in loading raws.") userlog.error(traceback.format_exc()) else: return node_collection
def walk_rawfiles_into_tagnode_collection(directory, node_collection=None): """Load the graphics-relevant content of raw files into memory. * directory is a directory containing the raw files you want to load into memory. Files with duplicate names will be treated as the same file, even if they're in different sub-folders. * node_collection is an optional parameter, to let you add additional raw files to the same node_collection. It is formatted the same as the return dict. The function returns a dictionary of string:dict{string:TagNode}. The outer key is a filename which contains some graphics-relevant content. The inner key is the tag corresponding with a top-level TagNode in that file, and maps to that TagNode. This format is the expected input format of both parameters of bind_graphics_to_targets(graphics_nodes, target_nodes). """ if node_collection is None: node_collection = {} try: for root, dirs, files in os.walk(directory): for rawfile in files: # Only look at .txt files if '.txt' not in rawfile: userlog.info("Skipping file %s...", rawfile) continue userlog.info("Loading graphics tags from %s...", rawfile) global template_tree # curr_template_node keeps track of what format of tag # we've most recently seen, and thus what's valid next curr_template_node = template_tree # curr_real_node keeps track of the tag we stored that # corresponds to the most local instance of # curr_template_node. curr_real_node = None tarpath = os.path.join(root, rawfile) openfile = open(tarpath, encoding='cp437') for line in openfile: for tag in parsing.tags(line): matching_node = curr_template_node.find_match(tag) if matching_node is not None: curr_template_node = matching_node if ((curr_real_node is None or matching_node._tag in template_tree._children)): curr_real_node = TagNode(rawfile, matching_node, tag) else: while (curr_real_node is not None and matching_node._tag not in curr_real_node._template._children): curr_real_node = curr_real_node._parent curr_real_node = TagNode(rawfile, matching_node, tag, curr_real_node) if rawfile not in node_collection: node_collection[rawfile] = {} if curr_real_node._parent is None: node_collection[rawfile][tag] = curr_real_node openfile.close() userlog.info("Finished processing %s .", rawfile) except: userlog.error("Exception in loading raws.") userlog.error(traceback.format_exc()) else: return node_collection
def _apply_graphics_to_file(graphics_to_apply, file, sourceroot, targetpath): """ Writes merged raws belonging to a single file. * graphics_to_apply is a collection of BoundNode trees formatted as { file: {topleveltag:BoundNode}}. This is the format returned by BoundNode.bind_graphics_tags. * file is the name of the file to apply graphics to, without any information about its parent directories. * sourceroot is the path to the directory containing the source raw version of 'file'. * targetpath is the path to the output file, with the name of the file included. For each line in the raw source file, the function searches BoundNode for a matching tag for each tag. If the tag is found, its contents are replaced in the line with a merged version from the appropriate BoundNode. Then the line - modified or unmodified - is written out to the output file. """ userlog.info("Merging graphics into %s ...", file) curr_dict = graphics_to_apply[file] curr_node = None targetfile = open(targetpath, 'wt', encoding='cp437') sourcefile = open(os.path.join(sourceroot, file), 'rt', encoding='cp437') linecount = 0 tags_to_reset_addl = [] for line in sourcefile: linecount = linecount + 1 modified_line = parsing.escape_problematic_literals(line) additional = [] for tag in parsing.tags(line): matching_node = None if tag in curr_dict.keys(): matching_node = curr_dict[tag] elif curr_node is not None: matching_node = curr_node.find_match(tag) if matching_node is not None: curr_node = matching_node matching_node.pop_self() if matching_node.is_there_a_difference(): merged_tag = matching_node.get_merged() if merged_tag is not None: replacement = matching_node.get_merged() userlog.debug("Replacing %s with %s at line %i.", tag, replacement, linecount) modified_line = modified_line.replace(tag, replacement) else: userlog.debug("Removing tag %s at line %i.", tag, linecount) to_remove = "[" + tag + "]" modified_line = modified_line.replace(to_remove, "") # modified_line = modified_line[:-1] + " (BAMM)\n" additional.extend(matching_node.pop_addl()) tags_to_reset_addl.append(matching_node) elif curr_node is not None: problem_parent = curr_node.find_targetsonly_owner(tag) if ((problem_parent is not None and problem_parent._targets_only[tag].has_graphics_info())): modderslog.info( "Object missing graphics information in %s : %s", targetpath, tag) # Targets without matching graphics modified_line = "No tag corresponding to (" + tag + \ ") was found in graphics source. -BAMM\n" + modified_line targetfile.writelines(modified_line) for tag_node in additional: linecount = linecount + 1 userlog.debug("Adding tag %s at line %i.", tag_node._tag, linecount) line_to_write = "[" + tag_node._tag + "]\n" targetfile.writelines(line_to_write) targetfile.flush() userlog.info("Finished outputting %s .", file) targetfile.close() sourcefile.close() # Resetting the additional tags for another for node in tags_to_reset_addl: node.reset_addl()
def _apply_graphics_to_file(graphics_to_apply, file, sourceroot, targetpath): """ Writes merged raws belonging to a single file. * graphics_to_apply is a collection of BoundNode trees formatted as { file: {topleveltag:BoundNode}}. This is the format returned by BoundNode.bind_graphics_tags. * file is the name of the file to apply graphics to, without any information about its parent directories. * sourceroot is the path to the directory containing the source raw version of 'file'. * targetpath is the path to the output file, with the name of the file included. For each line in the raw source file, the function searches BoundNode for a matching tag for each tag. If the tag is found, its contents are replaced in the line with a merged version from the appropriate BoundNode. Then the line - modified or unmodified - is written out to the output file. """ userlog.info("Merging graphics into %s ...", file) curr_dict = graphics_to_apply[file] curr_node = None targetfile = open(targetpath, 'wt', encoding='cp437') sourcefile = open(os.path.join(sourceroot, file), 'rt', encoding='cp437') linecount = 0 tags_to_reset_addl = [] for line in sourcefile: linecount = linecount + 1 modified_line = parsing.escape_problematic_literals(line) additional = [] for tag in parsing.tags(line): matching_node = None if tag in curr_dict.keys(): matching_node = curr_dict[tag] elif curr_node is not None: matching_node = curr_node.find_match(tag) if matching_node is not None: curr_node = matching_node matching_node.pop_self() if matching_node.is_there_a_difference(): merged_tag = matching_node.get_merged() if merged_tag is not None: replacement = matching_node.get_merged() userlog.debug("Replacing %s with %s at line %i.", tag, replacement, linecount) modified_line = modified_line.replace(tag, replacement) else: userlog.debug("Removing tag %s at line %i.", tag, linecount) to_remove = "[" + tag + "]" modified_line = modified_line.replace(to_remove, "") # modified_line = modified_line[:-1] + " (BAMM)\n" additional.extend(matching_node.pop_addl()) tags_to_reset_addl.append(matching_node) elif curr_node is not None: problem_parent = curr_node.find_targetsonly_owner(tag) if ((problem_parent is not None and problem_parent._targets_only[tag].has_graphics_info())): modderslog.info("Object missing graphics information in %s : %s", targetpath, tag) # Targets without matching graphics modified_line = "No tag corresponding to (" + tag + \ ") was found in graphics source. -BAMM\n" + modified_line targetfile.writelines(modified_line) for tag_node in additional: linecount = linecount + 1 userlog.debug("Adding tag %s at line %i.", tag_node._tag, linecount) line_to_write = "[" + tag_node._tag + "]\n" targetfile.writelines(line_to_write) targetfile.flush() userlog.info("Finished outputting %s .", file) targetfile.close() sourcefile.close() # Resetting the additional tags for another for node in tags_to_reset_addl: node.reset_addl()