diff --git a/.gitignore b/.gitignore index 3fc60194..f06dcd44 100644 --- a/.gitignore +++ b/.gitignore @@ -21,14 +21,12 @@ vendor/ # calibre-web *.db *.log -config.ini -cps/static/[0-9]* .idea/ *.bak *.log.* -tags settings.yaml gdrive_credentials client_secrets.json + diff --git a/cps/cli.py b/cps/cli.py index e76a12cc..8d410a90 100644 --- a/cps/cli.py +++ b/cps/cli.py @@ -43,7 +43,7 @@ parser.add_argument('-k', metavar='path', help='path and name to SSL keyfile, e.g. /opt/test.key, works only in combination with certfile') parser.add_argument('-v', '--version', action='version', help='Shows version number and exits Calibre-web', version=version_info()) -parser.add_argument('-i', metavar='ip-adress', help='Server IP-Adress to listen') +parser.add_argument('-i', metavar='ip-address', help='Server IP-Address to listen') parser.add_argument('-s', metavar='user:pass', help='Sets specific username to new password') args = parser.parse_args() diff --git a/cps/constants.py b/cps/constants.py index 50c34968..3b3b1482 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -106,7 +106,6 @@ except ValueError: del env_CALIBRE_PORT - EXTENSIONS_AUDIO = {'mp3', 'm4a', 'm4b'} EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'htmlz', 'rtf', 'odt'} EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'djvu', 'prc', 'doc', 'docx', @@ -126,7 +125,7 @@ def selected_roles(dictionary): BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, ' 'series_id, languages') -STABLE_VERSION = {'version': '0.6.6 Beta'} +STABLE_VERSION = {'version': '0.6.6'} NIGHTLY_VERSION = {} NIGHTLY_VERSION[0] = '$Format:%H$' diff --git a/cps/db.py b/cps/db.py index 1ef06427..67697468 100755 --- a/cps/db.py +++ b/cps/db.py @@ -25,13 +25,13 @@ import ast from sqlalchemy import create_engine from sqlalchemy import Table, Column, ForeignKey -from sqlalchemy import String, Integer, Boolean +from sqlalchemy import String, Integer, Boolean, Float from sqlalchemy.orm import relationship, sessionmaker, scoped_session from sqlalchemy.ext.declarative import declarative_base session = None -cc_exceptions = ['datetime', 'comments', 'float', 'composite', 'series'] +cc_exceptions = ['datetime', 'comments', 'composite', 'series'] cc_classes = {} engine = None @@ -378,6 +378,11 @@ def setup_db(config): 'id': Column(Integer, primary_key=True), 'book': Column(Integer, ForeignKey('books.id')), 'value': Column(Integer)} + elif row.datatype == 'float': + ccdict = {'__tablename__': 'custom_column_' + str(row.id), + 'id': Column(Integer, primary_key=True), + 'book': Column(Integer, ForeignKey('books.id')), + 'value': Column(Float)} else: ccdict = {'__tablename__': 'custom_column_' + str(row.id), 'id': Column(Integer, primary_key=True), @@ -385,7 +390,7 @@ def setup_db(config): cc_classes[row.id] = type(str('Custom_Column_' + str(row.id)), (Base,), ccdict) for cc_id in cc_ids: - if (cc_id[1] == 'bool') or (cc_id[1] == 'int'): + if (cc_id[1] == 'bool') or (cc_id[1] == 'int') or (cc_id[1] == 'float'): setattr(Books, 'custom_column_' + str(cc_id[0]), relationship(cc_classes[cc_id[0]], primaryjoin=( Books.id == cc_classes[cc_id[0]].book), diff --git a/cps/editbooks.py b/cps/editbooks.py index 7b78cf97..0bb005fb 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -175,7 +175,7 @@ def delete_book(book_id, book_format): cc_string = "custom_column_" + str(c.id) if not c.is_multiple: if len(getattr(book, cc_string)) > 0: - if c.datatype == 'bool' or c.datatype == 'integer': + if c.datatype == 'bool' or c.datatype == 'integer' or c.datatype == 'float': del_cc = getattr(book, cc_string)[0] getattr(book, cc_string).remove(del_cc) db.session.delete(del_cc) @@ -254,7 +254,7 @@ def edit_cc_data(book_id, book, to_save): else: cc_db_value = None if to_save[cc_string].strip(): - if c.datatype == 'int' or c.datatype == 'bool': + if c.datatype == 'int' or c.datatype == 'bool' or c.datatype == 'float': if to_save[cc_string] == 'None': to_save[cc_string] = None elif c.datatype == 'bool': @@ -697,7 +697,6 @@ def upload(): # Reread book. It's important not to filter the result, as it could have language which hide it from # current users view (tags are not stored/extracted from metadata and could also be limited) book = db.session.query(db.Books).filter(db.Books.id == book_id).first() - # upload book to gdrive if nesseccary and add "(bookid)" to folder name if config.config_use_google_drive: gdriveutils.updateGdriveCalibreFromLocal() diff --git a/cps/server.py b/cps/server.py index 8f060719..74c591ec 100755 --- a/cps/server.py +++ b/cps/server.py @@ -156,7 +156,7 @@ class WebServer(object): max_buffer_size=209700000, ssl_options=self.ssl_args) http_server.listen(self.listen_port, self.listen_address) - self.wsgiserver = IOLoop.instance() + self.wsgiserver = IOLoop.current() self.wsgiserver.start() # wait for stop signal self.wsgiserver.close(True) @@ -177,6 +177,8 @@ class WebServer(object): if not self.restart: log.info("Performing shutdown of Calibre-Web") + # prevent irritiating log of pending tasks message from asyncio + logger.get('asyncio').setLevel(logger.logging.CRITICAL) return True log.info("Performing restart of Calibre-Web") @@ -197,4 +199,4 @@ class WebServer(object): if _GEVENT: self.wsgiserver.close() else: - self.wsgiserver.add_callback(self.wsgiserver.stop) + self.wsgiserver.add_callback_from_signal(self.wsgiserver.stop) diff --git a/cps/static/js/caliBlur.js b/cps/static/js/caliBlur.js index 53f033ba..1bd5f69c 100644 --- a/cps/static/js/caliBlur.js +++ b/cps/static/js/caliBlur.js @@ -159,10 +159,12 @@ if ( $( 'body.book' ).length > 0 ) { real_custom_column = $( '.real_custom_columns' ); // $( '.real_custom_columns' ).remove(); $.each(real_custom_column, function(i, val) { - real_cc = $(this).text().split( ':' ); + var split = $(this).text().split( ':' ); + real_cc_key = split.shift(); + real_cc_value = split.join(':'); $( this ).text(""); - if (real_cc.length > 1) { - $( this ).append( '' + real_cc[0] + '' + real_cc[1] + '' ); + if (real_cc_value != "") { + $( this ).append( '' + real_cc_key + '' + real_cc_value + '' ); } }); //$( '.real_custom_columns:nth-child(3)' ).text(function() { diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index e734698a..78b427eb 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -1,8 +1,6 @@ {% extends "layout.html" %} {% block body %} {% if book %} - -
{{ book.title }} @@ -115,8 +113,8 @@ {% endif %} - {% if c.datatype == 'int' %} - + {% if c.datatype == 'int' or c.datatype == 'float' %} + {% endif %} {% if c.datatype in ['text', 'series'] and not c.is_multiple %} diff --git a/cps/templates/layout.html b/cps/templates/layout.html index 9ffb04f8..0e235ed3 100644 --- a/cps/templates/layout.html +++ b/cps/templates/layout.html @@ -44,7 +44,7 @@ - +
@@ -52,7 +52,7 @@ {% endblock %} diff --git a/cps/templates/shelf_order.html b/cps/templates/shelf_order.html index 77192c8c..0094fb31 100644 --- a/cps/templates/shelf_order.html +++ b/cps/templates/shelf_order.html @@ -5,19 +5,19 @@
{{_('Drag \'n drop to rearrange order')}}
{% for entry in entries %} -
+
- {{entry.title}} - {% if entry.series|length > 0 %} + {{entry['title']}} + {% if entry['series']|length > 0 %}
- {{entry.series_index}} - {{entry.series[0].name}} + {{entry['series_index']}} - {{entry['series'][0].name}} {% endif %}
- {% for author in entry.authors %} + {% for author in entry['authors'] %} {{author.name.replace('|',',')}} {% if not loop.last %} & diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html index ee486454..247f9159 100644 --- a/cps/templates/user_edit.html +++ b/cps/templates/user_edit.html @@ -46,7 +46,6 @@ {% endfor %}
- {% if registered_oauth.keys()| length > 0 %} {% for id, name in registered_oauth.items() %}
@@ -60,7 +59,6 @@
{% endif %} -
{% for element in sidebar %} {% if element['config_show'] %} diff --git a/cps/ub.py b/cps/ub.py index e8f9b75c..717e201a 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -307,7 +307,7 @@ class RemoteAuthToken(Base): __tablename__ = 'remote_auth_token' id = Column(Integer, primary_key=True) - auth_token = Column(String(8), unique=True) + auth_token = Column(String, unique=True) user_id = Column(Integer, ForeignKey('user.id')) verified = Column(Boolean, default=False) expiration = Column(DateTime) diff --git a/cps/updater.py b/cps/updater.py index 9fe6e828..7af8649c 100644 --- a/cps/updater.py +++ b/cps/updater.py @@ -198,7 +198,7 @@ class Updater(threading.Thread): ) additional_path = self.is_venv() if additional_path: - exclude = exclude + (additional_path) + exclude = exclude + (additional_path,) for root, dirs, files in os.walk(destination, topdown=True): for name in files: old_list.append(os.path.join(root, name).replace(destination, ''))