mirror of
https://github.com/kiwix/libkiwix.git
synced 2025-06-26 10:11:30 +00:00
The story of search_results.css static/skin/search_results.css was extracted from static/templates/no_search_result.html before the latter was dropped. static/templates/no_search_result.html in turn seems to be a copied and edited version of static/templates/search_result.html. In the context of exploratory work on the internationalization of kiwix-serve (PR #679) I noticed duplication of inline CSS across those two templates and intended to eliminated it. That goal was not fully accomplished (static/templates/search_result.html remained untouched) because by that time PR #679 grew too big and the efforts were diverted into splitting it into smaller ones. Thus search_results.css slipped into one of those small PRs, without making much sense because nothing really justifies preserving custom CSS in the "Fulltext search unavailable" error page. At the same time, it served as the only case where a link to a cacheable resource is generated in C++ code (rather than found in a template). This poses certain problems to the handling of cache-ids. A workaround is to expel the URL into a template so that it is processed by `kiwix-resources`. This commit merely demonstrates that solution. But whether it should be preserved (or rather the "Fulltext search unavailable" page should be deprived of CSS) is questionable.
117 lines
4.1 KiB
Python
Executable File
117 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
'''
|
|
Copyright 2022 Veloman Yunkan <veloman.yunkan@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or any
|
|
later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301, USA.
|
|
'''
|
|
|
|
import argparse
|
|
import hashlib
|
|
import os.path
|
|
import re
|
|
|
|
def read_resource_file(resource_file_path):
|
|
with open(resource_file_path, 'r') as f:
|
|
return [line.strip() for line in f]
|
|
|
|
def list_resources(resource_file_path):
|
|
for resource_path in read_resource_file(resource_file_path):
|
|
print(resource_path)
|
|
|
|
def get_resource_revision(base_dir, resource_path):
|
|
with open(os.path.join(base_dir, resource_path), 'rb') as f:
|
|
return hashlib.sha1(f.read()).hexdigest()[:8]
|
|
|
|
resource_revisions = {}
|
|
|
|
def fill_resource_revisions(resource_file_path):
|
|
base_dir = os.path.dirname(os.path.realpath(resource_file_path))
|
|
for resource in read_resource_file(resource_file_path):
|
|
resource_revisions[resource] = get_resource_revision(base_dir, resource)
|
|
|
|
RESOURCE_WITH_CACHEID_URL_PATTERN=r'([^"?]+)\?KIWIXCACHEID([^"]*)'
|
|
|
|
def set_cacheid(resource_matchobj):
|
|
path = resource_matchobj.group(1)
|
|
resource = path
|
|
root_prefix = '{{root}}/'
|
|
if resource.startswith(root_prefix):
|
|
resource = resource[len(root_prefix):]
|
|
extra_query = resource_matchobj.group(2)
|
|
cacheid = 'cacheid=' + resource_revisions[resource]
|
|
return f'{path}?{cacheid}{extra_query}'
|
|
|
|
def preprocess_line(line):
|
|
if 'KIWIXCACHEID' in line:
|
|
line = re.sub(RESOURCE_WITH_CACHEID_URL_PATTERN, set_cacheid, line)
|
|
assert not 'KIWIXCACHEID' in line
|
|
return line
|
|
|
|
def preprocess_template(srcpath, dstpath):
|
|
preprocessed_lines = []
|
|
with open(srcpath, 'r') as source:
|
|
for line in source:
|
|
preprocessed_lines.append(preprocess_line(line))
|
|
|
|
with open(dstpath, 'w') as target:
|
|
print("".join(preprocessed_lines), end='', file=target)
|
|
|
|
def symlink_resource(src, resource_path):
|
|
if os.path.exists(resource_path):
|
|
if os.path.islink(resource_path) and os.readlink(resource_path) == src:
|
|
return
|
|
os.remove(resource_path)
|
|
os.symlink(src, resource_path)
|
|
|
|
def preprocess_resource(srcdir, resource_path, outdir):
|
|
resource_dir = os.path.dirname(resource_path)
|
|
if resource_dir != '':
|
|
os.makedirs(os.path.join(outdir, resource_dir), exist_ok=True)
|
|
srcpath = os.path.join(srcdir, resource_path)
|
|
outpath = os.path.join(outdir, resource_path)
|
|
if resource_path.startswith('templates/'):
|
|
preprocess_template(srcpath, outpath)
|
|
else:
|
|
symlink_resource(srcpath, outpath)
|
|
|
|
def copy_file(src_path, dst_path):
|
|
with open(src_path, 'rb') as src:
|
|
with open(dst_path, 'wb') as dst:
|
|
dst.write(src.read())
|
|
|
|
def preprocess_resources(resource_file_path, outdir):
|
|
base_dir = os.path.dirname(os.path.realpath(resource_file_path))
|
|
resource_filename = os.path.basename(resource_file_path)
|
|
for resource in read_resource_file(resource_file_path):
|
|
preprocess_resource(base_dir, resource, outdir)
|
|
copy_file(resource_file_path, os.path.join(outdir, resource_filename))
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
commands = parser.add_mutually_exclusive_group()
|
|
commands.add_argument('--list-all', action='store_true')
|
|
commands.add_argument('--preprocess', action='store_true')
|
|
parser.add_argument('--outdir')
|
|
parser.add_argument('resource_file')
|
|
args = parser.parse_args()
|
|
|
|
if args.list_all:
|
|
list_resources(args.resource_file)
|
|
elif args.preprocess:
|
|
fill_resource_revisions(args.resource_file)
|
|
preprocess_resources(args.resource_file, args.outdir)
|