terms-search: add a /sources.html

This commit is contained in:
iacore
2026-06-14 12:25:55 +08:00
parent 6ba8719eb6
commit 27546d04a0
6 changed files with 88 additions and 41 deletions
+16
View File
@@ -0,0 +1,16 @@
# CodeGraph data files
# These are local to each machine and should not be committed
# Database
*.db
*.db-wal
*.db-shm
# Cache
cache/
# Logs
*.log
# Hook markers
.dirty
+1 -1
View File
@@ -1,4 +1,4 @@
# flyctl launch added from .gitignore .git
**/__pycache__ **/__pycache__
**/__pypackages__ **/__pypackages__
fly.toml fly.toml
+1 -1
View File
@@ -4,7 +4,7 @@ WORKDIR /app
RUN pip install --no-cache-dir flask duckdb gunicorn RUN pip install --no-cache-dir flask duckdb gunicorn
COPY server.py search.py termlib.duckdb ./ COPY . .
EXPOSE 8910 EXPOSE 8910
+21 -39
View File
@@ -3,47 +3,23 @@ import sys, os
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import duckdb import duckdb
from flask import Flask, request, jsonify, render_template_string from flask import Flask, request, jsonify, render_template
import search as s import search as s
app = Flask(__name__) app = Flask(__name__)
HTML = r'''<!DOCTYPE html>
<meta charset="utf-8">
<title>静心学堂中英文翻译对照表</title>
<h1>静心学堂(非官方)中英文翻译对照表</h1>
<form method="get">
<input name="q" value="{{ q }}" placeholder="query (e.g. 空性 emptiness)">
<input name="loc" value="{{ loc }}" placeholder="loc filter">
<input name="src" value="{{ src }}" placeholder="src filter">
<input name="limit" value="{{ limit }}" size="4" placeholder="limit">
<button type="submit">Search</button>
</form>
{% if searched %}
{% if error %}<p>Error: {{ error }}</p>
{% else %}
<p>{{ count }} results</p>
<table border="1" cellpadding="4" cellspacing="0">
<tr><th>ZH</th><th>EN</th><th>LOC</th><th>SRC</th></tr>
{% for r in results %}
<tr>
<td>{{ r.zh }}</td>
<td>{{ r.en }}</td>
<td>{{ r.loc or '' }}</td>
<td>{{ r.source }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
'''
def do_search(q, loc, src, limit): def do_search(q, loc, src, limit):
with duckdb.connect(s.DB, read_only=True) as con: with duckdb.connect(s.DB, read_only=True) as con:
rows = s.search(con, q, loc, src, limit) rows = s.search(con, q, loc, src, limit)
return [{'zh': r[0], 'en': r[1], 'loc': r[2] or None, 'source': r[3]} for r in rows] return [{'zh': r[0], 'en': r[1], 'loc': r[2] or None, 'source': r[3]} for r in rows]
def do_sources():
with duckdb.connect(s.DB, read_only=True) as con:
rows = con.execute(
'SELECT source, COUNT(*) AS cnt FROM unified_terms_flat GROUP BY source ORDER BY cnt DESC'
).fetchall()
return [{'source': r[0], 'count': r[1]} for r in rows]
@app.route('/search') @app.route('/search')
def search(): def search():
try: try:
@@ -59,14 +35,20 @@ def search():
@app.route('/sources') @app.route('/sources')
def sources(): def sources():
try: try:
with duckdb.connect(s.DB, read_only=True) as con: sources = do_sources()
rows = con.execute( return jsonify(sources)
'SELECT source, COUNT(*) AS cnt FROM unified_terms_flat GROUP BY source ORDER BY cnt DESC'
).fetchall()
return jsonify([{'source': r[0], 'count': r[1]} for r in rows])
except Exception as e: except Exception as e:
return jsonify({'error': str(e)}), 500 return jsonify({'error': str(e)}), 500
@app.route('/sources.html')
def sources_html():
try:
sources = do_sources()
total = sum(s['count'] for s in sources)
return render_template('sources.html', sources=sources, total=total)
except Exception as e:
return render_template('sources.html', sources=[], total=0, error=str(e))
@app.route('/') @app.route('/')
def ui(): def ui():
q = request.args.get('q', '') q = request.args.get('q', '')
@@ -84,8 +66,8 @@ def ui():
count = len(results) count = len(results)
except Exception as e: except Exception as e:
error = str(e) error = str(e)
return render_template_string(HTML, q=q, loc=loc, src=src, limit=limit, return render_template('index.html', q=q, loc=loc, src=src, limit=limit,
searched=searched, results=results, count=count, error=error) searched=searched, results=results, count=count, error=error)
if __name__ == '__main__': if __name__ == '__main__':
app.run(port=8910) app.run(port=8910)
+30
View File
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>静心学堂中英文翻译对照表</title>
<h1>静心学堂(非官方)中英文翻译对照表</h1>
<p><a href="/">search</a> | <a href="/sources.html">sources</a></p>
<form method="get">
<input name="q" value="{{ q }}" placeholder="query (e.g. 空性 emptiness)">
<input name="loc" value="{{ loc }}" placeholder="loc filter">
<input name="src" value="{{ src }}" placeholder="src filter">
<input name="limit" value="{{ limit }}" size="4" placeholder="limit">
<button type="submit">Search</button>
</form>
{% if searched %}
{% if error %}<p>Error: {{ error }}</p>
{% else %}
<p>{{ count }} results</p>
<table border="1" cellpadding="4" cellspacing="0">
<tr><th>ZH</th><th>EN</th><th>LOC</th><th>SRC</th></tr>
{% for r in results %}
<tr>
<td>{{ r.zh }}</td>
<td>{{ r.en }}</td>
<td>{{ r.loc or '' }}</td>
<td>{{ r.source }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
+19
View File
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Sources — 静心学堂翻译对照表</title>
<h1>Sources</h1>
<p><a href="/">search</a> | <a href="/sources.html">sources</a></p>
{% if error %}<p>Error: {{ error }}</p>
{% else %}
<table border="1" cellpadding="4" cellspacing="0">
<tr><th>Source</th><th>Rows</th></tr>
{% for s in sources %}
<tr>
<td><a href="/?src={{ s.source }}">{{ s.source }}</a></td>
<td>{{ s.count }}</td>
</tr>
{% endfor %}
<tr><th>Total</th><th>{{ total }}</th></tr>
</table>
{% endif %}