Source code for MyCapytain.resources.proto.inventory

# -*- coding: utf-8 -*-
"""
.. module:: MyCapytain.resources.proto.inventory
   :synopsis: Prototypes for repository/inventory

.. moduleauthor:: Thibault Clérice <leponteineptique@gmail.com>


"""

from MyCapytain.common.reference import URN, Reference, Citation
from MyCapytain.common.metadata import Metadata
from past.builtins import basestring
from collections import defaultdict
from copy import copy
from lxml import etree
from six import text_type as str


[docs]class Resource(object): """ Resource represents any resource from the inventory """ def __init__(self, resource=None): """ Initiate a TextInventory resource :param resource: Resource representing the TextInventory :type resource: Any """ self.metadata = Metadata() self.resource = None if resource is not None: self.setResource(resource) def __getitem__(self, key): """ Direct key access function for Text objects """ if key == 0: return self elif isinstance(key, int) and 1 <= key <= len(self.parents): r = self.parents[key - 1] if isinstance(r, (list, tuple)): return r[0] else: return r elif isinstance(key, basestring): return self.__urnitem__(key) else: None def __eq__(self, other): if self is other: return True elif not isinstance(other, self.__class__): return False elif self.resource is None: # Not totally true return hasattr(self, "urn") and hasattr(other, "urn") and self.urn == other.urn return hasattr(self, "urn") and hasattr(other, "urn") and self.urn == other.urn and self.resource == other.resource def __str__(self): raise NotImplementedError()
[docs] def export(self, format=None): raise NotImplementedError()
def __urnitem__(self, key): urn = URN(key) if len(urn) <= 2: raise ValueError("Not valid urn") elif hasattr(self, "urn") and self.urn == urn: return self else: if hasattr(self, "urn"): i = len(self.urn) else: i = 2 if isinstance(self, TextInventory): children = self.textgroups elif isinstance(self, TextGroup): children = self.works elif isinstance(self, Work): children = self.texts order = ["", "", URN.TEXTGROUP, URN.WORK, URN.VERSION] while i <= len(urn) - 1: children = children[urn.upTo(order[i])] if not hasattr(children, "urn") or str(children.urn) != urn.upTo(order[i]): error = "Unrecognized urn at " + [ "URN namespace", "CTS Namespace", "URN Textgroup", "URN Work", "URN Version" ][i] raise ValueError(error) i += 1 return children
[docs] def setResource(self, resource): """ Set the object property resource :param resource: Resource representing the TextInventory :type resource: Any :rtype: Any :returns: Input resource """ self.resource = resource self.parse(resource) return self.resource
[docs] def parse(self, resource): """ Parse the object resource :param resource: Resource representing the TextInventory :type resource: Any :rtype: List """ raise NotImplementedError()
def __getstate__(self, children=True): """ Pickling method to be called upon dumping object :return: """ dic = copy(self.__dict__) if "xml" in dic: dic["xml"] = etree.tostring(dic["xml"], encoding=str) if "resource" in dic: del dic["resource"] """ The resource is unecessary in later than parsing state if "resource" in dic: dic["resource"] = str(dic["resource"]) """ return dic def __setstate__(self, dic): """ :param dic: :return: """ self.__dict__ = dic if "xml" in dic: self.xml = etree.fromstring(dic["xml"]) return self
[docs]class Text(Resource): """ Represents a CTS Text """ def __init__(self, resource=None, urn=None, parents=None, subtype="Edition"): """ Initiate a Work resource :param resource: Resource representing the TextInventory :type resource: Any :param urn: Identifier of the Text :type urn: str """ self.citation = None self.lang = None self.urn = None self.docname = None self.parents = list() self.subtype = subtype self.validate = None self.metadata = Metadata(keys=["label", "description", "namespaceMapping"]) if urn is not None: self.urn = URN(urn) if parents is not None: self.parents = parents self.lang = self.parents[0].lang if resource is not None: self.setResource(resource)
[docs] def translations(self, key=None): """ Get translations in given language :param key: Language ISO Code to filter on :return: """ return self.parents[0].getLang(key)
[docs] def editions(self): """ Get all editions of the texts :return: List of editions :rtype: [Text] """ return [ self.parents[0].texts[urn] for urn in self.parents[0].texts if self.parents[0].texts[urn].subtype == "Edition" ]
[docs]def Edition(resource=None, urn=None, parents=None): return Text(resource=resource, urn=urn, parents=parents, subtype="Edition")
[docs]def Translation(resource=None, urn=None, parents=None): return Text(resource=resource, urn=urn, parents=parents, subtype="Translation")
[docs]class Work(Resource): """ Represents a CTS Work """ def __init__(self, resource=None, urn=None, parents=None): """ Initiate a Work resource :param resource: Resource representing the TextInventory :type resource: Any :param urn: Identifier of the Work :type urn: str :param parents: List of parents for current object :type parents: Tuple.<TextInventory> """ self.lang = None self.urn = None self.texts = defaultdict(Text) self.parents = list() self.metadata = Metadata(keys=["title"]) if urn is not None: self.urn = URN(urn) if parents is not None: self.parents = parents if resource is not None: self.setResource(resource)
[docs] def getLang(self, key=None): """ Find a translation with given language :param key: Language to find :type key: basestring :rtype: [Text] :returns: List of availables translations """ if key is not None: return [self.texts[urn] for urn in self.texts if self.texts[urn].subtype == "Translation" and self.texts[urn].lang == key] else: return [self.texts[urn] for urn in self.texts if self.texts[urn].subtype == "Translation"]
[docs]class TextGroup(Resource): """ Represents a CTS Textgroup """ def __init__(self, resource=None, urn=None, parents=None): """ Initiate a TextGroup resource :param resource: Resource representing the TextInventory :type resource: Any :param urn: Identifier of the TextGroup :type urn: str :param parents: List of parents for current object :type parents: Tuple.<TextInventory> """ self.urn = None self.works = defaultdict(Work) self.parents = list() self.metadata = Metadata(keys=["groupname"]) if urn is not None: self.urn = URN(urn) if parents: self.parents = parents if resource is not None: self.setResource(resource)
[docs]class TextInventory(Resource): """ Represents a CTS Inventory file """ def __init__(self, resource=None, id=None): """ Initiate a TextInventory resource :param resource: Resource representing the TextInventory :type resource: Any :param id: Identifier of the TextInventory :type id: str """ self.textgroups = defaultdict(TextGroup) self.id = id self.parents = list() if resource is not None: self.setResource(resource) def __len__(self): """ :return: Number of texts available in the inventory """ return len([ text for tg in self.textgroups.values() for work in tg.works.values() for text in work.texts.values() ])