se implementa un esquema para modelar el xml
FossilOrigin-Name: e4de658f60fe8fcbb330923e14958a5d8f8e0e6395db4f992ec7da45062fa193
This commit is contained in:
		
							
								
								
									
										62
									
								
								facho/model/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								facho/model/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
|  | ||||
| class ModelMeta(type): | ||||
|     def __new__(cls, name, bases, ns): | ||||
|         new = type.__new__(cls, name, bases, ns) | ||||
|         if '__name__' in ns: | ||||
|             new.__name__ = ns['__name__'] | ||||
|         if '__namespace__' in ns: | ||||
|             new.__namespace__ = ns['__namespace__'] | ||||
|         else: | ||||
|             new.__namespace__ = {} | ||||
|              | ||||
|         return new | ||||
|  | ||||
| class ModelBase(object, metaclass=ModelMeta): | ||||
|  | ||||
|     def __new__(cls, *args, **kwargs): | ||||
|         obj = super().__new__(cls, *args, **kwargs) | ||||
|         obj._xml_attributes = {} | ||||
|         obj._fields = {} | ||||
|         obj._text = "" | ||||
|         obj._namespace_prefix = None | ||||
|          | ||||
|         return obj | ||||
|  | ||||
|     def __setitem__(self, key, val): | ||||
|         self._xml_attributes[key] = val | ||||
|  | ||||
|     def __getitem__(self, key): | ||||
|         return self._xml_attributes[key] | ||||
|  | ||||
|     def to_xml(self): | ||||
|         tag = self.__name__ | ||||
|         ns = '' | ||||
|         if self._namespace_prefix is not None: | ||||
|             ns = "%s:" % (self._namespace_prefix) | ||||
|  | ||||
|         pair_attributes = ["%s=\"%s\"" % (k, v) for (k, v) in self._xml_attributes.values()] | ||||
|  | ||||
|         for (prefix, url) in self.__namespace__.items(): | ||||
|             pair_attributes.append("xmlns:%s=\"%s\"" % (prefix, url)) | ||||
|         attributes = "" | ||||
|         if pair_attributes: | ||||
|             attributes = " " + " ".join(pair_attributes) | ||||
|  | ||||
|         content = "" | ||||
|  | ||||
|         for name, value in self._fields.items(): | ||||
|             if hasattr(value, 'to_xml'): | ||||
|                 print(self._fields) | ||||
|                 content += value.to_xml() | ||||
|             elif isinstance(value, str): | ||||
|                 content += value | ||||
|         content += self._text | ||||
|  | ||||
|         if content == "": | ||||
|             return "<%s%s%s/>" % (ns, tag, attributes) | ||||
|         else: | ||||
|             return "<%s%s%s>%s</%s%s>" % (ns, tag, attributes, content, ns, tag) | ||||
|  | ||||
| class Model(ModelBase): | ||||
|     pass | ||||
|          | ||||
							
								
								
									
										5
									
								
								facho/model/fields/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								facho/model/fields/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| from .attribute import Attribute | ||||
| from .many2one import Many2One | ||||
| from .model import Model | ||||
|  | ||||
| __all__ = [Attribute, Many2One, Model] | ||||
							
								
								
									
										17
									
								
								facho/model/fields/attribute.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								facho/model/fields/attribute.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| from .field import Field | ||||
|  | ||||
| class Attribute(Field): | ||||
|     def __init__(self, tag): | ||||
|         self.tag = tag | ||||
|    | ||||
|     def __get__(self, inst, cls): | ||||
|         if inst is None: | ||||
|             return self | ||||
|  | ||||
|         assert self.name is not None | ||||
|         (tag, value) =  inst._xml_attributes[self.name] | ||||
|         return value | ||||
|  | ||||
|     def __set__(self, inst, value): | ||||
|         assert self.name is not None | ||||
|         inst._xml_attributes[self.name] = (self.tag, value) | ||||
							
								
								
									
										21
									
								
								facho/model/fields/field.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								facho/model/fields/field.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| class Field: | ||||
|     def __set_name__(self, owner, name): | ||||
|         self.name = name | ||||
|  | ||||
|     def __get__(self, inst, cls): | ||||
|         if inst is None: | ||||
|             return self | ||||
|         assert self.name is not None | ||||
|         return inst._fields[self.name] | ||||
|  | ||||
|     def __set__(self, inst, value): | ||||
|         assert self.name is not None | ||||
|         inst._fields[self.name] = value | ||||
|  | ||||
|     def _set_namespace(self, inst, name, namespaces): | ||||
|         if name is None: | ||||
|             return | ||||
|  | ||||
|         if name not in namespaces: | ||||
|             raise KeyError("namespace %s not found" % (name)) | ||||
|         inst._namespace_prefix = name | ||||
							
								
								
									
										35
									
								
								facho/model/fields/many2one.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								facho/model/fields/many2one.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| from .field import Field | ||||
|  | ||||
| class Many2One(Field): | ||||
|     def __init__(self, model, setter=None, namespace=None): | ||||
|         self.model = model | ||||
|         self.setter = setter | ||||
|         self.namespace = namespace | ||||
|  | ||||
|     def __set_name__(self, owner, name): | ||||
|         self.name = name | ||||
|  | ||||
|     def __get__(self, inst, cls): | ||||
|         if inst is None: | ||||
|             return self | ||||
|         assert self.name is not None | ||||
|         return inst._fields[self.name] | ||||
|          | ||||
|     def __set__(self, inst, value): | ||||
|         assert self.name is not None | ||||
|         class_model = self.model | ||||
|         inst_model = class_model() | ||||
|  | ||||
|         self._set_namespace(inst_model, self.namespace,  inst.__namespace__) | ||||
|         inst._fields[self.name] = inst_model | ||||
|  | ||||
|         # si hay setter manual se ejecuta | ||||
|         # de lo contrario se asigna como texto del elemento | ||||
|         setter = getattr(inst, self.setter or '', None) | ||||
|         if callable(setter): | ||||
|             setter(inst_model, value) | ||||
|         else: | ||||
|             inst_model._text = str(value) | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										26
									
								
								facho/model/fields/model.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								facho/model/fields/model.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| from .field import Field | ||||
|  | ||||
| class Model(Field): | ||||
|     def __init__(self, model, namespace=None): | ||||
|         self.model = model | ||||
|         self.namespace = namespace | ||||
|  | ||||
|     def __get__(self, inst, cls): | ||||
|         if inst is None: | ||||
|             return self | ||||
|         assert self.name is not None | ||||
|         return self._create_model(inst) | ||||
|  | ||||
|     def __set__(self, inst, value): | ||||
|         obj = self._create_model(inst) | ||||
|         obj._text = str(value) | ||||
|  | ||||
|     def _create_model(self, inst): | ||||
|         try: | ||||
|             return inst._fields[self.name] | ||||
|         except KeyError: | ||||
|             obj = self.model() | ||||
|             self._set_namespace(obj, self.namespace, inst.__namespace__) | ||||
|             inst._fields[self.name] = obj | ||||
|             return obj | ||||
|              | ||||
		Reference in New Issue
	
	Block a user