mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-25 09:30:31 +00:00
Upated testresult
Bugfix book table
This commit is contained in:
parent
cd5711e651
commit
d217676350
17
cps/db.py
17
cps/db.py
@ -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:
|
||||
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,6 +781,9 @@ class CalibreDB():
|
||||
if r.id in ids:
|
||||
authors_ordered.append(r)
|
||||
if not error:
|
||||
if combined:
|
||||
entry.Books.authors = authors_ordered
|
||||
else:
|
||||
entry.authors = authors_ordered
|
||||
if list_return:
|
||||
return entries
|
||||
@ -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()
|
||||
|
@ -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,6 +1197,10 @@ def edit_list_book(param):
|
||||
new_val = dict()
|
||||
new_val[param] = vals['value']
|
||||
edit_single_cc_data(book.id, book, param[14:], new_val)
|
||||
# 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:
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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="")
|
||||
|
@ -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}])
|
||||
},
|
||||
|
@ -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 %}
|
||||
|
@ -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">&</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) %}
|
||||
|
25
cps/web.py
25
cps/web.py
@ -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,22 +853,24 @@ 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,
|
||||
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)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user