Commit 24c743d2 authored by Ozzieisaacs's avatar Ozzieisaacs

Code cosmetics

parent 7bb5afa5
......@@ -34,7 +34,7 @@ def version_info():
parser = argparse.ArgumentParser(description='Calibre Web is a web app'
' providing a interface for browsing, reading and downloading eBooks\n', prog='cps.py')
' providing a interface for browsing, reading and downloading eBooks\n', prog='cps.py')
parser.add_argument('-p', metavar='path', help='path and name to settings db, e.g. /opt/cw.db')
parser.add_argument('-g', metavar='path', help='path and name to gdrive db, e.g. /opt/gd.db')
parser.add_argument('-c', metavar='path',
......
......@@ -25,7 +25,7 @@ import ast
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, ForeignKey
from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float
from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float, DateTime
from sqlalchemy.orm import relationship, sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base
......
This diff is collapsed.
......@@ -80,9 +80,13 @@ def formatdate_filter(val):
formatdate = datetime.datetime.strptime(conformed_timestamp[:15], "%Y%m%d %H%M%S")
return format_date(formatdate, format='medium', locale=get_locale())
except AttributeError as e:
log.error('Babel error: %s, Current user locale: %s, Current User: %s', e, current_user.locale, current_user.nickname)
log.error('Babel error: %s, Current user locale: %s, Current User: %s', e,
current_user.locale,
current_user.nickname
)
return formatdate
@jinjia.app_template_filter('formatdateinput')
def format_date_input(val):
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', val)
......
......@@ -385,7 +385,7 @@ def get_metadata(book):
name = get_series(book)
metadata["Series"] = {
"Name": get_series(book),
"Number": book.series_index,
"Number": book.series_index, # ToDo Check int() ?
"NumberFloat": float(book.series_index),
# Get a deterministic id based on the series name.
"Id": uuid.uuid3(uuid.NAMESPACE_DNS, name),
......@@ -407,8 +407,10 @@ def HandleTagCreate():
log.debug("Received malformed v1/library/tags request.")
abort(400, description="Malformed tags POST request. Data is missing 'Name' or 'Items' field")
# ToDO: Names are not unique ! -> filter only private shelfs
shelf = ub.session.query(ub.Shelf).filter(and_(ub.Shelf.name) == name, ub.Shelf.user_id ==
current_user.id).one_or_none()
current_user.id).one_or_none() # ToDO: shouldn't it ) at the end
if shelf and not shelf_lib.check_shelf_edit_permissions(shelf):
abort(401, description="User is unauthaurized to edit shelf.")
......@@ -517,6 +519,7 @@ def HandleTagRemoveItem(tag_id):
log.debug("Received malformed v1/library/tags/<tag_id>/items/delete request.")
abort(400, description="Malformed tags POST request. Data is missing 'Items' field")
# insconsitent to above requests
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.uuid == tag_id,
ub.Shelf.user_id == current_user.id).one_or_none()
if not shelf:
......@@ -552,7 +555,8 @@ def HandleTagRemoveItem(tag_id):
def sync_shelves(sync_token, sync_results):
new_tags_last_modified = sync_token.tags_last_modified
for shelf in ub.session.query(ub.ShelfArchive).filter(func.datetime(ub.ShelfArchive.last_modified) > sync_token.tags_last_modified, ub.ShelfArchive.user_id == current_user.id):
for shelf in ub.session.query(ub.ShelfArchive).filter(func.datetime(ub.ShelfArchive.last_modified) > sync_token.tags_last_modified,
ub.ShelfArchive.user_id == current_user.id):
new_tags_last_modified = max(shelf.last_modified, new_tags_last_modified)
sync_results.append({
......@@ -564,7 +568,8 @@ def sync_shelves(sync_token, sync_results):
}
})
for shelf in ub.session.query(ub.Shelf).filter(func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified, ub.Shelf.user_id == current_user.id):
for shelf in ub.session.query(ub.Shelf).filter(func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified,
ub.Shelf.user_id == current_user.id):
if not shelf_lib.check_shelf_view_permissions(shelf):
continue
......@@ -600,6 +605,7 @@ def create_kobo_tag(shelf):
book = db.session.query(db.Books).filter(db.Books.id == book_shelf.book_id).one_or_none()
if not book:
log.info(u"Book (id: %s) in BookShelf (id: %s) not found in book database", book_shelf.book_id, shelf.id)
# ToDo shouldn't it continue?
return None
tag["Items"].append(
{
......@@ -769,7 +775,8 @@ def HandleCoverImageRequest(book_uuid, width, height,Quality, isGreyscale):
height=height), 307)
else:
log.debug("Cover for unknown book: %s requested" % book_uuid)
return redirect_or_proxy_request()
# additional proxy request make no sense, -> direct return
return make_response(jsonify({}))
log.debug("Cover request received for book %s" % book_uuid)
return book_cover
......
......@@ -108,7 +108,7 @@ def setup(log_file, log_level=None):
r.setLevel(log_level)
# Otherwise name get's destroyed on windows
if log_file != LOG_TO_STDERR and log_file != LOG_TO_STDOUT:
if log_file != LOG_TO_STDERR and log_file != LOG_TO_STDOUT:
log_file = _absolute_log_file(log_file, DEFAULT_LOG_FILE)
previous_handler = r.handlers[0] if r.handlers else None
......
......@@ -30,7 +30,7 @@ except ImportError:
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage as SQLAlchemyBackend
from flask_dance.consumer.storage.sqla import first, _get_real_user
from sqlalchemy.orm.exc import NoResultFound
backend_resultcode = True # prevent storing values with this resultcode
backend_resultcode = True # prevent storing values with this resultcode
except ImportError:
pass
......@@ -97,7 +97,7 @@ try:
def set(self, blueprint, token, user=None, user_id=None):
uid = first([user_id, self.user_id, blueprint.config.get("user_id")])
u = first(_get_real_user(ref, self.anon_user)
for ref in (user, self.user, blueprint.config.get("user")))
for ref in (user, self.user, blueprint.config.get("user")))
if self.user_required and not u and not uid:
raise ValueError("Cannot set OAuth token without an associated user")
......
This diff is collapsed.
......@@ -43,7 +43,6 @@ from . import logger
log = logger.create()
def _readable_listen_address(address, port):
if ':' in address:
address = "[" + address + "]"
......@@ -84,7 +83,8 @@ class WebServer(object):
if os.path.isfile(certfile_path) and os.path.isfile(keyfile_path):
self.ssl_args = dict(certfile=certfile_path, keyfile=keyfile_path)
else:
log.warning('The specified paths for the ssl certificate file and/or key file seem to be broken. Ignoring ssl.')
log.warning('The specified paths for the ssl certificate file and/or key file seem to be broken. '
'Ignoring ssl.')
log.warning('Cert path: %s', certfile_path)
log.warning('Key path: %s', keyfile_path)
......
......@@ -49,10 +49,11 @@ def get_datetime_from_json(json_object, field_name):
return datetime.min
class SyncToken():
class SyncToken:
""" The SyncToken is used to persist state accross requests.
When serialized over the response headers, the Kobo device will propagate the token onto following requests to the service.
As an example use-case, the SyncToken is used to detect books that have been added to the library since the last time the device synced to the server.
When serialized over the response headers, the Kobo device will propagate the token onto following
requests to the service. As an example use-case, the SyncToken is used to detect books that have been added
to the library since the last time the device synced to the server.
Attributes:
books_last_created: Datetime representing the newest book that the device knows about.
......@@ -66,10 +67,11 @@ class SyncToken():
token_schema = {
"type": "object",
"properties": {"version": {"type": "string"}, "data": {"type": "object"},},
"properties": {"version": {"type": "string"}, "data": {"type": "object"}, },
}
# This Schema doesn't contain enough information to detect and propagate book deletions from Calibre to the device.
# A potential solution might be to keep a list of all known book uuids in the token, and look for any missing from the db.
# A potential solution might be to keep a list of all known book uuids in the token, and look for any missing
# from the db.
data_schema_v1 = {
"type": "object",
"properties": {
......
......@@ -25,7 +25,7 @@ from __future__ import division, print_function, unicode_literals
from flask import Blueprint, request, flash, redirect, url_for
from flask_babel import gettext as _
from flask_login import login_required, current_user
from sqlalchemy.sql.expression import func, or_, and_
from sqlalchemy.sql.expression import func
from . import logger, ub, searched_ids, db
from .web import render_title_template
......@@ -35,6 +35,7 @@ from .helper import common_filters
shelf = Blueprint('shelf', __name__)
log = logger.create()
def check_shelf_edit_permissions(cur_shelf):
if not cur_shelf.is_public and not cur_shelf.user_id == int(current_user.id):
log.error("User %s not allowed to edit shelf %s", current_user, cur_shelf)
......@@ -74,7 +75,7 @@ def add_to_shelf(shelf_id, book_id):
return "Sorry you are not allowed to add a book to the the shelf: %s" % shelf.name, 403
book_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id,
ub.BookShelf.book_id == book_id).first()
ub.BookShelf.book_id == book_id).first()
if book_in_shelf:
log.error("Book %s is already part of %s", book_id, shelf)
if not xhr:
......@@ -195,7 +196,6 @@ def remove_from_shelf(shelf_id, book_id):
return "Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name, 403
@shelf.route("/shelf/create", methods=["GET", "POST"])
@login_required
def create_shelf():
......@@ -214,21 +214,24 @@ def create_shelf():
.first() is None
if not is_shelf_name_unique:
flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]),
category="error")
else:
is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & (ub.Shelf.user_id == int(current_user.id))) \
.first() is None
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) &
(ub.Shelf.user_id == int(current_user.id)))\
.first() is None
if not is_shelf_name_unique:
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]),
category="error")
if is_shelf_name_unique:
try:
ub.session.add(shelf)
ub.session.commit()
flash(_(u"Shelf %(title)s created", title=to_save["title"]), category="success")
return redirect(url_for('shelf.show_shelf', shelf_id = shelf.id ))
return redirect(url_for('shelf.show_shelf', shelf_id=shelf.id))
except Exception:
flash(_(u"There was an error"), category="error")
return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Create a Shelf"), page="shelfcreate")
......@@ -240,7 +243,7 @@ def create_shelf():
@login_required
def edit_shelf(shelf_id):
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
if request.method == "POST":
if request.method == "POST":
to_save = request.form.to_dict()
is_shelf_name_unique = False
......@@ -251,15 +254,18 @@ def edit_shelf(shelf_id):
.first() is None
if not is_shelf_name_unique:
flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]),
category="error")
else:
is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & (ub.Shelf.user_id == int(current_user.id))) \
.filter(ub.Shelf.id != shelf_id) \
.first() is None
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) &
(ub.Shelf.user_id == int(current_user.id)))\
.filter(ub.Shelf.id != shelf_id)\
.first() is None
if not is_shelf_name_unique:
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]),
category="error")
if is_shelf_name_unique:
shelf.name = to_save["title"]
......@@ -283,7 +289,7 @@ def delete_shelf_helper(cur_shelf):
shelf_id = cur_shelf.id
ub.session.delete(cur_shelf)
ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).delete()
ub.session.add(ub.ShelfArchive(uuid = cur_shelf.uuid, user_id = cur_shelf.uuid))
ub.session.add(ub.ShelfArchive(uuid=cur_shelf.uuid, user_id=cur_shelf.uuid))
ub.session.commit()
log.info("successfully deleted %s", cur_shelf)
......@@ -295,7 +301,7 @@ def delete_shelf(shelf_id):
delete_shelf_helper(cur_shelf)
return redirect(url_for('web.index'))
# @shelf.route("/shelfdown/<int:shelf_id>")
@shelf.route("/shelf/<int:shelf_id>", defaults={'shelf_type': 1})
@shelf.route("/shelf/<int:shelf_id>/<int:shelf_type>")
def show_shelf(shelf_type, shelf_id):
......@@ -319,13 +325,12 @@ def show_shelf(shelf_type, shelf_id):
ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book.book_id).delete()
ub.session.commit()
return render_title_template(page, entries=result, title=_(u"Shelf: '%(name)s'", name=shelf.name),
shelf=shelf, page="shelf")
shelf=shelf, page="shelf")
else:
flash(_(u"Error opening shelf. Shelf does not exist or is not accessible"), category="error")
return redirect(url_for("web.index"))
@shelf.route("/shelf/order/<int:shelf_id>", methods=["GET", "POST"])
@login_required
def order_shelf(shelf_id):
......@@ -347,17 +352,17 @@ def order_shelf(shelf_id):
for book in books_in_shelf2:
cur_book = db.session.query(db.Books).filter(db.Books.id == book.book_id).filter(common_filters()).first()
if cur_book:
result.append({'title':cur_book.title,
'id':cur_book.id,
'author':cur_book.authors,
'series':cur_book.series,
'series_index':cur_book.series_index})
result.append({'title': cur_book.title,
'id': cur_book.id,
'author': cur_book.authors,
'series': cur_book.series,
'series_index': cur_book.series_index})
else:
cur_book = db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
result.append({'title':_('Hidden Book'),
'id':cur_book.id,
'author':[],
'series':[]})
result.append({'title': _('Hidden Book'),
'id': cur_book.id,
'author': [],
'series': []})
return render_title_template('shelf_order.html', entries=result,
title=_(u"Change order of Shelf: '%(name)s'", name=shelf.name),
shelf=shelf, page="shelforder")
......@@ -45,10 +45,10 @@ def process_open(command, quotes=(), env=None, sout=subprocess.PIPE, serr=subpro
def process_wait(command, serr=subprocess.PIPE):
'''Run command, wait for process to terminate, and return an iterator over lines of its output.'''
# Run command, wait for process to terminate, and return an iterator over lines of its output.
p = process_open(command, serr=serr)
p.wait()
for l in p.stdout.readlines():
if isinstance(l, bytes):
l = l.decode('utf-8')
yield l
for line in p.stdout.readlines():
if isinstance(line, bytes):
line = line.decode('utf-8')
yield line
......@@ -4,18 +4,18 @@
<div class="filterheader hidden-xs hidden-sm">
{% if entries.__len__() %}
{% if entries[0][0].sort %}
<button id="sort_name" class="btn btn-success"><b>B,A <-> A B</b></button>
{% if data == 'author' %}
<button id="sort_name" class="btn btn-primary"><b>B,A <-> A B</b></button>
{% endif %}
{% endif %}
<button id="desc" class="btn btn-success"><span class="glyphicon glyphicon-sort-by-alphabet"></span></button>
<button id="asc" class="btn btn-success"><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></button>
<button id="desc" class="btn btn-primary"><span class="glyphicon glyphicon-sort-by-alphabet"></span></button>
<button id="asc" class="btn btn-primary"><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></button>
{% if charlist|length %}
<button id="all" class="btn btn-success">{{_('All')}}</button>
<button id="all" class="btn btn-primary">{{_('All')}}</button>
{% endif %}
<div class="btn-group character" role="group">
{% for char in charlist%}
<button class="btn btn-success char">{{char.char}}</button>
<button class="btn btn-primary char">{{char.char}}</button>
{% endfor %}
</div>
</div>
......
This diff is collapsed.
......@@ -69,7 +69,7 @@ class Updater(threading.Thread):
def get_available_updates(self, request_method, locale):
if config.config_updatechannel == constants.UPDATE_STABLE:
return self._stable_available_updates(request_method)
return self._nightly_available_updates(request_method,locale)
return self._nightly_available_updates(request_method, locale)
def do_work(self):
try:
......@@ -132,7 +132,7 @@ class Updater(threading.Thread):
def pause(self):
self.can_run.clear()
#should just resume the thread
# should just resume the thread
def resume(self):
self.can_run.set()
......@@ -268,7 +268,7 @@ class Updater(threading.Thread):
def is_venv(self):
if (hasattr(sys, 'real_prefix')) or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
return os.sep + os.path.relpath(sys.prefix,constants.BASE_DIR)
return os.sep + os.path.relpath(sys.prefix, constants.BASE_DIR)
else:
return False
......@@ -280,7 +280,7 @@ class Updater(threading.Thread):
@classmethod
def _stable_version_info(cls):
return constants.STABLE_VERSION # Current version
return constants.STABLE_VERSION # Current version
def _nightly_available_updates(self, request_method, locale):
tz = datetime.timedelta(seconds=time.timezone if (time.localtime().tm_isdst == 0) else time.altzone)
......@@ -436,7 +436,7 @@ class Updater(threading.Thread):
patch_version_update > current_version[2]) or \
minor_version_update > current_version[1]:
parents.append([commit[i]['tag_name'], commit[i]['body'].replace('\r\n', '<p>')])
newer=True
newer = True
i -= 1
continue
if major_version_update < current_version[0]:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment