search is now PHP and is back in place
This commit is contained in:
parent
e16a7e3dea
commit
652d062d31
5 changed files with 109 additions and 2547 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@ __pycache__
|
||||||
_scratch
|
_scratch
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
keys.py
|
||||||
|
|
2507
elasticlunr.js
2507
elasticlunr.js
File diff suppressed because it is too large
Load diff
109
nasg.py
109
nasg.py
|
@ -14,7 +14,7 @@ import re
|
||||||
import imghdr
|
import imghdr
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import sqlite3
|
||||||
from shutil import copy2 as cp
|
from shutil import copy2 as cp
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
@ -28,7 +28,6 @@ import markdown
|
||||||
from feedgen.feed import FeedGenerator
|
from feedgen.feed import FeedGenerator
|
||||||
from bleach import clean
|
from bleach import clean
|
||||||
from emoji import UNICODE_EMOJI
|
from emoji import UNICODE_EMOJI
|
||||||
from py_mini_racer import py_mini_racer
|
|
||||||
import exiftool
|
import exiftool
|
||||||
import settings
|
import settings
|
||||||
|
|
||||||
|
@ -445,15 +444,12 @@ class Singular(MarkdownDoc):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def corpus(self):
|
def corpus(self):
|
||||||
return {
|
return "\n".join([
|
||||||
'url': self.url,
|
self.title,
|
||||||
'title': self.title,
|
|
||||||
'body': "\n".join([
|
|
||||||
self.name,
|
self.name,
|
||||||
self.summary,
|
self.summary,
|
||||||
self.content,
|
self.content,
|
||||||
])
|
])
|
||||||
}
|
|
||||||
|
|
||||||
async def render(self):
|
async def render(self):
|
||||||
if self.exists:
|
if self.exists:
|
||||||
|
@ -1036,39 +1032,72 @@ class Category(dict):
|
||||||
self.render_feed()
|
self.render_feed()
|
||||||
self.ping_websub()
|
self.ping_websub()
|
||||||
|
|
||||||
|
|
||||||
class Search(object):
|
class Search(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.js = py_mini_racer.MiniRacer()
|
self.fpath = os.path.join(
|
||||||
with open('elasticlunr.js') as f:
|
|
||||||
self.js.eval(f.read())
|
|
||||||
|
|
||||||
self.js.eval("""
|
|
||||||
var index = elasticlunr();
|
|
||||||
index.addField('title');
|
|
||||||
index.addField('body');
|
|
||||||
index.setRef('url');
|
|
||||||
|
|
||||||
""")
|
|
||||||
# index.saveDocument(false);
|
|
||||||
|
|
||||||
@property
|
|
||||||
def fpath(self):
|
|
||||||
return os.path.join(
|
|
||||||
settings.paths.get('build'),
|
settings.paths.get('build'),
|
||||||
'search.json'
|
'search.sqlite'
|
||||||
|
)
|
||||||
|
self.db = sqlite3.connect(self.fpath)
|
||||||
|
self.db.execute('PRAGMA auto_vacuum = INCREMENTAL;')
|
||||||
|
self.db.execute('PRAGMA journal_mode = MEMORY;')
|
||||||
|
self.db.execute('PRAGMA temp_store = MEMORY;')
|
||||||
|
self.db.execute('PRAGMA locking_mode = NORMAL;')
|
||||||
|
self.db.execute('PRAGMA synchronous = FULL;')
|
||||||
|
self.db.execute('PRAGMA encoding = "UTF-8";')
|
||||||
|
self.db.execute('''
|
||||||
|
CREATE VIRTUAL TABLE IF NOT EXISTS data USING fts4(
|
||||||
|
url,
|
||||||
|
mtime,
|
||||||
|
name,
|
||||||
|
title,
|
||||||
|
category,
|
||||||
|
content,
|
||||||
|
notindexed=category,
|
||||||
|
notindexed=url,
|
||||||
|
notindexed=mtime,
|
||||||
|
tokenize=porter
|
||||||
|
)'''
|
||||||
)
|
)
|
||||||
|
|
||||||
def add(self, data):
|
def __exit__(self):
|
||||||
self.js.eval("""
|
self.db.commit()
|
||||||
index.addDoc(%s);
|
self.db.execute('PRAGMA auto_vacuum;')
|
||||||
""" % (
|
self.db.close()
|
||||||
json.dumps(data)
|
|
||||||
|
def append(self, url, mtime, name, title, category, content):
|
||||||
|
# TODO: delete if mtime differs
|
||||||
|
mtime = int(mtime)
|
||||||
|
self.db.execute('''
|
||||||
|
INSERT OR IGNORE INTO data
|
||||||
|
(url, mtime, name, title, category, content)
|
||||||
|
VALUES (?,?,?,?,?,?);
|
||||||
|
''', (
|
||||||
|
url,
|
||||||
|
mtime,
|
||||||
|
name,
|
||||||
|
title,
|
||||||
|
category,
|
||||||
|
content
|
||||||
))
|
))
|
||||||
|
|
||||||
def save(self):
|
async def render(self):
|
||||||
with open(self.fpath, 'wt') as f:
|
r = J2.get_template('Search.j2.php').render({
|
||||||
f.write(json.dumps(self.js.eval("index.toJSON()")))
|
'post': {},
|
||||||
|
'site': settings.site,
|
||||||
|
'author': settings.author,
|
||||||
|
'meta': settings.meta,
|
||||||
|
'licence': settings.licence,
|
||||||
|
'tips': settings.tips,
|
||||||
|
'labels': settings.labels
|
||||||
|
})
|
||||||
|
target = os.path.join(
|
||||||
|
settings.paths.get('build'),
|
||||||
|
'search.php'
|
||||||
|
)
|
||||||
|
with open(target, 'wt') as f:
|
||||||
|
logging.info("rendering to %s", target)
|
||||||
|
f.write(r)
|
||||||
|
|
||||||
|
|
||||||
def make():
|
def make():
|
||||||
|
@ -1104,9 +1133,18 @@ def make():
|
||||||
for i in post.images.values():
|
for i in post.images.values():
|
||||||
worker.append(i.downsize())
|
worker.append(i.downsize())
|
||||||
worker.append(post.render())
|
worker.append(post.render())
|
||||||
search.add(post.corpus)
|
|
||||||
sitemap[post.url] = post.mtime
|
sitemap[post.url] = post.mtime
|
||||||
|
search.append(
|
||||||
|
url=post.url,
|
||||||
|
mtime=post.mtime,
|
||||||
|
name=post.name,
|
||||||
|
title=post.title,
|
||||||
|
category=post.category,
|
||||||
|
content=post.content
|
||||||
|
)
|
||||||
|
|
||||||
|
search.__exit__()
|
||||||
|
worker.append(search.render())
|
||||||
for category in categories.values():
|
for category in categories.values():
|
||||||
worker.append(category.render())
|
worker.append(category.render())
|
||||||
|
|
||||||
|
@ -1128,8 +1166,7 @@ def make():
|
||||||
with open(t, 'wt') as f:
|
with open(t, 'wt') as f:
|
||||||
f.write("\n".join(sorted(sitemap.keys())))
|
f.write("\n".join(sorted(sitemap.keys())))
|
||||||
|
|
||||||
# dump search index
|
|
||||||
search.save()
|
|
||||||
|
|
||||||
end = int(round(time.time() * 1000))
|
end = int(round(time.time() * 1000))
|
||||||
logging.info('process took %d ms' % (end - start))
|
logging.info('process took %d ms' % (end - start))
|
||||||
|
|
33
templates/Search.j2.php
Normal file
33
templates/Search.j2.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{% extends "base.j2.html" %}
|
||||||
|
{% block lang %}{% endblock %}
|
||||||
|
{% block title %}Search results for: <?php echo($_GET['q']); ?>{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<section class="content-body">
|
||||||
|
<header>
|
||||||
|
<h1>Search results for: <?php echo($_GET['q']); ?></h1>
|
||||||
|
</header>
|
||||||
|
<?php
|
||||||
|
$db = new SQLite3('./search.sqlite', SQLITE3_OPEN_READONLY);
|
||||||
|
$q = str_replace('-', '+', $_GET['q']);
|
||||||
|
$sql = $db->prepare("
|
||||||
|
SELECT
|
||||||
|
url, category, title, snippet(data, '', '', '[...]', 5, 24)
|
||||||
|
FROM
|
||||||
|
data
|
||||||
|
WHERE
|
||||||
|
data MATCH :q
|
||||||
|
ORDER BY
|
||||||
|
category
|
||||||
|
");
|
||||||
|
$sql->bindValue(':q', $q);
|
||||||
|
$results = $sql->execute();
|
||||||
|
|
||||||
|
printf("<dl>");
|
||||||
|
while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
|
||||||
|
printf('<dt><a href="%s">%s</a></dt><dd>%s</dd>', $row['url'], $row['title'], $row["snippet(data, '', '', '[...]', 5, 24)"]);
|
||||||
|
|
||||||
|
}
|
||||||
|
printf("</dl>");
|
||||||
|
?>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
|
@ -76,14 +76,12 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!--
|
<form role="search" method="get" class="search-form" action="/search.php">
|
||||||
<form role="search" method="get" class="search-form" action="/search">
|
|
||||||
<label for="s">Search</label>
|
<label for="s">Search</label>
|
||||||
<input type="search" class="search-field" placeholder="search..."
|
<input type="search" class="search-field" placeholder="search..."
|
||||||
value="" name="s" id="s" title="Search for:" />
|
value="" name="q" id="q" title="Search for:" />
|
||||||
<input type="submit" class="search-submit" value="Go ➡" />
|
<input type="submit" class="search-submit" value="Go ➡" />
|
||||||
</form>
|
</form>
|
||||||
-->
|
|
||||||
|
|
||||||
<p class="contrast">
|
<p class="contrast">
|
||||||
<a title="toggle site colour scheme" href="#"
|
<a title="toggle site colour scheme" href="#"
|
||||||
|
|
Loading…
Reference in a new issue