Пример #1
0
	def __init__(self,repo):
		DataBase.__init__(self,"drawings", repo)
		self.dimdrawings = []
		self.condrawings = []
		self.conlocations = []

		self.dimdrawing_classes = Links()
		self.condrawings_classes = BipartiteLinks()
		self.conlocations_condrawings = BipartiteLinks()

		self.collection_dimdrawings = Links()
		self.collection_condrawings = Links()

		if not exists(join(self.backend_root)):
			e = MalformedRepositoryError("drawings directory does not exist")
			e.set_repo_path(path)
			raise e

		for coll in listdir(self.backend_root):
			basefilename = join(self.backend_root,coll,"%s.base" % coll)
			if not exists(basefilename):
				#skip directory that is no collection
				continue
			if coll not in repo.collections:
				raise MalformedRepositoryError(
					"Drawings for unknown collection found: %s " % coll)
					
			base_info =  list(yaml.load_all(open(basefilename,"r","utf8")))
			if len(base_info) != 1:
				raise MalformedCollectionError(
					"Not exactly one YAML document found in file %s" % basefilename)
			base_info = base_info[0]

			for drawing_element in base_info:
				if drawing_element["type"] == "drawing-dimensions":
					draw = DrawingDimensions(drawing_element,coll,self.backend_root)
					if draw.get_svg() is None and draw.get_png() is None:
						raise MalformedRepositoryError("No drawing files present for %s/%s" % (coll,draw.filename))

					self.dimdrawings.append(draw)

					if drawing_element["classids"] == []:
						raise MalformedBaseError("Drawing with no associated classes found")
					for id in drawing_element["classids"]:
						self.dimdrawing_classes.add_link(draw,self.repo.classes[id])
					self.collection_dimdrawings.add_link(repo.collections[coll],draw)
				if drawing_element["type"] == "drawing-connector":
					draw = DrawingConnectors(drawing_element,coll,self.backend_root)
					if draw.get_svg() is None and draw.get_png() is None:
						raise MalformedRepositoryError("No drawing files present for %s/%s" % (coll,draw.filename))

					if not draw.location in self.conlocations:
						self.conlocations.append(draw.location)
					self.conlocations_condrawings.add_link(draw.location,draw)

					self.condrawings.append(draw)
					for id in drawing_element["classids"]:
						self.condrawings_classes.add_link(draw,self.repo.classes[id])
					self.collection_condrawings.add_link(repo.collections[coll],draw)
Пример #2
0
	def __init__(self,repo):
		DataBase.__init__(self,"openscad",repo)

		self.modules = []
		self.scadfiles = []
		self.connectors = []

		self.module_classes = Links()
		self.scadfile_modules = Links()
		self.collection_modules = Links()
		self.collection_scadfiles = Links()
		self.module_connectors = BijectiveLinks()

		if not exists(join(self.backend_root)):
			e = MalformedRepositoryError("openscad directory does not exist")
			e.set_repo_path(repo.path)
			raise e

		for coll in listdir(self.backend_root):
			basefilename = join(self.backend_root,coll,"%s.base" % coll)
			if not exists(basefilename):
				#skip directory that is no collection
				continue
			base =  list(yaml.load_all(open(basefilename,"r","utf8")))
			if len(base) != 1:
				raise MalformedCollectionError(
						"No YAML document found in file %s" % basefilename)
			base = base[0]
			for basefile in base:
				scadfile = SCADFile(basefile,coll)
				self.scadfiles.append(scadfile)
				self.collection_scadfiles.add_link(repo.collections[coll],scadfile)
				if basefile["type"] == "module":
					for mod in basefile["modules"]:
						try:
							module = SCADModule(mod,basefile,coll)
							self.modules.append(module)
							self.collection_modules.add_link(repo.collections[coll],module)
							self.scadfile_modules.add_link(scadfile,module)

							if "connectors" in mod:
								connectors = Connectors(mod["connectors"])
								self.module_connectors.add_link(module,connectors)

							for id in module.classids:
								if not id in repo.classes:
									raise MalformedBaseError(
										"Unknown class %s" % id)
								if self.module_classes.contains_dst(repo.classes[id]):
									raise NonUniqueBaseError(id)
								self.module_classes.add_link(module,repo.classes[id])
						except ParsingError as e:
							e.set_base(basefile["filename"])
							raise e
				else:
					raise MalformedBaseError("Unknown base type %s" % basefile["type"])
Пример #3
0
	def __init__(self,repo):
		DataBase.__init__(self,"freecad",repo)
		self.bases = []

		self.base_classes = Links()
		self.collection_bases = Links()

		if not exists(self.backend_root):
			e = MalformedRepositoryError("freecad directory does not exist")
			e.set_repo_path(repo.path)
			raise e

		for coll in listdir(self.backend_root):
			basefilename = join(self.backend_root,coll,"%s.base" % coll)
			if not exists(basefilename):
				#skip directory that is no collection
				continue
			base_info =  list(yaml.load_all(open(basefilename,"r","utf8")))
			if len(base_info) != 1:
				raise MalformedCollectionError(
						"Not exactly one YAML document found in file %s" % basefilename)
			base_info = base_info[0]
			for basefile in base_info:
				if basefile["type"] == "function":
					basepath = join(self.backend_root,coll,basefile["filename"])
					if not exists(basepath):
						raise MalformedBaseError("Python module %s does not exist" % basepath)
					for func in basefile["functions"]:
						try:
							function = BaseFunction(func,basefile,coll,self.backend_root)
							self.bases.append(function)
							self.collection_bases.add_link(repo.collections[coll],function)
							for id in func["classids"]:
								if not id in repo.classes:
									raise MalformedBaseError(
										"Unknown class %s" % id)
								if self.base_classes.contains_dst(repo.classes[id]):
									raise NonUniqueBaseError(id)
								self.base_classes.add_link(function,repo.classes[id])
						except ParsingError as e:
							e.set_base(basefile["filename"])
							e.set_collection(coll)
							raise e
				else:
					raise MalformedBaseError("Unknown base type %s" % basefile["type"])
Пример #4
0
class OpenSCADData(DataBase):
	def __init__(self,repo):
		DataBase.__init__(self,"openscad",repo)

		self.modules = []
		self.scadfiles = []
		self.connectors = []

		self.module_classes = Links()
		self.scadfile_modules = Links()
		self.collection_modules = Links()
		self.collection_scadfiles = Links()
		self.module_connectors = BijectiveLinks()

		if not exists(join(self.backend_root)):
			e = MalformedRepositoryError("openscad directory does not exist")
			e.set_repo_path(repo.path)
			raise e

		for coll in listdir(self.backend_root):
			basefilename = join(self.backend_root,coll,"%s.base" % coll)
			if not exists(basefilename):
				#skip directory that is no collection
				continue
			base =  list(yaml.load_all(open(basefilename,"r","utf8")))
			if len(base) != 1:
				raise MalformedCollectionError(
						"No YAML document found in file %s" % basefilename)
			base = base[0]
			for basefile in base:
				scadfile = SCADFile(basefile,coll)
				self.scadfiles.append(scadfile)
				self.collection_scadfiles.add_link(repo.collections[coll],scadfile)
				if basefile["type"] == "module":
					for mod in basefile["modules"]:
						try:
							module = SCADModule(mod,basefile,coll)
							self.modules.append(module)
							self.collection_modules.add_link(repo.collections[coll],module)
							self.scadfile_modules.add_link(scadfile,module)

							if "connectors" in mod:
								connectors = Connectors(mod["connectors"])
								self.module_connectors.add_link(module,connectors)

							for id in module.classids:
								if not id in repo.classes:
									raise MalformedBaseError(
										"Unknown class %s" % id)
								if self.module_classes.contains_dst(repo.classes[id]):
									raise NonUniqueBaseError(id)
								self.module_classes.add_link(module,repo.classes[id])
						except ParsingError as e:
							e.set_base(basefile["filename"])
							raise e
				else:
					raise MalformedBaseError("Unknown base type %s" % basefile["type"])

	def iternames(self,items=["name"],**kwargs):
		"""
		Iterator over all names of the repo.
		
		Possible items to request: name, multiname, collection, class, module
		"""
		check_iterator_arguments(items,"name",["multiname","collection","class","module"],kwargs)

		for name,multiname,coll,cl in self.repo.iternames(["name","multiname","collection","class"]):
			its = {"name" : name, "multiname" : multiname, "collection" : coll, "class" : cl}

			if self.module_classes.contains_dst(cl):
				its["module"] = self.module_classes.get_src(cl)
				if filter_iterator_items(its,kwargs):
					yield tuple(its[key] for key in items)

	def iterstandards(self,items=["standard"],**kwargs):
		"""
		Iterator over all standards of the repo.
		
		Possible items to request: standard, multistandard, collection, class, module
		"""
		check_iterator_arguments(items,"standard",["multistandard","collection","class","module"],kwargs)

		for standard,multistandard,coll,cl in self.repo.iterstandards(["standard","multistandard","collection","class"]):
			its = {"standard" : standard, "multistandard" : multistandard, "collection" : coll, "class" : cl}

			if self.module_classes.contains_dst(cl):
				its["module"] = self.module_classes.get_src(cl)
				if filter_iterator_items(its,kwargs):
					yield tuple(its[key] for key in items)

	def iterclasses(self,items=["class"],**kwargs):
		"""
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection, scadfile, module
		"""
		check_iterator_arguments(items,"class",["collection","scadfile","module"],kwargs)

		for cl, coll in self.repo.iterclasses(["class","collection"]):
			its = {"class" : cl, "collection" : coll}
			if self.module_classes.contains_dst(cl):
				its["module"] = self.module_classes.get_src(cl)
				its["scadfile"] = self.scadfile_modules.get_src(its["module"])
				if filter_iterator_items(its,kwargs):
					yield tuple(its[key] for key in items)

	def itermodules(self,items=["module"],**kwargs):
		"""
		Iterator over all OpenSCAD modules of the repo.

		Possible items to request: module, classes, collection
		"""
		check_iterator_arguments(items,"module",["classes","collection"],kwargs)

		for module in self.modules:
			its = {"module" : module}
			its["collection"] = self.collection_modules.get_src(module)
			its["classes"] = self.module_classes.get_dsts(module)

			if filter_iterator_items(its,kwargs):
				yield tuple(its[key] for key in items)

	def iterscadfiles(self,items=["scadfile"],**kwargs):
		"""
		Iterator over all OpenSCAD files of the repo.

		Possible items to request: scadfile, collection
		"""
		check_iterator_arguments(items,"scadfile",["collection"],kwargs)

		for sf in self.scadfiles:
			its = {"scadfile" : sf}
			its["collection"] = self.collection_scadfiles.get_src(sf)

			if filter_iterator_items(its,kwargs):
				yield tuple(its[key] for key in items)
Пример #5
0
    def __init__(self, path):
        # check for conformity
        if not exists(path):
            e = MalformedRepositoryError("Repo directory does not exist")
            e.set_repo_path(path)
            raise e
        if not exists(join(path, "data")):
            e = MalformedRepositoryError("No data directory found")
            e.set_repo_path(path)
            raise e

        self.path = path

        # objects that have an id
        self.classes = {}
        self.collections = {}
        self.names = {}
        self.standards = {}
        self.multinames = {}
        self.multistandards = {}
        self.bodies = {}

        # relations
        self.class_names = Links()
        self.class_standards = Links()
        self.multiname_names = Links()
        self.multistandard_standards = Links()
        self.body_standards = Links()
        self.body_multistandards = Links()
        self.collection_classes = Links()
        self.collection_standards = Links()
        self.collection_multistandards = Links()
        self.collection_names = Links()
        self.collection_multinames = Links()
        self.standard_replaced = Links(1)

        # load collection data
        for filename in os.listdir(join(path, "data")):
            if splitext(filename)[1] != ".blt":
                continue

            raw_coll = list(yaml.load_all(open(join(path, "data", filename), "r", "utf8")))
            if len(raw_coll) == 0:
                raise MalformedCollectionError("No YAML document found in file %s" % filename)
            if len(raw_coll) > 1:
                raise MalformedCollectionError("More than one YAML document found in file %s" % filename)
                # we only consider the first YAML document
            raw_coll = raw_coll[0]

            if not isinstance(raw_coll["classes"], list):
                raise MalformedCollectionError("No class in collection %s" % raw_coll["id"])

            if raw_coll["id"] in self.collections:
                raise MalformedCollectionError("Duplicate collection id %s" % raw_coll["id"])

            if raw_coll["id"] != splitext(filename)[0]:
                raise MalformedCollectionError("Collection ID is not identical with file name: %s" % filename)
            for c in raw_coll["id"]:
                if not c in string.ascii_letters + string.digits + "_":
                    raise MalformedCollectionError("Collection ID contains invalid character: %s" % c)

            try:
                coll = Collection(raw_coll)
                self.collections[coll.id] = coll
            except ParsingError as e:
                e.set_repo_path(path)
                e.set_collection(filename)
                raise e

            for cl in raw_coll["classes"]:

                if cl["id"] in self.classes:
                    raise MalformedRepositoryError("Duplicate class id %s" % cl["id"])

                try:
                    cls = Class(cl)
                    self.classes[cls.id] = cls
                except ParsingError as e:
                    e.set_class(cl["id"])
                    e.set_repo_path(path)
                    e.set_collection(filename)
                    raise e

                self.collection_classes.add_link(coll, cls)

                names = []
                standards = []
                if "names" in cl:
                    if isinstance(cl["names"], list):
                        names = cl["names"]
                    else:
                        names = [cl["names"]]
                if "standards" in cl:
                    if isinstance(cl["standards"], list):
                        standards = cl["standards"]
                    else:
                        standards = [cl["standards"]]

                if len(names + standards) == 0:
                    raise MalformedCollectionError("Encountered class with no names: %s" % raw_coll["id"])

                for cn in names:
                    try:
                        name = ClassName(cn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e
                    if name.get_id() in self.names:
                        raise MalformedRepositoryError("Duplicate name %s" % name.get_id())

                    self.names[name.get_id()] = name
                    self.class_names.add_link(cls, name)

                    multinameid = name.group.get_safe()
                    if multinameid:
                        if not multinameid in self.multinames:
                            multiname = MultiName(name.group)
                            self.multinames[multinameid] = multiname
                        else:
                            multiname = self.multinames[multinameid]
                        self.collection_multinames.add_link(coll, multiname)
                        self.multiname_names.add_link(multiname, name)
                    else:
                        self.collection_names.add_link(coll, name)

                for sn in standards:
                    try:
                        standard = ClassStandard(sn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e

                    if standard.get_id() in self.standards:
                        raise MalformedRepositoryError("Duplicate standard %s" % standard.get_id())

                    self.standards[standard.get_id()] = standard
                    self.class_standards.add_link(cls, standard)

                    bodyid = standard.body
                    if bodyid in self.bodies:
                        body = self.bodies[bodyid]
                    else:
                        body = StandardBody(bodyid)
                        self.bodies[bodyid] = body

                    self.body_standards.add_link(body, standard)
                    self.collection_standards.add_link(coll, standard)

                    multistdid = standard.group.get_safe()
                    if multistdid:
                        if not multistdid in self.multistandards:
                            multistd = MultiStandard(standard.group)
                            self.multistandards[multistdid] = multistd
                            self.body_multistandards.add_link(body, multistd)
                            self.collection_multistandards.add_link(coll, multistd)
                        else:
                            multistd = self.multistandards[multistdid]

                        self.multistandard_standards.add_link(multistd, standard)

        for standard in self.standards.values():
            if not standard.replaces is None:
                if not standard.replaces in self.standards:
                    raise MalformedRepositoryError(
                        "Unknown replace field %s in standard %s" % (standard.replaces, standard.get_id())
                    )
                self.standard_replaced.add_link(standard, self.standards[standard.replaces])
Пример #6
0
class Repository:
    def __init__(self, path):
        # check for conformity
        if not exists(path):
            e = MalformedRepositoryError("Repo directory does not exist")
            e.set_repo_path(path)
            raise e
        if not exists(join(path, "data")):
            e = MalformedRepositoryError("No data directory found")
            e.set_repo_path(path)
            raise e

        self.path = path

        # objects that have an id
        self.classes = {}
        self.collections = {}
        self.names = {}
        self.standards = {}
        self.multinames = {}
        self.multistandards = {}
        self.bodies = {}

        # relations
        self.class_names = Links()
        self.class_standards = Links()
        self.multiname_names = Links()
        self.multistandard_standards = Links()
        self.body_standards = Links()
        self.body_multistandards = Links()
        self.collection_classes = Links()
        self.collection_standards = Links()
        self.collection_multistandards = Links()
        self.collection_names = Links()
        self.collection_multinames = Links()
        self.standard_replaced = Links(1)

        # load collection data
        for filename in os.listdir(join(path, "data")):
            if splitext(filename)[1] != ".blt":
                continue

            raw_coll = list(yaml.load_all(open(join(path, "data", filename), "r", "utf8")))
            if len(raw_coll) == 0:
                raise MalformedCollectionError("No YAML document found in file %s" % filename)
            if len(raw_coll) > 1:
                raise MalformedCollectionError("More than one YAML document found in file %s" % filename)
                # we only consider the first YAML document
            raw_coll = raw_coll[0]

            if not isinstance(raw_coll["classes"], list):
                raise MalformedCollectionError("No class in collection %s" % raw_coll["id"])

            if raw_coll["id"] in self.collections:
                raise MalformedCollectionError("Duplicate collection id %s" % raw_coll["id"])

            if raw_coll["id"] != splitext(filename)[0]:
                raise MalformedCollectionError("Collection ID is not identical with file name: %s" % filename)
            for c in raw_coll["id"]:
                if not c in string.ascii_letters + string.digits + "_":
                    raise MalformedCollectionError("Collection ID contains invalid character: %s" % c)

            try:
                coll = Collection(raw_coll)
                self.collections[coll.id] = coll
            except ParsingError as e:
                e.set_repo_path(path)
                e.set_collection(filename)
                raise e

            for cl in raw_coll["classes"]:

                if cl["id"] in self.classes:
                    raise MalformedRepositoryError("Duplicate class id %s" % cl["id"])

                try:
                    cls = Class(cl)
                    self.classes[cls.id] = cls
                except ParsingError as e:
                    e.set_class(cl["id"])
                    e.set_repo_path(path)
                    e.set_collection(filename)
                    raise e

                self.collection_classes.add_link(coll, cls)

                names = []
                standards = []
                if "names" in cl:
                    if isinstance(cl["names"], list):
                        names = cl["names"]
                    else:
                        names = [cl["names"]]
                if "standards" in cl:
                    if isinstance(cl["standards"], list):
                        standards = cl["standards"]
                    else:
                        standards = [cl["standards"]]

                if len(names + standards) == 0:
                    raise MalformedCollectionError("Encountered class with no names: %s" % raw_coll["id"])

                for cn in names:
                    try:
                        name = ClassName(cn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e
                    if name.get_id() in self.names:
                        raise MalformedRepositoryError("Duplicate name %s" % name.get_id())

                    self.names[name.get_id()] = name
                    self.class_names.add_link(cls, name)

                    multinameid = name.group.get_safe()
                    if multinameid:
                        if not multinameid in self.multinames:
                            multiname = MultiName(name.group)
                            self.multinames[multinameid] = multiname
                        else:
                            multiname = self.multinames[multinameid]
                        self.collection_multinames.add_link(coll, multiname)
                        self.multiname_names.add_link(multiname, name)
                    else:
                        self.collection_names.add_link(coll, name)

                for sn in standards:
                    try:
                        standard = ClassStandard(sn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e

                    if standard.get_id() in self.standards:
                        raise MalformedRepositoryError("Duplicate standard %s" % standard.get_id())

                    self.standards[standard.get_id()] = standard
                    self.class_standards.add_link(cls, standard)

                    bodyid = standard.body
                    if bodyid in self.bodies:
                        body = self.bodies[bodyid]
                    else:
                        body = StandardBody(bodyid)
                        self.bodies[bodyid] = body

                    self.body_standards.add_link(body, standard)
                    self.collection_standards.add_link(coll, standard)

                    multistdid = standard.group.get_safe()
                    if multistdid:
                        if not multistdid in self.multistandards:
                            multistd = MultiStandard(standard.group)
                            self.multistandards[multistdid] = multistd
                            self.body_multistandards.add_link(body, multistd)
                            self.collection_multistandards.add_link(coll, multistd)
                        else:
                            multistd = self.multistandards[multistdid]

                        self.multistandard_standards.add_link(multistd, standard)

        for standard in self.standards.values():
            if not standard.replaces is None:
                if not standard.replaces in self.standards:
                    raise MalformedRepositoryError(
                        "Unknown replace field %s in standard %s" % (standard.replaces, standard.get_id())
                    )
                self.standard_replaced.add_link(standard, self.standards[standard.replaces])

    def iternames(self, items=["name"], **kwargs):
        """
		Iterator over all names of the repo.
		
		Possible items to request: name, multiname, collection, class
		"""
        check_iterator_arguments(items, "name", ["multiname", "collection", "class"], kwargs)

        for name in self.names.values():
            its = {"name": name}
            its["class"] = self.class_names.get_src(name)
            if self.multiname_names.contains_dst(name):
                its["multiname"] = self.multiname_names.get_src(name)
                its["collection"] = self.collection_multinames.get_src(multiname)
            else:
                its["multiname"] = None
                its["collection"] = self.collection_names.get_src(name)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itermultinames(self, items=["multiname"], **kwargs):
        """
		Iterator over all multinames of the repo.

		Possible items to rerquest: multiname, names, collection
		"""
        check_iterator_arguments(items, "multiname", ["names", "collection"], kwargs)

        for mname in self.multinames.values():
            its = {"multiname": mname}
            its["names"] = self.multiname_names.get_dsts(mname)
            its["collection"] = self.collection_multinames.get_src(mname)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def iterstandards(self, items=["standard"], **kwargs):
        """
		Iterator over all standards of the repo.
		
		Possible items to request: standard, multistandard, body, collection, class
		"""
        check_iterator_arguments(items, "standard", ["multistandard", "body", "collection", "class"], kwargs)

        for std in self.standards.values():
            its = {"standard": std}
            its["class"] = self.class_standards.get_src(std)
            its["body"] = self.body_standards.get_src(std)

            if self.multistandard_standards.contains_dst(std):
                its["multistandard"] = self.multistandard_standards.get_src(std)
                its["collection"] = self.collection_multistandards.get_src(its["multistandard"])
            else:
                its["multistandard"] = None
                its["collection"] = self.collection_standards.get_src(std)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itermultistandards(self, items=["multistandard"], **kwargs):
        """
		Iterator over all multistandards of the repo.

		Possible items to rerquest: multistandard, standards, collection, body
		"""
        check_iterator_arguments(items, "multistandard", ["standards", "collection", "body"], kwargs)

        for mstandard in self.multistandards.values():
            its = {"multistandard": mstandard}
            its["standards"] = self.multistandard_standards.get_dsts(mstandard)
            its["collection"] = self.collection_multistandards.get_src(mstandard)
            its["body"] = self.body_multistandards.get_src(mstandard)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def iterclasses(self, items=["class"], **kwargs):
        """
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection
		"""
        check_iterator_arguments(items, "class", ["collection"], kwargs)

        for cl in self.classes.values():
            its = {"class": cl}
            its["collection"] = self.collection_classes.get_src(cl)
            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itercollections(self):
        """
		Iterator over all collections of the repo.
		
		Not possible to request items
		"""
        for coll in self.collections.values():
            yield (coll,)

    def iterbodies(self):
        """
		Iterator over all standard bodies of the repo.
		
		Not possible to request items
		"""
        for body in self.bodies.values():
            yield (body,)
Пример #7
0
    def __init__(self, repo):
        DataBase.__init__(self, "openscad", repo)

        self.modules = []
        self.scadfiles = []
        self.connectors = []

        self.module_classes = Links()
        self.scadfile_modules = Links()
        self.collection_modules = Links()
        self.collection_scadfiles = Links()
        self.module_connectors = BijectiveLinks()

        if not exists(join(self.backend_root)):
            e = MalformedRepositoryError("openscad directory does not exist")
            e.set_repo_path(repo.path)
            raise e

        for coll in listdir(self.backend_root):
            basefilename = join(self.backend_root, coll, "%s.base" % coll)
            if not exists(basefilename):
                #skip directory that is no collection
                continue
            base = list(yaml.load_all(open(basefilename, "r", "utf8")))
            if len(base) != 1:
                raise MalformedCollectionError(
                    "No YAML document found in file %s" % basefilename)
            base = base[0]
            for basefile in base:
                scadfile = SCADFile(basefile, coll)
                self.scadfiles.append(scadfile)
                self.collection_scadfiles.add_link(repo.collections[coll],
                                                   scadfile)
                if basefile["type"] == "module":
                    for mod in basefile["modules"]:
                        try:
                            module = SCADModule(mod, basefile, coll)
                            self.modules.append(module)
                            self.collection_modules.add_link(
                                repo.collections[coll], module)
                            self.scadfile_modules.add_link(scadfile, module)

                            if "connectors" in mod:
                                connectors = Connectors(mod["connectors"])
                                self.module_connectors.add_link(
                                    module, connectors)

                            for id in module.classids:
                                if not id in repo.classes:
                                    raise MalformedBaseError(
                                        "Unknown class %s" % id)
                                if self.module_classes.contains_dst(
                                        repo.classes[id]):
                                    raise NonUniqueBaseError(id)
                                self.module_classes.add_link(
                                    module, repo.classes[id])
                        except ParsingError as e:
                            e.set_base(basefile["filename"])
                            raise e
                else:
                    raise MalformedBaseError("Unknown base type %s" %
                                             basefile["type"])
Пример #8
0
class OpenSCADData(DataBase):
    def __init__(self, repo):
        DataBase.__init__(self, "openscad", repo)

        self.modules = []
        self.scadfiles = []
        self.connectors = []

        self.module_classes = Links()
        self.scadfile_modules = Links()
        self.collection_modules = Links()
        self.collection_scadfiles = Links()
        self.module_connectors = BijectiveLinks()

        if not exists(join(self.backend_root)):
            e = MalformedRepositoryError("openscad directory does not exist")
            e.set_repo_path(repo.path)
            raise e

        for coll in listdir(self.backend_root):
            basefilename = join(self.backend_root, coll, "%s.base" % coll)
            if not exists(basefilename):
                #skip directory that is no collection
                continue
            base = list(yaml.load_all(open(basefilename, "r", "utf8")))
            if len(base) != 1:
                raise MalformedCollectionError(
                    "No YAML document found in file %s" % basefilename)
            base = base[0]
            for basefile in base:
                scadfile = SCADFile(basefile, coll)
                self.scadfiles.append(scadfile)
                self.collection_scadfiles.add_link(repo.collections[coll],
                                                   scadfile)
                if basefile["type"] == "module":
                    for mod in basefile["modules"]:
                        try:
                            module = SCADModule(mod, basefile, coll)
                            self.modules.append(module)
                            self.collection_modules.add_link(
                                repo.collections[coll], module)
                            self.scadfile_modules.add_link(scadfile, module)

                            if "connectors" in mod:
                                connectors = Connectors(mod["connectors"])
                                self.module_connectors.add_link(
                                    module, connectors)

                            for id in module.classids:
                                if not id in repo.classes:
                                    raise MalformedBaseError(
                                        "Unknown class %s" % id)
                                if self.module_classes.contains_dst(
                                        repo.classes[id]):
                                    raise NonUniqueBaseError(id)
                                self.module_classes.add_link(
                                    module, repo.classes[id])
                        except ParsingError as e:
                            e.set_base(basefile["filename"])
                            raise e
                else:
                    raise MalformedBaseError("Unknown base type %s" %
                                             basefile["type"])

    def iternames(self, items=["name"], **kwargs):
        """
		Iterator over all names of the repo.
		
		Possible items to request: name, multiname, collection, class, module
		"""
        check_iterator_arguments(
            items, "name", ["multiname", "collection", "class", "module"],
            kwargs)

        for name, multiname, coll, cl in self.repo.iternames(
            ["name", "multiname", "collection", "class"]):
            its = {
                "name": name,
                "multiname": multiname,
                "collection": coll,
                "class": cl
            }

            if self.module_classes.contains_dst(cl):
                its["module"] = self.module_classes.get_src(cl)
                if filter_iterator_items(its, kwargs):
                    yield tuple(its[key] for key in items)

    def iterstandards(self, items=["standard"], **kwargs):
        """
		Iterator over all standards of the repo.
		
		Possible items to request: standard, multistandard, collection, class, module
		"""
        check_iterator_arguments(
            items, "standard",
            ["multistandard", "collection", "class", "module"], kwargs)

        for standard, multistandard, coll, cl in self.repo.iterstandards(
            ["standard", "multistandard", "collection", "class"]):
            its = {
                "standard": standard,
                "multistandard": multistandard,
                "collection": coll,
                "class": cl
            }

            if self.module_classes.contains_dst(cl):
                its["module"] = self.module_classes.get_src(cl)
                if filter_iterator_items(its, kwargs):
                    yield tuple(its[key] for key in items)

    def iterclasses(self, items=["class"], **kwargs):
        """
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection, scadfile, module
		"""
        check_iterator_arguments(items, "class",
                                 ["collection", "scadfile", "module"], kwargs)

        for cl, coll in self.repo.iterclasses(["class", "collection"]):
            its = {"class": cl, "collection": coll}
            if self.module_classes.contains_dst(cl):
                its["module"] = self.module_classes.get_src(cl)
                its["scadfile"] = self.scadfile_modules.get_src(its["module"])
                if filter_iterator_items(its, kwargs):
                    yield tuple(its[key] for key in items)

    def itermodules(self, items=["module"], **kwargs):
        """
		Iterator over all OpenSCAD modules of the repo.

		Possible items to request: module, classes, collection
		"""
        check_iterator_arguments(items, "module", ["classes", "collection"],
                                 kwargs)

        for module in self.modules:
            its = {"module": module}
            its["collection"] = self.collection_modules.get_src(module)
            its["classes"] = self.module_classes.get_dsts(module)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def iterscadfiles(self, items=["scadfile"], **kwargs):
        """
		Iterator over all OpenSCAD files of the repo.

		Possible items to request: scadfile, collection
		"""
        check_iterator_arguments(items, "scadfile", ["collection"], kwargs)

        for sf in self.scadfiles:
            its = {"scadfile": sf}
            its["collection"] = self.collection_scadfiles.get_src(sf)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)
Пример #9
0
class FreeCADData(DataBase):
	def __init__(self,repo):
		DataBase.__init__(self,"freecad",repo)
		self.bases = []

		self.base_classes = Links()
		self.collection_bases = Links()

		if not exists(self.backend_root):
			e = MalformedRepositoryError("freecad directory does not exist")
			e.set_repo_path(repo.path)
			raise e

		for coll in listdir(self.backend_root):
			basefilename = join(self.backend_root,coll,"%s.base" % coll)
			if not exists(basefilename):
				#skip directory that is no collection
				continue
			base_info =  list(yaml.load_all(open(basefilename,"r","utf8")))
			if len(base_info) != 1:
				raise MalformedCollectionError(
						"Not exactly one YAML document found in file %s" % basefilename)
			base_info = base_info[0]
			for basefile in base_info:
				if basefile["type"] == "function":
					basepath = join(self.backend_root,coll,basefile["filename"])
					if not exists(basepath):
						raise MalformedBaseError("Python module %s does not exist" % basepath)
					for func in basefile["functions"]:
						try:
							function = BaseFunction(func,basefile,coll,self.backend_root)
							self.bases.append(function)
							self.collection_bases.add_link(repo.collections[coll],function)
							for id in func["classids"]:
								if not id in repo.classes:
									raise MalformedBaseError(
										"Unknown class %s" % id)
								if self.base_classes.contains_dst(repo.classes[id]):
									raise NonUniqueBaseError(id)
								self.base_classes.add_link(function,repo.classes[id])
						except ParsingError as e:
							e.set_base(basefile["filename"])
							e.set_collection(coll)
							raise e
				else:
					raise MalformedBaseError("Unknown base type %s" % basefile["type"])

	def iterclasses(self,items=["class"],**kwargs):
		"""
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection, base
		"""
		check_iterator_arguments(items,"class",["collection","base"],kwargs)

		for cl,coll in self.repo.iterclasses(["class","collection"]):
			its = {"class" : cl, "collection" : coll}
			if self.base_classes.contains_dst(cl):
				its["base"] = self.base_classes.get_src(cl)

				if filter_iterator_items(its,kwargs):
					yield tuple(its[key] for key in items)

	def iterstandards(self,items=["standard"],**kwargs):
		"""
		Iterator over all standards of the repo.

		Possible items to request: standard, multistandard, body, collection, class, base
		"""
		check_iterator_arguments(items,"standard",["multistandard","body", "collection","class","base"],kwargs)

		parent = ["standard","multistandard","body", "collection","class"]
		for tup in self.repo.iterstandards(parent):
			its = dict(zip(parent,tup))
			if self.base_classes.contains_dst(its["class"]):
				its["base"] = self.base_classes.get_src(its["class"])
				if filter_iterator_items(its,kwargs):
					yield tuple(its[key] for key in items)

	def iternames(self,items=["name"],**kwargs):
		"""
		Iterator over all names of the repo.

		Possible items to request: name, multiname, collection, class, base
		"""
		check_iterator_arguments(items,"name",["multiname", "collection","class","base"],kwargs)

		parent = ["name","multiname", "collection","class"]
		for tup in self.repo.iternames(parent):
			its = dict(zip(parent,tup))
			if self.base_classes.contains_dst(its["class"]):
				its["base"] = self.base_classes.get_src(its["class"])
				if filter_iterator_items(its,kwargs):
					yield tuple(its[key] for key in items)

	def iterbases(self,items=["base"],**kwargs):
		"""
		Iterator over all freecad bases of the repo.
		
		Possible items to request: base, classes, collection
		"""
		check_iterator_arguments(items,"base",["classes", "collection"],kwargs)

		for base in self.bases:
			its = {"base" : base}
			its["collection"] = self.collection_bases.get_src(base)
			its["classes"] = self.base_classes.get_dsts(base)

			if filter_iterator_items(its,kwargs):
				yield tuple(its[key] for key in items)
Пример #10
0
    def __init__(self, repo):
        DataBase.__init__(self, "drawings", repo)
        self.dimdrawings = []
        self.condrawings = []
        self.conlocations = []

        self.dimdrawing_classes = Links()
        self.condrawings_classes = BipartiteLinks()
        self.conlocations_condrawings = BipartiteLinks()

        self.collection_dimdrawings = Links()
        self.collection_condrawings = Links()

        if not exists(join(self.backend_root)):
            e = MalformedRepositoryError("drawings directory does not exist")
            e.set_repo_path(path)
            raise e

        for coll in listdir(self.backend_root):
            basefilename = join(self.backend_root, coll, "%s.base" % coll)
            if not exists(basefilename):
                #skip directory that is no collection
                continue
            if coll not in repo.collections:
                raise MalformedRepositoryError(
                    "Drawings for unknown collection found: %s " % coll)

            base_info = list(yaml.load_all(open(basefilename, "r", "utf8")))
            if len(base_info) != 1:
                raise MalformedCollectionError(
                    "Not exactly one YAML document found in file %s" %
                    basefilename)
            base_info = base_info[0]

            for drawing_element in base_info:
                if drawing_element["type"] == "drawing-dimensions":
                    draw = DrawingDimensions(drawing_element, coll,
                                             self.backend_root)
                    if draw.get_svg() is None and draw.get_png() is None:
                        raise MalformedRepositoryError(
                            "No drawing files present for %s/%s" %
                            (coll, draw.filename))

                    self.dimdrawings.append(draw)

                    if drawing_element["classids"] == []:
                        raise MalformedBaseError(
                            "Drawing with no associated classes found")
                    for id in drawing_element["classids"]:
                        self.dimdrawing_classes.add_link(
                            draw, self.repo.classes[id])
                    self.collection_dimdrawings.add_link(
                        repo.collections[coll], draw)
                if drawing_element["type"] == "drawing-connector":
                    draw = DrawingConnectors(drawing_element, coll,
                                             self.backend_root)
                    if draw.get_svg() is None and draw.get_png() is None:
                        raise MalformedRepositoryError(
                            "No drawing files present for %s/%s" %
                            (coll, draw.filename))

                    if not draw.location in self.conlocations:
                        self.conlocations.append(draw.location)
                    self.conlocations_condrawings.add_link(draw.location, draw)

                    self.condrawings.append(draw)
                    for id in drawing_element["classids"]:
                        self.condrawings_classes.add_link(
                            draw, self.repo.classes[id])
                    self.collection_condrawings.add_link(
                        repo.collections[coll], draw)
Пример #11
0
class DrawingsData(DataBase):
    def __init__(self, repo):
        DataBase.__init__(self, "drawings", repo)
        self.dimdrawings = []
        self.condrawings = []
        self.conlocations = []

        self.dimdrawing_classes = Links()
        self.condrawings_classes = BipartiteLinks()
        self.conlocations_condrawings = BipartiteLinks()

        self.collection_dimdrawings = Links()
        self.collection_condrawings = Links()

        if not exists(join(self.backend_root)):
            e = MalformedRepositoryError("drawings directory does not exist")
            e.set_repo_path(path)
            raise e

        for coll in listdir(self.backend_root):
            basefilename = join(self.backend_root, coll, "%s.base" % coll)
            if not exists(basefilename):
                #skip directory that is no collection
                continue
            if coll not in repo.collections:
                raise MalformedRepositoryError(
                    "Drawings for unknown collection found: %s " % coll)

            base_info = list(yaml.load_all(open(basefilename, "r", "utf8")))
            if len(base_info) != 1:
                raise MalformedCollectionError(
                    "Not exactly one YAML document found in file %s" %
                    basefilename)
            base_info = base_info[0]

            for drawing_element in base_info:
                if drawing_element["type"] == "drawing-dimensions":
                    draw = DrawingDimensions(drawing_element, coll,
                                             self.backend_root)
                    if draw.get_svg() is None and draw.get_png() is None:
                        raise MalformedRepositoryError(
                            "No drawing files present for %s/%s" %
                            (coll, draw.filename))

                    self.dimdrawings.append(draw)

                    if drawing_element["classids"] == []:
                        raise MalformedBaseError(
                            "Drawing with no associated classes found")
                    for id in drawing_element["classids"]:
                        self.dimdrawing_classes.add_link(
                            draw, self.repo.classes[id])
                    self.collection_dimdrawings.add_link(
                        repo.collections[coll], draw)
                if drawing_element["type"] == "drawing-connector":
                    draw = DrawingConnectors(drawing_element, coll,
                                             self.backend_root)
                    if draw.get_svg() is None and draw.get_png() is None:
                        raise MalformedRepositoryError(
                            "No drawing files present for %s/%s" %
                            (coll, draw.filename))

                    if not draw.location in self.conlocations:
                        self.conlocations.append(draw.location)
                    self.conlocations_condrawings.add_link(draw.location, draw)

                    self.condrawings.append(draw)
                    for id in drawing_element["classids"]:
                        self.condrawings_classes.add_link(
                            draw, self.repo.classes[id])
                    self.collection_condrawings.add_link(
                        repo.collections[coll], draw)

    def iterclasses(self, items=["class"], **kwargs):
        """
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection, dimdrawing, condrawings
		"""
        check_iterator_arguments(items, "class",
                                 ["collection", "dimdrawing", "condrawings"],
                                 kwargs)

        for cl, coll in self.repo.iterclasses(["class", "collection"]):
            its = {"class": cl, "collection": coll}
            if self.condrawings_classes.contains_dst(cl):
                its["condrawings"] = self.condrawings_classes.get_srcs(cl)
            else:
                its["condrawings"] = []
            if self.dimdrawing_classes.contains_dst(cl):
                its["dimdrawing"] = self.dimdrawing_classes.get_src(cl)
            else:
                its["dimdrawing"] = None

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def iterdimdrawings(self, items=["dimdrawing"], **kwargs):
        """
		Iterator over all dimension drawings of the repo.
		
		Possible items to request: dimdrawing, classes, collection
		"""
        check_iterator_arguments(items, "dimdrawing",
                                 ["classes", "collection"], kwargs)

        for draw in self.dimdrawings:
            its = {"dimdrawing": draw}
            its["collection"] = self.collection_dimdrawings.get_src(draw)
            its["classes"] = self.dimdrawing_classes.get_dsts(draw)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itercondrawings(self, items=["condrawing"], **kwargs):
        """
		Iterator over all connector drawings of the repo.
		
		Possible items to request: condrawing, conlocations, classes, collection
		"""
        check_iterator_arguments(items, "condrawing",
                                 ["conlocations", "classes", "collection"],
                                 kwargs)

        for draw in self.condrawings:
            its = {"condrawing": draw}
            its["collection"] = self.collection_condrawings.get_src(draw)
            its["classes"] = self.condrawings_classes.get_dsts(draw)
            its["conlocations"] = self.conlocations_condrawings.get_srcs(draw)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)
Пример #12
0
class DrawingsData(DataBase):
	def __init__(self,repo):
		DataBase.__init__(self,"drawings", repo)
		self.dimdrawings = []
		self.condrawings = []
		self.conlocations = []

		self.dimdrawing_classes = Links()
		self.condrawings_classes = BipartiteLinks()
		self.conlocations_condrawings = BipartiteLinks()

		self.collection_dimdrawings = Links()
		self.collection_condrawings = Links()

		if not exists(join(self.backend_root)):
			e = MalformedRepositoryError("drawings directory does not exist")
			e.set_repo_path(path)
			raise e

		for coll in listdir(self.backend_root):
			basefilename = join(self.backend_root,coll,"%s.base" % coll)
			if not exists(basefilename):
				#skip directory that is no collection
				continue
			if coll not in repo.collections:
				raise MalformedRepositoryError(
					"Drawings for unknown collection found: %s " % coll)
					
			base_info =  list(yaml.load_all(open(basefilename,"r","utf8")))
			if len(base_info) != 1:
				raise MalformedCollectionError(
					"Not exactly one YAML document found in file %s" % basefilename)
			base_info = base_info[0]

			for drawing_element in base_info:
				if drawing_element["type"] == "drawing-dimensions":
					draw = DrawingDimensions(drawing_element,coll,self.backend_root)
					if draw.get_svg() is None and draw.get_png() is None:
						raise MalformedRepositoryError("No drawing files present for %s/%s" % (coll,draw.filename))

					self.dimdrawings.append(draw)

					if drawing_element["classids"] == []:
						raise MalformedBaseError("Drawing with no associated classes found")
					for id in drawing_element["classids"]:
						self.dimdrawing_classes.add_link(draw,self.repo.classes[id])
					self.collection_dimdrawings.add_link(repo.collections[coll],draw)
				if drawing_element["type"] == "drawing-connector":
					draw = DrawingConnectors(drawing_element,coll,self.backend_root)
					if draw.get_svg() is None and draw.get_png() is None:
						raise MalformedRepositoryError("No drawing files present for %s/%s" % (coll,draw.filename))

					if not draw.location in self.conlocations:
						self.conlocations.append(draw.location)
					self.conlocations_condrawings.add_link(draw.location,draw)

					self.condrawings.append(draw)
					for id in drawing_element["classids"]:
						self.condrawings_classes.add_link(draw,self.repo.classes[id])
					self.collection_condrawings.add_link(repo.collections[coll],draw)

	def iterclasses(self,items=["class"],**kwargs):
		"""
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection, dimdrawing, condrawings
		"""
		check_iterator_arguments(items,"class",["collection","dimdrawing","condrawings"],kwargs)

		for cl,coll in self.repo.iterclasses(["class","collection"]):
			its = {"class" : cl, "collection" : coll}
			if self.condrawings_classes.contains_dst(cl):
				its["condrawings"] = self.condrawings_classes.get_srcs(cl)
			else:
				its["condrawings"] = []
			if self.dimdrawing_classes.contains_dst(cl):
				its["dimdrawing"] = self.dimdrawing_classes.get_src(cl)
			else:
				its["dimdrawing"] = None

			if filter_iterator_items(its,kwargs):
				yield tuple(its[key] for key in items)

	def iterdimdrawings(self,items=["dimdrawing"],**kwargs):
		"""
		Iterator over all dimension drawings of the repo.
		
		Possible items to request: dimdrawing, classes, collection
		"""
		check_iterator_arguments(items,"dimdrawing",["classes", "collection"],kwargs)

		for draw in self.dimdrawings:
			its = {"dimdrawing" : draw}
			its["collection"] = self.collection_dimdrawings.get_src(draw);
			its["classes"] = self.dimdrawing_classes.get_dsts(draw)

			if filter_iterator_items(its,kwargs):
				yield tuple(its[key] for key in items)

	def itercondrawings(self,items=["condrawing"],**kwargs):
		"""
		Iterator over all connector drawings of the repo.
		
		Possible items to request: condrawing, conlocations, classes, collection
		"""
		check_iterator_arguments(items,"condrawing",["conlocations", "classes", "collection"],kwargs)

		for draw in self.condrawings:
			its = {"condrawing" : draw}
			its["collection"] = self.collection_condrawings.get_src(draw)
			its["classes"] = self.condrawings_classes.get_dsts(draw)
			its["conlocations"] = self.conlocations_condrawings.get_srcs(draw)

			if filter_iterator_items(its,kwargs):
				yield tuple(its[key] for key in items)
Пример #13
0
    def __init__(self, path):
        #check for conformity
        if not exists(path):
            e = MalformedRepositoryError("Repo directory does not exist")
            e.set_repo_path(path)
            raise e
        if not exists(join(path, "data")):
            e = MalformedRepositoryError("No data directory found")
            e.set_repo_path(path)
            raise e

        self.path = path

        #objects that have an id
        self.classes = {}
        self.collections = {}
        self.names = {}
        self.standards = {}
        self.multinames = {}
        self.multistandards = {}
        self.bodies = {}

        #relations
        self.class_names = Links()
        self.class_standards = Links()
        self.multiname_names = Links()
        self.multistandard_standards = Links()
        self.body_standards = Links()
        self.body_multistandards = Links()
        self.collection_classes = Links()
        self.collection_standards = Links()
        self.collection_multistandards = Links()
        self.collection_names = Links()
        self.collection_multinames = Links()
        self.standard_replaced = Links(1)

        #load collection data
        for filename in os.listdir(join(path, "data")):
            if splitext(filename)[1] != ".blt":
                continue

            raw_coll = list(
                yaml.load_all(open(join(path, "data", filename), "r", "utf8")))
            if len(raw_coll) == 0:
                raise MalformedCollectionError(
                    "No YAML document found in file %s" % filename)
            if len(raw_coll) > 1:
                raise MalformedCollectionError(
                    "More than one YAML document found in file %s" % filename)
            #we only consider the first YAML document
            raw_coll = raw_coll[0]

            if not isinstance(raw_coll["classes"], list):
                raise MalformedCollectionError("No class in collection %s" %
                                               raw_coll["id"])

            if raw_coll["id"] in self.collections:
                raise MalformedCollectionError("Duplicate collection id %s" %
                                               raw_coll["id"])

            if raw_coll["id"] != splitext(filename)[0]:
                raise MalformedCollectionError(
                    "Collection ID is not identical with file name: %s" %
                    filename)
            for c in raw_coll["id"]:
                if not c in string.ascii_letters + string.digits + "_":
                    raise MalformedCollectionError(
                        "Collection ID contains invalid character: %s" % c)

            try:
                coll = Collection(raw_coll)
                self.collections[coll.id] = coll
            except ParsingError as e:
                e.set_repo_path(path)
                e.set_collection(filename)
                raise e

            for cl in raw_coll['classes']:

                if cl["id"] in self.classes:
                    raise MalformedRepositoryError("Duplicate class id %s" %
                                                   cl["id"])

                try:
                    cls = Class(cl)
                    self.classes[cls.id] = cls
                except ParsingError as e:
                    e.set_class(cl["id"])
                    e.set_repo_path(path)
                    e.set_collection(filename)
                    raise e

                self.collection_classes.add_link(coll, cls)

                names = []
                standards = []
                if 'names' in cl:
                    if isinstance(cl['names'], list):
                        names = cl['names']
                    else:
                        names = [cl['names']]
                if 'standards' in cl:
                    if isinstance(cl['standards'], list):
                        standards = cl['standards']
                    else:
                        standards = [cl['standards']]

                if len(names + standards) == 0:
                    raise MalformedCollectionError(
                        "Encountered class with no names: %s" % raw_coll["id"])

                for cn in names:
                    try:
                        name = ClassName(cn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e
                    if name.get_id() in self.names:
                        raise MalformedRepositoryError("Duplicate name %s" %
                                                       name.get_id())

                    self.names[name.get_id()] = name
                    self.class_names.add_link(cls, name)

                    multinameid = name.group.get_safe()
                    if multinameid:
                        if not multinameid in self.multinames:
                            multiname = MultiName(name.group)
                            self.multinames[multinameid] = multiname
                        else:
                            multiname = self.multinames[multinameid]
                        self.collection_multinames.add_link(coll, multiname)
                        self.multiname_names.add_link(multiname, name)
                    else:
                        self.collection_names.add_link(coll, name)

                for sn in standards:
                    try:
                        standard = ClassStandard(sn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e

                    if standard.get_id() in self.standards:
                        raise MalformedRepositoryError(
                            "Duplicate standard %s" % standard.get_id())

                    self.standards[standard.get_id()] = standard
                    self.class_standards.add_link(cls, standard)

                    bodyid = standard.body
                    if bodyid in self.bodies:
                        body = self.bodies[bodyid]
                    else:
                        body = StandardBody(bodyid)
                        self.bodies[bodyid] = body

                    self.body_standards.add_link(body, standard)
                    self.collection_standards.add_link(coll, standard)

                    multistdid = standard.group.get_safe()
                    if multistdid:
                        if not multistdid in self.multistandards:
                            multistd = MultiStandard(standard.group)
                            self.multistandards[multistdid] = multistd
                            self.body_multistandards.add_link(body, multistd)
                            self.collection_multistandards.add_link(
                                coll, multistd)
                        else:
                            multistd = self.multistandards[multistdid]

                        self.multistandard_standards.add_link(
                            multistd, standard)

        for standard in self.standards.values():
            if not standard.replaces is None:
                if not standard.replaces in self.standards:
                    raise MalformedRepositoryError(
                        "Unknown replace field %s in standard %s" %
                        (standard.replaces, standard.get_id()))
                self.standard_replaced.add_link(
                    standard, self.standards[standard.replaces])
Пример #14
0
class Repository:
    def __init__(self, path):
        #check for conformity
        if not exists(path):
            e = MalformedRepositoryError("Repo directory does not exist")
            e.set_repo_path(path)
            raise e
        if not exists(join(path, "data")):
            e = MalformedRepositoryError("No data directory found")
            e.set_repo_path(path)
            raise e

        self.path = path

        #objects that have an id
        self.classes = {}
        self.collections = {}
        self.names = {}
        self.standards = {}
        self.multinames = {}
        self.multistandards = {}
        self.bodies = {}

        #relations
        self.class_names = Links()
        self.class_standards = Links()
        self.multiname_names = Links()
        self.multistandard_standards = Links()
        self.body_standards = Links()
        self.body_multistandards = Links()
        self.collection_classes = Links()
        self.collection_standards = Links()
        self.collection_multistandards = Links()
        self.collection_names = Links()
        self.collection_multinames = Links()
        self.standard_replaced = Links(1)

        #load collection data
        for filename in os.listdir(join(path, "data")):
            if splitext(filename)[1] != ".blt":
                continue

            raw_coll = list(
                yaml.load_all(open(join(path, "data", filename), "r", "utf8")))
            if len(raw_coll) == 0:
                raise MalformedCollectionError(
                    "No YAML document found in file %s" % filename)
            if len(raw_coll) > 1:
                raise MalformedCollectionError(
                    "More than one YAML document found in file %s" % filename)
            #we only consider the first YAML document
            raw_coll = raw_coll[0]

            if not isinstance(raw_coll["classes"], list):
                raise MalformedCollectionError("No class in collection %s" %
                                               raw_coll["id"])

            if raw_coll["id"] in self.collections:
                raise MalformedCollectionError("Duplicate collection id %s" %
                                               raw_coll["id"])

            if raw_coll["id"] != splitext(filename)[0]:
                raise MalformedCollectionError(
                    "Collection ID is not identical with file name: %s" %
                    filename)
            for c in raw_coll["id"]:
                if not c in string.ascii_letters + string.digits + "_":
                    raise MalformedCollectionError(
                        "Collection ID contains invalid character: %s" % c)

            try:
                coll = Collection(raw_coll)
                self.collections[coll.id] = coll
            except ParsingError as e:
                e.set_repo_path(path)
                e.set_collection(filename)
                raise e

            for cl in raw_coll['classes']:

                if cl["id"] in self.classes:
                    raise MalformedRepositoryError("Duplicate class id %s" %
                                                   cl["id"])

                try:
                    cls = Class(cl)
                    self.classes[cls.id] = cls
                except ParsingError as e:
                    e.set_class(cl["id"])
                    e.set_repo_path(path)
                    e.set_collection(filename)
                    raise e

                self.collection_classes.add_link(coll, cls)

                names = []
                standards = []
                if 'names' in cl:
                    if isinstance(cl['names'], list):
                        names = cl['names']
                    else:
                        names = [cl['names']]
                if 'standards' in cl:
                    if isinstance(cl['standards'], list):
                        standards = cl['standards']
                    else:
                        standards = [cl['standards']]

                if len(names + standards) == 0:
                    raise MalformedCollectionError(
                        "Encountered class with no names: %s" % raw_coll["id"])

                for cn in names:
                    try:
                        name = ClassName(cn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e
                    if name.get_id() in self.names:
                        raise MalformedRepositoryError("Duplicate name %s" %
                                                       name.get_id())

                    self.names[name.get_id()] = name
                    self.class_names.add_link(cls, name)

                    multinameid = name.group.get_safe()
                    if multinameid:
                        if not multinameid in self.multinames:
                            multiname = MultiName(name.group)
                            self.multinames[multinameid] = multiname
                        else:
                            multiname = self.multinames[multinameid]
                        self.collection_multinames.add_link(coll, multiname)
                        self.multiname_names.add_link(multiname, name)
                    else:
                        self.collection_names.add_link(coll, name)

                for sn in standards:
                    try:
                        standard = ClassStandard(sn)
                    except ParsingError as e:
                        e.set_class(cls.id)
                        raise e

                    if standard.get_id() in self.standards:
                        raise MalformedRepositoryError(
                            "Duplicate standard %s" % standard.get_id())

                    self.standards[standard.get_id()] = standard
                    self.class_standards.add_link(cls, standard)

                    bodyid = standard.body
                    if bodyid in self.bodies:
                        body = self.bodies[bodyid]
                    else:
                        body = StandardBody(bodyid)
                        self.bodies[bodyid] = body

                    self.body_standards.add_link(body, standard)
                    self.collection_standards.add_link(coll, standard)

                    multistdid = standard.group.get_safe()
                    if multistdid:
                        if not multistdid in self.multistandards:
                            multistd = MultiStandard(standard.group)
                            self.multistandards[multistdid] = multistd
                            self.body_multistandards.add_link(body, multistd)
                            self.collection_multistandards.add_link(
                                coll, multistd)
                        else:
                            multistd = self.multistandards[multistdid]

                        self.multistandard_standards.add_link(
                            multistd, standard)

        for standard in self.standards.values():
            if not standard.replaces is None:
                if not standard.replaces in self.standards:
                    raise MalformedRepositoryError(
                        "Unknown replace field %s in standard %s" %
                        (standard.replaces, standard.get_id()))
                self.standard_replaced.add_link(
                    standard, self.standards[standard.replaces])

    def iternames(self, items=["name"], **kwargs):
        """
		Iterator over all names of the repo.
		
		Possible items to request: name, multiname, collection, class
		"""
        check_iterator_arguments(items, "name",
                                 ["multiname", "collection", "class"], kwargs)

        for name in self.names.values():
            its = {"name": name}
            its["class"] = self.class_names.get_src(name)
            if self.multiname_names.contains_dst(name):
                its["multiname"] = self.multiname_names.get_src(name)
                its["collection"] = self.collection_multinames.get_src(
                    multiname)
            else:
                its["multiname"] = None
                its["collection"] = self.collection_names.get_src(name)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itermultinames(self, items=["multiname"], **kwargs):
        """
		Iterator over all multinames of the repo.

		Possible items to rerquest: multiname, names, collection
		"""
        check_iterator_arguments(items, "multiname", ["names", "collection"],
                                 kwargs)

        for mname in self.multinames.values():
            its = {"multiname": mname}
            its["names"] = self.multiname_names.get_dsts(mname)
            its["collection"] = self.collection_multinames.get_src(mname)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def iterstandards(self, items=["standard"], **kwargs):
        """
		Iterator over all standards of the repo.
		
		Possible items to request: standard, multistandard, body, collection, class
		"""
        check_iterator_arguments(
            items, "standard",
            ["multistandard", "body", "collection", "class"], kwargs)

        for std in self.standards.values():
            its = {"standard": std}
            its["class"] = self.class_standards.get_src(std)
            its["body"] = self.body_standards.get_src(std)

            if self.multistandard_standards.contains_dst(std):
                its["multistandard"] = self.multistandard_standards.get_src(
                    std)
                its["collection"] = self.collection_multistandards.get_src(
                    its["multistandard"])
            else:
                its["multistandard"] = None
                its["collection"] = self.collection_standards.get_src(std)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itermultistandards(self, items=["multistandard"], **kwargs):
        """
		Iterator over all multistandards of the repo.

		Possible items to rerquest: multistandard, standards, collection, body
		"""
        check_iterator_arguments(items, "multistandard",
                                 ["standards", "collection", "body"], kwargs)

        for mstandard in self.multistandards.values():
            its = {"multistandard": mstandard}
            its["standards"] = self.multistandard_standards.get_dsts(mstandard)
            its["collection"] = self.collection_multistandards.get_src(
                mstandard)
            its["body"] = self.body_multistandards.get_src(mstandard)

            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def iterclasses(self, items=["class"], **kwargs):
        """
		Iterator over all classes of the repo.
		
		Possible items to request: class, collection
		"""
        check_iterator_arguments(items, "class", ["collection"], kwargs)

        for cl in self.classes.values():
            its = {"class": cl}
            its["collection"] = self.collection_classes.get_src(cl)
            if filter_iterator_items(its, kwargs):
                yield tuple(its[key] for key in items)

    def itercollections(self):
        """
		Iterator over all collections of the repo.
		
		Not possible to request items
		"""
        for coll in self.collections.values():
            yield (coll, )

    def iterbodies(self):
        """
		Iterator over all standard bodies of the repo.
		
		Not possible to request items
		"""
        for body in self.bodies.values():
            yield (body, )