Skip to content

Commit db08261

Browse files
authored
Merge pull request #50 from seanboyce/dev
Add error handling to ISBN Auto-add
2 parents 7aa65c2 + 3c32c22 commit db08261

9 files changed

Lines changed: 345 additions & 15 deletions

File tree

templates/FR/config.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ <h1>Modifier la configuration de la Librairie</h1>
4949

5050
</form>
5151
<a style = "border:none;" href = "/backups"> <button>Gestion des backups</button></a>
52+
<a style = "border:none;" href = "/backups"> <button>Statistiques</button></a>
5253
<a style = "border:none;" href = "/"> <button>Retour</button></a>
5354
</div>
5455

templates/FR/stats.html

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
{% extends "base.html" %}
2+
{% block main %}
3+
4+
<!-- Banner -->
5+
<!-- Two -->
6+
<section id="two">
7+
<div class="inner" style = "padding: 20px 0 1em 0;">
8+
9+
{% for error in errors %}
10+
<p style="color: red">{{ error }}</p>
11+
{% endfor %}
12+
<!-- Search Input-->
13+
14+
<form style = "margin-bottom:0px;" onsubmit="stats();return false;">
15+
<span>Options:&nbsp;&nbsp;<br class="mobileshow"></span><br>
16+
<input type="radio" id="is_count" name="countSum" onclick="countContent();" value="False" checked>
17+
<label for="is_count">Comptez</label><br>
18+
<input type="radio" id="is_sum" name="countSum" onclick="sumContent();" value="True">
19+
<label for="is_sum">Additionez</label><br>
20+
<label for="groupBy">Grouper par :</label>
21+
<select style="margin-bottom:10px;" name="groupBy" id="groupBy">
22+
{% if fields %}
23+
<option value="">Sélectionnez un champ</option>
24+
{% for field in fields %}
25+
{% if field == "customField1" %}
26+
<option value='customField1'>{{ config.customFieldName1 }}</option>
27+
{% elif field == "customField2" %}
28+
<option value='customField2'>{{ config.customFieldName2 }}</option>
29+
{% else %}
30+
<option value='{{ field }}'>{{ field }}</option>
31+
{% endif %}
32+
{% endfor %}
33+
{% else %}
34+
<option value="">Erreur lors de la récupération des champs de la base de données. Cela ne devrait jamais se produire.</option>
35+
{% endif %}
36+
</select>
37+
<span id="hide_if_count" style="display:none">
38+
<label for="target">Champ à additionner (les valeurs non numériques sont ignorées)</label>
39+
<select style="margin-bottom:10px;" name="target" id="target">
40+
{% if fields %}
41+
<option value="">Sélectionnez un champ</option>
42+
{% for field in fields %}
43+
{% if field == "customField1" %}
44+
<option value='customField1'>{{ config.customFieldName1 }}</option>
45+
{% elif field == "customField2" %}
46+
<option value='customField2'>{{ config.customFieldName2 }}</option>
47+
{% else %}
48+
<option value='{{ field }}'>{{ field }}</option>
49+
{% endif %}
50+
{% endfor %}
51+
{% else %}
52+
<option value="">Erreur lors de la récupération des champs de la base de données. Cela ne devrait jamais se produire.</option>
53+
{% endif %}
54+
</select>
55+
</span>
56+
<input style ="float:left;" type="submit" value="Summarize!">
57+
</form>
58+
<br><br>
59+
60+
<h2 id="result_count" style="margin-top:25px; margin-bottom:15px;">Résultats</h2>
61+
62+
<div class="container">
63+
<p id="results">Aucun résultat</p>
64+
</div>
65+
66+
</div>
67+
68+
</section>
69+
70+
<script>
71+
//Default view is to show first 50 books until user enters something into search
72+
73+
var itemdata = [];
74+
//Core search function
75+
async function stats() {
76+
//reset pagination on new search
77+
var isSum = document.getElementById("is_sum").checked;
78+
if (isSum === true) {
79+
var target = document.getElementById("target").value;
80+
} else {
81+
var target = document.getElementById("groupBy").value;
82+
}
83+
var groupBy = document.getElementById("groupBy").value;
84+
var data = JSON.stringify({"isSum": isSum, "group": groupBy,"target": target});
85+
console.log(data);
86+
var xhr = new XMLHttpRequest();
87+
var url = "/stats";
88+
xhr.open("POST", url, true);
89+
xhr.setRequestHeader("Content-Type", "application/json");
90+
xhr.onreadystatechange = function () {
91+
if (xhr.readyState === 4 && xhr.status === 200) {
92+
tableIt((JSON.parse(xhr.responseText)));
93+
94+
}
95+
};
96+
xhr.send(data);
97+
}
98+
99+
function tableIt(resData){
100+
var table_str = '<table><thead><tr><th>Article</th><th>Valeur</th></tr></thead>';
101+
table_str += '<tbody>';
102+
$.each(resData, function(key, value){
103+
table_str +='<tr><td>'+key+'</td><td>'+value+'</td></tr>';
104+
});
105+
$("#results").html(table_str);
106+
}
107+
108+
function countContent(){
109+
document.getElementById("hide_if_count").style.display = "none";
110+
}
111+
112+
function sumContent(){
113+
document.getElementById("hide_if_count").style.display = "block";
114+
115+
}
116+
</script>
117+
{% endblock %}

templates/bookDetails.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ <h3><strong><u>Book Details</strong></u></h3>
1515
<p><strong>Summary</strong>: {{ book.summary}}</p>
1616
<p><strong>Genre</strong>: {{ book.genre}}</p>
1717
<p><strong>Library</strong>: {{ book.library}}</p>
18-
<p><strong>Shelf</strong>: {{book.shelf}}</p>
18+
<p><strong>Location</strong>: {{book.shelf}}</p>
1919

2020
</div>
2121
<div style="width:30%; min-width: 280px; float:left;">

templates/config.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ <h1>Update Library Configuration</h1>
4545

4646
</form>
4747
<a style = "border:none;" href = "/backups"> <button>Backup Management</button></a>
48+
<a style = "border:none;" href = "/stats"> <button>Library Stats</button></a>
4849
<a style = "border:none;" href = "/"> <button>Back</button></a>
4950
</div>
5051

templates/newBook.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ <h1>Add a New Book</h1>
6868
</p>
6969

7070
<p>
71-
<p><label for="">Shelf</label></p>
71+
<p><label for="">Location</label></p>
7272
<input type="text" name="shelf" value="{{ shelf }}" >
7373
</p>
7474

@@ -162,7 +162,7 @@ <h1>Add a New Book</h1>
162162
</p>
163163

164164
<p>
165-
<p><label for="">Shelf</label></p>
165+
<p><label for="">Location</label></p>
166166
<input type="text" name="shelf" value="{{ shelf }}" >
167167
</p>
168168

templates/stats.html

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
{% extends "base.html" %}
2+
{% block main %}
3+
4+
<!-- Banner -->
5+
<!-- Two -->
6+
<section id="two">
7+
<div class="inner" style = "padding: 20px 0 1em 0;">
8+
9+
{% for error in errors %}
10+
<p style="color: red">{{ error }}</p>
11+
{% endfor %}
12+
<!-- Search Input-->
13+
14+
<form style = "margin-bottom:0px;" onsubmit="stats();return false;">
15+
<span>Options:&nbsp;&nbsp;<br class="mobileshow"></span><br>
16+
<input type="radio" id="is_count" name="countSum" onclick="countContent();" value="False" checked>
17+
<label for="is_count">Count</label><br>
18+
<input type="radio" id="is_sum" name="countSum" onclick="sumContent();" value="True">
19+
<label for="is_sum">Sum</label><br>
20+
<label for="groupBy">Field to group by:</label>
21+
<select style="margin-bottom:10px;" name="groupBy" id="groupBy">
22+
{% if fields %}
23+
<option value="">Select a field to query</option>
24+
{% for field in fields %}
25+
{% if field == "customField1" %}
26+
<option value='customField1'>{{ config.customFieldName1 }}</option>
27+
{% elif field == "customField2" %}
28+
<option value='customField2'>{{ config.customFieldName2 }}</option>
29+
{% else %}
30+
<option value='{{ field }}'>{{ field }}</option>
31+
{% endif %}
32+
{% endfor %}
33+
{% else %}
34+
<option value="">Error fetching database fields. This should never happen.</option>
35+
{% endif %}
36+
</select>
37+
<span id="hide_if_count" style="display:none">
38+
<label for="target">Field to sum by (non-number contents ignored)</label>
39+
<select style="margin-bottom:10px;" name="target" id="target">
40+
{% if fields %}
41+
<option value="">Select a field to query</option>
42+
{% for field in fields %}
43+
{% if field == "customField1" %}
44+
<option value='customField1'>{{ config.customFieldName1 }}</option>
45+
{% elif field == "customField2" %}
46+
<option value='customField2'>{{ config.customFieldName2 }}</option>
47+
{% else %}
48+
<option value='{{ field }}'>{{ field }}</option>
49+
{% endif %}
50+
{% endfor %}
51+
{% else %}
52+
<option value="">Error fetching database fields. This should never happen.</option>
53+
{% endif %}
54+
</select>
55+
</span>
56+
<input style ="float:left;" type="submit" value="Summarize!">
57+
</form>
58+
<br><br>
59+
60+
<h2 id="result_count" style="margin-top:25px; margin-bottom:15px;">Results</h2>
61+
62+
<div class="container">
63+
<p id="results">No results yet.</p>
64+
</div>
65+
66+
</div>
67+
68+
</section>
69+
70+
<script>
71+
//Default view is to show first 50 books until user enters something into search
72+
73+
var itemdata = [];
74+
//Core search function
75+
async function stats() {
76+
//reset pagination on new search
77+
var isSum = document.getElementById("is_sum").checked;
78+
if (isSum === true) {
79+
var target = document.getElementById("target").value;
80+
} else {
81+
var target = document.getElementById("groupBy").value;
82+
}
83+
var groupBy = document.getElementById("groupBy").value;
84+
var data = JSON.stringify({"isSum": isSum, "group": groupBy,"target": target});
85+
console.log(data);
86+
var xhr = new XMLHttpRequest();
87+
var url = "/stats";
88+
xhr.open("POST", url, true);
89+
xhr.setRequestHeader("Content-Type", "application/json");
90+
xhr.onreadystatechange = function () {
91+
if (xhr.readyState === 4 && xhr.status === 200) {
92+
tableIt((JSON.parse(xhr.responseText)));
93+
94+
}
95+
};
96+
xhr.send(data);
97+
}
98+
99+
function tableIt(resData){
100+
var table_str = '<table><thead><tr><th>Item</th><th>Value</th></tr></thead>';
101+
table_str += '<tbody>';
102+
$.each(resData, function(key, value){
103+
table_str +='<tr><td>'+key+'</td><td>'+value+'</td></tr>';
104+
});
105+
$("#results").html(table_str);
106+
}
107+
108+
function countContent(){
109+
document.getElementById("hide_if_count").style.display = "none";
110+
}
111+
112+
function sumContent(){
113+
document.getElementById("hide_if_count").style.display = "block";
114+
115+
}
116+
</script>
117+
{% endblock %}

templates/updateBook.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ <h1>Update a Book</h1>
6969
<input type="text" name="library" value="{{ book.library }}">
7070
</p>
7171
<p>
72-
<p><label for="">Shelf</label></p>
72+
<p><label for="">Location</label></p>
7373
<input type="text" name="shelf" value="{{ book.shelf }}" >
7474
</p>
7575
<p>

ubiblio/crud.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,61 +103,61 @@ def searchBooks(db: Session, title, author, skip: int, onlyEbooks: bool, noEbook
103103
models.Book.author.icontains(author)) & (models.Book.owned==True) & (models.Book.ebook==True))).with_entities(func.count()).scalar()
104104
result = db.query(models.Book).filter(
105105
(or_(models.Book.title.icontains(title),
106-
models.Book.author.icontains(author)) & (models.Book.owned==True) & (models.Book.ebook==True))).limit(limit).offset(skip).all()
106+
models.Book.author.icontains(author)) & (models.Book.owned==True) & (models.Book.ebook==True))).order_by(models.Book.title.asc()).limit(limit).offset(skip).all()
107107
return result, resultCount
108108
elif (onlyEbooks==False) and (noEbooks==True):
109109
resultCount = db.query(models.Book).filter(
110110
(or_(models.Book.title.icontains(title),
111111
models.Book.author.icontains(author)) & (models.Book.owned==True) & (models.Book.ebook==False))).with_entities(func.count()).scalar()
112112
result = db.query(models.Book).filter(
113113
(or_(models.Book.title.icontains(title),
114-
models.Book.author.icontains(author)) & (models.Book.owned==True) & (models.Book.ebook==False))).limit(limit).offset(skip).all()
114+
models.Book.author.icontains(author)) & (models.Book.owned==True) & (models.Book.ebook==False))).order_by(models.Book.title.asc()).limit(limit).offset(skip).all()
115115
return result, resultCount
116116
else:
117117
resultCount = db.query(models.Book).filter(
118118
or_(models.Book.title.icontains(title),
119119
models.Book.author.icontains(author)) & (models.Book.owned==True)).with_entities(func.count()).scalar()
120120
result = db.query(models.Book).filter(
121121
or_(models.Book.title.icontains(title),
122-
models.Book.author.icontains(author)) & (models.Book.owned==True)).limit(limit).offset(skip).all()
122+
models.Book.author.icontains(author)) & (models.Book.owned==True)).order_by(models.Book.title.asc()).limit(limit).offset(skip).all()
123123
return result, resultCount
124124

125125
def searchBooksbyAuthor(db: Session, author, skip: int, onlyEbooks: bool, noEbooks:bool, limit: int = 50):
126126
if (onlyEbooks==True) and (noEbooks==False):
127127
resultCount = db.query(models.Book).filter(
128128
models.Book.author.icontains(author) & (models.Book.owned==True) & (models.Book.ebook==True)).with_entities(func.count()).scalar()
129129
result = db.query(models.Book).filter(
130-
models.Book.author.icontains(author) & (models.Book.owned==True) & (models.Book.ebook==True)).limit(limit).offset(skip).all()
130+
models.Book.author.icontains(author) & (models.Book.owned==True) & (models.Book.ebook==True)).order_by(models.Book.author.asc()).limit(limit).offset(skip).all()
131131
return result, resultCount
132132
elif (onlyEbooks==False) and (noEbooks==True):
133133
result = db.query(models.Book).filter(
134-
models.Book.author.icontains(author) & (models.Book.owned==True) & (models.Book.ebook==False)).limit(limit).offset(skip).all()
134+
models.Book.author.icontains(author) & (models.Book.owned==True) & (models.Book.ebook==False)).order_by(models.Book.author.asc()).limit(limit).offset(skip).all()
135135
resultCount = db.query(models.Book).filter(
136136
models.Book.author.icontains(author) & (models.Book.owned==True) & (models.Book.ebook==False)).with_entities(func.count()).scalar()
137137
return result, resultCount
138138
else:
139139
result = db.query(models.Book).filter(
140-
models.Book.author.icontains(author) & (models.Book.owned==True)).limit(limit).offset(skip).all()
140+
models.Book.author.icontains(author) & (models.Book.owned==True)).order_by(models.Book.author.asc()).limit(limit).offset(skip).all()
141141
resultCount = db.query(models.Book).filter(
142142
models.Book.author.icontains(author) & (models.Book.owned==True)).with_entities(func.count()).scalar()
143143
return result, resultCount
144144

145145
def searchBooksbyTitle(db: Session, title, skip: int, onlyEbooks: bool, noEbooks:bool, limit: int = 50):
146146
if (onlyEbooks==True) and (noEbooks==False):
147147
result = db.query(models.Book).filter(
148-
models.Book.title.icontains(title) & (models.Book.owned==True) & (models.Book.ebook==True)).limit(limit).offset(skip).all()
148+
models.Book.title.icontains(title) & (models.Book.owned==True) & (models.Book.ebook==True)).order_by(models.Book.title.asc()).limit(limit).offset(skip).all()
149149
resultCount = db.query(models.Book).filter(
150150
models.Book.title.icontains(title) & (models.Book.owned==True) & (models.Book.ebook==True)).with_entities(func.count()).scalar()
151151
return result, resultCount
152152
elif (onlyEbooks==False) and (noEbooks==True):
153153
result = db.query(models.Book).filter(
154-
models.Book.title.icontains(title) & (models.Book.owned==True) & (models.Book.ebook==False)).limit(limit).offset(skip).all()
154+
models.Book.title.icontains(title) & (models.Book.owned==True) & (models.Book.ebook==False)).order_by(models.Book.title.asc()).limit(limit).offset(skip).all()
155155
resultCount = db.query(models.Book).filter(
156156
models.Book.title.icontains(title) & (models.Book.owned==True) & (models.Book.ebook==False)).with_entities(func.count()).scalar()
157157
return result, resultCount
158158
else:
159159
result = db.query(models.Book).filter(
160-
models.Book.title.icontains(title) & (models.Book.owned==True)).limit(limit).offset(skip).all()
160+
models.Book.title.icontains(title) & (models.Book.owned==True)).order_by(models.Book.title.asc()).limit(limit).offset(skip).all()
161161
resultCount = db.query(models.Book).filter(
162162
models.Book.title.icontains(title) & (models.Book.owned==True)).with_entities(func.count()).scalar()
163163
return result, resultCount
@@ -610,3 +610,25 @@ def updateVkey(db: Session, newKey: schemas.vkey):
610610
except Exception as e:
611611
print(e)
612612
return False
613+
614+
615+
def stats(db: Session, isSum, group, target):
616+
if (isSum == True) and (len(group)) == 0:
617+
results = db.query(getattr(models.Book, target), func.sum(getattr(models.Book, target))).all()
618+
return dict(results)
619+
elif (isSum == False) and (len(group)) == 0:
620+
results = db.query(getattr(models.Book, target), func.count()).all()
621+
return dict(results)
622+
elif (isSum == True) and (len(group)) != 0:
623+
results = db.query(getattr(models.Book, group), func.sum(getattr(models.Book, target))).group_by(getattr(models.Book, group)).all()
624+
return dict(results)
625+
else:
626+
results = db.query(getattr(models.Book, target), func.count()).group_by(getattr(models.Book, group)).all()
627+
return dict(results)
628+
629+
#def advancedSearch(db: Session, isSum, group, target):
630+
#author,title,location, genre
631+
#ebook / not ebook
632+
#ISBN
633+
#library, shelf
634+
#2 custom fields

0 commit comments

Comments
 (0)