Parcourir la source

add endpoint to generate prayer from query parameters

Daniel Sheffield il y a 1 an
Parent
commit
daff6140e6
3 fichiers modifiés avec 122 ajouts et 14 suppressions
  1. 1 1
      create-views.sql
  2. 113 7
      rest/pyapi.py
  3. 8 6
      xml/pg_view_style.xsl

+ 1 - 1
create-views.sql

@@ -45,7 +45,7 @@ FOR r IN
   SELECT tableid, c.name, p.translation AS translation, p.reference AS reference FROM pg_categories AS c JOIN UNNEST(p_name, p_translation, p_reference) AS p(name, translation, reference) ON c.name = p.name
 LOOP
   SELECT t.translation, t.text INTO translation, txt FROM getfallbacktext(r.translation, getdefaulttranslation(), r.reference) AS t;
-  RETURN QUERY SELECT r.tableid, r.name, translation, reference, txt;
+  RETURN QUERY SELECT r.tableid, r.name, translation, normalizeverse(r.reference::character varying)::text, txt;
 END LOOP;
 RETURN;
 END

+ 113 - 7
rest/pyapi.py

@@ -1,28 +1,134 @@
 # Copyright (c) Daniel Sheffield 2022
 # All rights reserved.
-from bottle import route, run, template, response
+from bottle import route, request, run, template, response, abort
 import psycopg
-from psycopg import Cursor
+from psycopg import Cursor, sql
 import os
 user = os.getenv('USER')
 password = os.getenv('PASSWORD')
 host = 'host=localhost'
 conn: Cursor = psycopg.connect(f"{host} dbname=pgdb user={user} {password}")
-statement = """SELECT
-  table_to_xml_and_xmlschema('pg_random_view_default_if_null'::regclass,
+random_statement = """SELECT
+  query_to_xml('SELECT category, translation, reference, txt
+    FROM pg_random_view_default_if_null
+    JOIN pg_categories ON category = name
+    ORDER BY tableid ASC',
   false, false, ''::text);"""
+specified_statement = sql.SQL("""SELECT query_to_xml($$SELECT category, translation, reference, txt
+  FROM getprayer(
+    {categories}::text[],
+    {translations}::text[],
+    {references}::text[]
+  ) ORDER BY ordinal ASC$$, false, false, ''::text);""")
 heading = """<?xml version="1.0" encoding="UTF-8"?>
 <?xml-stylesheet type="text/xsl" href="https://shandan.one/xml/pg_view_style.xsl"?>
 """
+random_schema = """
+<xsd:schema
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:simpleType name="UDT.pgdb.pg_catalog.text">
+  <xsd:restriction base="xsd:string">
+  </xsd:restriction>
+</xsd:simpleType>
+
+<xsd:simpleType name="VARCHAR">
+  <xsd:restriction base="xsd:string">
+  </xsd:restriction>
+</xsd:simpleType>
+
+<xsd:complexType name="RowType.pgdb.public.pg_random_view_default_if_null">
+  <xsd:sequence>
+    <xsd:element name="category" type="UDT.pgdb.pg_catalog.text" minOccurs="0"></xsd:element>
+    <xsd:element name="translation" type="VARCHAR" minOccurs="0"></xsd:element>
+    <xsd:element name="reference" type="UDT.pgdb.pg_catalog.text" minOccurs="0"></xsd:element>
+    <xsd:element name="txt" type="VARCHAR" minOccurs="0"></xsd:element>
+  </xsd:sequence>
+</xsd:complexType>
+
+<xsd:complexType name="TableType.pgdb.public.pg_random_view_default_if_null">
+  <xsd:sequence>
+    <xsd:element name="row" type="RowType.pgdb.public.pg_random_view_default_if_null" minOccurs="0" maxOccurs="unbounded"/>
+  </xsd:sequence>
+</xsd:complexType>
+
+<xsd:element name="table" type="TableType.pgdb.public.pg_random_view_default_if_null"/>
+
+</xsd:schema>
+"""
+specified_heading = heading + """
+<xsd:element name="table" type="TableType.pgdb.public.pg_view"/>
+
+</xsd:schema>
+"""
+specified_schema = """
+<xsd:schema
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+<xsd:simpleType name="UDT.pgdb.pg_catalog.text">
+  <xsd:restriction base="xsd:string">
+  </xsd:restriction>
+</xsd:simpleType>
+
+<xsd:simpleType name="VARCHAR">
+  <xsd:restriction base="xsd:string">
+  </xsd:restriction>
+</xsd:simpleType>
+
+<xsd:complexType name="RowType.pgdb.public.pg_view">
+  <xsd:sequence>
+    <xsd:element name="category" type="UDT.pgdb.pg_catalog.text" minOccurs="0"></xsd:element>
+    <xsd:element name="translation" type="VARCHAR" minOccurs="0"></xsd:element>
+    <xsd:element name="reference" type="UDT.pgdb.pg_catalog.text" minOccurs="0"></xsd:element>
+    <xsd:element name="txt" type="VARCHAR" minOccurs="0"></xsd:element>
+  </xsd:sequence>
+</xsd:complexType>
+
+<xsd:complexType name="TableType.pgdb.public.pg_view">
+  <xsd:sequence>
+    <xsd:element name="row" type="RowType.pgdb.public.pg_view" minOccurs="0" maxOccurs="unbounded"/>
+  </xsd:sequence>
+</xsd:complexType>
+
+<xsd:element name="table" type="TableType.pgdb.public.pg_view"/>
+
+</xsd:schema>
+"""
 
 @route('/pyapi/random')
-def index():
+def random():
+    try:
+        with conn.cursor() as cur:
+            xml = cur.execute(random_statement).fetchone()[0].splitlines()
+    finally:
+        conn.commit()
+    response.content_type = 'application/xhtml+xml; charset=utf-8'
+    return f"{heading}{xml[0]}{random_schema}" + '\n'.join(xml[1:])
+
+@route('/pyapi/pg')
+def specified():
+    kingdom = { 'a_kingdom', 'z_kingdom' }
+    categories = [ k for k in request.query.keys() ]
+    translations = []
+    references = []
+    for c in categories:
+        r, t = request.query[c].split(' ',1)
+        references.append(r)
+        translations.append(t)
+
+    if len(kingdom - set(categories)) not in (0, 2,):
+        raise abort(400, f"Both of {kingdom} must be specified or neither specified. Missing: {kingdom - set(categories)}")
+
     try:
         with conn.cursor() as cur:
-            xml = cur.execute(statement).fetchone()[0]
+            xml = cur.execute(specified_statement.format(
+                categories=sql.Literal(categories),
+                translations=sql.Literal(translations),
+                references=sql.Literal(references)
+            )).fetchone()[0].splitlines()
     finally:
         conn.commit()
     response.content_type = 'application/xhtml+xml; charset=utf-8'
-    return f"{heading}{xml}"
+    return f"{heading}{xml[0]}{specified_schema}" + '\n'.join(xml[1:])
 
 run(host='192.168.0.20', port=11888)

+ 8 - 6
xml/pg_view_style.xsl

@@ -25,11 +25,14 @@ All rights reserved.
       <head>
         <title>
         <xsl:choose>
-          <xsl:when test="name(current()) = 'pg_random_view_default_if_null'">
+          <xsl:when test="$tabletypename = 'TableType.pgdb.public.pg_random_view_default_if_null'">
           Random Prayer Generator
           </xsl:when>
+          <xsl:when test="$tabletypename = 'TableType.pgdb.public.pg_view'">
+          Prayer Generator
+          </xsl:when>
           <xsl:otherwise>
-          <xsl:value-of select="name(current())"/>
+          <xsl:value-of select="$tabletypename"/>
           </xsl:otherwise>
         </xsl:choose>
         </title>
@@ -37,11 +40,10 @@ All rights reserved.
         <xsl:attribute name="name">title</xsl:attribute>
         <xsl:attribute name="content">
         <xsl:choose>
-          <xsl:when test="name(current()) = 'pg_random_view_default_if_null'">
-          Random Prayer Generator
-          </xsl:when>
+          <xsl:when test="$tabletypename = 'TableType.pgdb.public.pg_random_view_default_if_null'">Random Prayer Generator</xsl:when>
+          <xsl:when test="$tabletypename = 'TableType.pgdb.public.pg_view'">Prayer Generator</xsl:when>
           <xsl:otherwise>
-          <xsl:value-of select="name(current())"/>
+          <xsl:value-of select="$tabletypename"/>
           </xsl:otherwise>
         </xsl:choose>
         </xsl:attribute>