def extractFileToTmp(zipFilePath: str): """ Extracts the zipFile to the temporary directory of the system. """ zipFile = ZipFile(zipFilePath) tmpDir = util.getSystemTmp() extractionPath = os.path.join(tmpDir, os.path.basename(zipFilePath)) logger.debug("Extracting {} to {}".format(zipFile.filename, extractionPath)) zipFile.extractall(extractionPath) return extractionPath
def createNewBcfFile(name): """ Create a new working directory called `name`. This working directory contains everything the resulting BCF file will be comprised of. To generate the actual BCF file call zipToBcfFile """ logger.debug("Creating new working directory {}".format(name)) project = p.Project(uuid4(), name) newTmpDir = util.getSystemTmp(createNew = True) newBcfDir = os.path.join(newTmpDir, name) util.setBcfDir(newBcfDir) os.mkdir(newBcfDir) addElement(project) return project
def readBcfFile(bcfFile: str): """ Reads the bcfFile into the memory. Before each file is parsed into the class structure it gets validated against its corresponding XSD file. If parsing went successful then a value other than a object of type Project is returned. """ logger.debug("Reading file {} and instantiating the data"\ " model".format(bcfFile)) tmpDir = util.getSystemTmp() (projectSchemaPath, extensionsSchemaPath,\ markupSchemaPath, versionSchemaPath,\ visinfoSchemaPath) = util.copySchemas(tmpDir) # extensionsSchemaPath is optional and currently not used => does not need # to be downloaded. if (projectSchemaPath is None or markupSchemaPath is None or versionSchemaPath is None or visinfoSchemaPath is None): logger.error("One or more schema files could not be downloaded!"\ "Please try again in a few moments") return None bcfExtractedPath = extractFileToTmp(bcfFile) # before a file gets read into memory it needs to get validated (i.e.: # before the corresponding build* function is called, validate with # xmlschema) ### Check version ### versionFilePath = os.path.join(bcfExtractedPath, "bcf.version") if not os.path.exists(versionFilePath): logger.error( "No bcf.version file found in {}. This file is not optional.") return None error = validateFile(versionFilePath, versionSchemaPath, bcfFile) if error != "": logger.error(error) return None version = getVersion(bcfExtractedPath, versionSchemaPath) if version not in SUPPORTED_VERSIONS: logger.error("BCF version {} is not supported by this plugin. Supported"\ "versions are: {}".format(version, SUPPORTED_VERSIONS), file=sys.stderr) return None ### Validate project and build ### # project.bcfp is optional, but it is necessary for the data model proj = Project(UUID(int=0)) projectFilePath = os.path.join(bcfExtractedPath, "project.bcfp") if os.path.exists(projectFilePath): error = validateFile(projectFilePath, projectSchemaPath, bcfFile) if error != "": msg = ("{} is not completely valid. Some parts won't be"\ " available.".format(projectFilePath)) logger.debug(msg) logger.error("{}.\n Following the error"\ " message:\n{}".format(msg, error)) proj = buildProject(projectFilePath, projectSchemaPath) ### Iterate over the topic directories ### topicDirectories = util.getDirectories(bcfExtractedPath) for topic in topicDirectories: logger.debug("Topic {} gets builded next".format(topic)) ### Validate all viewpoint files in the directory, and build them ### topicDir = os.path.join(bcfExtractedPath, topic) markupFilePath = os.path.join(topicDir, "markup.bcf") logger.debug("reading topic {}".format(topicDir)) error = validateFile(markupFilePath, markupSchemaPath, bcfFile) if error != "": msg = ("markup.bcf of topic {} does not comply with the standard" " of versions {}."\ " Some parts won't be available.".format(topic, SUPPORTED_VERSIONS)) logger.error(msg) logger.error("{}\nError:\n{}".format(msg, error)) markup = buildMarkup(markupFilePath, markupSchemaPath) # generate a viewpoint object for all viewpoints listed in the markup # object and add them to the ViewpointReference object (`viewpoint`) # inside markup for vpRef in markup.viewpoints: vpPath = os.path.join(topicDir, vpRef.file.uri) try: # if some required element was not found, indicated by a key # error then skip the viewpoint vp = buildViewpoint(vpPath, visinfoSchemaPath) except KeyError as err: logger.error("{} is required in a viewpoint file." " Viewpoint {}/{} is skipped"\ "".format(str(err), topic, vpRef.file)) continue else: vpRef.viewpoint = vp markup.containingObject = proj # add the finished markup object to the project proj.topicList.append(markup) util.setBcfDir(bcfExtractedPath) logger.debug("BCF file is read in and open in"\ " {}".format(bcfExtractedPath)) return proj
pass else: FREECAD = True if FreeCAD.GuiUp: FreeCAD.Console.PrintMessage("set util.GUI\n") import FreeCADGui as FGui GUI = True frontend = None if not check_dependencies(): raise ImportError # delete temporary artifacts import util util.deleteTmp() # create working directory path = util.getSystemTmp() logfile = os.path.join(path, LOGFILE) # generate config for root logger logHandlers = [getFileHandler(logfile)] if FREECAD: logHandlers.append(getFreeCADHandler()) else: logHandlers.append(getStdoutHandler()) logging.basicConfig(level=logging.INFO, handlers=logHandlers) # for nonGUI-mode import __all__ of pI into this namespace from programmaticInterface import *
def addElement(element): """ Adds a new element to the correct file in the working directory. In this context an element can be a simple or complex xml element as well as just an attribute of an element that was added to the datamodel and shall now be added to the file as well. Both additions have the following approach in common: - the current file is read into an xml.etree.ElementTree structure. - this structure is updated with the new values - the old file is overwritten with the updated xml.etree.ElementTree structure For the addition of attributes it is assumed that the containing element already exists in the file. This element is searched for and expanded by the new attribute. For the addition of elements the parent element is searched for, and in the predefined sequence of the parent the right insertion index is looked up, since the element cant just be appended, otherwise it would not be schema conform anymore. """ logger.debug("Adding element {} to the working"\ " directory.".format(element.__class__)) addToProject = False # filename in which `element` will be found fileName = getFileOfElement(element) if not fileName: raise ValueError("{} is not applicable to be added to anyone"\ "file".format(element.xmlName)) elif fileName == projectFileName: addToProject = True if fileName is None: raise NotImplementedError("Writing of bcf.version"\ " is not supported") bcfPath = util.getBcfDir() topicPath = "" if not addToProject: topicDir = getTopicDir(element) if not topicPath and addToProject: raise RuntimeError("Element {} could not be associated to any topic."\ "This may be the case if properties in project.bcfp should be"\ "modified, which is currently not implemented!".format(str(element))) topicPath = os.path.join(bcfPath, topicDir) filePath = "" if not addToProject: filePath = os.path.join(topicPath, fileName) # file path shall only be set if an element shall be added to project.bcfp # and not project.bcfp shall be created in the first place elif addToProject and not isinstance(element, p.Project): filePath = os.path.join(bcfPath, fileName) logger.debug("Element is going to be added to"\ " {}".format(filePath)) if isinstance(element, p.Project): workDir = util.getSystemTmp() logger.debug("Creating new project in {}".format(workDir)) _createProject(element, workDir) return # adds a complete new topic folder to the zip file if isinstance(element, m.Markup): logger.debug("Creating new markup file in"\ " {}".format(topicPath)) _createMarkup(element, topicPath) return xmltree = ET.parse(filePath) xmlroot = xmltree.getroot() # different handling for attributes and elements if isinstance(element, p.Attribute): logger.debug("Element is added as attribute.") xmlroot = _addAttribute(element, xmlroot) else: logger.debug("Element is added as XML node.") xmlroot = _addElement(element, xmlroot) # generate viewpoint.bcfv file for added viewpoint if (isinstance(element, m.ViewpointReference) and element.viewpoint is not None and element.viewpoint.state == iS.State.States.ADDED): logger.debug("Creating new viewpoint file in"\ " {}".format(topicPath)) _createViewpoint(element, topicPath) writeXMLFile(xmlroot, filePath)