Merge with branch develop

Release version
pull/1218/head
Ozzieisaacs 5 years ago
parent 3a70c86f49
commit 7c89f0b5b9

4
.gitignore vendored

@ -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

@ -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()

@ -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$'

@ -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),

@ -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()

@ -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)

@ -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( '<span>' + real_cc[0] + '</span><span>' + real_cc[1] + '</span>' );
if (real_cc_value != "") {
$( this ).append( '<span>' + real_cc_key + '</span><span>' + real_cc_value + '</span>' );
}
});
//$( '.real_custom_columns:nth-child(3)' ).text(function() {

@ -1,8 +1,6 @@
{% extends "layout.html" %}
{% block body %}
{% if book %}
<div class="col-sm-3 col-lg-3 col-xs-12">
<div class="cover">
<img src="{{ url_for('web.get_cover', book_id=book.id) }}" alt="{{ book.title }}"/>
@ -115,8 +113,8 @@
</select>
{% endif %}
{% if c.datatype == 'int' %}
<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 %}">
{% if c.datatype == 'int' or c.datatype == 'float' %}
<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 %}
{% if c.datatype in ['text', 'series'] and not c.is_multiple %}

@ -44,7 +44,7 @@
<label for="query" class="sr-only">{{_('Search')}}</label>
<input type="text" class="form-control" id="query" name="query" placeholder="{{_('Search')}}">
<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>
</div>
</form>
@ -52,7 +52,7 @@
<div class="navbar-collapse collapse">
{% if g.user.is_authenticated or g.allow_anonymous %}
<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>
{% endif %}
<ul class="nav navbar-nav navbar-right" id="main-nav">
@ -229,7 +229,6 @@
});
});
</script>
{% block js %}{% endblock %}
</body>
</html>

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

@ -5,19 +5,19 @@
<div>{{_('Drag \'n drop to rearrange order')}}</div>
<div id="sortTrue" class="list-group">
{% 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="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 class="col-lg-10 col-sm-8 col-xs-12">
{{entry.title}}
{% if entry.series|length > 0 %}
{{entry['title']}}
{% if entry['series']|length > 0 %}
<br>
{{entry.series_index}} - {{entry.series[0].name}}
{{entry['series_index']}} - {{entry['series'][0].name}}
{% endif %}
<br>
{% for author in entry.authors %}
{% for author in entry['authors'] %}
{{author.name.replace('|',',')}}
{% if not loop.last %}
&amp;

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

@ -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)

@ -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, ''))

Loading…
Cancel
Save