1
0
Fork 0
mirror of https://github.com/Findus23/cr-search.git synced 2024-09-19 15:23:44 +02:00
cr-search/server.py

120 lines
3.6 KiB
Python
Raw Normal View History

2020-03-08 18:48:14 +01:00
import logging
2020-03-07 10:45:39 +01:00
from flask import request, jsonify, Response
from peewee import fn, Alias, SQL, DoesNotExist, Expression
from playhouse.postgres_ext import TS_MATCH
2020-03-07 10:45:39 +01:00
from playhouse.shortcuts import model_to_dict
from psycopg2._psycopg import cursor
from app import app
from models import *
2020-03-08 18:48:14 +01:00
logger = logging.getLogger('peewee')
logger.addHandler(logging.StreamHandler())
logger.setLevel(logging.DEBUG)
2020-03-08 14:48:04 +01:00
2020-03-07 10:45:39 +01:00
def add_cors(response):
header = response.headers
header['Access-Control-Allow-Origin'] = '*'
return response
2020-04-15 18:11:45 +02:00
global_excludes = [Line.search_text, Episode.phrases_imported, Episode.text_imported, Person.series]
2020-04-07 11:08:52 +02:00
2020-03-08 14:48:04 +01:00
@app.route("/api/suggest")
2020-03-07 10:45:39 +01:00
def question():
2020-03-08 14:48:04 +01:00
query: str = request.args.get('query')
2020-03-07 10:45:39 +01:00
until = request.args.get('until')
2020-04-15 18:11:45 +02:00
series = request.args.get('series')
if not query or not until or not series:
2020-03-07 10:45:39 +01:00
return "no suggest query", 400
2020-03-08 18:48:14 +01:00
if len(query) > 50:
return "too long query", 400
phrases = Phrase.select(Phrase.text, Alias(fn.SUM(Phrase.count), "total_count")).join(Episode).where(
2020-04-15 18:11:45 +02:00
(Episode.series == series) &
2020-03-08 18:48:14 +01:00
(Episode.episode_number <= until) &
2020-03-08 19:49:06 +01:00
(Phrase.text.contains(query))
2020-03-08 14:48:04 +01:00
).group_by(Phrase.text).order_by(SQL("total_count DESC")).limit(10)
2020-03-07 10:45:39 +01:00
return jsonify([p.text for p in phrases])
2020-03-08 14:48:04 +01:00
@app.route("/api/search")
2020-03-07 10:45:39 +01:00
def search():
query = request.args.get('query')
until = request.args.get('until')
2020-04-15 18:11:45 +02:00
series = request.args.get('series')
if not query or not until or not series:
2020-03-07 10:45:39 +01:00
return "no suggest query", 400
2020-03-08 18:48:14 +01:00
if len(query) > 50:
return "too long query", 400
2020-03-07 10:45:39 +01:00
a = Alias(fn.ts_rank_cd(Line.search_text, fn.websearch_to_tsquery('english', query), 1 + 4), "rank")
2020-03-07 10:45:39 +01:00
results = Line.select(Line, Person, Episode, Series, a).where(
Expression(Line.search_text, TS_MATCH, fn.websearch_to_tsquery('english', query))
2020-03-07 10:45:39 +01:00
&
(Episode.episode_number <= until)
&
2020-04-15 18:11:45 +02:00
(Episode.series == series)
).order_by(SQL("rank DESC")) \
.join(Person).switch(Line) \
.join(Episode).join(Series) \
2020-04-28 19:45:52 +02:00
.limit(50)
2020-03-07 10:45:39 +01:00
if len(results) == 0:
result: cursor = db.execute_sql("select websearch_to_tsquery('english',%s)", [query])
2020-03-07 10:45:39 +01:00
parsed = result.fetchone()[0]
if not parsed:
return jsonify({
"status": "warning",
"message": "Only stop words were used. Please try to add a less common word to the search."
})
2020-03-07 10:45:39 +01:00
else:
2020-03-08 14:48:04 +01:00
resp: Response = jsonify({"status": "warning", "message": f"No results were found for \"{parsed}\""})
resp.status_code = 404
return resp
2020-03-07 10:45:39 +01:00
data = []
d: Line
ri = 0
for d in results:
2020-04-07 11:08:52 +02:00
entry = model_to_dict(d, extra_attrs=["rank"], exclude=global_excludes)
2020-03-07 10:45:39 +01:00
entry["rank"] = float(entry["rank"])
data.append({"centerID": d.id, "resultID": ri, "offset": 1, "lines": [entry]})
ri += 1
return jsonify(data)
2020-03-08 14:48:04 +01:00
@app.route("/api/expand")
2020-03-07 10:45:39 +01:00
def expand():
center_id = request.args.get('centerID')
offset = int(request.args.get('offset', 1))
if not center_id:
return "no central line ID", 400
try:
center: Line = Line.select().where(Line.id == center_id).get()
except DoesNotExist:
return "not found", 404
lines = Line.select().where(
(Line.episode == center.episode) & (Line.order << [center.order - offset, center.order + offset])
)
l: Line
data = []
for l in lines:
2020-04-07 11:08:52 +02:00
entry = model_to_dict(l, exclude=global_excludes)
2020-03-07 10:45:39 +01:00
data.append(entry)
return jsonify(data)
if __name__ == "__main__":
app.debug = True
app.after_request(add_cors)
app.run()