Merge with branch develop

Release version
This commit is contained in:
Ozzieisaacs 2020-02-23 09:07:02 +01:00
parent 3a70c86f49
commit 7c89f0b5b9
14 changed files with 35 additions and 35 deletions

4
.gitignore vendored
View File

@ -21,14 +21,12 @@ vendor/
# calibre-web # calibre-web
*.db *.db
*.log *.log
config.ini
cps/static/[0-9]*
.idea/ .idea/
*.bak *.bak
*.log.* *.log.*
tags
settings.yaml settings.yaml
gdrive_credentials gdrive_credentials
client_secrets.json client_secrets.json

View File

@ -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') 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', parser.add_argument('-v', '--version', action='version', help='Shows version number and exits Calibre-web',
version=version_info()) 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') parser.add_argument('-s', metavar='user:pass', help='Sets specific username to new password')
args = parser.parse_args() args = parser.parse_args()

View File

@ -106,7 +106,6 @@ except ValueError:
del env_CALIBRE_PORT del env_CALIBRE_PORT
EXTENSIONS_AUDIO = {'mp3', 'm4a', 'm4b'} EXTENSIONS_AUDIO = {'mp3', 'm4a', 'm4b'}
EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'htmlz', 'rtf', 'odt'} 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', 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, ' BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, '
'series_id, languages') 'series_id, languages')
STABLE_VERSION = {'version': '0.6.6 Beta'} STABLE_VERSION = {'version': '0.6.6'}
NIGHTLY_VERSION = {} NIGHTLY_VERSION = {}
NIGHTLY_VERSION[0] = '$Format:%H$' NIGHTLY_VERSION[0] = '$Format:%H$'

View File

@ -25,13 +25,13 @@ import ast
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy import Table, Column, ForeignKey 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.orm import relationship, sessionmaker, scoped_session
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
session = None session = None
cc_exceptions = ['datetime', 'comments', 'float', 'composite', 'series'] cc_exceptions = ['datetime', 'comments', 'composite', 'series']
cc_classes = {} cc_classes = {}
engine = None engine = None
@ -378,6 +378,11 @@ def setup_db(config):
'id': Column(Integer, primary_key=True), 'id': Column(Integer, primary_key=True),
'book': Column(Integer, ForeignKey('books.id')), 'book': Column(Integer, ForeignKey('books.id')),
'value': Column(Integer)} '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: else:
ccdict = {'__tablename__': 'custom_column_' + str(row.id), ccdict = {'__tablename__': 'custom_column_' + str(row.id),
'id': Column(Integer, primary_key=True), '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) cc_classes[row.id] = type(str('Custom_Column_' + str(row.id)), (Base,), ccdict)
for cc_id in cc_ids: 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]], setattr(Books, 'custom_column_' + str(cc_id[0]), relationship(cc_classes[cc_id[0]],
primaryjoin=( primaryjoin=(
Books.id == cc_classes[cc_id[0]].book), Books.id == cc_classes[cc_id[0]].book),

View File

@ -175,7 +175,7 @@ def delete_book(book_id, book_format):
cc_string = "custom_column_" + str(c.id) cc_string = "custom_column_" + str(c.id)
if not c.is_multiple: if not c.is_multiple:
if len(getattr(book, cc_string)) > 0: 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] del_cc = getattr(book, cc_string)[0]
getattr(book, cc_string).remove(del_cc) getattr(book, cc_string).remove(del_cc)
db.session.delete(del_cc) db.session.delete(del_cc)
@ -254,7 +254,7 @@ def edit_cc_data(book_id, book, to_save):
else: else:
cc_db_value = None cc_db_value = None
if to_save[cc_string].strip(): 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': if to_save[cc_string] == 'None':
to_save[cc_string] = None to_save[cc_string] = None
elif c.datatype == 'bool': 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 # 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) # 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() 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 # upload book to gdrive if nesseccary and add "(bookid)" to folder name
if config.config_use_google_drive: if config.config_use_google_drive:
gdriveutils.updateGdriveCalibreFromLocal() gdriveutils.updateGdriveCalibreFromLocal()

View File

@ -156,7 +156,7 @@ class WebServer(object):
max_buffer_size=209700000, max_buffer_size=209700000,
ssl_options=self.ssl_args) ssl_options=self.ssl_args)
http_server.listen(self.listen_port, self.listen_address) http_server.listen(self.listen_port, self.listen_address)
self.wsgiserver = IOLoop.instance() self.wsgiserver = IOLoop.current()
self.wsgiserver.start() self.wsgiserver.start()
# wait for stop signal # wait for stop signal
self.wsgiserver.close(True) self.wsgiserver.close(True)
@ -177,6 +177,8 @@ class WebServer(object):
if not self.restart: if not self.restart:
log.info("Performing shutdown of Calibre-Web") 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 return True
log.info("Performing restart of Calibre-Web") log.info("Performing restart of Calibre-Web")
@ -197,4 +199,4 @@ class WebServer(object):
if _GEVENT: if _GEVENT:
self.wsgiserver.close() self.wsgiserver.close()
else: else:
self.wsgiserver.add_callback(self.wsgiserver.stop) self.wsgiserver.add_callback_from_signal(self.wsgiserver.stop)

View File

@ -159,10 +159,12 @@ if ( $( 'body.book' ).length > 0 ) {
real_custom_column = $( '.real_custom_columns' ); real_custom_column = $( '.real_custom_columns' );
// $( '.real_custom_columns' ).remove(); // $( '.real_custom_columns' ).remove();
$.each(real_custom_column, function(i, val) { $.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(""); $( this ).text("");
if (real_cc.length > 1) { if (real_cc_value != "") {
$( this ).append( '<span>' + real_cc[0] + '</span><span>' + real_cc[1] + '</span>' ); $( this ).append( '<span>' + real_cc_key + '</span><span>' + real_cc_value + '</span>' );
} }
}); });
//$( '.real_custom_columns:nth-child(3)' ).text(function() { //$( '.real_custom_columns:nth-child(3)' ).text(function() {

View File

@ -1,8 +1,6 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
{% if book %} {% if book %}
<div class="col-sm-3 col-lg-3 col-xs-12"> <div class="col-sm-3 col-lg-3 col-xs-12">
<div class="cover"> <div class="cover">
<img src="{{ url_for('web.get_cover', book_id=book.id) }}" alt="{{ book.title }}"/> <img src="{{ url_for('web.get_cover', book_id=book.id) }}" alt="{{ book.title }}"/>
@ -115,8 +113,8 @@
</select> </select>
{% endif %} {% endif %}
{% if c.datatype == 'int' %} {% if c.datatype == 'int' or c.datatype == 'float' %}
<input type="number" step="1" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" value="{% if book['custom_column_' ~ c.id]|length > 0 %}{{ book['custom_column_' ~ c.id][0].value }}{% endif %}"> <input type="number" step="{% if c.datatype == 'float' %}0.01{% else %}1{% endif %}" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" value="{% if book['custom_column_' ~ c.id]|length > 0 %}{{ book['custom_column_' ~ c.id][0].value }}{% endif %}">
{% endif %} {% endif %}
{% if c.datatype in ['text', 'series'] and not c.is_multiple %} {% if c.datatype in ['text', 'series'] and not c.is_multiple %}

View File

@ -44,7 +44,7 @@
<label for="query" class="sr-only">{{_('Search')}}</label> <label for="query" class="sr-only">{{_('Search')}}</label>
<input type="text" class="form-control" id="query" name="query" placeholder="{{_('Search')}}"> <input type="text" class="form-control" id="query" name="query" placeholder="{{_('Search')}}">
<span class="input-group-btn"> <span class="input-group-btn">
<button type="submit" class="btn btn-default">{{_('Go!')}}</button> <button type="submit" id="query_submit" class="btn btn-default">{{_('Go!')}}</button>
</span> </span>
</div> </div>
</form> </form>
@ -52,7 +52,7 @@
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
{% if g.user.is_authenticated or g.allow_anonymous %} {% if g.user.is_authenticated or g.allow_anonymous %}
<ul class="nav navbar-nav "> <ul class="nav navbar-nav ">
<li><a href="{{url_for('web.advanced_search')}}"><span class="glyphicon glyphicon-search"></span><span class="hidden-sm">{{_('Advanced Search')}}</span></a></li> <li><a href="{{url_for('web.advanced_search')}}" id="advanced_search"><span class="glyphicon glyphicon-search"></span><span class="hidden-sm">{{_('Advanced Search')}}</span></a></li>
</ul> </ul>
{% endif %} {% endif %}
<ul class="nav navbar-nav navbar-right" id="main-nav"> <ul class="nav navbar-nav navbar-right" id="main-nav">
@ -229,7 +229,6 @@
}); });
}); });
</script> </script>
{% block js %}{% endblock %} {% block js %}{% endblock %}
</body> </body>
</html> </html>

View File

@ -167,7 +167,7 @@
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<button type="submit" class="btn btn-default">{{_('Submit')}}</button> <button type="submit" id="adv_submit" class="btn btn-default">{{_('Submit')}}</button>
</form> </form>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -5,19 +5,19 @@
<div>{{_('Drag \'n drop to rearrange order')}}</div> <div>{{_('Drag \'n drop to rearrange order')}}</div>
<div id="sortTrue" class="list-group"> <div id="sortTrue" class="list-group">
{% for entry in entries %} {% for entry in entries %}
<div id="{{entry.id}}" class="list-group-item"> <div id="{{entry['id']}}" class="list-group-item">
<div class="row"> <div class="row">
<div class="col-lg-2 col-sm-4 hidden-xs"> <div class="col-lg-2 col-sm-4 hidden-xs">
<img class="cover-height" src="{{ url_for('web.get_cover', book_id=entry.id) }}"> <img class="cover-height" src="{{ url_for('web.get_cover', book_id=entry['id']) }}">
</div> </div>
<div class="col-lg-10 col-sm-8 col-xs-12"> <div class="col-lg-10 col-sm-8 col-xs-12">
{{entry.title}} {{entry['title']}}
{% if entry.series|length > 0 %} {% if entry['series']|length > 0 %}
<br> <br>
{{entry.series_index}} - {{entry.series[0].name}} {{entry['series_index']}} - {{entry['series'][0].name}}
{% endif %} {% endif %}
<br> <br>
{% for author in entry.authors %} {% for author in entry['authors'] %}
{{author.name.replace('|',',')}} {{author.name.replace('|',',')}}
{% if not loop.last %} {% if not loop.last %}
&amp; &amp;

View File

@ -46,7 +46,6 @@
{% endfor %} {% endfor %}
</select> </select>
</div> </div>
{% if registered_oauth.keys()| length > 0 %} {% if registered_oauth.keys()| length > 0 %}
{% for id, name in registered_oauth.items() %} {% for id, name in registered_oauth.items() %}
<div class="form-group"> <div class="form-group">
@ -60,7 +59,6 @@
</div> </div>
{% endif %} {% endif %}
<div class="col-sm-6"> <div class="col-sm-6">
{% for element in sidebar %} {% for element in sidebar %}
{% if element['config_show'] %} {% if element['config_show'] %}

View File

@ -307,7 +307,7 @@ class RemoteAuthToken(Base):
__tablename__ = 'remote_auth_token' __tablename__ = 'remote_auth_token'
id = Column(Integer, primary_key=True) 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')) user_id = Column(Integer, ForeignKey('user.id'))
verified = Column(Boolean, default=False) verified = Column(Boolean, default=False)
expiration = Column(DateTime) expiration = Column(DateTime)

View File

@ -198,7 +198,7 @@ class Updater(threading.Thread):
) )
additional_path = self.is_venv() additional_path = self.is_venv()
if additional_path: if additional_path:
exclude = exclude + (additional_path) exclude = exclude + (additional_path,)
for root, dirs, files in os.walk(destination, topdown=True): for root, dirs, files in os.walk(destination, topdown=True):
for name in files: for name in files:
old_list.append(os.path.join(root, name).replace(destination, '')) old_list.append(os.path.join(root, name).replace(destination, ''))