#!/usr/bin/env python3

from bottle import route, run, Bottle, get, post, request, response, static_file, url
from urllib.parse import quote
import os.path
from elasticsearch import Elasticsearch
from elasticsearch.exceptions import NotFoundError
import yaml
import sys
import json
from rdflib import Graph, plugin
import mimerender
import cgi

mimerender.register_mime("turtle", ("text/turtle","text/n3"))
mimerender.register_mime("rdfxml", ("application/rdf+xml", "application/xml"))
mimerender.register_mime("nt", ("application/n-triples",))
#mimerender.register_mime("jsonld", ("application/ld+json",))
produces = mimerender.BottleMimeRender()

conf = {}

def find_static():
    cwd = None
    try:
        cwd = os.path.dirname(__file__)
    except NameError:
        cwd = "."
    return os.path.abspath(os.path.join(cwd, "static"))

static_root = find_static()


es=None
def elasticsearch():
    global es
    if es is not None:
        return es
    es_hosts = conf.get("elasticsearch")
    print(es_hosts)
    es = Elasticsearch(es_hosts)
    return es

def es_search(query):
    search = { "query": {
                  "query_string": {
                          "query": query,
                          "default_operator": "AND"
                        },
                    },
                    "size": 25,
             }
    return elasticsearch().search(body = search)

@get("/")
def index():
    return static_file("index.html", static_root)

def render_rdf(doc, format):
    g = Graph().parse(data=json.dumps(doc), format="json-ld", publicID=request.url)
    return g.serialize(format=format)

def json_pretty(doc):
    return json.dumps(doc, indent=4, sort_keys=True)

@get("/search/:query")
@produces(
    default = "json",
    #json = lambda **doc: doc,
    json = lambda **doc: json_pretty(doc),
    jsonld = lambda **doc: json.dumps(doc),
    html = lambda **doc: "<!DOCTYPE html><html><body><pre>%s</pre></body></html>" % cgi.escape(json_pretty(doc)),
    turtle = lambda **doc: render_rdf(doc, "turtle"),
    rdfxml = lambda **doc: render_rdf(doc, "xml"),
    nt = lambda **doc: render_rdf(doc, "nt")
)
def search_json(query):
    id = quote(url("/search/:query", query=query))
    json = { "@context": {"@vocab": "http://example.com/"}, "@id": id, "query": query, "hits": [] }
    hits = json["hits"]
    search = es_search(query)
    for hit in search["hits"]["hits"]:
        hits.append(hit["_source"])
        #hits.append({"@id": hit["_id"]})
    return json


def main(config_file, *args):
    global conf
    with open(config_file) as f:
        conf = yaml.load(f)
    run(host='localhost', port=8839, reloader=True)

if __name__ == "__main__":
   main(*sys.argv[1:])

@@ -1687,28 +1687,215 @@
 e)%0A%0A
-@get(%22/search/:
+def html_pre(json):%0A    template = %22%22%22%3C!DOCTYPE html%3E%3Chtml%3E%3Cbody%3E%0A    %3Cpre%3E%0A%25s%0A    %3C/pre%3E%0A    %3C/body%3E%3C/html%3E%0A    %22%22%22%0A    return template %25 cgi.escape(json_pretty(json))%0A%0A@get(%22/search%22)%0A@get(%22/search/%3C
 query
+%3E
 %22)%0A@
@@ -2073,95 +2073,21 @@
 oc: 
-%22%3C!DOCTYPE html%3E%3Chtml%3E%3Cbody%3E%3Cpre%3E%25s%3C/pre%3E%3C/body%3E%3C/html%3E%22 %25 cgi.escape(json
+html
 _pre
-tty
 (doc)
-)
 ,%0A  
@@ -2253,27 +2253,136 @@
 h_json(query
+=None
 ):%0A
+    if query is None:%0A        # Get from ?q parameter instead, if exist%0A        query = request.query.q%0A
     id = quo
@@ -2401,14 +2401,15 @@
 rch/
-:
+%3C
 query
+%3E
 %22, q
@@ -2421,16 +2421,142 @@
 query))%0A
+    response.set_header(%22Content-Location%22, id)%0A    # CORS header%0A    response.set_header(%22Access-Control-Allow-Origin%22, %22*%22)%0A
     json

support ?q= as well