From 3f3d1bcb32a6a7c3e675d786598b4c02e21845b3 Mon Sep 17 00:00:00 2001 From: hylom Date: Thu, 22 Feb 2018 21:16:54 +0900 Subject: [PATCH] ns_search: create 'newslash_searchd' module --- src/ns_search/newslash_searchd/__init__.py | 8 +++ src/ns_search/newslash_searchd/codes.py | 6 ++ src/ns_search/newslash_searchd/router.py | 97 ++++++++++++++++++++++++++++++ src/ns_search/newslash_searchd/searchd.py | 39 ++++++++++++ src/ns_search/ns_searchd.py | 19 ++++++ 5 files changed, 169 insertions(+) create mode 100644 src/ns_search/newslash_searchd/__init__.py create mode 100644 src/ns_search/newslash_searchd/codes.py create mode 100644 src/ns_search/newslash_searchd/router.py create mode 100644 src/ns_search/newslash_searchd/searchd.py create mode 100644 src/ns_search/ns_searchd.py diff --git a/src/ns_search/newslash_searchd/__init__.py b/src/ns_search/newslash_searchd/__init__.py new file mode 100644 index 00000000..9692fcd8 --- /dev/null +++ b/src/ns_search/newslash_searchd/__init__.py @@ -0,0 +1,8 @@ +# coding: utf-8 +'''newslash_searchd: Search daemon for newslash''' +__author__ = 'Hiromichi Matsushima ' +__version__ = "0.1.0" + +from searchd import Searchd + +__all__ = [] diff --git a/src/ns_search/newslash_searchd/codes.py b/src/ns_search/newslash_searchd/codes.py new file mode 100644 index 00000000..438bd6e9 --- /dev/null +++ b/src/ns_search/newslash_searchd/codes.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 +'''router: HTTP Status codes''' + +status_code = { + +} diff --git a/src/ns_search/newslash_searchd/router.py b/src/ns_search/newslash_searchd/router.py new file mode 100644 index 00000000..15b75379 --- /dev/null +++ b/src/ns_search/newslash_searchd/router.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 +'''router: Routing and preprocess system for Web applications''' + +import httplib +import json + +class Response(object): + def __init__(self, start_response): + self.status = None + self.response_headers = [] + self.finished = False + self.response_bodies = [] + self.start_response = start_response + + def add_response(self, response): + self.response_bodies.append(response) + + def add_header(self, name, value): + self.response_headers.append((name, value)) + + def set_status_code(self, code): + self.status = "{} {}".format(code, httplib.responses[code]) + + def render_json(self, data): + self.add_header("Content-Type", "application/json") + raw_json = json.dumps(data, ensure_ascii=False) + self.add_response(raw_json.encode('utf-8')) + + def render(self, code=None, **kwargs): + if code is not None: + self.set_status_code(code) + if 'json' in kwargs: + return self.render_json(kwargs["json"]) + + def finish(self, code=None, body=None): + if code is not None: + self.set_status_code(code) + + if self.status is None: + self.set_status_code(200) + + if body is not None: + self.add_response(body) + + self.start_response(self.status, self.response_headers) + self.finished = True + + +class Request(object): + def __init__(self, environ): + self.environ = environ + self.body = self.decode_request_body() + + def decode_request_body(self): + content_type = self.environ['CONTENT_TYPE'] + if content_type == 'application/json': + return self._decode_json() + return None + + def _decode_json(self): + body_len = int(self.environ.get('CONTENT_LENGTH', 0)) + if body_len > 0: + raw_req = self.environ['wsgi.input'] + raw_json = raw_req.read(body_len) + return json.loads(raw_json) + return None + + +class Router(object): + def __init__(self): + pass + + def __call__(self, environ, start_response): + req = Request(environ) + resp = Response(start_response) + + method = environ['REQUEST_METHOD'] + try: + if method == 'GET': + self.get(req, resp) + elif method == 'POST': + self.post(req, resp) + else: + self.fallback(req, resp) + except AttributeError: + self.fallback(req, resp) + + if not resp.finished: + resp.finish() + + return resp.response_bodies + + def fallback(self, req, resp): + resp.finish(500, "Internal Server Error") + + + diff --git a/src/ns_search/newslash_searchd/searchd.py b/src/ns_search/newslash_searchd/searchd.py new file mode 100644 index 00000000..440278fc --- /dev/null +++ b/src/ns_search/newslash_searchd/searchd.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 +''' searchd: Search daemon for Newslash''' + +from router import Router +import lucene_wrapper + +class Searchd(Router): + def __init__(self): + super(Searchd, self).__init__() + + def get(self, req, resp): + resp.render(200, json={"error": 0}) + + def post(self, req, resp): + # check request body is valid + if req.body is None: + resp.render(400) + return + + # start query + query = req.body.get('query', '') + limit = req.body.get('limit', 10) + + searcher = lucene_wrapper.Searcher(index_directory="./lucene_index") + query = lucene_wrapper.Query("content_text", query) + result = searcher.search(query, limit) + + resp_body = { + "total_hits": result.total_hits, + "hits": [] + } + + for item in result: + resp_body["hits"].append({ "number": item.number, + "id": item.id, + "title": item.title, + "content_text": item.content_text}) + + resp.render(200, json=resp_body) diff --git a/src/ns_search/ns_searchd.py b/src/ns_search/ns_searchd.py new file mode 100644 index 00000000..e04338ab --- /dev/null +++ b/src/ns_search/ns_searchd.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# -*- coding: utf-8 + +from wsgiref.simple_server import make_server + +from newslash_searchd import Searchd +import lucene_wrapper + +if __name__ == '__main__': + # start Java VM + lucene_wrapper.init_vm() + + app = Searchd() + server = make_server('', 6000, app) + + print("starting server at localhost:6000...") + server.serve_forever() + + -- 2.11.0