Updated testresults

Fix goodreads
Remove unused import
Limit number of routes for book pages
This commit is contained in:
Ozzie Isaacs
2025-09-20 11:21:34 +02:00
parent 6b11d0b4f3
commit a6fdd8ab36
4 changed files with 138 additions and 70 deletions

View File

@@ -29,7 +29,7 @@
from urllib.parse import urlparse, urljoin from urllib.parse import urlparse, urljoin
from flask import request, url_for, redirect, current_app from flask import request, url_for, current_app
def is_safe_url(target): def is_safe_url(target):

View File

@@ -22,7 +22,7 @@ import requests
from goodreads.client import GoodreadsClient from goodreads.client import GoodreadsClient
from goodreads.request import GoodreadsRequest from goodreads.request import GoodreadsRequest
import xmltodict from lxml import etree
try: try:
import Levenshtein import Levenshtein
@@ -33,6 +33,39 @@ from .. import logger
from ..clean_html import clean_string from ..clean_html import clean_string
def etree_to_dict(t):
"""
Convert lxml ElementTree to a nested dict (similar to xmltodict).
"""
d = {t.tag: {} if t.attrib else None}
children = list(t)
if children:
dd = {}
for dc in map(etree_to_dict, children):
for k, v in dc.items():
if k in dd:
if not isinstance(dd[k], list):
dd[k] = [dd[k]]
dd[k].append(v)
else:
dd[k] = v
d = {t.tag: dd}
if t.attrib:
d[t.tag].update(('@' + k, v) for k, v in t.attrib.items())
text = (t.text or '').strip()
if text:
if children or t.attrib:
d[t.tag]['#text'] = text
else:
d[t.tag] = text
return d
class my_GoodreadsClient(GoodreadsClient): class my_GoodreadsClient(GoodreadsClient):
def request(self, *args, **kwargs): def request(self, *args, **kwargs):
@@ -59,7 +92,9 @@ class my_GoodreadsRequest(GoodreadsRequest):
if resp.status_code != 200: if resp.status_code != 200:
raise GoodreadsRequestException(resp.reason, self.path) raise GoodreadsRequestException(resp.reason, self.path)
if self.req_format == 'xml': if self.req_format == 'xml':
data_dict = xmltodict.parse(resp.content) root = etree.fromstring(resp.content)
data_dict = etree_to_dict(root)
return data_dict['GoodreadsResponse'] return data_dict['GoodreadsResponse']
else: else:
raise Exception("Invalid format") raise Exception("Invalid format")

View File

@@ -812,14 +812,19 @@ def index(page):
return render_books_list("newest", sort_param, 1, page) return render_books_list("newest", sort_param, 1, page)
@web.route('/<data>/<sort_param>', defaults={'page': 1, 'book_id': 1})
@web.route('/<data>/<sort_param>/', defaults={'page': 1, 'book_id': 1})
@web.route('/<data>/<sort_param>/<book_id>', defaults={'page': 1})
@web.route('/<data>/<sort_param>/<book_id>/<int:page>')
@login_required_if_no_ano @login_required_if_no_ano
def books_list(data, sort_param, book_id, page): def books_list(data, sort_param, book_id, page):
return render_books_list(data, sort_param, book_id, page) return render_books_list(data, sort_param, book_id, page)
# Limit number of routes to avoid redirects
data =["rated", "discover", "unread", "read", "hot", "download", "author", "publisher", "series", "ratings", "formats",
"category", "language", "archived", "search", "advsearch", "newest"]
for d in data:
web.add_url_rule('/{}/<sort_param>'.format(d), view_func=books_list, defaults={'page': 1, 'book_id': 1, "data": d})
web.add_url_rule('/{}/<sort_param>/'.format(d), view_func=books_list, defaults={'page': 1, 'book_id': 1, "data": d})
web.add_url_rule('/{}/<sort_param>/<book_id>'.format(d), view_func=books_list, defaults={'page': 1, "data": d})
web.add_url_rule('/{}/<sort_param>/<book_id>/<int:page>'.format(d), defaults={"data": d}, view_func=books_list)
@web.route("/table") @web.route("/table")
@user_login_required @user_login_required

View File

@@ -37,20 +37,20 @@
<div class="row"> <div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;"> <div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;">
<p class='text-justify attribute'><strong>Start Time: </strong>2025-09-09 21:15:46</p> <p class='text-justify attribute'><strong>Start Time: </strong>2025-09-21 09:23:41</p>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3"> <div class="col-xs-6 col-md-6 col-sm-offset-3">
<p class='text-justify attribute'><strong>Stop Time: </strong>2025-09-10 04:34:48</p> <p class='text-justify attribute'><strong>Stop Time: </strong>2025-09-21 16:46:10</p>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3"> <div class="col-xs-6 col-md-6 col-sm-offset-3">
<p class='text-justify attribute'><strong>Duration: </strong>6h 7 min</p> <p class='text-justify attribute'><strong>Duration: </strong>6h 10 min</p>
</div> </div>
</div> </div>
</div> </div>
@@ -1670,12 +1670,12 @@
<tr id="su" class="errorClass"> <tr id="su" class="passClass">
<td>TestEditAuthorsGdrive</td> <td>TestEditAuthorsGdrive</td>
<td class="text-center">7</td> <td class="text-center">7</td>
<td class="text-center">6</td> <td class="text-center">7</td>
<td class="text-center">0</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center">1</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center"> <td class="text-center">
<a onclick="showClassDetail('c15', 7)">Detail</a> <a onclick="showClassDetail('c15', 7)">Detail</a>
@@ -1738,32 +1738,11 @@
<tr id="et15.7" class="none bg-info"> <tr id='pt15.7' class='hiddenRow bg-success'>
<td> <td>
<div class='testcase'>TestEditAuthorsGdrive - test_rename_capital_on_upload</div> <div class='testcase'>TestEditAuthorsGdrive - test_rename_capital_on_upload</div>
</td> </td>
<td colspan='6'> <td colspan='6' align='center'>PASS</td>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et15.7')">ERROR</a>
</div>
<!--css div popup start-->
<div id="div_et15.7" class="popup_window test_output" style="display:block;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
onclick="document.getElementById('div_et15.7').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File &#34;/home/ozzie/Development/calibre-web-test/test/test_edit_books_author_gdrive.py&#34;, line 592, in test_rename_capital_on_upload
self.assertEqual(&#39;Useless&#39;, details[&#39;title&#39;])
~~~~~~~^^^^^^^^^
KeyError: &#39;title&#39;</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr> </tr>
@@ -2757,11 +2736,11 @@ IndexError: list index out of range</pre>
<tr id="su" class="passClass"> <tr id="su" class="failClass">
<td>TestKoboSync</td> <td>TestKoboSync</td>
<td class="text-center">12</td> <td class="text-center">12</td>
<td class="text-center">12</td> <td class="text-center">11</td>
<td class="text-center">0</td> <td class="text-center">1</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center"> <td class="text-center">
@@ -2852,11 +2831,31 @@ IndexError: list index out of range</pre>
<tr id='pt30.10' class='hiddenRow bg-success'> <tr id="ft30.10" class="none bg-danger">
<td> <td>
<div class='testcase'>TestKoboSync - test_sync_shelf</div> <div class='testcase'>TestKoboSync - test_sync_shelf</div>
</td> </td>
<td colspan='6' align='center'>PASS</td> <td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.10')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft30.10" class="popup_window test_output" style="display:block;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
onclick="document.getElementById('div_ft30.10').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File &#34;/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py&#34;, line 373, in test_sync_shelf
self.assertEqual(1, len(data), data)
AssertionError: 1 != 0 : []</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr> </tr>
@@ -3083,13 +3082,13 @@ IndexError: list index out of range</pre>
<tr id="su" class="passClass"> <tr id="su" class="passClass">
<td>TestSecurity</td> <td>TestSecurity</td>
<td class="text-center">5</td> <td class="text-center">6</td>
<td class="text-center">5</td> <td class="text-center">6</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center"> <td class="text-center">
<a onclick="showClassDetail('c33', 5)">Detail</a> <a onclick="showClassDetail('c33', 6)">Detail</a>
</td> </td>
</tr> </tr>
@@ -3139,6 +3138,15 @@ IndexError: list index out of range</pre>
</tr> </tr>
<tr id='pt33.6' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestSecurity - test_x_forwarded_host</div>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id="su" class="passClass"> <tr id="su" class="passClass">
@@ -4782,11 +4790,11 @@ AssertionError: False is not true</pre>
<tr id="su" class="skipClass"> <tr id="su" class="failClass">
<td>TestThumbnails</td> <td>TestThumbnails</td>
<td class="text-center">8</td> <td class="text-center">8</td>
<td class="text-center">7</td> <td class="text-center">6</td>
<td class="text-center">0</td> <td class="text-center">1</td>
<td class="text-center">0</td> <td class="text-center">0</td>
<td class="text-center">1</td> <td class="text-center">1</td>
<td class="text-center"> <td class="text-center">
@@ -4859,11 +4867,31 @@ AssertionError: False is not true</pre>
<tr id='pt52.8' class='hiddenRow bg-success'> <tr id="ft52.8" class="none bg-danger">
<td> <td>
<div class='testcase'>TestThumbnails - test_sideloaded_book</div> <div class='testcase'>TestThumbnails - test_sideloaded_book</div>
</td> </td>
<td colspan='6' align='center'>PASS</td> <td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft52.8')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft52.8" class="popup_window test_output" style="display:block;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
onclick="document.getElementById('div_ft52.8').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File &#34;/home/ozzie/Development/calibre-web-test/test/test_thumbnails.py&#34;, line 317, in test_sideloaded_book
self.assertAlmostEqual(diff(BytesIO(list_cover), BytesIO(old_list_cover), delete_diff_file=True), 0.0,
AssertionError: 0.004562894976745623 != 0.0 within 0.0001 delta (0.004562894976745623 difference)</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
</tr> </tr>
@@ -6069,10 +6097,10 @@ AssertionError: False is not true</pre>
<tr id='total_row' class="text-center bg-grey"> <tr id='total_row' class="text-center bg-grey">
<td>Total</td> <td>Total</td>
<td>537</td> <td>538</td>
<td>523</td> <td>523</td>
<td>5</td> <td>7</td>
<td>2</td> <td>1</td>
<td>7</td> <td>7</td>
<td>&nbsp;</td> <td>&nbsp;</td>
</tr> </tr>
@@ -6101,7 +6129,7 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>Platform</th> <th>Platform</th>
<td>Linux 6.8.0-79-generic #79-Ubuntu SMP PREEMPT_DYNAMIC Tue Aug 12 14:42:46 UTC 2025 x86_64 x86_64</td> <td>Linux 6.8.0-83-generic #83-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep 5 21:46:54 UTC 2025 x86_64 x86_64</td>
<td>Basic</td> <td>Basic</td>
</tr> </tr>
@@ -6281,13 +6309,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestBackupMetadataGdrive</td> <td>TestBackupMetadataGdrive</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestBackupMetadataGdrive</td> <td>TestBackupMetadataGdrive</td>
</tr> </tr>
@@ -6311,13 +6339,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestCliGdrivedb</td> <td>TestCliGdrivedb</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestCliGdrivedb</td> <td>TestCliGdrivedb</td>
</tr> </tr>
@@ -6341,13 +6369,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestEbookConvertCalibreGDrive</td> <td>TestEbookConvertCalibreGDrive</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestEbookConvertCalibreGDrive</td> <td>TestEbookConvertCalibreGDrive</td>
</tr> </tr>
@@ -6371,13 +6399,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestEbookConvertGDriveKepubify</td> <td>TestEbookConvertGDriveKepubify</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestEbookConvertGDriveKepubify</td> <td>TestEbookConvertGDriveKepubify</td>
</tr> </tr>
@@ -6413,13 +6441,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestEditAuthorsGdrive</td> <td>TestEditAuthorsGdrive</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestEditAuthorsGdrive</td> <td>TestEditAuthorsGdrive</td>
</tr> </tr>
@@ -6449,13 +6477,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestEditBooksOnGdrive</td> <td>TestEditBooksOnGdrive</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestEditBooksOnGdrive</td> <td>TestEditBooksOnGdrive</td>
</tr> </tr>
@@ -6491,13 +6519,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestEmbedMetadataGdrive</td> <td>TestEmbedMetadataGdrive</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestEmbedMetadataGdrive</td> <td>TestEmbedMetadataGdrive</td>
</tr> </tr>
@@ -6521,13 +6549,13 @@ AssertionError: False is not true</pre>
<tr> <tr>
<th>google-api-python-client</th> <th>google-api-python-client</th>
<td>2.181.0</td> <td>2.182.0</td>
<td>TestSetupGdrive</td> <td>TestSetupGdrive</td>
</tr> </tr>
<tr> <tr>
<th>httplib2</th> <th>httplib2</th>
<td>0.30.0</td> <td>0.31.0</td>
<td>TestSetupGdrive</td> <td>TestSetupGdrive</td>
</tr> </tr>
@@ -6623,7 +6651,7 @@ AssertionError: False is not true</pre>
</div> </div>
<script> <script>
drawCircle(523, 5, 2, 7); drawCircle(523, 7, 1, 7);
showCase(5); showCase(5);
</script> </script>