From 66b372db0c6b5cbb9b72aa0ea462181468f11987 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed <fawzi.mohamed@fhi-berlin.mpg.de> Date: Mon, 19 Feb 2018 15:34:54 +0100 Subject: [PATCH] automatically set calculation_file_uri --- common/python/nomadcore/simple_parser.py | 49 ++++++++++++++++++++---- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/common/python/nomadcore/simple_parser.py b/common/python/nomadcore/simple_parser.py index 4d116dc..8834a60 100644 --- a/common/python/nomadcore/simple_parser.py +++ b/common/python/nomadcore/simple_parser.py @@ -20,6 +20,9 @@ from nomadcore.unit_conversion import unit_conversion from nomadcore.caching_backend import CachingLevel, ActiveBackend from nomadcore.annotator import Annotator import io +from future.standard_library import install_aliases +install_aliases() +from urllib.parse import urlparse, urlunparse logger = logging.getLogger("nomadcore.simple_parser") annotate = False @@ -59,6 +62,16 @@ class PushbackLineFile(object): self.lines.append(line) self.lineNr -= 1 +def uriFromRelPath(baseUri, basePath, newPath): + """returns an uri corresponding to newPath assuming that base path has uri baseUri. +This will never change the net location (archive).""" + p1 = os.path.normpath(os.path.abspath(basePath)) + p2 = os.path.normpath(os.path.abspath(newPath)) + rPath = os.path.relpath(p2,p1) + bUri = urlparse(baseUri) + nUri = bUri._replace(path = os.path.normpath(os.path.join(bUri.path, rPath))) + return urlunparse(nUri) + class SimpleMatcher(object): """A Something that matches either a single line, or multiple lines grouped together. This is the base of a declarative parser.""" @@ -1071,8 +1084,8 @@ class SimpleParserBuilder(object): logger.info("Parsing tree after optimization:") self.rootMatcher.printParsingTree() - def buildParser(self, fIn, backend, superContext): - return SimpleParser(self, fIn, backend, superContext) + def buildParser(self, fIn, backend, superContext, baseUri, basePath): + return SimpleParser(self, fIn, backend, superContext, baseUri, basePath) def writeMatchers(self, outF, extraIndent = 0): outF.write("[") @@ -1102,7 +1115,7 @@ class SimpleParserBuilder(object): outF.write("}") class SimpleParser(object): - def __init__(self, parserBuilder, fIn, backend, superContext = None): + def __init__(self, parserBuilder, fIn, backend, superContext = None, baseUri = None, basePath = None): self.parserBuilder = parserBuilder self.fIn = fIn self.backend = backend @@ -1110,6 +1123,13 @@ class SimpleParser(object): self.skipped = 0 self.superContext = superContext self.lastMatch = {} + self.baseUri = baseUri + self.basePath = basePath + if backend.sectionManagers is not None: + r=backend.sectionManagers.get("section_run") + if r: + r.onOpen.append(self.emitBaseUri) + annofilename = None # by default, ignore empty lines in coverage analysis self.coverageIgnore = getattr(superContext, 'coverageIgnore', @@ -1128,6 +1148,17 @@ class SimpleParser(object): for k,v in sorted(compiledRootMatcher.matcher.fixedStartValues.items()): compiledRootMatcher.addValue(backend, k, v) + def uriForPath(self, path): + """return the uri corresponding to the given path""" + if self.baseUri and self.basePath and path: + return uriFromRelPath(self.baseUri, self.basePath, path) + return path + + def emitBaseUri(self, backend, gIndex, section): + """writes out the uri to the sources""" + if self.baseUri: + backend.addValue("calculation_file_uri", self.baseUri) + def enterInState(self, stateIndex): compiledMatcher = self.parserBuilder.compiledMatchers[stateIndex] sects = OrderedDict() @@ -1285,9 +1316,9 @@ def compileParser(simpleParser, metaInfo, metaInfoToKeep, default_units=None, me logger.debug(s.getvalue()) return parserBuilder -def runParser(compiledParser, backend, superContext, fIn): +def runParser(compiledParser, backend, superContext, fIn, uri, path): """parses the open file fIn with the given compiledParser into the backend using superContext as parser SuperContext""" - parser = compiledParser.buildParser(PushbackLineFile(fIn), backend, superContext = superContext) + parser = compiledParser.buildParser(PushbackLineFile(fIn), backend, superContext = superContext, baseUri = uri, basePath = path) try: superContext.startedParsing(fIn.name, parser) except AttributeError: @@ -1301,7 +1332,7 @@ def defaultParseFile(parserInfo): with open(path, "r") as fIn: backend.startedParsingSession(uri, parserInfo) try: - parsingStats = runParser(parserBuilder, backend, superContext, fIn) + parsingStats = runParser(parserBuilder, backend, superContext, fIn, uri, path) backend.finishedParsingSession( "ParseSuccess", None, parsingStats=parsingStats) @@ -1538,6 +1569,7 @@ class AncillaryParser(object): parser: The mains parser that is already running. It is used to get the current metadata and backend. superContext: Context for the ancillary parser. """ + self.mainParser = parser default_units = parser.parserBuilder.default_units metainfo_units = parser.parserBuilder.metainfo_units # compile parser @@ -1568,7 +1600,10 @@ class AncillaryParser(object): Args: fIn: File that is parsed. """ - runParser(self.compiledParser, self.backend, self.superContext, PushbackLineFile(fIn)) + currentUri = self.mainParser.uriForPath(fIn.name) + if currentUri: + self.backend.superBackend.addValue("calculation_file_uri", currentUri) + runParser(self.compiledParser, self.backend, self.superContext, PushbackLineFile(fIn), self.mainParser.baseUri, self.mainParser.basePath) class ParserOptimizer(object): -- GitLab