Source code for MyCapytain.resources.texts.api

from __future__ import unicode_literals
from six import text_type as str

import MyCapytain.resources.proto.text
import MyCapytain.resources.texts.tei
import MyCapytain.resources.inventory
import MyCapytain.endpoints.proto
import MyCapytain.common.metadata
import MyCapytain.common.utils


[docs]class Text(MyCapytain.resources.proto.text.Text): """ Passage representing object prototype :param urn: A URN identifier :type urn: MyCapytain.common.reference.URN :param resource: An API endpoint :type resource: MyCapytain.endpoints.proto.CTS :param citation: Citation for children level :type citation: MyCapytain.resources.texts.tei.Citation :param id: Identifier of the subreference without URN informations :type id: List """ DEFAULT_LANG = "eng" def __init__(self, urn, resource, citation=None, **kwargs): __doc__ = Text.__doc__ super(Text, self).__init__(urn=urn, citation=citation, **kwargs) self._cRefPattern = None self.resource = resource if citation is not None: self.citation = citation if "metadata" in kwargs and isinstance(kwargs["metadata"], MyCapytain.common.metadata.Metadata): self.metadata = kwargs["metadata"] else: self.metadata = MyCapytain.common.metadata.Metadata([ "groupname", "label", "title" ]) self.passages = []
[docs] def getValidReff(self, level=1, reference=None): """ Given a resource, Text will compute valid reffs :param level: Depth required. If not set, should retrieve first encountered level (1 based) :type level: Int :param reference: Subreference (optional) :type reference: Reference :rtype: List.basestring :returns: List of levels """ if reference: urn = "{0}:{1}".format(self.urn, reference) else: urn = str(self.urn) if level == -1: level = len(self.citation) xml = self.resource.getValidReff( level=level, urn=urn ) xml = MyCapytain.common.utils.xmlparser(xml) self.__parse_request(xml.xpath("//ti:request", namespaces=MyCapytain.common.utils.NS)[0]) for ref in xml.xpath( "//ti:reply//ti:urn/text()", namespaces=MyCapytain.common.utils.NS ): self.passages.append(ref) return self.passages
[docs] def getPassage(self, reference=None): """ Retrieve a passage and store it in the object :param reference: Reference of the passage :type reference: MyCapytain.common.reference.Reference or List of basestring :rtype: Passage :returns: Object representing the passage :raises: *TypeError* when reference is not a list or a Reference """ if reference: urn = "{0}:{1}".format(self.urn, reference) else: urn = str(self.urn) response = MyCapytain.common.utils.xmlparser(self.resource.getPassage(urn=urn)) self.__parse_request(response.xpath("//ti:request", namespaces=MyCapytain.common.utils.NS)[0]) return Passage(urn=urn, resource=response, parent=self)
[docs] def getPassagePlus(self, reference=None): """ Retrieve a passage and informations around it and store it in the object :param reference: Reference of the passage :type reference: MyCapytain.common.reference.Reference or List of basestring :rtype: Passage :returns: Object representing the passage :raises: *TypeError* when reference is not a list or a Reference """ if reference: urn = "{0}:{1}".format(self.urn, reference) else: urn = str(self.urn) response = MyCapytain.common.utils.xmlparser(self.resource.getPassagePlus(urn=urn)) self.__parse_request(response.xpath("//ti:reply/ti:label", namespaces=MyCapytain.common.utils.NS)[0]) return Passage(urn=urn, resource=response, parent=self)
def __parse_request(self, xml): """ :param xml: :return: .. TODO: Finish self.citation parsing """ for node in xml.xpath(".//ti:groupname", namespaces=MyCapytain.common.utils.NS): lang = node.get("xml:lang") or Text.DEFAULT_LANG self.metadata["groupname"][lang] = node.text for node in xml.xpath(".//ti:title", namespaces=MyCapytain.common.utils.NS): lang = node.get("xml:lang") or Text.DEFAULT_LANG self.metadata["title"][lang] = node.text for node in xml.xpath(".//ti:label", namespaces=MyCapytain.common.utils.NS): lang = node.get("xml:lang") or Text.DEFAULT_LANG self.metadata["label"][lang] = node.text # Need to code that p if self.citation is None: self.citation = MyCapytain.resources.inventory.Citation.ingest( xml, xpath=".//ti:citation[not(ancestor::ti:citation)]" )
[docs] def getLabel(self): """ Retrieve metadata about the text :rtype: Metadata :returns: Dictionary with label informations """ response = MyCapytain.common.utils.xmlparser( self.resource.getLabel(urn=str(self.urn)) ) self.__parse_request(response.xpath("//ti:reply/ti:label", namespaces=MyCapytain.common.utils.NS)[0]) return self.metadata
@property def reffs(self): """ Get all valid reffs for every part of the Text :rtype: MyCapytain.resources.texts.tei.Citation """ if self.citation is None: reffs = [self.getValidReff()] return reffs + [ reff for reffs in [self.getValidReff(level=i) for i in range(2, len(self.citation) + 1)] for reff in reffs ] else: return [ reff for reffs in [self.getValidReff(level=i) for i in range(1, len(self.citation) + 1)] for reff in reffs ]
[docs]class Passage(MyCapytain.resources.texts.tei.Passage): def __init__(self, urn, resource, *args, **kwargs): super(Passage, self).__init__(resource=resource, *args, **kwargs) self.urn = urn # Could be set during parsing self._next = None self._prev = None self.__first = None self.__last = None self.__parse() @property def next(self): """ Following passage :rtype: Passage :returns: Following passage at same level """ if self._next is not None: _next = self._next else: # Request the next urn _prev, _next = Passage.prevnext( self.parent.resource.getPrevNextUrn(urn=str(self.urn)) ) self.parent.resource.getPassage(urn=_next) @property def prev(self): """ Previous passage :rtype: Passage :returns: Previous passage at same level """ if self._prev is not None: _prev = self._prev else: # Request the next urn _prev, _next = Passage.prevnext( self.parent.resource.getPrevNextUrn(urn=str(self.urn)) ) return self.parent.resource.getPassage(urn=_prev) def __parse(self): """ Given self.resource, split informations from the CTS API :return: None """ self.resource = self.resource.xpath("//ti:passage/tei:TEI", namespaces=MyCapytain.common.utils.NS)[0] self._prev, self._next = Passage.prevnext(self.resource) @staticmethod
[docs] def prevnext(resource): """ Parse a resource to get the prev and next urn :param resource: XML Resource :type resource: etree._Element :return: Tuple representing previous and next urn :rtype: (str, str) """ _prev, _next = None, None resource = MyCapytain.common.utils.xmlparser(resource) prevnext = resource.xpath("//ti:prevnext", namespaces=MyCapytain.common.utils.NS) if len(prevnext) > 0: prevnext = prevnext[0] _next_xpath = prevnext.xpath("ti:next/ti:urn/text()", namespaces=MyCapytain.common.utils.NS) _prev_xpath = prevnext.xpath("ti:prev/ti:urn/text()", namespaces=MyCapytain.common.utils.NS) if len(_next_xpath): _next = _next_xpath[0] if len(_prev_xpath): _prev = _prev_xpath[0] return _prev, _next