From 121fa288d20e54cf517b241f352d8606f6512b85 Mon Sep 17 00:00:00 2001 From: augustin64 Date: Wed, 17 Aug 2022 09:44:31 +0200 Subject: [PATCH] Ajout de la recherche google --- partitioncloud/albums.py | 10 ++- partitioncloud/partition.py | 17 +++++ partitioncloud/schema.sql | 6 ++ partitioncloud/search.py | 82 ++++++++++++++++++++- partitioncloud/static/style.css | 5 ++ partitioncloud/templates/albums/search.html | 18 ++++- 6 files changed, 131 insertions(+), 7 deletions(-) diff --git a/partitioncloud/albums.py b/partitioncloud/albums.py index c8ac232..93ad3a9 100644 --- a/partitioncloud/albums.py +++ b/partitioncloud/albums.py @@ -11,7 +11,7 @@ from flask import (Blueprint, abort, flash, redirect, render_template, request, from .auth import login_required from .db import get_db from .utils import User, Album, get_all_partitions -from .search import search as srch +from . import search bp = Blueprint("albums", __name__, url_prefix="/albums") @@ -27,14 +27,16 @@ def index(): @bp.route("/search", methods=["POST"]) @login_required -def search(): +def search_page(): if "query" not in request.form or request.form["query"] == "": flash("Aucun terme de recherche spécifié.") return redirect("/albums") query = request.form["query"] - partitions = srch(query, get_all_partitions()) - return render_template("albums/search.html", partitions=partitions, query=query) + search.flush_cache() + partitions_local = search.local_search(query, get_all_partitions()) + google_results = search.online_search(query) + return render_template("albums/search.html", partitions=partitions_local, google_results=google_results, query=query) @bp.route("/") def album(uuid): diff --git a/partitioncloud/partition.py b/partitioncloud/partition.py index 1982b54..8cc4d21 100644 --- a/partitioncloud/partition.py +++ b/partitioncloud/partition.py @@ -29,6 +29,23 @@ def partition(uuid): return send_file(os.path.join("partitions", f"{uuid}.pdf")) +@bp.route("/search/") +@login_required +def partition_search(uuid): + db = get_db() + partition = db.execute( + """ + SELECT * FROM search_results + WHERE uuid = ? + """, + (uuid,) + ).fetchone() + + if partition is None: + abort(404) + return send_file(os.path.join("search-partitions", f"{uuid}.pdf")) + + @bp.route("/") @admin_required def index(): diff --git a/partitioncloud/schema.sql b/partitioncloud/schema.sql index 10dae17..ea28e2d 100644 --- a/partitioncloud/schema.sql +++ b/partitioncloud/schema.sql @@ -3,6 +3,7 @@ DROP TABLE IF EXISTS partition; DROP TABLE IF EXISTS album; DROP TABLE IF EXISTS contient_partition; DROP TABLE IF EXISTS contient_user; +DROP TABLE IF EXISTS search_results; CREATE TABLE user ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -35,3 +36,8 @@ CREATE TABLE contient_user ( album_id INTEGER NOT NULL, PRIMARY KEY (user_id, album_id) ); + +CREATE TABLE search_results ( + uuid TEXT(36) PRIMARY KEY, + creation_time TEXT NULL DEFAULT (datetime('now', 'localtime')) +); \ No newline at end of file diff --git a/partitioncloud/search.py b/partitioncloud/search.py index e310eeb..164153b 100644 --- a/partitioncloud/search.py +++ b/partitioncloud/search.py @@ -2,8 +2,16 @@ """ Module implémentant la recherche de partitions par mots-clés """ +from uuid import uuid4 +import urllib.request +import os -def search(query, partitions): +import googlesearch + +from .db import get_db + + +def local_search(query, partitions): """ Renvoie les 5 résultats les plus pertinents parmi une liste donnée """ @@ -30,3 +38,75 @@ def search(query, partitions): else: break return sorted_partitions[:min(5,len(sorted_partitions))] + + +def online_search(query): + """ + Renvoie les 5 résultats les plus pertinents depuis google + """ + db = get_db() + query = f"partition filetype:pdf {query}" + partitions = [] + results = googlesearch.search( + query, + num=5, + stop=5, + pause=1 + ) + for element in results: + while True: + try: + uuid = str(uuid4()) + db.execute( + """ + INSERT INTO search_results (uuid) + VALUES (?) + """, + (uuid,) + ) + urllib.request.urlretrieve(element, f"partitioncloud/search-partitions/{uuid}.pdf") + + os.system( + f'/usr/bin/convert -thumbnail\ + "178^>" -background white -alpha \ + remove -crop 178x178+0+0 \ + partitioncloud/search-partitions/{uuid}.pdf[0] \ + partitioncloud/static/search-thumbnails/{uuid}.jpg' + ) + partitions.append( + { + "name": element.split("://")[1].split("/")[0], + "uuid": uuid + } + ) + db.commit() + break + except db.IntegrityError: + pass + except urllib.error.HTTPError as e: + print(e) + return partitions + + +def flush_cache(): + """ + Supprimer les résultats de recherche datant de plus de 15 minutes + """ + db = get_db() + expired_cache = db.execute( + """ + SELECT uuid FROM search_results + WHERE creation_time <= datetime('now', '-15 minutes', 'localtime') + """ + ).fetchall() + for element in expired_cache: + uuid = element["uuid"] + os.remove(f"partitioncloud/search-partitions/{uuid}.pdf") + os.remove(f"partitioncloud/static/search-thumbnails/{uuid}.jpg") + + db.execute( + """ + DELETE FROM search_results + WHERE creation_time <= datetime('now', '-15 minutes', 'localtime') + """ + ) \ No newline at end of file diff --git a/partitioncloud/static/style.css b/partitioncloud/static/style.css index dc1bc32..74e5e1a 100644 --- a/partitioncloud/static/style.css +++ b/partitioncloud/static/style.css @@ -174,6 +174,11 @@ input[type=submit] { overflow-x: scroll; } +#search-partitions-grid { + display: flex; + overflow-x: scroll; +} + #header-actions { margin-bottom: 5px; } diff --git a/partitioncloud/templates/albums/search.html b/partitioncloud/templates/albums/search.html index 57852f0..4ebebf8 100644 --- a/partitioncloud/templates/albums/search.html +++ b/partitioncloud/templates/albums/search.html @@ -6,6 +6,7 @@ {% block content %} {% if partitions|length != 0 %} +

Résultats dans la bibliothèque locale

{% for partition in partitions %} @@ -19,7 +20,20 @@ {% endfor %}
-{% else %} -
Aucune partition ne correspond aux termes de votre requête
+{% endif %} +{% if google_results|length != 0 %} +

Résultats de la recherche en ligne

+
+ {% for partition in google_results %} + +
+ +
+
{{ partition["name"] }}
+
+
+
+ {% endfor %} +
{% endif %} {% endblock %} \ No newline at end of file