start of search

This commit is contained in:
crunk 2024-06-29 15:21:47 +02:00
parent d6f5d41fb7
commit 0ac59269e7
6 changed files with 113 additions and 3 deletions

View File

@ -8,6 +8,8 @@ from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CSRFProtect from flask_wtf.csrf import CSRFProtect
APP = Flask(__name__, static_folder="static") APP = Flask(__name__, static_folder="static")
db = SQLAlchemy() db = SQLAlchemy()
migrate = Migrate() migrate = Migrate()
@ -46,6 +48,7 @@ def create_app():
migrate.init_app(APP, db, render_as_batch=True) migrate.init_app(APP, db, render_as_batch=True)
bcrypt.init_app(APP) bcrypt.init_app(APP)
@APP.context_processor @APP.context_processor
def inject_title(): def inject_title():
return dict(title=APP.config["title"]) return dict(title=APP.config["title"])

View File

@ -4,3 +4,7 @@ from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, validators from wtforms import StringField, SubmitField, validators
from wtforms.validators import Length from wtforms.validators import Length
from wtforms.widgets import TextArea from wtforms.widgets import TextArea
class SearchForm(FlaskForm):
searchfield = StringField("Search distribusi-verse archive")
submit = SubmitField("Search")

View File

@ -1,8 +1,41 @@
import os import os
from flask import Blueprint, render_template
from whoosh.fields import * from whoosh.fields import *
from whoosh.index import open_dir from whoosh.index import open_dir
from whoosh.qparser import QueryParser from whoosh.qparser import QueryParser
from search.forms.searchform import SearchForm
searchpages = Blueprint(
"search",
__name__,
template_folder="templates/search",
static_folder="static",
)
SCRIPT_DIR = os.path.dirname(__file__) SCRIPT_DIR = os.path.dirname(__file__)
DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "../data")) SEARCH_DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "searchdata"))
@searchpages.route("/", methods=["GET", "POST"])
def searchpage():
searchform = SearchForm()
found_distribusis = []
if searchform.validate_on_submit():
found_distribusis = search(searchform.searchfield.data)
template = render_template(
"search.html",
searchform=searchform,
found_distribusis=found_distribusis,
)
return template
def search(searchinput):
"""search and get search result titles and return them as distribusi ids"""
ix = open_dir(SEARCH_DATA_DIR)
with ix.searcher() as searcher:
query = QueryParser("content", ix.schema).parse(searchinput)
search_results = searcher.search(query)
found_distribusis = []
for result in search_results:
found_distribusis.append(result["title"])
return found_distribusis

View File

@ -0,0 +1,47 @@
import os
from whoosh.fields import *
from whoosh.index import create_in
from whoosh.qparser import QueryParser
from models.distribusi_model import Distribusis
import flask_apscheduler
SCRIPT_DIR = os.path.dirname(__file__)
SEARCH_DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "searchdata"))
def init_search_index(APP):
scheduler = flask_apscheduler.APScheduler()
scheduler.api_enabled = False
scheduler.init_app(APP)
scheduler.start()
index_distribusis(APP)
index_distribusi_files(APP)
@scheduler.task("interval", id="update", minutes=60)
def update_search_index():
index_distribusis(APP)
index_distribusi_files(APP)
def index_distribusis(APP):
schema = Schema(
title=TEXT(stored=True), path=ID(stored=True), content=TEXT
)
ix = create_in(SEARCH_DATA_DIR, schema)
writer = ix.writer()
distribusis = _visible_distribusis(APP)
for distribusi in distribusis:
writer.add_document(title=distribusi.distribusiname, path="/a", content=distribusi.description)
writer.commit()
def index_distribusi_files(APP):
APP.logger.info("searching distribusi files not implemented yet.")
def _visible_distribusis(APP):
with APP.app_context():
distribusis = Distribusis.query.filter(
Distribusis.visible.isnot(False)
).all()
return distribusis

View File

@ -1,3 +1,23 @@
{% extends "base/base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="distribusiverse" class="maincontent">
<form method="POST" enctype="multipart/form-data" action="{{ url_for('search.searchpage') }}">
{{ searchform.csrf_token }}
<fieldset class="required">
{{ searchform.searchfield.label }}
{{ searchform.searchfield }}
{% for message in searchform.searchfield.errors %}
<div class="error">{{ message }}</div>
{% endfor %}
</fieldset>
<fieldset class="button required">
{{ searchform.submit }}
</fieldset>
</form>
<div class="searchresults">
{% for found_distribusis in found_distribusis %}
<p>{{found_distribusis}}</p>
{% endfor %}
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -26,6 +26,8 @@ from statuspengguna.forgotpassword import forgot_password
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper
from statuspengguna.loginuser import login_section from statuspengguna.loginuser import login_section
from statuspengguna.registeruser import register_user from statuspengguna.registeruser import register_user
from search.search import searchpages
from search.search_index import init_search_index
APP = create_app() APP = create_app()
stash_page = Blueprint("stash_page", __name__, static_folder="stash") stash_page = Blueprint("stash_page", __name__, static_folder="stash")
@ -36,7 +38,8 @@ APP.register_blueprint(register_user, url_prefix="/register")
APP.register_blueprint(forgot_password, url_prefix="/login/forgotpassword") APP.register_blueprint(forgot_password, url_prefix="/login/forgotpassword")
APP.register_blueprint(admin_page, url_prefix="/admin") APP.register_blueprint(admin_page, url_prefix="/admin")
APP.register_blueprint(distribusikan, url_prefix="/distribusikan") APP.register_blueprint(distribusikan, url_prefix="/distribusikan")
APP.register_blueprint(searchpages, url_prefix="/search")
init_search_index(APP)
@APP.before_request @APP.before_request
def session_handler(): def session_handler():