Web-LangTag/search.py

136 lines
5.9 KiB
Python
Executable File

#!/usr/bin/env python3
# You can test it with:
# curl --request POST --data string=foobar\&what=language http://localhost:4000
import urllib.parse
# PostgreSQL interface
import psycopg2
# HTML templates http://www.yattag.org/
from yattag import Doc
# TODO include the standard elements such as CSS and footer
# For testing only:
import wsgiref.simple_server
REDIRECTION_URL = "https://www.langtag.net/registries/registry-html" # For
# local testing: Firefox apparently does not accept a redirect to a
# file.
def pack(start_response, status, title, body, headers = []):
doc, tag, text = Doc().tagtext()
doc.asis("<?xml version=\"1.0\" ?>\n")
doc.asis("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">")
with tag("html", ("xml:lang", "en"), lang = "en", xmlns = "http://www.w3.org/1999/xhtml"):
with tag("head"):
with tag("title"):
text(title)
with tag("body"):
doc.asis(body.getvalue())
data = doc.getvalue()
datae = data.encode()
response_headers = [("Content-type", "text/html; charset=UTF-8"),
("Content-Length", str(len(datae)))]
if headers != []:
for header in headers:
response_headers.append(header)
start_response(status, response_headers)
return [datae]
def application(environ, start_response):
if environ["REQUEST_METHOD"] != "POST":
status = "405 Method unavailable"
msg = "Unsupported HTTP method \"%s\"\r\n" % environ["REQUEST_METHOD"]
doc, tag, text = Doc().tagtext()
with tag("p"):
text(msg)
return pack(start_response, status, msg, doc)
try:
body_size = int(environ.get("CONTENT_LENGTH", 0))
except (ValueError):
body_size = 0
body = environ["wsgi.input"].read(body_size)
query = urllib.parse.parse_qsl(body.decode())
form = {}
headers = []
for q in query:
form[q[0]] = q[1]
for mandatory in ["string", "what"]:
if mandatory not in form:
status = "400 Invalid request"
msg = "Missing \"%s\" in request\r\n" % mandatory
doc, tag, text = Doc().tagtext()
with tag("p"):
text(msg)
return pack(start_response, status, msg, doc)
if form["what"] == "language":
sql = "SELECT code,suppressscript,preferredvalue,added,comments FROM Languages WHERE code = %s"
term = form["string"].lower()
elif form["what"] == "script":
sql = "SELECT code,added,comments FROM Scripts WHERE code = %s"
term = form["string"].capitalize()
elif form["what"] == "region":
sql = "SELECT code,added,comments FROM Regions WHERE code = %s"
term = form["string"].upper()
elif form["what"] == "variant":
sql = "SELECT code,added,comments FROM Variants WHERE code = %s"
term = form["string"].lower()
else:
status = "400 Invalid request"
msg = "Unknown search category \"%s\"\r\n" % form["what"]
doc, tag, text = Doc().tagtext()
with tag("p"):
text(msg)
return pack(start_response, status, msg, doc)
cursor.execute(sql, (term, ))
mytuple = cursor.fetchone()
status = "200 OK"
doc, tag, text = Doc().tagtext()
title = "Result for %s" % term
if mytuple is not None:
status = "307 Redirect"
url = "%s/%s/%s.html" % (REDIRECTION_URL, form["what"], mytuple[0])
headers.append(("Location", url))
msg = "Redirect to %s\r\n" % (url)
with tag("p"):
text("Redirect to ")
with tag("a", href = url):
text(url)
text("\r\n")
else:
if form["what"] == "language":
sql = "SELECT Languages.code, Descriptions.description FROM Languages,Descriptions_Languages,Descriptions WHERE Descriptions_Languages.description = Descriptions.id AND Descriptions_Languages.lang = Languages.code AND position(%s in lower(Descriptions.description)) > 0;"
elif form["what"] == "script":
sql = "SELECT Scripts.code, Descriptions.description FROM Scripts,Descriptions_Scripts,Descriptions WHERE Descriptions_Scripts.description = Descriptions.id AND Descriptions_Scripts.script = Scripts.code AND position(%s in lower(Descriptions.description)) > 0;"
elif form["what"] == "region":
sql = "SELECT Regions.code, Descriptions.description FROM Regions,Descriptions_Regions,Descriptions WHERE Descriptions_Regions.description = Descriptions.id AND Descriptions_Regions.region = Regions.code AND position(%s in lower(Descriptions.description)) > 0;"
elif form["what"] == "variant":
sql = "SELECT Variants.code, Descriptions.description FROM Variants,Descriptions_Variants,Descriptions WHERE Descriptions_Variants.description = Descriptions.id AND Descriptions_Variants.variant = Variants.code AND position(%s in lower(Descriptions.description)) > 0;"
cursor.execute(sql, (form["string"].lower(), ))
found = False
with tag("h1"):
text("Results for %s" % form["string"])
with tag("p"):
with tag("ul"):
for tuple in cursor.fetchall():
code = tuple[0]
description = tuple[1]
with tag("li"):
with tag("a", href = "%s/%s/%s.html" % (REDIRECTION_URL, form["what"], code)):
text("%s: %s\r\n" % (code, description))
found = True
if not found:
with tag("li"):
text("\"%s\" not found\r\n" % term)
return pack(start_response, status, title, doc, headers)
# Initialize
conn = psycopg2.connect("dbname=lsr")
cursor = conn.cursor()
if __name__ == "__main__":
httpd = wsgiref.simple_server.make_server("", 4000, application)
httpd.serve_forever()