Add search functionality
This commit is contained in:
parent
f067850ab6
commit
d3d892f3e1
|
@ -1,2 +1,3 @@
|
|||
__pycache__
|
||||
config.toml
|
||||
venv/
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -8,10 +8,16 @@ 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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -4,21 +4,26 @@
|
|||
|
||||
{% block body %}
|
||||
|
||||
{% if path != "/" %}
|
||||
<a href=".."><--</a>
|
||||
<br /><br />
|
||||
{% endif %}
|
||||
<form action="/search" method="GET">
|
||||
<input type="text" name="q" />
|
||||
<input type="submit" value="Buscar" />
|
||||
</form>
|
||||
|
||||
{% for dir in dirs %}
|
||||
<a href="{{ path_join(path, dir) }}">{{ dir }}</a><br />
|
||||
{% endfor %}
|
||||
{% if path != "/" %}
|
||||
<a href=".."><--</a>
|
||||
<br /><br />
|
||||
{% endif %}
|
||||
|
||||
<br /><br />
|
||||
{% for dir in dirs %}
|
||||
<a href="{{ path_join(path, dir) }}">{{ dir }}</a><br />
|
||||
{% endfor %}
|
||||
|
||||
<h3>Archivos</h3>
|
||||
<br /><br />
|
||||
|
||||
{% for file in files %}
|
||||
<a href="{{ path_join(path, file) }}">{{ file }}</a><br />
|
||||
{% endfor %}
|
||||
<h3>Archivos</h3>
|
||||
|
||||
{% for file in files %}
|
||||
<a href="{{ path_join(path, file) }}">{{ file }}</a><br />
|
||||
{% endfor %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
|
@ -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>
|
||||
|
||||
{% if path != "/" %}
|
||||
<a href=".."><--</a>
|
||||
<br /><br />
|
||||
{% endif %}
|
||||
|
||||
{% 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 %}
|
Loading…
Reference in New Issue