diff --git a/src/bcf/bcf/v3/bcfxml.py b/src/bcf/bcf/v3/bcfxml.py index e69de29bb2..110e6866e2 100644 --- a/src/bcf/bcf/v3/bcfxml.py +++ b/src/bcf/bcf/v3/bcfxml.py @@ -0,0 +1,106 @@ +import os +import uuid +import shutil +import zipfile +import logging +import tempfile +import bcf.v3.data +from datetime import datetime +from xml.dom import minidom +from xmlschema import XMLSchema +from contextlib import contextmanager +from shutil import copyfile + +cwd = os.path.dirname(os.path.realpath(__file__)) + + +@contextmanager +def cd(newdir): + prevdir = os.getcwd() + os.chdir(os.path.expanduser(newdir)) + try: + yield + finally: + os.chdir(prevdir) + + +class BcfXml: + def __init__(self): + self.filepath = None + self.logger = logging.getLogger("bcfxml") + self.author = "john@doe.com" + self.project = bcf.v3.data.Project() + self.version = "3.0" + self.topics = {} + + def new_project(self): + self.project.project_id = str(uuid.uuid4()) + self.project.name = "New Project" + self.topics = {} + if self.filepath: + self.close_project() + self.filepath = tempfile.mkdtemp() + self.edit_project() + self.edit_version() + + def get_project(self, filepath=None): + if os.path.isfile(os.path.join(self.filepath, "project.bcfp")): + data = self._read_xml("project.bcfp", "project.xsd") + self.project.project_id = data["Project"]["@ProjectId"] + self.project.name = data["Project"].get("Name") + return self.project + + def edit_project(self): + self.document = minidom.Document() + root = self._create_element(self.document, "ProjectInfo") + project = self._create_element(root, "Project", {"ProjectId": self.project.project_id}) + if self.project.name: + self._create_element(project, "Name", text=self.project.name) + with open(os.path.join(self.filepath, "project.bcfp"), "wb") as f: + f.write(self.document.toprettyxml(encoding="utf-8")) + + def save_project(self, filepath): + with cd(self.filepath): + zip_file = zipfile.ZipFile(filepath, "w", zipfile.ZIP_DEFLATED) + for root, dirs, files in os.walk("./"): + for file in files: + zip_file.write(os.path.join(root, file)) + zip_file.close() + + def get_version(self): + data = self._read_xml("bcf.version", "version.xsd") + self.version = data["@VersionId"] + return self.version + + def edit_version(self): + self.document = minidom.Document() + root = self._create_element(self.document, "Version", {"VersionId": self.version}) + with open(os.path.join(self.filepath, "bcf.version"), "wb") as f: + f.write(self.document.toprettyxml(encoding="utf-8")) + + def close_project(self): + shutil.rmtree(self.filepath) + + def _read_xml(self, filename, xsd): + schema = XMLSchema(os.path.join(cwd, "xsd", xsd)) + filepath = os.path.join(self.filepath, filename) + (data, errors) = schema.to_dict(filepath, validation="lax") + for error in errors: + self.logger.error(error) + return data + + def _create_element(self, parent, name, attributes={}, text=None): + element = self.document.createElement(name) + for key, value in attributes.items(): + if isinstance(value, bool): + element.setAttribute(key, str(value).lower()) + elif value: + element.setAttribute(key, value) + if text is not None: + text = self.document.createTextNode(str(text)) + element.appendChild(text) + parent.appendChild(element) + return element + + def __del__(self): + self.close_project() diff --git a/src/bcf/bcf/v3/data.py b/src/bcf/bcf/v3/data.py index e69de29bb2..ab073e52b7 100644 --- a/src/bcf/bcf/v3/data.py +++ b/src/bcf/bcf/v3/data.py @@ -0,0 +1,4 @@ +class Project: + def __init__(self): + self.project_id = "" + self.name = "" \ No newline at end of file diff --git a/src/bcf/bcf/v3/xsd/documents.xsd b/src/bcf/bcf/v3/xsd/documents.xsd new file mode 100644 index 0000000000..f02331f65c --- /dev/null +++ b/src/bcf/bcf/v3/xsd/documents.xsd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/bcf/bcf/v3/xsd/extensions.xsd b/src/bcf/bcf/v3/xsd/extensions.xsd new file mode 100644 index 0000000000..f22f79d88d --- /dev/null +++ b/src/bcf/bcf/v3/xsd/extensions.xsd @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/bcf/bcf/v3/xsd/markup.xsd b/src/bcf/bcf/v3/xsd/markup.xsd new file mode 100644 index 0000000000..59185058a3 --- /dev/null +++ b/src/bcf/bcf/v3/xsd/markup.xsd @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/bcf/bcf/v3/xsd/project.xsd b/src/bcf/bcf/v3/xsd/project.xsd new file mode 100644 index 0000000000..9383d037df --- /dev/null +++ b/src/bcf/bcf/v3/xsd/project.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/bcf/bcf/v3/xsd/shared-types.xsd b/src/bcf/bcf/v3/xsd/shared-types.xsd new file mode 100644 index 0000000000..93dd4843fb --- /dev/null +++ b/src/bcf/bcf/v3/xsd/shared-types.xsd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/bcf/bcf/v3/xsd/version.xsd b/src/bcf/bcf/v3/xsd/version.xsd new file mode 100644 index 0000000000..608b45fa71 --- /dev/null +++ b/src/bcf/bcf/v3/xsd/version.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/bcf/bcf/v3/xsd/visinfo.xsd b/src/bcf/bcf/v3/xsd/visinfo.xsd new file mode 100644 index 0000000000..49ef666712 --- /dev/null +++ b/src/bcf/bcf/v3/xsd/visinfo.xsd @@ -0,0 +1,220 @@ + + + + + + VisualizationInfo documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + view's visible vertical size in meters + + + + + + Proportional relationship between the width and the height of the view (w/h). + + + + + + + + + + + + + + Vertical field of view, in degrees. + It is currently limited to a value between 45 and 60 degrees. + This limitation will be dropped in the next release and viewers + should be expect values outside this range in current implementations. + + + + + + + Proportional relationship between the width and the height of the view (w/h). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +