Bugfixes kobo sync
This commit is contained in:
parent
3be47d6e57
commit
ac54899415
|
@ -40,7 +40,7 @@ from sqlalchemy.exc import IntegrityError, OperationalError, InvalidRequestError
|
||||||
from sqlalchemy.sql.expression import func, or_, text
|
from sqlalchemy.sql.expression import func, or_, text
|
||||||
|
|
||||||
from . import constants, logger, helper, services
|
from . import constants, logger, helper, services
|
||||||
from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils
|
from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils, kobo_sync_status
|
||||||
from .helper import check_valid_domain, send_test_mail, reset_password, generate_password_hash, check_email, \
|
from .helper import check_valid_domain, send_test_mail, reset_password, generate_password_hash, check_email, \
|
||||||
valid_email, check_username
|
valid_email, check_username
|
||||||
from .gdriveutils import is_gdrive_ready, gdrive_support
|
from .gdriveutils import is_gdrive_ready, gdrive_support
|
||||||
|
@ -1432,8 +1432,13 @@ def _handle_edit_user(to_save, content, languages, translations, kobo_support):
|
||||||
else:
|
else:
|
||||||
content.sidebar_view &= ~constants.DETAIL_RANDOM
|
content.sidebar_view &= ~constants.DETAIL_RANDOM
|
||||||
|
|
||||||
|
old_state = content.kobo_only_shelves_sync
|
||||||
content.kobo_only_shelves_sync = int(to_save.get("kobo_only_shelves_sync") == "on") or 0
|
content.kobo_only_shelves_sync = int(to_save.get("kobo_only_shelves_sync") == "on") or 0
|
||||||
|
# 1 -> 0: nothing has to be done
|
||||||
|
# 0 -> 1: all synced books have to be added to archived books, + currently synced shelfs
|
||||||
|
# which don't have to be synced have to be removed (added to Shelf archive)
|
||||||
|
if old_state == 0 and content.kobo_only_shelves_sync == 1:
|
||||||
|
kobo_sync_status.update_on_sync_shelfs(content.id)
|
||||||
if to_save.get("default_language"):
|
if to_save.get("default_language"):
|
||||||
content.default_language = to_save["default_language"]
|
content.default_language = to_save["default_language"]
|
||||||
if to_save.get("locale"):
|
if to_save.get("locale"):
|
||||||
|
|
|
@ -173,11 +173,9 @@ def HandleSyncRequest():
|
||||||
.join(ub.KoboSyncedBooks, ub.KoboSyncedBooks.book_id == db.Books.id, isouter=True)
|
.join(ub.KoboSyncedBooks, ub.KoboSyncedBooks.book_id == db.Books.id, isouter=True)
|
||||||
.filter(or_(ub.KoboSyncedBooks.user_id != current_user.id,
|
.filter(or_(ub.KoboSyncedBooks.user_id != current_user.id,
|
||||||
ub.KoboSyncedBooks.book_id == None))
|
ub.KoboSyncedBooks.book_id == None))
|
||||||
#.filter(or_(db.Books.last_modified > sync_token.books_last_modified,
|
.filter(ub.BookShelf.date_added > sync_token.books_last_modified)
|
||||||
# ub.BookShelf.date_added > sync_token.books_last_modified))
|
|
||||||
.filter(ub.BookShelf.date_added > sync_token.books_last_modified) #?? or also or from above
|
|
||||||
.filter(db.Data.format.in_(KOBO_FORMATS))
|
.filter(db.Data.format.in_(KOBO_FORMATS))
|
||||||
.filter(calibre_db.common_filters())
|
.filter(calibre_db.common_filters(allow_show_archived=True))
|
||||||
.order_by(db.Books.id)
|
.order_by(db.Books.id)
|
||||||
.order_by(ub.ArchivedBook.last_modified)
|
.order_by(ub.ArchivedBook.last_modified)
|
||||||
.join(ub.BookShelf, db.Books.id == ub.BookShelf.book_id)
|
.join(ub.BookShelf, db.Books.id == ub.BookShelf.book_id)
|
||||||
|
@ -204,8 +202,6 @@ def HandleSyncRequest():
|
||||||
.order_by(db.Books.id)
|
.order_by(db.Books.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
#if sync_token.books_last_id > -1:
|
|
||||||
# changed_entries = changed_entries.filter(db.Books.id > sync_token.books_last_id)
|
|
||||||
|
|
||||||
reading_states_in_new_entitlements = []
|
reading_states_in_new_entitlements = []
|
||||||
if sqlalchemy_version2:
|
if sqlalchemy_version2:
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from . import ub
|
from . import ub
|
||||||
|
import datetime
|
||||||
|
from sqlalchemy.sql.expression import or_
|
||||||
|
|
||||||
|
|
||||||
def add_synced_books(book_id):
|
def add_synced_books(book_id):
|
||||||
|
@ -32,3 +34,38 @@ def add_synced_books(book_id):
|
||||||
def remove_synced_book(book_id):
|
def remove_synced_book(book_id):
|
||||||
ub.session.query(ub.KoboSyncedBooks).filter(ub.KoboSyncedBooks.book_id == book_id).delete()
|
ub.session.query(ub.KoboSyncedBooks).filter(ub.KoboSyncedBooks.book_id == book_id).delete()
|
||||||
ub.session_commit()
|
ub.session_commit()
|
||||||
|
|
||||||
|
def add_archived_books(book_id):
|
||||||
|
archived_book = (
|
||||||
|
ub.session.query(ub.ArchivedBook)
|
||||||
|
.filter(ub.ArchivedBook.book_id == book_id)
|
||||||
|
.first()
|
||||||
|
)
|
||||||
|
if not archived_book:
|
||||||
|
archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id)
|
||||||
|
archived_book.is_archived = True
|
||||||
|
archived_book.last_modified = datetime.datetime.utcnow()
|
||||||
|
|
||||||
|
ub.session.merge(archived_book)
|
||||||
|
ub.session_commit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# select all books which are synced by the current user and do not belong to a synced shelf and them to archive
|
||||||
|
# select all shelfs from current user which are synced and do not belong to the "only sync" shelfs
|
||||||
|
def update_on_sync_shelfs(content_id):
|
||||||
|
books_to_archive = (ub.session.query(ub.KoboSyncedBooks)
|
||||||
|
.join(ub.BookShelf, ub.KoboSyncedBooks.book_id == ub.BookShelf.book_id, isouter=True)
|
||||||
|
.join(ub.Shelf, ub.Shelf.user_id == content_id, isouter=True)
|
||||||
|
.filter(or_(ub.Shelf.kobo_sync == 0, ub.Shelf.kobo_sync == None))
|
||||||
|
.filter(ub.KoboSyncedBooks.user_id == content_id).all())
|
||||||
|
for b in books_to_archive:
|
||||||
|
add_archived_books(b.book_id)
|
||||||
|
ub.session.query(ub.KoboSyncedBooks).filter(ub.KoboSyncedBooks.book_id == b.book_id).filter(ub.KoboSyncedBooks.user_id == content_id).delete()
|
||||||
|
ub.session_commit()
|
||||||
|
|
||||||
|
shelfs_to_archive = ub.session.query(ub.Shelf).filter(ub.Shelf.user_id == content_id).filter(
|
||||||
|
ub.Shelf.kobo_sync == 0).all()
|
||||||
|
for a in shelfs_to_archive:
|
||||||
|
ub.session.add(ub.ShelfArchive(uuid=a.uuid, user_id=content_id))
|
||||||
|
ub.session_commit()
|
||||||
|
|
14
cps/web.py
14
cps/web.py
|
@ -46,7 +46,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
from . import constants, logger, isoLanguages, services
|
from . import constants, logger, isoLanguages, services
|
||||||
from . import babel, db, ub, config, get_locale, app
|
from . import babel, db, ub, config, get_locale, app
|
||||||
from . import calibre_db
|
from . import calibre_db, kobo_sync_status
|
||||||
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
|
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
|
||||||
from .helper import check_valid_domain, render_task_status, check_email, check_username, \
|
from .helper import check_valid_domain, render_task_status, check_email, check_username, \
|
||||||
get_cc_columns, get_book_cover, get_download_link, send_mail, generate_random_password, \
|
get_cc_columns, get_book_cover, get_download_link, send_mail, generate_random_password, \
|
||||||
|
@ -1628,7 +1628,13 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations,
|
||||||
current_user.default_language = to_save["default_language"]
|
current_user.default_language = to_save["default_language"]
|
||||||
if to_save.get("locale"):
|
if to_save.get("locale"):
|
||||||
current_user.locale = to_save["locale"]
|
current_user.locale = to_save["locale"]
|
||||||
|
old_state = current_user.kobo_only_shelves_sync
|
||||||
|
# 1 -> 0: nothing has to be done
|
||||||
|
# 0 -> 1: all synced books have to be added to archived books, + currently synced shelfs which
|
||||||
|
# don't have to be synced have to be removed (added to Shelf archive)
|
||||||
current_user.kobo_only_shelves_sync = int(to_save.get("kobo_only_shelves_sync") == "on") or 0
|
current_user.kobo_only_shelves_sync = int(to_save.get("kobo_only_shelves_sync") == "on") or 0
|
||||||
|
if old_state == 0 and current_user.kobo_only_shelves_sync == 1:
|
||||||
|
kobo_sync_status.update_on_sync_shelfs(current_user.id)
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
flash(str(ex), category="error")
|
flash(str(ex), category="error")
|
||||||
|
@ -1754,12 +1760,6 @@ def show_book(book_id):
|
||||||
for index in range(0, len(entries.languages)):
|
for index in range(0, len(entries.languages)):
|
||||||
entries.languages[index].language_name = isoLanguages.get_language_name(get_locale(), entries.languages[
|
entries.languages[index].language_name = isoLanguages.get_language_name(get_locale(), entries.languages[
|
||||||
index].lang_code)
|
index].lang_code)
|
||||||
#try:
|
|
||||||
# entries.languages[index].language_name = isoLanguages.get_language_name(get_locale(), LC.parse(entries.languages[index].lang_code)
|
|
||||||
# .get_language_name(get_locale())
|
|
||||||
#except UnknownLocaleError:
|
|
||||||
# entries.languages[index].language_name = _(
|
|
||||||
# isoLanguages.get(part3=entries.languages[index].lang_code).name)
|
|
||||||
cc = get_cc_columns(filter_config_custom_read=True)
|
cc = get_cc_columns(filter_config_custom_read=True)
|
||||||
book_in_shelfs = []
|
book_in_shelfs = []
|
||||||
shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
|
shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
|
||||||
|
|
|
@ -37,14 +37,14 @@
|
||||||
<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>2021-10-07 20:52:54</p>
|
<p class='text-justify attribute'><strong>Start Time: </strong>2021-10-09 19:48:39</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>2021-10-08 00:16:00</p>
|
<p class='text-justify attribute'><strong>Stop Time: </strong>2021-10-09 23:11:14</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -592,8 +592,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="text-left pull-left">
|
<div class="text-left pull-left">
|
||||||
<pre class="text-left">Traceback (most recent call last):
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 330, in test_convert_only
|
File "/home/ozzie/Development/calibre-web-test/test/test_ebook_convert_gdrive.py", line 332, in test_convert_only
|
||||||
self.assertEqual(ret[-3]['result'], 'Finished')
|
self.assertEqual(ret[-2]['result'], 'Finished')
|
||||||
AssertionError: 'Failed' != 'Finished'
|
AssertionError: 'Failed' != 'Finished'
|
||||||
- Failed
|
- Failed
|
||||||
+ Finished</pre>
|
+ Finished</pre>
|
||||||
|
@ -1810,13 +1810,13 @@ AttributeError: 'bool' object has no attribute 'text'</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="su" class="errorClass">
|
<tr id="su" class="skipClass">
|
||||||
<td>TestKoboSync</td>
|
<td>TestKoboSync</td>
|
||||||
<td class="text-center">10</td>
|
<td class="text-center">10</td>
|
||||||
<td class="text-center">6</td>
|
<td class="text-center">9</td>
|
||||||
<td class="text-center">3</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">1</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a onclick="showClassDetail('c21', 10)">Detail</a>
|
<a onclick="showClassDetail('c21', 10)">Detail</a>
|
||||||
</td>
|
</td>
|
||||||
|
@ -1842,31 +1842,11 @@ AttributeError: 'bool' object has no attribute 'text'</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="et21.3" class="none bg-info">
|
<tr id='st21.3' class='none bg-warning'>
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestKoboSync - test_kobo_sync_selected_shelfs</div>
|
<div class='testcase'>TestKoboSync - test_kobo_sync_selected_shelfs</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6'>
|
<td colspan='6' align='center'>SKIP</td>
|
||||||
<div class="text-center">
|
|
||||||
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et21.3')">ERROR</a>
|
|
||||||
</div>
|
|
||||||
<!--css div popup start-->
|
|
||||||
<div id="div_et21.3" 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_et21.3').style.display='none'"><span
|
|
||||||
aria-hidden="true">×</span></button>
|
|
||||||
</div>
|
|
||||||
<div class="text-left pull-left">
|
|
||||||
<pre class="text-left">Traceback (most recent call last):
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 618, in test_kobo_sync_selected_shelfs
|
|
||||||
self.assertIn("NewTag", data3[2])
|
|
||||||
IndexError: list index out of range</pre>
|
|
||||||
</div>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
<!--css div popup end-->
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1880,31 +1860,11 @@ IndexError: list index out of range</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="ft21.5" class="none bg-danger">
|
<tr id='pt21.5' class='hiddenRow bg-success'>
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestKoboSync - test_sync_changed_book</div>
|
<div class='testcase'>TestKoboSync - test_sync_changed_book</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_ft21.5')">FAIL</a>
|
|
||||||
</div>
|
|
||||||
<!--css div popup start-->
|
|
||||||
<div id="div_ft21.5" 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_ft21.5').style.display='none'"><span
|
|
||||||
aria-hidden="true">×</span></button>
|
|
||||||
</div>
|
|
||||||
<div class="text-left pull-left">
|
|
||||||
<pre class="text-left">Traceback (most recent call last):
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 285, in test_sync_changed_book
|
|
||||||
self.assertEqual(1, len(data))
|
|
||||||
AssertionError: 1 != 0</pre>
|
|
||||||
</div>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
<!--css div popup end-->
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1927,31 +1887,11 @@ AssertionError: 1 != 0</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="ft21.8" class="none bg-danger">
|
<tr id='pt21.8' class='hiddenRow bg-success'>
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestKoboSync - test_sync_shelf</div>
|
<div class='testcase'>TestKoboSync - test_sync_shelf</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_ft21.8')">FAIL</a>
|
|
||||||
</div>
|
|
||||||
<!--css div popup start-->
|
|
||||||
<div id="div_ft21.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_ft21.8').style.display='none'"><span
|
|
||||||
aria-hidden="true">×</span></button>
|
|
||||||
</div>
|
|
||||||
<div class="text-left pull-left">
|
|
||||||
<pre class="text-left">Traceback (most recent call last):
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 303, in test_sync_shelf
|
|
||||||
self.assertEqual(1, len(data))
|
|
||||||
AssertionError: 1 != 0</pre>
|
|
||||||
</div>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
<!--css div popup end-->
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1965,31 +1905,11 @@ AssertionError: 1 != 0</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="ft21.10" class="none bg-danger">
|
<tr id='pt21.10' class='hiddenRow bg-success'>
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestKoboSync - test_sync_upload</div>
|
<div class='testcase'>TestKoboSync - test_sync_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_ft21.10')">FAIL</a>
|
|
||||||
</div>
|
|
||||||
<!--css div popup start-->
|
|
||||||
<div id="div_ft21.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_ft21.10').style.display='none'"><span
|
|
||||||
aria-hidden="true">×</span></button>
|
|
||||||
</div>
|
|
||||||
<div class="text-left pull-left">
|
|
||||||
<pre class="text-left">Traceback (most recent call last):
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 269, in test_sync_upload
|
|
||||||
self.assertEqual(1, len(data))
|
|
||||||
AssertionError: 1 != 0</pre>
|
|
||||||
</div>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
<!--css div popup end-->
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
@ -4093,10 +4013,10 @@ AssertionError: True is not false</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>353</td>
|
<td>353</td>
|
||||||
<td>341</td>
|
<td>344</td>
|
||||||
<td>5</td>
|
|
||||||
<td>2</td>
|
<td>2</td>
|
||||||
<td>5</td>
|
<td>1</td>
|
||||||
|
<td>6</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -4496,7 +4416,7 @@ AssertionError: True is not false</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
drawCircle(341, 5, 2, 5);
|
drawCircle(344, 2, 1, 6);
|
||||||
showCase(5);
|
showCase(5);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user