class NemoResource(unittest.TestCase): """ Test Suite for Nemo """ endpoint = HttpCtsResolver(HttpCtsRetriever("http://website.com/cts/api")) body_xsl = "tests/test_data/xsl_test.xml" def setUp(self): with open("tests/test_data/getcapabilities.xml", "r") as f: self.getCapabilities = RequestPatch(f) with open("tests/test_data/getvalidreff.xml", "r") as f: self.getValidReff_single = RequestPatch(f) self.getValidReff = RequestPatchChained( [self.getCapabilities, self.getValidReff_single]) with open("tests/test_data/getpassage.xml", "r") as f: self.getPassage = RequestPatch(f) self.getPassage_Capabilities = RequestPatchChained( [self.getCapabilities, self.getPassage]) with open("tests/test_data/getpassageplus.xml", "r") as f: self.getPassagePlus = RequestPatch(f) with open("tests/test_data/getprevnext.xml", "r") as f: self.getPrevNext = RequestPatch(f) self.getPassage_Route = RequestPatchChained( [self.getCapabilities, self.getPassage, self.getPrevNext]) self.nemo = Nemo(resolver=NemoResource.endpoint, app=Flask(__name__))
def runner(method, address, port, host, css, xslt, groupby, debug): resolver = None app = Flask(__name__) if method == "cts-api": resolver = HttpCtsResolver(HttpCtsRetriever(address)) elif method == "cts-local": resolver = CtsCapitainsLocalResolver([address]) if xslt is not None: xslt = {"default": xslt} # We set up Nemo nemo = Nemo(app=app, name="nemo", base_url="", css=css, transform=xslt, resolver=resolver, chunker={ "default": lambda x, y: level_grouper(x, y, groupby=groupby) }) # We run the app app.debug = debug app.run(port=port, host=host) # For test purposes return nemo, app
def setUp(self): self.resolver = HttpCtsResolver(HttpCtsRetriever("http://localhost")) self.resolver.endpoint.getPassagePlus = MagicMock(return_value=GET_PASSAGE_PLUS) self.resolver.endpoint.getPassage = MagicMock(return_value=GET_PASSAGE) self.resolver.endpoint.getPrevNextUrn = MagicMock(return_value=NEXT_PREV) self.resolver.endpoint.getValidReff = MagicMock(return_value=GET_VALID_REFF) self.resolver.endpoint.getCapabilities = MagicMock(return_value=GET_CAPABILITIES)
def fetch_text_structure(urn, endpoint="http://cts.perseids.org/api/cts"): """ Fetches the text structure of a given work from a CTS endpoint. :param urn: the work's CTS URN (at the work-level!, e.g."urn:cts:greekLit:tlg0012.tlg001") :type urn: string :param endpoint: the URL of the CTS endpoint to use (defaults to Perseids') :type endpoint: string :return: a dict with keys "urn", "provenance", "valid_reffs", "levels" :rtype: dict """ structure = {"urn": urn, "provenance": endpoint, "valid_reffs": {}} orig_edition = None suffix = 'grc' if 'greekLit' in urn else 'lat' resolver = HttpCtsResolver(HttpCtsRetriever(endpoint)) work_metadata = resolver.getMetadata(urn) # among all editions for this work, pick the one in Greek or Latin try: orig_edition = next( iter(work_metadata.children[edition] for edition in work_metadata.children if suffix in str(work_metadata.children[edition].urn))) except Exception as e: print(e) return None assert orig_edition is not None # get information about the work's citation scheme structure["levels"] = [(n + 1, level.name.lower()) for n, level in enumerate(orig_edition.citation)] # for each hierarchical level of the text # fetch all citable text elements for level_n, level_label in structure["levels"]: structure["valid_reffs"][level_n] = [] for ref in resolver.getReffs(urn, level=level_n): print(ref) element = { "current": "{}:{}".format(urn, ref), } if "." in ref: element["parent"] = "{}:{}".format( urn, ".".join(ref.split(".")[:level_n - 1])) textual_node = resolver.getTextualNode(textId=urn, subreference=ref, prevnext=True) if textual_node.nextId is not None: element["previous"] = "{}:{}".format(urn, textual_node.nextId) if textual_node.prevId is not None: element["following"] = "{}:{}".format(urn, textual_node.prevId) structure["valid_reffs"][level_n].append(element) return structure
def test_get_reffs_contextual(self): """ Ensure getReffs works with context """ endpoint = HttpCtsRetriever(self.url) endpoint.getValidReff = mock.MagicMock(return_value=GET_VALID_REFF) text = CtsText("urn:cts:latinLit:phi1294.phi002.perseus-lat2", retriever=endpoint) passage = CtsPassage( urn="urn:cts:latinLit:phi1294.phi002.perseus-lat2:1", resource=GET_PASSAGE, retriever=endpoint) passage.getReffs() endpoint.getValidReff.assert_called_with( urn="urn:cts:latinLit:phi1294.phi002.perseus-lat2:1", level=2)
def setUp(self): a = Citation(name="line") b = Citation(name="poem", child=a) self.citation = Citation(name="book", child=b) self.url = "http://services.perseids.org/remote/cts" self.endpoint = HttpCtsRetriever(self.url) self.endpoint.getPassage = mock.MagicMock(return_value=GET_PASSAGE) self.endpoint.getPrevNextUrn = mock.MagicMock(return_value=NEXT_PREV) self.endpoint.getValidReff = mock.MagicMock( return_value=GET_VALID_REFF) self.endpoint.getFirstUrn = mock.MagicMock(return_value=Get_FIRST) self.text = CtsText("urn:cts:latinLit:phi1294.phi002.perseus-lat2", self.endpoint, citation=self.citation)
def test_citation_failure(self): """ Example for Resolver failed : some response have an issue with not available Citations ? """ retriever = HttpCtsRetriever("http://cts.dh.uni-leipzig.de/remote/cts/") retriever.getPassage = MagicMock(return_value=GET_PASSAGE_CITATION_FAILURE) resolver = HttpCtsResolver(retriever) # We require a passage : passage is now a CapitainsCtsPassage object passage = resolver.getTextualNode("urn:cts:latinLit:phi1294.phi002.perseus-lat2", "1.1") # We need an export as plaintext self.assertEqual( passage.export(output=Mimetypes.PLAINTEXT), "I Hic est quem legis ille, quem requiris, Toto notus in orbe Martialis Argutis epigrammaton libellis: \n"\ " Cui, lector studiose, quod dedisti Viventi decus atque sentienti, Rari post cineres habent poetae. ", "Parsing should be successful" )
def test_first_urn_whenreference(self): endpoint = HttpCtsRetriever(self.url) endpoint.getFirstUrn = mock.MagicMock(return_value=Get_FIRST) text = CtsText("urn:cts:latinLit:phi1294.phi002.perseus-lat2", retriever=endpoint) passage = CtsPassage( urn="urn:cts:latinLit:phi1294.phi002.perseus-lat2:1", resource=GET_PASSAGE, retriever=endpoint) first = passage.getFirstUrn("1.1") endpoint.getFirstUrn.assert_called_with( "urn:cts:latinLit:phi1294.phi002.perseus-lat2:1.1") self.assertEqual( first, "1.pr", "Parsing should be done and getFirstUrn should treat correctly full urn" )
def setUp(self): a = Citation( name="line", refsDecl="/tei:TEI/tei:text/tei:body/tei:div/tei:div[@n='$1' and @type='section']/tei:div[@n='$2']/tei:l[@n='$3']" ) b = Citation( name="poem", child=a, refsDecl="/tei:TEI/tei:text/tei:body/tei:div/tei:div[@n='$1' and @type='section']/tei:div[@n='$2']" ) self.citation = Citation( name="book", child=b, refsDecl="/tei:TEI/tei:text/tei:body/tei:div/tei:div[@n='$1' and @type='section']" ) self.endpoint = HttpCtsRetriever("http://services.perseids.org/remote/cts")
def test_first_urn_when_empty(self): endpoint = HttpCtsRetriever(self.url) endpoint.getFirstUrn = mock.MagicMock(return_value=Get_FIRST_EMPTY) text = CtsText("urn:cts:latinLit:phi1294.phi002.perseus-lat2", retriever=endpoint) passage = CtsPassage( urn="urn:cts:latinLit:phi1294.phi002.perseus-lat2:1", resource=GET_PASSAGE, retriever=endpoint) first = passage.firstId endpoint.getFirstUrn.assert_called_with( "urn:cts:latinLit:phi1294.phi002.perseus-lat2:1") self.assertEqual( first, None, "Endpoint should be called and none should be returned if there is none" )
def setUp(self): nautilus_cache = RedisCache() app = Flask("Nautilus") self.cache = Cache(config={'CACHE_TYPE': 'simple'}) self.nautilus = FlaskNautilus( app=app, resolver=NautilusCTSResolver(["./tests/test_data/latinLit"]), flask_caching=self.cache, logger=logger ) app.debug = True self.cache.init_app(app) self.app = app.test_client() self.parent = HttpCtsRetriever("/cts") self.resolver = HttpCtsResolver(endpoint=self.parent) logassert.setup(self, self.nautilus.logger.name) self.nautilus.logger.disabled = True def call(this, parameters={}): """ Call an endpoint given the parameters :param parameters: Dictionary of parameters :type parameters: dict :rtype: text """ parameters = { key: str(parameters[key]) for key in parameters if parameters[key] is not None } if this.inventory is not None and "inv" not in parameters: parameters["inv"] = this.inventory request = self.app.get("/cts?{}".format( "&".join( ["{}={}".format(key, value) for key, value in parameters.items()]) ) ) self.parent.called.append(parameters) return request.data.decode() self.parent.called = [] self.parent.call = lambda x: call(self.parent, x)
from MyCapytain.retrievers.cts5 import HttpCtsRetriever # We set up a retriever which communicates with an API available in Leipzig retriever = HttpCtsRetriever("http://cts.dh.uni-leipzig.de/api/cts") # We require a passage : passage is now a Passage object passage = retriever.getPassage( "urn:cts:latinLit:phi1294.phi002.perseus-lat2:1.1") # Passage is now equal to the string content of http://cts.dh.uni-leipzig.de/api/cts/?request=GetPassage&urn=urn:cts:latinLit:phi1294.phi002.perseus-lat2:1.1 print(passage) """ <GetPassage><request><requestName>GetPassage</requestName><requestUrn>urn:cts:latinLit:phi1294.phi002.perseus-lat2:1.1</requestUrn></request> <reply><urn>urn:cts:latinLit:phi1294.phi002.perseus-lat2:1.1</urn><passage><TEI> <text n="urn:cts:latinLit:phi1294.phi002.perseus-lat2" xml:id="stoa0045.stoa0"><body> <div type="edition" n="urn:cts:latinLit:phi1294.phi002.perseus-lat2" xml:lang="lat"> <div type="textpart" subtype="book" n="1"><div type="textpart" subtype="poem" n="1"> <head>I</head> <l n="1">Hic est quem legis ille, quem requiris, </l> <l n="2">Toto notus in orbe Martialis </l> <l n="3">Argutis epigrammaton libellis: <pb/></l> <l n="4">Cui, lector studiose, quod dedisti </l> <l n="5">Viventi decus atque sentienti, </l> <l n="6">Rari post cineres habent poetae. </l> </div></div></div></body></text></TEI></passage></reply> """
def api_resolver(endpoint) -> Resolver: return HttpCtsResolver(HttpCtsRetriever(endpoint))
help='remote CTS server') parser.add_argument('--index', metavar="FILE", default=Config.INDEX, help='corpus index file') parser.add_argument('--corpus', metavar="DIR", default=Config.DATA, help='local corpus directory') args = parser.parse_args() # clean destination directory dest = os.path.join(args.corpus, 'xml') if os.path.exists(dest): shutil.rmtree(dest) os.makedirs(dest) else: os.makedirs(dest) # Read the corpus metadata with open(args.index) as f: corpus = [Text.metaFromDict(rec) for rec in json.load(f)] # Create a Resolver instance resolver = HttpCtsResolver(HttpCtsRetriever(args.server)) for text in corpus: retrieveXML(resolver, text, os.path.join(dest, text.author)) print()