Upated testresult

Bugfix book table
This commit is contained in:
Ozzie Isaacs 2021-12-05 13:04:13 +01:00
parent cd5711e651
commit d217676350
11 changed files with 3226 additions and 585 deletions

View File

@ -756,16 +756,21 @@ class CalibreDB():
except Exception as ex:
log.debug_or_exception(ex)
# display authors in right order
entries = self.order_authors(entries, True)
entries = self.order_authors(entries, True, join_archive_read)
return entries, randm, pagination
# Orders all Authors in the list according to authors sort
def order_authors(self, entries, list_return=False):
def order_authors(self, entries, list_return=False, combined=False):
for entry in entries:
sort_authors = entry.author_sort.split('&')
if combined:
sort_authors = entry.Books.author_sort.split('&')
ids = [a.id for a in entry.Books.authors]
else:
sort_authors = entry.author_sort.split('&')
ids = [a.id for a in entry.authors]
authors_ordered = list()
error = False
ids = [a.id for a in entry.authors]
for auth in sort_authors:
results = self.session.query(Authors).filter(Authors.sort == auth.lstrip().strip()).all()
# ToDo: How to handle not found authorname
@ -776,7 +781,10 @@ class CalibreDB():
if r.id in ids:
authors_ordered.append(r)
if not error:
entry.authors = authors_ordered
if combined:
entry.Books.authors = authors_ordered
else:
entry.authors = authors_ordered
if list_return:
return entries
else:
@ -841,7 +849,8 @@ class CalibreDB():
))
# read search results from calibre-database and return it (function is used for feed and simple search
def get_search_results(self, term, offset=None, order=None, limit=None, config_read_column=False, *join):
def get_search_results(self, term, offset=None, order=None, limit=None, allow_show_archived=False,
config_read_column=False, *join):
order = order[0] if order else [Books.sort]
pagination = None
result = self.search_query(term, config_read_column, *join).order_by(*order).all()

View File

@ -50,6 +50,7 @@ from .services.worker import WorkerThread
from .tasks.upload import TaskUpload
from .render_template import render_title_template
from .usermanagement import login_required_if_no_ano
from .kobo_sync_status import change_archived_books
try:
from functools import wraps
@ -1185,10 +1186,9 @@ def edit_list_book(param):
ret = Response(json.dumps({'success': True,
'newValue': ' & '.join([author.replace('|',',') for author in input_authors])}),
mimetype='application/json')
elif param =='is_archive':
# ToDo save
ret = Response(json.dumps({'success': True, 'newValue': vals['value']}),
mimetype='application/json')
elif param =='is_archived':
change_archived_books(book.id, vals['value']=="True")
ret = ""
elif param =='read_status':
# ToDo save
ret = Response(json.dumps({'success': True, 'newValue': vals['value']}),
@ -1197,8 +1197,12 @@ def edit_list_book(param):
new_val = dict()
new_val[param] = vals['value']
edit_single_cc_data(book.id, book, param[14:], new_val)
ret = Response(json.dumps({'success': True, 'newValue': vals['value']}),
mimetype='application/json')
# ToDo: Very hacky find better solution
if vals['value'] in ["True", "False"]:
ret = ""
else:
ret = Response(json.dumps({'success': True, 'newValue': vals['value']}),
mimetype='application/json')
else:
return _("Parameter not found"), 400
book.last_modified = datetime.utcnow()

View File

@ -52,7 +52,7 @@ except ImportError:
from . import calibre_db
from .tasks.convert import TaskConvert
from . import logger, config, get_locale, db, ub
from . import logger, config, get_locale, db, ub, kobo_sync_status
from . import gdriveutils as gd
from .constants import STATIC_DIR as _STATIC_DIR
from .subproc_wrapper import process_wait
@ -431,7 +431,8 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa
for file in file_list:
shutil.move(os.path.normcase(os.path.join(dir_name, file)),
os.path.normcase(os.path.join(new_path + dir_name[len(path):], file)))
# os.unlink(os.path.normcase(os.path.join(dir_name, file)))
# change location in database to new author/title path
localbook.path = os.path.join(new_authordir, new_titledir).replace('\\','/')
except (OSError) as ex:
log.error("Rename title from: %s to %s: %s", path, new_path, ex)
log.debug(ex, exc_info=True)
@ -441,12 +442,11 @@ def update_dir_structure_file(book_id, calibrepath, first_author, orignal_filepa
# Rename all files from old names to new names
try:
clean_author_database(renamed_author, calibrepath)
if first_author not in renamed_author:
clean_author_database([first_author], calibrepath, localbook)
if not renamed_author and not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0:
shutil.rmtree(os.path.dirname(path))
except (OSError) as ex:
except (OSError, FileNotFoundError) as ex:
log.error("Error in rename file in path %s", ex)
log.debug(ex, exc_info=True)
return _("Error in rename file in path: %(error)s", error=str(ex))

View File

@ -949,7 +949,8 @@ def HandleBookDeletionRequest(book_uuid):
return redirect_or_proxy_request()
book_id = book.id
archived_book = (
is_archived = kobo_sync_status.change_archived_books(book_id, True)
'''archived_book = (
ub.session.query(ub.ArchivedBook)
.filter(ub.ArchivedBook.book_id == book_id)
.first()
@ -960,8 +961,8 @@ def HandleBookDeletionRequest(book_uuid):
archived_book.last_modified = datetime.datetime.utcnow()
ub.session.merge(archived_book)
ub.session_commit()
if archived_book.is_archived:
ub.session_commit()'''
if is_archived:
kobo_sync_status.remove_synced_book(book_id)
return "", 204

View File

@ -20,7 +20,7 @@
from flask_login import current_user
from . import ub
import datetime
from sqlalchemy.sql.expression import or_
from sqlalchemy.sql.expression import or_, and_
# Add the current book id to kobo_synced_books table for current user, if entry is already present,
# do nothing (safety precaution)
@ -42,18 +42,18 @@ def remove_synced_book(book_id):
ub.session_commit()
def add_archived_books(book_id):
archived_book = (ub.session.query(ub.ArchivedBook)
.filter(ub.ArchivedBook.book_id == book_id)
.filter(ub.ArchivedBook.user_id == current_user.id)
.first())
def change_archived_books(book_id, state=None, message=None):
archived_book = ub.session.query(ub.ArchivedBook).filter(and_(ub.ArchivedBook.user_id == int(current_user.id),
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.is_archived = state if state else not archived_book.is_archived
archived_book.last_modified = datetime.datetime.utcnow()
ub.session.merge(archived_book)
ub.session_commit()
ub.session_commit(message)
return archived_book.is_archived
# select all books which are synced by the current user and do not belong to a synced shelf and them to archive
@ -65,7 +65,7 @@ def update_on_sync_shelfs(user_id):
.filter(or_(ub.Shelf.kobo_sync == 0, ub.Shelf.kobo_sync == None))
.filter(ub.KoboSyncedBooks.user_id == user_id).all())
for b in books_to_archive:
add_archived_books(b.book_id)
change_archived_books(b.book_id, True)
ub.session.query(ub.KoboSyncedBooks) \
.filter(ub.KoboSyncedBooks.book_id == b.book_id) \
.filter(ub.KoboSyncedBooks.user_id == user_id).delete()

View File

@ -528,8 +528,8 @@ def get_metadata_calibre_companion(uuid, library):
def feed_search(term):
if term:
entries, __, ___ = calibre_db.get_search_results(term, config_read_column=config.config_read_column)
entriescount = len(entries) if len(entries) > 0 else 1
pagination = Pagination(1, entriescount, entriescount)
entries_count = len(entries) if len(entries) > 0 else 1
pagination = Pagination(1, entries_count, entries_count)
return render_xml_template('feed.xml', searchterm=term, entries=entries, pagination=pagination)
else:
return render_xml_template('feed.xml', searchterm="")

View File

@ -810,10 +810,11 @@ function checkboxChange(checkbox, userId, field, field_index) {
}
function BookCheckboxChange(checkbox, userId, field) {
var value = checkbox.checked ? "True" : "False";
$.ajax({
method: "post",
url: getPath() + "/ajax/editbooks/" + field,
data: {"pk": userId, "value": checkbox.checked},
data: {"pk": userId, "value": value},
error: function(data) {
handleListServerResponse([{type:"danger", message:data.responseText}])
},

View File

@ -71,8 +71,8 @@
<!--th data-field="pubdate" data-type="date" data-visible="{{visiblility.get('pubdate')}}" data-viewformat="dd.mm.yyyy" id="pubdate" data-sortable="true">{{_('Publishing Date')}}</th-->
{{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, true) }}
<th data-field="comments" id="comments" data-escape="true" data-editable-mode="popup" data-visible="{{visiblility.get('comments')}}" data-sortable="false" {% if g.user.role_edit() %} data-editable-type="wysihtml5" data-editable-url="{{ url_for('editbook.edit_list_book', param='comments')}}" data-edit="true" data-editable-title="{{_('Enter comments')}}"{% endif %}>{{_('Comments')}}</th>
{{ book_checkbox_row('is_archived', _('Enter Archiv Status'), false)}}
{{ book_checkbox_row('read_status', _('Enter Read Status'), false)}}
{{ book_checkbox_row('is_archived', _('Archiv Status'), false)}}
{{ book_checkbox_row('read_status', _('Read Status'), false)}}
{% for c in cc %}
{% if c.datatype == "int" %}
<th data-field="custom_column_{{ c.id|string }}" id="custom_column_{{ c.id|string }}" data-visible="{{visiblility.get('custom_column_'+ c.id|string)}}" data-sortable="false" {% if g.user.role_edit() %} data-editable-type="number" data-editable-placeholder="1" data-editable-step="1" data-editable-url="{{ url_for('editbook.edit_list_book', param='custom_column_'+ c.id|string)}}" data-edit="true" data-editable-title="{{_('Enter ') + c.name}}"{% endif %}>{{c.name}}</th>
@ -89,7 +89,7 @@
{% elif c.datatype == "comments" %}
<th data-field="custom_column_{{ c.id|string }}" id="custom_column_{{ c.id|string }}" data-escape="true" data-editable-mode="popup" data-visible="{{visiblility.get('custom_column_'+ c.id|string)}}" data-sortable="false" {% if g.user.role_edit() %} data-editable-type="wysihtml5" data-editable-url="{{ url_for('editbook.edit_list_book', param='custom_column_'+ c.id|string)}}" data-edit="true" data-editable-title="{{_('Enter ') + c.name}}"{% endif %}>{{c.name}}</th>
{% elif c.datatype == "bool" %}
{{ book_checkbox_row('custom_column_' + c.id|string, _('Enter ') + c.name, c.name, visiblility, all_roles, false)}}
{{ book_checkbox_row('custom_column_' + c.id|string, c.name, false)}}
{% else %}
<!--{{ text_table_row('custom_column_' + c.id|string, _('Enter ') + c.name, c.name, false, false) }} -->
{% endif %}

View File

@ -41,21 +41,21 @@
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="cover">
{% if entry.has_cover is defined %}
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<span class="img" title="{{entry.title}}" >
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
{% if entry.id in read_book_ids %}<span class="badge read glyphicon glyphicon-ok"></span>{% endif %}
{% if entry.Books.has_cover is defined %}
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<span class="img" title="{{entry.Books.title}}" >
<img src="{{ url_for('web.get_cover', book_id=entry.Books.id) }}" alt="{{ entry.Books.title }}" />
{% if entry.Books.id in read_book_ids %}<span class="badge read glyphicon glyphicon-ok"></span>{% endif %}
</span>
</a>
{% endif %}
</div>
<div class="meta">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p title="{{entry.title}}" class="title">{{entry.title|shortentitle}}</p>
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p title="{{entry.Books.title}}" class="title">{{entry.Books.title|shortentitle}}</p>
</a>
<p class="author">
{% for author in entry.authors %}
{% for author in entry.Books.authors %}
{% if loop.index > g.config_authors_max and g.config_authors_max != 0 %}
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
@ -71,24 +71,24 @@
<a class="author-name" href="{{url_for('web.books_list', data='author', sort_param='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
{% for format in entry.data %}
{% for format in entry.Books.data %}
{% if format.format|lower in g.constants.EXTENSIONS_AUDIO %}
<span class="glyphicon glyphicon-music"></span>
{% endif %}
{% endfor %}
</p>
{% if entry.series.__len__() > 0 %}
{% if entry.Books.series.__len__() > 0 %}
<p class="series">
<a href="{{url_for('web.books_list', data='series', sort_param='new', book_id=entry.series[0].id )}}">
{{entry.series[0].name}}
<a href="{{url_for('web.books_list', data='series', sort_param='new', book_id=entry.Books.series[0].id )}}">
{{entry.Books.series[0].name}}
</a>
({{entry.series_index|formatseriesindex}})
({{entry.Books.series_index|formatseriesindex}})
</p>
{% endif %}
{% if entry.ratings.__len__() > 0 %}
{% if entry.Books.ratings.__len__() > 0 %}
<div class="rating">
{% for number in range((entry.ratings[0].rating/2)|int(2)) %}
{% for number in range((entry.Books.ratings[0].rating/2)|int(2)) %}
<span class="glyphicon glyphicon-star good"></span>
{% if loop.last and loop.index < 5 %}
{% for numer in range(5 - loop.index) %}

View File

@ -56,6 +56,7 @@ from .redirect import redirect_back
from .usermanagement import login_required_if_no_ano
from .kobo_sync_status import remove_synced_book
from .render_template import render_title_template
from .kobo_sync_status import change_archived_books
feature_support = {
'ldap': bool(services.ldap),
@ -197,17 +198,8 @@ def toggle_read(book_id):
@web.route("/ajax/togglearchived/<int:book_id>", methods=['POST'])
@login_required
def toggle_archived(book_id):
archived_book = ub.session.query(ub.ArchivedBook).filter(and_(ub.ArchivedBook.user_id == int(current_user.id),
ub.ArchivedBook.book_id == book_id)).first()
if archived_book:
archived_book.is_archived = not archived_book.is_archived
archived_book.last_modified = datetime.utcnow()
else:
archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id)
archived_book.is_archived = True
ub.session.merge(archived_book)
ub.session_commit("Book {} archivebit toggled".format(book_id))
if archived_book.is_archived:
is_archived = change_archived_books(book_id, message="Book {} archivebit toggled".format(book_id))
if is_archived:
remove_synced_book(book_id)
return ""
@ -759,6 +751,7 @@ def render_search_results(term, offset=None, order=None, limit=None):
offset,
order,
limit,
False,
config.config_read_column,
*join)
return render_title_template('search.html',
@ -836,7 +829,7 @@ def list_books():
elif not state:
order = [db.Books.timestamp.desc()]
total_count = filtered_count = calibre_db.session.query(db.Books).filter(calibre_db.common_filters(False)).count()
total_count = filtered_count = calibre_db.session.query(db.Books).filter(calibre_db.common_filters(allow_show_archived=True)).count()
if state is not None:
if search:
books = calibre_db.search_query(search, config.config_read_column).all()
@ -860,24 +853,26 @@ def list_books():
books =calibre_db.session.query(db.Books, None, ub.ArchivedBook.is_archived)
books = (books.outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id,
int(current_user.id) == ub.ArchivedBook.user_id))
.filter(calibre_db.common_filters()).all())
.filter(calibre_db.common_filters(allow_show_archived=True)).all())
entries = calibre_db.get_checkbox_sorted(books, state, off, limit, order, True)
elif search:
entries, filtered_count, __ = calibre_db.get_search_results(search,
off,
[order,''],
limit,
True,
config.config_read_column,
*join)
else:
entries, __, __ = calibre_db.fill_indexpage((int(off) / (int(limit)) + 1),
limit,
db.Books,
True,
order,
True,
config.config_read_column,
*join)
entries, __, __ = calibre_db.fill_indexpage_with_archived_books((int(off) / (int(limit)) + 1),
db.Books,
limit,
True,
order,
True,
True,
config.config_read_column,
*join)
result = list()
for entry in entries:

File diff suppressed because it is too large Load Diff