Commit 709fa88c authored by OzzieIsaacs's avatar OzzieIsaacs

Navbar reduced to icons on smaller screens

Feedback updater improved (#81)
parent 3cadde65
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
import os import os
import sys import sys
import time
base_path = os.path.dirname(os.path.abspath(__file__)) base_path = os.path.dirname(os.path.abspath(__file__))
# Insert local directories into path # Insert local directories into path
...@@ -22,7 +21,7 @@ if __name__ == '__main__': ...@@ -22,7 +21,7 @@ if __name__ == '__main__':
http_server.listen(web.ub.config.config_port) http_server.listen(web.ub.config.config_port)
IOLoop.instance().start() IOLoop.instance().start()
if web.global_task == 0: if web.helper.global_task == 0:
print("Performing restart of Calibre-web") print("Performing restart of Calibre-web")
os.execl(sys.executable, sys.executable, *sys.argv) os.execl(sys.executable, sys.executable, *sys.argv)
else: else:
......
...@@ -6,7 +6,7 @@ import ub ...@@ -6,7 +6,7 @@ import ub
from flask import current_app as app from flask import current_app as app
import logging import logging
import smtplib import smtplib
import tempfile from tempfile import gettempdir
import socket import socket
import sys import sys
import os import os
...@@ -21,13 +21,22 @@ from email.MIMEText import MIMEText ...@@ -21,13 +21,22 @@ from email.MIMEText import MIMEText
from email.generator import Generator from email.generator import Generator
from flask_babel import gettext as _ from flask_babel import gettext as _
import subprocess import subprocess
import threading
import shutil import shutil
import requests
import zipfile
from tornado.ioloop import IOLoop
try: try:
import unidecode import unidecode
use_unidecode=True use_unidecode=True
except: except:
use_unidecode=False use_unidecode=False
# Global variables
global_task = None
updater_thread = None
def update_download(book_id, user_id): def update_download(book_id, user_id):
check = ub.session.query(ub.Downloads).filter(ub.Downloads.user_id == user_id).filter(ub.Downloads.book_id == check = ub.session.query(ub.Downloads).filter(ub.Downloads.user_id == user_id).filter(ub.Downloads.book_id ==
book_id).first() book_id).first()
...@@ -267,14 +276,46 @@ def update_dir_stucture(book_id, calibrepath): ...@@ -267,14 +276,46 @@ def update_dir_stucture(book_id, calibrepath):
book.path = new_authordir + '/' + book.path.split('/')[1] book.path = new_authordir + '/' + book.path.split('/')[1]
db.session.commit() db.session.commit()
class Updater(threading.Thread):
def file_to_list(file): def __init__(self):
threading.Thread.__init__(self)
self.status=0
def run(self):
global global_task
self.status=1
r = requests.get('https://api.github.com/repos/janeczku/calibre-web/zipball/master', stream=True)
fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0]
self.status=2
z = zipfile.ZipFile(StringIO(r.content))
self.status=3
tmp_dir = gettempdir()
z.extractall(tmp_dir)
self.status=4
self.update_source(os.path.join(tmp_dir,os.path.splitext(fname)[0]),ub.config.get_main_dir)
self.status=5
global_task = 0
db.session.close()
db.engine.dispose()
ub.session.close()
ub.engine.dispose()
self.status=6
# stop tornado server
server = IOLoop.instance()
server.add_callback(server.stop)
self.status=7
def get_update_status(self):
return self.status
def file_to_list(self, file):
return [x.strip() for x in open(file, 'r') if not x.startswith('#EXT')] return [x.strip() for x in open(file, 'r') if not x.startswith('#EXT')]
def one_minus_two(one, two): def one_minus_two(self, one, two):
return [x for x in one if x not in set(two)] return [x for x in one if x not in set(two)]
def reduce_dirs(delete_files, new_list): def reduce_dirs(self, delete_files, new_list):
new_delete = [] new_delete = []
for file in delete_files: for file in delete_files:
parts = file.split(os.sep) parts = file.split(os.sep)
...@@ -294,57 +335,57 @@ def reduce_dirs(delete_files, new_list): ...@@ -294,57 +335,57 @@ def reduce_dirs(delete_files, new_list):
break break
return list(set(new_delete)) return list(set(new_delete))
def reduce_files(remove_items, exclude_items): def reduce_files(self, remove_items, exclude_items):
rf = [] rf = []
for item in remove_items: for item in remove_items:
if not item in exclude_items: if not item in exclude_items:
rf.append(item) rf.append(item)
return rf return rf
def moveallfiles(root_src_dir, root_dst_dir): def moveallfiles(self, root_src_dir, root_dst_dir):
change_permissions = True change_permissions = True
if sys.platform == "win32" or sys.platform == "darwin": if sys.platform == "win32" or sys.platform == "darwin":
change_permissions=False change_permissions = False
else: else:
app.logger.debug('Update on OS-System : '+sys.platform ) app.logger.debug('Update on OS-System : ' + sys.platform)
#print('OS-System: '+sys.platform ) # print('OS-System: '+sys.platform )
new_permissions=os.stat(root_dst_dir) new_permissions = os.stat(root_dst_dir)
#print new_permissions # print new_permissions
for src_dir, dirs, files in os.walk(root_src_dir): for src_dir, dirs, files in os.walk(root_src_dir):
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1) dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
if not os.path.exists(dst_dir): if not os.path.exists(dst_dir):
os.makedirs(dst_dir) os.makedirs(dst_dir)
#print('Create-Dir: '+dst_dir) # print('Create-Dir: '+dst_dir)
if change_permissions: if change_permissions:
#print('Permissions: User '+str(new_permissions.st_uid)+' Group '+str(new_permissions.st_uid)) # print('Permissions: User '+str(new_permissions.st_uid)+' Group '+str(new_permissions.st_uid))
os.chown(dst_dir,new_permissions.st_uid,new_permissions.st_gid) os.chown(dst_dir, new_permissions.st_uid, new_permissions.st_gid)
for file_ in files: for file_ in files:
src_file = os.path.join(src_dir, file_) src_file = os.path.join(src_dir, file_)
dst_file = os.path.join(dst_dir, file_) dst_file = os.path.join(dst_dir, file_)
if os.path.exists(dst_file): if os.path.exists(dst_file):
if change_permissions: if change_permissions:
permission=os.stat(dst_file) permission = os.stat(dst_file)
#print('Remove file before copy: '+dst_file) # print('Remove file before copy: '+dst_file)
os.remove(dst_file) os.remove(dst_file)
else: else:
if change_permissions: if change_permissions:
permission=new_permissions permission = new_permissions
shutil.move(src_file, dst_dir) shutil.move(src_file, dst_dir)
#print('Move File '+src_file+' to '+dst_dir) # print('Move File '+src_file+' to '+dst_dir)
if change_permissions: if change_permissions:
try: try:
os.chown(dst_file, permission.st_uid, permission.st_uid) os.chown(dst_file, permission.st_uid, permission.st_uid)
#print('Permissions: User '+str(new_permissions.st_uid)+' Group '+str(new_permissions.st_uid)) # print('Permissions: User '+str(new_permissions.st_uid)+' Group '+str(new_permissions.st_uid))
except: except:
e = sys.exc_info() e = sys.exc_info()
#print('Fail '+str(dst_file)+' error: '+str(e)) # print('Fail '+str(dst_file)+' error: '+str(e))
return return
def update_source(self, source, destination):
def update_source(source,destination):
# destination files # destination files
old_list=list() old_list = list()
exclude = (['vendor' + os.sep + 'kindlegen.exe','vendor' + os.sep + 'kindlegen','/app.db','vendor','/update.py']) exclude = (
['vendor' + os.sep + 'kindlegen.exe', 'vendor' + os.sep + 'kindlegen', '/app.db', 'vendor', '/update.py'])
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, ''))
...@@ -358,26 +399,23 @@ def update_source(source,destination): ...@@ -358,26 +399,23 @@ def update_source(source,destination):
for name in dirs: for name in dirs:
new_list.append(os.path.join(root, name).replace(source, '')) new_list.append(os.path.join(root, name).replace(source, ''))
delete_files = one_minus_two(old_list, new_list) delete_files = self.one_minus_two(old_list, new_list)
#print('raw delete list', delete_files)
rf= reduce_files(delete_files, exclude) rf = self.reduce_files(delete_files, exclude)
#print('reduced delete list', rf)
remove_items = reduce_dirs(rf, new_list) remove_items = self.reduce_dirs(rf, new_list)
#print('delete files', remove_items)
moveallfiles(source, destination) self.moveallfiles(source, destination)
for item in remove_items: for item in remove_items:
item_path = os.path.join(destination, item[1:]) item_path = os.path.join(destination, item[1:])
if os.path.isdir(item_path): if os.path.isdir(item_path):
print("Delete dir "+ item_path) app.logger.debug("Delete dir " + item_path)
shutil.rmtree(item_path) shutil.rmtree(item_path)
else: else:
try: try:
print("Delete file "+ item_path) app.logger.debug("Delete file " + item_path)
os.remove(item_path) os.remove(item_path)
except: except:
print("Could not remove:"+item_path) app.logger.debug("Could not remove:" + item_path)
shutil.rmtree(source, ignore_errors=True) shutil.rmtree(source, ignore_errors=True)
...@@ -47,3 +47,7 @@ span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: te ...@@ -47,3 +47,7 @@ span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: te
.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary{ background-color: #1C5484; } .btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary{ background-color: #1C5484; }
.btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { background-color: #89B9E2; } .btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { background-color: #89B9E2; }
.btn-toolbar>.btn+.btn, .btn-toolbar>.btn-group+.btn, .btn-toolbar>.btn+.btn-group, .btn-toolbar>.btn-group+.btn-group { margin-left:0px; } .btn-toolbar>.btn+.btn, .btn-toolbar>.btn-group+.btn, .btn-toolbar>.btn+.btn-group, .btn-toolbar>.btn-group+.btn-group { margin-left:0px; }
.spinner {margin:0 41%;}
.spinner2 {margin:0 41%;}
var displaytext;
var updateTimerID;
var updateText;
$(function() { $(function() {
$('.discover .row').isotope({ $('.discover .row').isotope({
...@@ -31,7 +34,9 @@ $(function() { ...@@ -31,7 +34,9 @@ $(function() {
url: window.location.pathname+"/../../shutdown", url: window.location.pathname+"/../../shutdown",
data: {"parameter":0}, data: {"parameter":0},
success: function(data) { success: function(data) {
return alert(data.text);} $('#spinner').show();
displaytext=data.text;
window.setTimeout(restartTimer, 3000);}
}); });
}); });
$("#shutdown").click(function() { $("#shutdown").click(function() {
...@@ -50,17 +55,66 @@ $(function() { ...@@ -50,17 +55,66 @@ $(function() {
dataType: 'json', dataType: 'json',
url: window.location.pathname+"/../../get_update_status", url: window.location.pathname+"/../../get_update_status",
success: function(data) { success: function(data) {
$("#check_for_update").html(button_text);
if (data.status == true) { if (data.status == true) {
$("#check_for_update").addClass('hidden'); $("#check_for_update").addClass('hidden');
$("#perform_update").removeClass('hidden'); $("#perform_update").removeClass('hidden');
}else{ $("#update_info").removeClass('hidden');
$("#check_for_update").html(button_text); $("#update_info").find('span').html(data.commit);
};} }
}
});
});
$("#perform_update").click(function() {
$('#spinner2').show();
$.ajax({
type: "POST",
dataType: 'json',
data: { start: "True"},
url: window.location.pathname+"/../../get_updater_status",
success: function(data) {
updateText=data.text
$("#UpdateprogressDialog #Updatecontent").html(updateText[data.status]);
console.log(data.status);
updateTimerID=setInterval(updateTimer, 2000);}
}); });
}); });
}); });
function restartTimer() {
$('#spinner').hide();
$('#RestartDialog').modal('hide');
}
function updateTimer() {
$.ajax({
dataType: 'json',
url: window.location.pathname+"/../../get_updater_status",
success: function(data) {
console.log(data.status);
$("#UpdateprogressDialog #Updatecontent").html(updateText[data.status]);
if (data.status >6){
clearInterval(updateTimerID);
$('#spinner2').hide();
$('#UpdateprogressDialog #updateFinished').removeClass('hidden');
$("#check_for_update").removeClass('hidden');
$("#perform_update").addClass('hidden');
}
},
error: function() {
console.log('Done');
clearInterval(updateTimerID);
$('#spinner2').hide();
$("#UpdateprogressDialog #Updatecontent").html(updateText[7]);
$('#UpdateprogressDialog #updateFinished').removeClass('hidden');
$("#check_for_update").removeClass('hidden');
$("#perform_update").addClass('hidden');
}
});
}
$(window).resize(function(event) { $(window).resize(function(event) {
$('.discover .row').isotope('reLayout'); $('.discover .row').isotope('reLayout');
}); });
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
{% block body %} {% block body %}
<div class="discover"> <div class="discover">
<h2>{{_('User list')}}</h2> <h2>{{_('User list')}}</h2>
<div id="divLoading"></div>
<table class="table table-striped" id="table_user"> <table class="table table-striped" id="table_user">
<tr> <tr>
<th>{{_('Nickname')}}</th> <th>{{_('Nickname')}}</th>
...@@ -76,11 +77,13 @@ ...@@ -76,11 +77,13 @@
<div class="btn btn-default"><a href="{{url_for('configuration')}}">{{_('Configuration')}}</a></div> <div class="btn btn-default"><a href="{{url_for('configuration')}}">{{_('Configuration')}}</a></div>
<h2>{{_('Administration')}}</h2> <h2>{{_('Administration')}}</h2>
{% if not development %} {% if not development %}
<p>{{_('Current commit timestamp')}}: {{commit}} </p> <div>{{_('Current commit timestamp')}}: <span>{{commit}} </span></div>
<div class="btn btn-default" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-web')}}</a></div> <div class="hidden" id="update_info">{{_('Newest commit timestamp')}}: <span></span></div>
<div class="btn btn-default" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-web')}}</a></div> <p></p>
<div class="btn btn-default" id="check_for_update">{{_('Check for update')}}</a></div> <div class="btn btn-default" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-web')}}</div>
<a href="{{url_for('update')}}" class="btn btn-default hidden" id="perform_update">{{_('Perform Update')}}</a> <div class="btn btn-default" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-web')}}</div>
<div class="btn btn-default" id="check_for_update">{{_('Check for update')}}</div>
<div class="btn btn-default hidden" id="perform_update" data-toggle="modal" data-target="#UpdateprogressDialog">{{_('Perform Update')}}</div>
{% endif %} {% endif %}
</div> </div>
<!-- Modal --> <!-- Modal -->
...@@ -88,15 +91,17 @@ ...@@ -88,15 +91,17 @@
<div class="modal-dialog modal-sm"> <div class="modal-dialog modal-sm">
<!-- Modal content--> <!-- Modal content-->
<div class="modal-content"> <div class="modal-content">
<div class="modal-header bg-info"> <div class="modal-header bg-info"></div>
</div>
<div class="modal-body text-center"> <div class="modal-body text-center">
<p>{{_('Do you really want to restart Calibre-web?')}}</p> <p>{{_('Do you really want to restart Calibre-web?')}}</p>
<button type="button" class="btn btn-default" id="restart" data-dismiss="modal">{{_('Ok')}}</button> <div id="spinner" class="spinner" style="display:none;">
<img id="img-spinner" src="/static/css/images/loading-icon.gif"/>
</div>
<p></p>
<button type="button" class="btn btn-default" id="restart" >{{_('Ok')}}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Back')}}</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{_('Back')}}</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div id="ShutdownDialog" class="modal fade" role="dialog"> <div id="ShutdownDialog" class="modal fade" role="dialog">
...@@ -114,5 +119,23 @@ ...@@ -114,5 +119,23 @@
</div> </div>
</div> </div>
<div id="UpdateprogressDialog" class="modal fade" role="dialog">
<div class="modal-dialog modal-sm">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header bg-info text-center">
<span>{{_('Updating, please do not reload page')}}</span>
</div>
<div class="modal-body text-center">
<div id="spinner2" class="spinner2" style="display:none;">
<img id="img-spinner" src="/static/css/images/loading-icon.gif"/>
</div>
<p></p>
<div id="Updatecontent"></div>
<p></p>
<button type="button" class="btn btn-default hidden" id="updateFinished" data-dismiss="modal">{{_('Ok')}}</button>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse">
{% if g.user.is_authenticated or g.user.is_anonymous() %} {% if g.user.is_authenticated or g.user.is_anonymous() %}
<ul class="nav navbar-nav "> <ul class="nav navbar-nav ">
<li><a href="{{url_for('advanced_search')}}"><span class="glyphicon glyphicon-search"></span> {{_('Advanced Search')}}</a></li> <li><a href="{{url_for('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">
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
import mimetypes import mimetypes
import logging import logging
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
from tempfile import gettempdir
import textwrap import textwrap
from flask import Flask, render_template, session, request, Response, redirect, url_for, send_from_directory, \ from flask import Flask, render_template, session, request, Response, redirect, url_for, send_from_directory, \
make_response, g, flash, abort make_response, g, flash, abort
...@@ -39,9 +38,10 @@ import sys ...@@ -39,9 +38,10 @@ import sys
import subprocess import subprocess
import re import re
import db import db
import thread
from shutil import move, copyfile from shutil import move, copyfile
from tornado.ioloop import IOLoop from tornado.ioloop import IOLoop
import StringIO
try: try:
from wand.image import Image from wand.image import Image
...@@ -51,9 +51,6 @@ except ImportError, e: ...@@ -51,9 +51,6 @@ except ImportError, e:
use_generic_pdf_cover = True use_generic_pdf_cover = True
from cgi import escape from cgi import escape
# Global variables
global_task = None
# Proxy Helper class # Proxy Helper class
class ReverseProxied(object): class ReverseProxied(object):
...@@ -668,7 +665,7 @@ def get_opds_download_link(book_id, format): ...@@ -668,7 +665,7 @@ def get_opds_download_link(book_id, format):
file_name = book.title file_name = book.title
if len(book.authors) > 0: if len(book.authors) > 0:
file_name = book.authors[0].name + '-' + file_name file_name = book.authors[0].name + '-' + file_name
file_name = helper.get_valid_filename(file_name) # file_name = helper.get_valid_filename(file_name)
response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + format)) response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + format))
response.headers["Content-Disposition"] = "attachment; filename=\"%s.%s\"" % (data.name, format) response.headers["Content-Disposition"] = "attachment; filename=\"%s.%s\"" % (data.name, format)
return response return response
...@@ -716,10 +713,39 @@ def get_update_status(): ...@@ -716,10 +713,39 @@ def get_update_status():
commit = requests.get('https://api.github.com/repos/janeczku/calibre-web/git/refs/heads/master').json() commit = requests.get('https://api.github.com/repos/janeczku/calibre-web/git/refs/heads/master').json()
if "object" in commit and commit['object']['sha'] != commit_id: if "object" in commit and commit['object']['sha'] != commit_id:
status['status'] = True status['status'] = True
commitdate = requests.get('https://api.github.com/repos/janeczku/calibre-web/git/commits/'+commit['object']['sha']).json()
if "committer" in commitdate:
status['commit'] = commitdate['committer']['date']
else:
status['commit'] = u'Unknown'
else: else:
status['status'] = False status['status'] = False
return json.dumps(status) return json.dumps(status)
@app.route("/get_updater_status", methods=['GET','POST'])
@login_required
@admin_required
def get_updater_status():
status = {}
if request.method == "POST":
commit = request.form.to_dict()
if "start" in commit and commit['start'] == 'True':
text={
"1": _(u'Requesting update package'),
"2": _(u'Downloading update package'),
"3": _(u'Unzipping update package'),
"4": _(u'Files are replaced'),
"5": _(u'Database connections are closed'),
"6": _(u'Server is stopped'),
"7": _(u'Update finished, please press okay and reload page')
}
status['text']=text
helper.updater_thread = helper.Updater()
helper.updater_thread.start()
status['status']=helper.updater_thread.get_update_status()
elif request.method == "GET":
status['status']=helper.updater_thread.get_update_status()
return json.dumps(status)
@app.route("/get_languages_json", methods=['GET', 'POST']) @app.route("/get_languages_json", methods=['GET', 'POST'])
...@@ -1032,7 +1058,7 @@ def shutdown(): ...@@ -1032,7 +1058,7 @@ def shutdown():
server.add_callback(server.stop) server.add_callback(server.stop)
showtext = {} showtext = {}
if task == 0: if task == 0:
showtext['text'] = _(u'Performing Restart, please reload page') showtext['text'] = _(u'Server restarted, please reload page')
else: else:
showtext['text'] = _(u'Performing shutdown of server, please close window') showtext['text'] = _(u'Performing shutdown of server, please close window')
return json.dumps(showtext) return json.dumps(showtext)
...@@ -1043,23 +1069,10 @@ def shutdown(): ...@@ -1043,23 +1069,10 @@ def shutdown():
@login_required @login_required
@admin_required @admin_required
def update(): def update():
global global_task helper.updater_thread = helper.Updater()
r = requests.get('https://api.github.com/repos/janeczku/calibre-web/zipball/master', stream=True)
fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0]
z = zipfile.ZipFile(StringIO.StringIO(r.content))
tmp_dir = gettempdir()
z.extractall(tmp_dir)
helper.update_source(os.path.join(tmp_dir,os.path.splitext(fname)[0]),config.get_main_dir)
global_task = 0
db.session.close()
db.engine.dispose()
ub.session.close()
ub.engine.dispose()
# stop tornado server
server = IOLoop.instance()
server.add_callback(server.stop)
flash(_(u"Update done"), category="info") flash(_(u"Update done"), category="info")
return logout() return ""
@app.route("/search", methods=["GET"]) @app.route("/search", methods=["GET"])
@login_required_if_no_ano @login_required_if_no_ano
...@@ -1605,7 +1618,6 @@ def configuration_helper(origin): ...@@ -1605,7 +1618,6 @@ def configuration_helper(origin):
if request.method == "POST": if request.method == "POST":
to_save = request.form.to_dict() to_save = request.form.to_dict()
content = ub.session.query(ub.Settings).first() content = ub.session.query(ub.Settings).first()
# ToDo: check lib vaild, and change without restart
if "config_calibre_dir" in to_save: if "config_calibre_dir" in to_save:
if content.config_calibre_dir != to_save["config_calibre_dir"]: if content.config_calibre_dir != to_save["config_calibre_dir"]:
content.config_calibre_dir = to_save["config_calibre_dir"] content.config_calibre_dir = to_save["config_calibre_dir"]
......
This diff is collapsed.
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