This commit is contained in:
cbartondock 2021-10-16 09:27:39 -04:00
commit 5695268d1b
70 changed files with 12579 additions and 12483 deletions

View File

@ -145,7 +145,7 @@ def shutdown():
else: else:
showtext['text'] = _(u'Performing shutdown of server, please close window') showtext['text'] = _(u'Performing shutdown of server, please close window')
# stop gevent/tornado server # stop gevent/tornado server
web_server.stop(task==0) web_server.stop(task == 0)
return json.dumps(showtext) return json.dumps(showtext)
if task == 2: if task == 2:

View File

@ -267,10 +267,9 @@ def HandleSyncRequest():
entries = calibre_db.session.execute(changed_entries).all() entries = calibre_db.session.execute(changed_entries).all()
book_count = len(entries) book_count = len(entries)
else: else:
#entries = changed_entries.all()
book_count = changed_entries.count() book_count = changed_entries.count()
# last entry: # last entry:
# sync_cont = entries[-1].Books.id or -1 if book_count else -1 cont_sync = bool(book_count)
log.debug("Remaining books to Sync: {}".format(book_count)) log.debug("Remaining books to Sync: {}".format(book_count))
# generate reading state data # generate reading state data
changed_reading_states = ub.session.query(ub.KoboReadingState) changed_reading_states = ub.session.query(ub.KoboReadingState)
@ -282,18 +281,18 @@ def HandleSyncRequest():
.filter(current_user.id == ub.Shelf.user_id)\ .filter(current_user.id == ub.Shelf.user_id)\
.filter(ub.Shelf.kobo_sync, .filter(ub.Shelf.kobo_sync,
or_( or_(
func.datetime(ub.KoboReadingState.last_modified) > sync_token.reading_state_last_modified, ub.KoboReadingState.last_modified > sync_token.reading_state_last_modified,
func.datetime(ub.BookShelf.date_added) > sync_token.books_last_modified func.datetime(ub.BookShelf.date_added) > sync_token.books_last_modified
)).distinct() )).distinct()
else: else:
changed_reading_states = changed_reading_states.filter( changed_reading_states = changed_reading_states.filter(
func.datetime(ub.KoboReadingState.last_modified) > sync_token.reading_state_last_modified) ub.KoboReadingState.last_modified > sync_token.reading_state_last_modified)
changed_reading_states = changed_reading_states.filter( changed_reading_states = changed_reading_states.filter(
and_(ub.KoboReadingState.user_id == current_user.id, and_(ub.KoboReadingState.user_id == current_user.id,
ub.KoboReadingState.book_id.notin_(reading_states_in_new_entitlements))) ub.KoboReadingState.book_id.notin_(reading_states_in_new_entitlements)))
cont_sync |= bool(changed_reading_states.count() > SYNC_ITEM_LIMIT)
for kobo_reading_state in changed_reading_states.all(): for kobo_reading_state in changed_reading_states.limit(SYNC_ITEM_LIMIT).all():
book = calibre_db.session.query(db.Books).filter(db.Books.id == kobo_reading_state.book_id).one_or_none() book = calibre_db.session.query(db.Books).filter(db.Books.id == kobo_reading_state.book_id).one_or_none()
if book: if book:
sync_results.append({ sync_results.append({
@ -311,7 +310,7 @@ def HandleSyncRequest():
sync_token.reading_state_last_modified = new_reading_state_last_modified sync_token.reading_state_last_modified = new_reading_state_last_modified
# sync_token.books_last_id = books_last_id # sync_token.books_last_id = books_last_id
return generate_sync_response(sync_token, sync_results, book_count) return generate_sync_response(sync_token, sync_results, cont_sync)
def generate_sync_response(sync_token, sync_results, set_cont=False): def generate_sync_response(sync_token, sync_results, set_cont=False):
@ -682,6 +681,9 @@ def sync_shelves(sync_token, sync_results, only_kobo_shelves=False):
} }
} }
}) })
ub.session.delete(shelf)
ub.session_commit()
extra_filters = [] extra_filters = []
if only_kobo_shelves: if only_kobo_shelves:

View File

@ -180,13 +180,15 @@ function initProgressClick() {
function loadFromArrayBuffer(ab) { function loadFromArrayBuffer(ab) {
var lastCompletion = 0; var lastCompletion = 0;
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' });
loadArchiveFormats(['rar', 'zip', 'tar'], function() { loadArchiveFormats(['rar', 'zip', 'tar'], function() {
// Open the file as an archive // Open the file as an archive
archiveOpenFile(ab, function (archive) { archiveOpenFile(ab, function (archive) {
if (archive) { if (archive) {
totalImages = archive.entries.length totalImages = archive.entries.length
console.info('Uncompressing ' + archive.archive_type + ' ...'); console.info('Uncompressing ' + archive.archive_type + ' ...');
archive.entries.forEach(function(e, i) { entries = archive.entries.sort((a,b) => collator.compare(a.name, b.name));
entries.forEach(function(e, i) {
updateProgress( (i + 1)/ totalImages * 100); updateProgress( (i + 1)/ totalImages * 100);
if (e.is_file) { if (e.is_file) {
e.readData(function(d) { e.readData(function(d) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@
</div> </div>
<table id="books-table" class="table table-no-bordered table-striped" <table id="books-table" class="table table-no-bordered table-striped"
data-url="{{url_for('web.list_books')}}"> data-url="{{url_for('web.list_books')}}" data-locale="{{ g.user.locale }}">
<thead> <thead>
<tr> <tr>
{% if g.user.role_edit() %} {% if g.user.role_edit() %}
@ -97,6 +97,7 @@
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-locale-all.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script>
{% if not g.user.locale == 'en' %} {% if not g.user.locale == 'en' %}

View File

@ -80,7 +80,7 @@
</div> </div>
<button id="domain_allow_submit" class="btn btn-default">{{_('Add')}}</button> <button id="domain_allow_submit" class="btn btn-default">{{_('Add')}}</button>
</form> </form>
<table class="table table-no-bordered" id="domain-allow-table" data-url="{{url_for('admin.list_domain', allow=1)}}" data-id-field="id" data-show-header="false" data-editable-mode="inline"> <table class="table table-no-bordered" id="domain-allow-table" data-url="{{url_for('admin.list_domain', allow=1)}}" data-id-field="id" data-show-header="false" data-editable-mode="inline" data-locale="{{ g.user.locale }}">
<thead> <thead>
<tr> <tr>
<th data-field="domain" id="domain-allow" data-escape="true" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain', allow = 1)}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th> <th data-field="domain" id="domain-allow" data-escape="true" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain', allow = 1)}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
@ -90,7 +90,7 @@
</thead> </thead>
</table> </table>
<h2>{{_('Denied Domains (Blacklist)')}}</h2> <h2>{{_('Denied Domains (Blacklist)')}}</h2>
<table class="table table-no-bordered" id="domain-deny-table" data-url="{{url_for('admin.list_domain', allow=0)}}" data-id-field="id" data-show-header="false" data-editable-mode="inline"> <table class="table table-no-bordered" id="domain-deny-table" data-url="{{url_for('admin.list_domain', allow=0)}}" data-id-field="id" data-show-header="false" data-editable-mode="inline" data-locale="{{ g.user.locale }}">
<thead> <thead>
<tr> <tr>
<th data-field="domain" id="domain-deny" data-escape="true" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain', allow = 0)}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th> <th data-field="domain" id="domain-deny" data-escape="true" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain', allow = 0)}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
@ -120,6 +120,7 @@
{% block js %} {% block js %}
{% if g.allow_registration %} {% if g.allow_registration %}
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-locale-all.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/table.js') }}"></script> <script src="{{ url_for('static', filename='js/table.js') }}"></script>

View File

@ -20,7 +20,7 @@
<div class="form-group col-sm-6"> <div class="form-group col-sm-6">
<label for="publishstart">{{_('Published Date From')}}</label> <label for="publishstart">{{_('Published Date From')}}</label>
<div class="input-group"> <div class="input-group">
<input type="text" class="datepicker form-control" name="publish_start" id="publishstart" value=""> <input type="text" class="datepicker form-control" name="publishstart" id="publishstart" value="">
<input type="text" class="form-control fake-input hidden" id="fake_publishstart" value=""> <input type="text" class="form-control fake-input hidden" id="fake_publishstart" value="">
<span class="input-group-btn"> <span class="input-group-btn">
<button type="button" id="publishstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button> <button type="button" id="publishstart_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>

View File

@ -7,6 +7,7 @@
{% endif %} {% endif %}
{% if g.user.is_authenticated %} {% if g.user.is_authenticated %}
{% if (g.user.role_edit_shelfs() and shelf.is_public ) or not shelf.is_public %} {% if (g.user.role_edit_shelfs() and shelf.is_public ) or not shelf.is_public %}
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="btn btn-danger" id="delete_shelf" data-value="{{ shelf.id }}">{{ _('Delete this Shelf') }}</div> <div class="btn btn-danger" id="delete_shelf" data-value="{{ shelf.id }}">{{ _('Delete this Shelf') }}</div>
<a id="edit_shelf" href="{{ url_for('shelf.edit_shelf', shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Edit Shelf Properties') }} </a> <a id="edit_shelf" href="{{ url_for('shelf.edit_shelf', shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Edit Shelf Properties') }} </a>
{% if entries.__len__() %} {% if entries.__len__() %}

View File

@ -5,7 +5,7 @@
{% block body %} {% block body %}
<div class="discover"> <div class="discover">
<h2>{{_('Tasks')}}</h2> <h2>{{_('Tasks')}}</h2>
<table class="table table-no-bordered" id="tasktable" data-url="{{ url_for('web.get_email_status_json') }}" data-sort-name="starttime" data-sort-order="asc"> <table class="table table-no-bordered" id="tasktable" data-url="{{ url_for('web.get_email_status_json') }}" data-sort-name="starttime" data-sort-order="asc" data-locale="{{ g.user.locale }}">
<thead> <thead>
<tr> <tr>
{% if g.user.role_admin() %} {% if g.user.role_admin() %}
@ -25,6 +25,7 @@
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-locale-all.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/table.js') }}"></script> <script src="{{ url_for('static', filename='js/table.js') }}"></script>
{% endblock %} {% endblock %}

View File

@ -125,7 +125,7 @@
</div> </div>
</div> </div>
<table id="user-table" class="table table-no-bordered table-striped" <table id="user-table" class="table table-no-bordered table-striped"
data-url="{{url_for('admin.list_users')}}"> data-url="{{url_for('admin.list_users')}}" data-locale="{{ g.user.locale }}">
<thead> <thead>
<tr> <tr>
<th data-name="edit" data-buttontext="{{_('Edit User')}}" data-visible="{{visiblility.get('edit')}}" data-formatter="singleUserFormatter">{{_('Edit')}}</th> <th data-name="edit" data-buttontext="{{_('Edit User')}}" data-visible="{{visiblility.get('edit')}}" data-formatter="singleUserFormatter">{{_('Edit')}}</th>
@ -139,7 +139,7 @@
{{ user_table_row('allowed_tags', _("Edit Allowed Tags"), _("Allowed Tags"), false, tags) }} {{ user_table_row('allowed_tags', _("Edit Allowed Tags"), _("Allowed Tags"), false, tags) }}
{{ user_table_row('denied_tags', _("Edit Denied Tags"), _("Denied Tags"), false, tags) }} {{ user_table_row('denied_tags', _("Edit Denied Tags"), _("Denied Tags"), false, tags) }}
{{ user_table_row('allowed_column_value', _("Edit Allowed Column Values"), _("Allowed Column Values"), false, custom_values) }} {{ user_table_row('allowed_column_value', _("Edit Allowed Column Values"), _("Allowed Column Values"), false, custom_values) }}
{{ user_table_row('denied_column_value', _("Edit Denied Column Values"), _("Denied Columns Values"), false, custom_values) }} {{ user_table_row('denied_column_value', _("Edit Denied Column Values"), _("Denied Column Values"), false, custom_values) }}
{{ user_checkbox_row("role", "admin_role", _('Admin'), visiblility, all_roles)}} {{ user_checkbox_row("role", "admin_role", _('Admin'), visiblility, all_roles)}}
{{ user_checkbox_row("role", "passwd_role", _('Change Password'), visiblility, all_roles)}} {{ user_checkbox_row("role", "passwd_role", _('Change Password'), visiblility, all_roles)}}
{{ user_checkbox_row("role", "upload_role",_('Upload'), visiblility, all_roles)}} {{ user_checkbox_row("role", "upload_role",_('Upload'), visiblility, all_roles)}}
@ -181,6 +181,7 @@
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-locale-all.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bootstrap-select.min.js')}}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-select.min.js')}}"></script>
@ -189,4 +190,3 @@
{% endif %} {% endif %}
<script src="{{ url_for('static', filename='js/table.js') }}"></script> <script src="{{ url_for('static', filename='js/table.js') }}"></script>
{% endblock %} {% endblock %}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -781,6 +781,7 @@ def list_books():
if sort == "state": if sort == "state":
state = json.loads(request.args.get("state", "[]")) state = json.loads(request.args.get("state", "[]"))
# order = [db.Books.timestamp.asc()] if order == "asc" else [db.Books.timestamp.desc()] # ToDo wrong: sort ticked
elif sort == "tags": elif sort == "tags":
order = [db.Tags.name.asc()] if order == "asc" else [db.Tags.name.desc()] order = [db.Tags.name.asc()] if order == "asc" else [db.Tags.name.desc()]
join = db.books_tags_link,db.Books.id == db.books_tags_link.c.book, db.Tags join = db.books_tags_link,db.Books.id == db.books_tags_link.c.book, db.Tags
@ -805,7 +806,7 @@ def list_books():
total_count = filtered_count = calibre_db.session.query(db.Books).count() total_count = filtered_count = calibre_db.session.query(db.Books).count()
if state: if state is not None:
if search: if search:
books = calibre_db.search_query(search).all() books = calibre_db.search_query(search).all()
filtered_count = len(books) filtered_count = len(books)
@ -1198,7 +1199,7 @@ def adv_search_serie(q, include_series_inputs, exclude_series_inputs):
def adv_search_shelf(q, include_shelf_inputs, exclude_shelf_inputs): def adv_search_shelf(q, include_shelf_inputs, exclude_shelf_inputs):
q = q.outerjoin(ub.BookShelf, db.Books.id == ub.BookShelf.book_id)\ q = q.outerjoin(ub.BookShelf, db.Books.id == ub.BookShelf.book_id)\
.filter(or_(ub.BookShelf.shelf == None, ub.BookShelf.shelf.notin_(exclude_shelf_inputs))) .filter(or_(ub.BookShelf.shelf is None, ub.BookShelf.shelf.notin_(exclude_shelf_inputs)))
if len(include_shelf_inputs) > 0: if len(include_shelf_inputs) > 0:
q = q.filter(ub.BookShelf.shelf.in_(include_shelf_inputs)) q = q.filter(ub.BookShelf.shelf.in_(include_shelf_inputs))
return q return q
@ -1228,7 +1229,7 @@ def extend_search_term(searchterm,
format_date(datetime.strptime(pub_end, "%Y-%m-%d"), format_date(datetime.strptime(pub_end, "%Y-%m-%d"),
format='medium', locale=get_locale())]) format='medium', locale=get_locale())])
except ValueError: except ValueError:
pub_start = u"" pub_end = u""
elements = {'tag': db.Tags, 'serie':db.Series, 'shelf':ub.Shelf} elements = {'tag': db.Tags, 'serie':db.Series, 'shelf':ub.Shelf}
for key, db_element in elements.items(): for key, db_element in elements.items():
tag_names = calibre_db.session.query(db_element).filter(db_element.id.in_(tags['include_' + key])).all() tag_names = calibre_db.session.query(db_element).filter(db_element.id.in_(tags['include_' + key])).all()
@ -1299,7 +1300,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
column_end = term.get('custom_column_' + str(c.id) + '_end') column_end = term.get('custom_column_' + str(c.id) + '_end')
if column_start: if column_start:
searchterm.extend([u"{} >= {}".format(c.name, searchterm.extend([u"{} >= {}".format(c.name,
format_date(datetime.strptime(column_start, "%Y-%m-%d"), format_date(datetime.strptime(column_start, "%Y-%m-%d").date(),
format='medium', format='medium',
locale=get_locale()) locale=get_locale())
)]) )])
@ -1361,7 +1362,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
flask_session['query'] = json.dumps(term) flask_session['query'] = json.dumps(term)
ub.store_ids(q) ub.store_ids(q)
result_count = len(q) result_count = len(q)
if offset != None and limit != None: if offset is not None and limit is not None:
offset = int(offset) offset = int(offset)
limit_all = offset + int(limit) limit_all = offset + int(limit)
pagination = Pagination((offset / (int(limit)) + 1), limit, result_count) pagination = Pagination((offset / (int(limit)) + 1), limit, result_count)
@ -1561,7 +1562,7 @@ def login():
else: else:
ip_Address = request.headers.get('X-Forwarded-For', request.remote_addr) ip_Address = request.headers.get('X-Forwarded-For', request.remote_addr)
if 'forgot' in form and form['forgot'] == 'forgot': if 'forgot' in form and form['forgot'] == 'forgot':
if user != None and user.name != "Guest": if user is not None and user.name != "Guest":
ret, __ = reset_password(user.id) ret, __ = reset_password(user.id)
if ret == 1: if ret == 1:
flash(_(u"New Password was send to your email address"), category="info") flash(_(u"New Password was send to your email address"), category="info")

File diff suppressed because it is too large Load Diff