Merge with branch develop
Release version
This commit is contained in:
parent
3a70c86f49
commit
7c89f0b5b9
4
.gitignore
vendored
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$'
|
||||
|
|
11
cps/db.py
11
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),
|
||||
|
|
|
@ -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 %}
|
||||
&
|
||||
|
|
|
@ -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…
Reference in New Issue
Block a user