Add csv-export and manual ISBN
This commit is contained in:
parent
cb8b6ab4fa
commit
6bffd45051
27
app.py
27
app.py
@ -1,4 +1,5 @@
|
||||
from flask import Flask, render_template, redirect, url_for, request, abort, g
|
||||
from flask import Flask, render_template, redirect, request, g, flash
|
||||
import secrets
|
||||
import json
|
||||
|
||||
from book import Book
|
||||
@ -7,12 +8,16 @@ import isbn_db
|
||||
app = Flask(__name__)
|
||||
|
||||
app.config["DATABASE"] = "data/books.sqlite"
|
||||
app.config["SECRET_KEY"] = secrets.token_hex()
|
||||
|
||||
@app.route("/submit-isbn")
|
||||
def submit_isbn():
|
||||
if "isbn" not in request.args:
|
||||
return "/submit-isbn?isbn=xxxxxx"
|
||||
|
||||
if request.args["isbn"] == "":
|
||||
return "Pas d'ISBN spécifié"
|
||||
|
||||
try:
|
||||
book = Book(request.args["isbn"])
|
||||
except ValueError:
|
||||
@ -29,6 +34,11 @@ def submit_isbn():
|
||||
return f"{book.title} ajouté (plusieurs occurrences)"
|
||||
return f"{book.title} ajouté"
|
||||
|
||||
@app.route("/web-submit-isbn")
|
||||
def web_submit_isbn():
|
||||
flash(submit_isbn())
|
||||
return redirect("/")
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
return render_template("index.html", books=isbn_db.get_all_books())
|
||||
@ -65,6 +75,21 @@ def update_book():
|
||||
isbn_db.update_book(book)
|
||||
return redirect("/")
|
||||
|
||||
@app.route("/export-csv")
|
||||
def export_csv():
|
||||
books = isbn_db.get_all_books()
|
||||
|
||||
csv = "ISBN;Titre;Auteur;Éditeur;Date;Nombre\n"
|
||||
for book in books:
|
||||
csv += f"{book.isbn};{book.title};{book.author};{book.publisher};{book.publish_date};{book.count}\n"
|
||||
|
||||
# return as file with a good filename
|
||||
return app.response_class(
|
||||
csv,
|
||||
mimetype="text/csv",
|
||||
headers={"Content-Disposition": "attachment;filename=books.csv"}
|
||||
)
|
||||
|
||||
@app.after_request
|
||||
def after_request(response):
|
||||
"""Automatically close db after each request"""
|
||||
|
@ -1,4 +1,4 @@
|
||||
@import url('/static/font/iosevka.css');
|
||||
/*@import url('/static/font/iosevka.css');*/
|
||||
|
||||
/** Color Schemes */
|
||||
/* Themes used: Catppuccin Latte & Moccha
|
||||
@ -32,6 +32,7 @@
|
||||
--color-base: #1e1e2e;
|
||||
--color-mantle: #181825;
|
||||
--color-crust: #11111b;
|
||||
--color-action: #333d5d;
|
||||
--font-family: Iosevka Web;
|
||||
}
|
||||
|
||||
@ -64,6 +65,7 @@
|
||||
--color-base: #eff1f5;
|
||||
--color-mantle: #e6e9ef;
|
||||
--color-crust: #dce0e8;
|
||||
--color-action: #cdd6f4;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +185,7 @@ input[type=number] {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
button, input[type="submit"] {
|
||||
color: inherit;
|
||||
background-color: var(--color-crust);
|
||||
border-color: var(--color-crust);
|
||||
@ -192,9 +194,15 @@ button {
|
||||
border-width: 2px;
|
||||
padding: 5px;
|
||||
font-family: inherit;
|
||||
width: unset;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
dialog > button, dialog > form > input[type="submit"] {
|
||||
background-color: var(--color-base);
|
||||
border-color: var(--color-base);
|
||||
}
|
||||
|
||||
button:hover, input[type="submit"]:hover {
|
||||
border-color: var(--color-lavender);
|
||||
}
|
||||
|
||||
@ -247,7 +255,7 @@ table {
|
||||
margin: 3px;
|
||||
border-radius: 3px;
|
||||
box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.2);
|
||||
background-color: #cdd6f4;
|
||||
background-color: var(--color-action);
|
||||
}
|
||||
|
||||
th {
|
||||
@ -263,7 +271,7 @@ table tr:nth-child(even) td{
|
||||
|
||||
dialog {
|
||||
/* Geometry */
|
||||
border-width: 2px;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
|
||||
/* Colors */
|
||||
@ -271,4 +279,9 @@ dialog {
|
||||
color: var(--color-text);
|
||||
|
||||
min-width: 75vw;
|
||||
}
|
||||
|
||||
#add-book {
|
||||
max-width: 300px;
|
||||
margin: auto;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Table{% endblock %}
|
||||
{% block title %}Liste des livres{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
<h1>Table des livres</h1>
|
||||
@ -20,7 +20,7 @@
|
||||
<input type="text" id="edit-publisher" name="publisher"><br>
|
||||
<label for="edit-quantity">Quantité:</label><br>
|
||||
<input type="number" id="edit-quantity" name="count"><br>
|
||||
<button type="submit">Mettre à jour</button>
|
||||
<input type="submit" value="Mettre à jour">
|
||||
</form>
|
||||
<button onclick="hideEditBookDialog()">Annuler</button>
|
||||
</dialog>
|
||||
@ -29,10 +29,17 @@
|
||||
<b id="delete-book-name">Nom du livre...</b>
|
||||
<form id="delete-book-form" action="/delete-book" method="post">
|
||||
<input type="hidden" id="delete-isbn" value="" name="isbn">
|
||||
<button type="submit">Oui</button>
|
||||
<input type="submit" value="Oui">
|
||||
</form>
|
||||
<button id="cancel-delete">Annuler</button>
|
||||
</dialog>
|
||||
<div id="add-book">
|
||||
Ajouter manuellement
|
||||
<form action="web-submit-isbn">
|
||||
<input type="text" name="isbn" placeholder="ISBN">
|
||||
<input type="submit" value="Ajouter">
|
||||
</form>
|
||||
</div>
|
||||
<table id="books-table">
|
||||
<tr>
|
||||
<th>ISBN</th>
|
||||
@ -50,7 +57,7 @@
|
||||
<td><p {% if book.author == None %}class="red"{% endif %}>{{ book.author }}</p></td>
|
||||
<td><p {% if book.publish_date == None %}class="red"{% endif %}>{{ book.publish_date }}</p></td>
|
||||
<td><p {% if book.publisher == None %}class="red"{% endif %}>{{ book.publisher }}</p></td>
|
||||
<td>{{ book.count }}</td>
|
||||
<td><p {% if book.count != 1 %}class="red"{% endif %}>{{ book.count }}</p></td>
|
||||
<td>
|
||||
<button class="action" onclick="edit_book({{ book.isbn }})">✏️</button>
|
||||
<button class="action" onclick="delete_book({{ book.isbn }})">🗑️</button>
|
||||
@ -58,4 +65,6 @@
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<br/>
|
||||
<a href="/export-csv" download="books.csv">Exporter en CSV</a>
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user