Add search functionality

This commit is contained in:
Dendy 2024-01-25 02:19:00 +01:00
parent f067850ab6
commit 059bb76266
9 changed files with 143 additions and 24 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
__pycache__
config.toml
venv/

8
requirements.txt Normal file
View File

@ -0,0 +1,8 @@
blinker==1.7.0
click==8.1.7
Flask==3.0.1
itsdangerous==2.1.2
Jinja2==3.1.3
MarkupSafe==2.1.4
Unidecode==1.3.8
Werkzeug==3.0.1

View File

@ -1,11 +1,11 @@
#!/usr/bin/env python3
import os
import tomllib
from flask import Flask, render_template, send_file
with open("config.toml", "rb") as f:
config = tomllib.load(f)
from flask import Flask, render_template, send_file, request
from . import file
from . import config
app = Flask(
__name__,
@ -18,13 +18,11 @@ app.jinja_env.globals.update(
path_join=os.path.join,
)
# Catch all
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def index(path):
internal_path = os.path.join(config['base_path'], path)
internal_path = os.path.join(config.get('base_path'), path)
path = '/' + path
# Checks ###################################################
@ -61,3 +59,29 @@ def index(path):
# Path exists, not a folder, must be a file, send
return send_file(internal_path)
@app.route('/search')
def search():
q = request.args.get('q', '')
if q == '':
return (
render_template(
"error.html",
code=400,
msg='No search string provided.',
),
400,
)
ret = file.search(q)
return (
render_template(
"search.html",
list=ret,
q=q,
),
200,
)

8
src/config.py Normal file
View File

@ -0,0 +1,8 @@
import tomllib
with open("config.toml", "rb") as f:
config = tomllib.load(f)
def get(q: str):
return config.get(q, None)

45
src/file.py Normal file
View File

@ -0,0 +1,45 @@
import os
import threading
from unidecode import unidecode
from . import config
filelist = None
filelist_lock = threading.Lock()
def filter_strings(q, lst, processor):
q = unidecode(q).lower().split()
ret = []
for entry in lst:
processed_entry = unidecode(processor(entry)).lower()
if all(word in processed_entry for word in q):
ret.append(entry)
return ret
def search(q: str):
with filelist_lock:
global filelist
if filelist is None:
filelist = []
for root, dirs, files in os.walk(config.get('base_path'), topdown=True):
# We want the root relative to the base path
rel_root = root[len(config.get('base_path')):]
# Don't search search hidden stuff
[dirs.remove(x) for x in list(dirs) if x.startswith('.')]
[files.remove(x) for x in list(files) if x.startswith('.')]
filelist += map(lambda x: [rel_root, x], dirs + files)
copy_filelist = filelist
ret = filter_strings(q, copy_filelist, lambda x: x[1])
return ret

View File

@ -7,11 +7,17 @@ body {
a {
text-decoration: none;
color: lightgrey;
}
a:visited {
color: grey;
}
a:hover {
color: #191919;
background-color: white;
}
input {
border: 1px solid black;
background-color: white;
}
.base_path {
color: grey;
}

View File

@ -6,13 +6,13 @@
<meta name="description" content="" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %}{% endblock %} - {{ config["name"] }}</title>
<title>{% block title %}{% endblock %} - {{ config.get("name") }}</title>
<link
rel="stylesheet"
href="{{ url_for('static', filename='style/main.css') }}"
/>
<link rel="icon" href="{{ config["favicon"] }}">
<link rel="icon" href="{{ config.get("favicon") }}">
{# <script src="{{ url_for('static', filename='lib/htmx.min.js') }}"></script> #}
</head>

View File

@ -4,6 +4,12 @@
{% block body %}
<form action="/search" method="GET">
<input type="text" name="q" />
<input type="submit" value="Buscar" />
</form>
<br />
{% if path != "/" %}
<a href="..">&lt;--</a>
<br /><br />

21
templates/search.html Normal file
View File

@ -0,0 +1,21 @@
{% extends 'base.html' %}
{% block title %}{{ path }}{% endblock %}
{% block body %}
<form action="/search" method="GET">
<input type="text" name="q" value="{{ q }}"/>
<input type="submit" value="Buscar" />
</form>
<br />
<a href="/">&lt;--</a>
<br /><br />
{% for entry in list %}
<a href="{{ path_join(entry[0], entry[1]) }}"><span class="base_path">{{ entry[0] }}/</span>{{ entry[1] }}</a><br />
{% endfor %}
{% endblock %}