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