Add logging / Optimize CSS

This commit is contained in:
Jan Broer 2016-03-28 21:07:13 +02:00
parent 34cd613e29
commit 13a024a77d
6 changed files with 36 additions and 50 deletions

View File

@ -3,6 +3,7 @@
from cps import db, ub from cps import db, ub
from cps import config from cps import config
from flask import current_app as app
import smtplib import smtplib
import sys import sys
@ -29,19 +30,17 @@ def update_download(book_id, user_id):
def make_mobi(book_id): def make_mobi(book_id):
kindlegen = os.path.join(config.MAIN_DIR, "vendor", "kindlegen") kindlegen = os.path.join(config.MAIN_DIR, "vendor", "kindlegen")
if not os.path.exists(kindlegen): if not os.path.exists(kindlegen):
print "make_mobie: kindlegen binary not found in: %s" % kindlegen app.logger.error("make_mobi: kindlegen binary not found in: %s" % kindlegen)
return None return None
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()
data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == 'EPUB').first() data = db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == 'EPUB').first()
if not data: if not data:
print "make_mobie: epub format not found for book id: %d" % book_id app.logger.error("make_mobi: epub format not found for book id: %d" % book_id)
return None return None
file_path = os.path.join(config.DB_ROOT, book.path, data.name) file_path = os.path.join(config.DB_ROOT, book.path, data.name)
# print os.path.getsize(file_path + ".epub")
if os.path.exists(file_path + ".epub"): if os.path.exists(file_path + ".epub"):
# print u"conversion started for %s" % book.title
check = subprocess.call([kindlegen, file_path + ".epub"], stdout=subprocess.PIPE) check = subprocess.call([kindlegen, file_path + ".epub"], stdout=subprocess.PIPE)
if not check or check < 2: if not check or check < 2:
book.data.append(db.Data( book.data.append(db.Data(
@ -53,15 +52,14 @@ def make_mobi(book_id):
db.session.commit() db.session.commit()
return file_path + ".mobi" return file_path + ".mobi"
else: else:
print "make_mobie: kindlegen failed to convert book" app.logger.error("make_mobi: kindlegen failed with error while converting book")
return None return None
else: else:
print "make_mobie: epub not found: " + file_path + ".epub" app.logger.error("make_mobie: epub not found: %s.epub" % file_path)
return None return None
def send_mail(book_id, kindle_mail): def send_mail(book_id, kindle_mail):
'''Send email with attachments''' '''Send email with attachments'''
is_mobi = False is_mobi = False
is_azw = False is_azw = False
is_azw3 = False is_azw3 = False
@ -73,14 +71,12 @@ def send_mail(book_id, kindle_mail):
msg = MIMEMultipart() msg = MIMEMultipart()
msg['From'] = settings["mail_from"] msg['From'] = settings["mail_from"]
msg['To'] = kindle_mail msg['To'] = kindle_mail
msg['Subject'] = 'Sent to Kindle' msg['Subject'] = 'Send to Kindle'
text = 'This email has been sent via calibre web.' text = 'This email has been sent via calibre web.'
msg.attach(MIMEText(text)) msg.attach(MIMEText(text))
use_ssl = settings.get('mail_use_ssl', 0) use_ssl = settings.get('mail_use_ssl', 0)
print "use ssl: %d" % use_ssl
# attach files # attach files
#msg.attach(self.get_attachment(file_path)) #msg.attach(self.get_attachment(file_path))
@ -102,8 +98,7 @@ def send_mail(book_id, kindle_mail):
formats["pdf"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".pdf") formats["pdf"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".pdf")
if len(formats) == 0: if len(formats) == 0:
print "no formats found" return "Could not find any formats suitable for sending by email"
return "Could not find any formats that can be send by email"
if 'azw3' in formats: if 'azw3' in formats:
msg.attach(get_attachment(formats['azw3'])) msg.attach(get_attachment(formats['azw3']))
@ -120,7 +115,7 @@ def send_mail(book_id, kindle_mail):
elif 'pdf' in formats: elif 'pdf' in formats:
msg.attach(get_attachment(formats['pdf'])) msg.attach(get_attachment(formats['pdf']))
else: else:
return "Could not find any formats that can be send by email" return "Could not find any formats suitable for sending by email"
# convert MIME message to string # convert MIME message to string
fp = StringIO() fp = StringIO()
@ -141,9 +136,9 @@ def send_mail(book_id, kindle_mail):
mailserver.login(settings["mail_login"], settings["mail_password"]) mailserver.login(settings["mail_login"], settings["mail_password"])
mailserver.sendmail(settings["mail_login"], kindle_mail, msg) mailserver.sendmail(settings["mail_login"], kindle_mail, msg)
mailserver.quit() mailserver.quit()
except smtplib.SMTPException: except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException), e:
traceback.print_exc() app.logger.error(traceback.print_exc())
return "Error communicating with the mail server, please check the logs for details." return "Failed to send mail: %s" % str(e)
return None return None

View File

@ -8,9 +8,9 @@ a{color: #45b29d}a:hover{color: #444;}
.container-fluid img{display:block;max-width:100%;height:auto} .container-fluid img{display:block;max-width:100%;height:auto}
.container-fluid .discover{margin-bottom:50px} .container-fluid .discover{margin-bottom:50px}
.container-fluid .new-books{border-top:1px solid #ccc}.container-fluid .new-books h2{margin:50px 0 0 0} .container-fluid .new-books{border-top:1px solid #ccc}.container-fluid .new-books h2{margin:50px 0 0 0}
.container-fluid .book{margin-top:20px}.container-fluid .book .cover{height:225px;position:relative}.container-fluid .book .cover img{border:1px solid #ccc;border-radius:5px;box-sizeing:border-box;height:100%;bottom:0;position:absolute} .container-fluid .book{margin-top:20px}.container-fluid .book .cover{height:225px;position:relative}.container-fluid .book .cover img{border:3px solid #fff;border-radius:5px;box-sizeing:border-box;height:100%;bottom:0;position:absolute;-webkit-box-shadow: 0 5px 8px -6px #777;-moz-box-shadow: 0 5px 8px -6px #777;box-shadow: 0 5px 8px -6px #777;}
.container-fluid .book .meta{margin-top:10px}.container-fluid .book .meta p{margin:0} .container-fluid .book .meta{margin-top:10px}.container-fluid .book .meta p{margin:0}
.container-fluid .book .meta .title{font-weight:bold;font-size:16px;color:#444} .container-fluid .book .meta .title{font-weight:bold;font-size:15px;color:#444}
.container-fluid .book .meta .author{font-size:12px;color:#999} .container-fluid .book .meta .author{font-size:12px;color:#999}
.container-fluid .book .meta .rating{margin-top:5px}.rating .glyphicon-star{color:#999}.rating .glyphicon-star.good{color:#45b29d} .container-fluid .book .meta .rating{margin-top:5px}.rating .glyphicon-star{color:#999}.rating .glyphicon-star.good{color:#45b29d}
.navbar-brand{font-family: 'Grand Hotel', cursive; font-size: 35px; color: #45b29d !important;} .navbar-brand{font-family: 'Grand Hotel', cursive; font-size: 35px; color: #45b29d !important;}
@ -20,3 +20,11 @@ a{color: #45b29d}a:hover{color: #444;}
span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: text-top;} span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: text-top;}
.book-meta {padding-bottom: 20px;} .book-meta {padding-bottom: 20px;}
.book-meta .tags a {display: inline;} .book-meta .tags a {display: inline;}
.container-fluid .single .cover img {
border: 3px solid #fff;
border-radius: 5px;
box-sizeing: border-box;
-webkit-box-shadow: 0 5px 8px -6px #777;
-moz-box-shadow: 0 5px 8px -6px #777;
box-shadow: 0 5px 8px -6px #777;
}

View File

@ -126,7 +126,6 @@
{% endif %} {% endif %}
{% if g.user.role %} {% if g.user.role %}
</br>
<div class="btn-toolbar" role="toolbar"> <div class="btn-toolbar" role="toolbar">
<div class="btn-group" role="group" aria-label="Edit/Delete book"> <div class="btn-group" role="group" aria-label="Edit/Delete book">
<a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" role="button"><span class="glyphicon glyphicon-edit"></span> Edit metadata</a> <a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" role="button"><span class="glyphicon glyphicon-edit"></span> Edit metadata</a>

View File

@ -8,11 +8,11 @@
<input type="text" class="form-control" name="mail_server" id="mail_server" value="{{content.mail_server}}"> <input type="text" class="form-control" name="mail_server" id="mail_server" value="{{content.mail_server}}">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="mail_port">SMTP port (usually 25 for unencrypted and 587 for StartTLS)</label> <label for="mail_port">SMTP port (usually 25 for plain SMTP and 587 for SSL)</label>
<input type="text" class="form-control" name="mail_port" id="mail_port" value="{{content.mail_port}}"> <input type="text" class="form-control" name="mail_port" id="mail_port" value="{{content.mail_port}}">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="mail_use_ssl">Server requires encryption (StartTLS)</label> <label for="mail_use_ssl">Server uses SSL (StartTLS)</label>
<input type="checkbox" name="mail_use_ssl" id="mail_use_ssl" {% if content.mail_use_ssl %}checked{% endif %}> <input type="checkbox" name="mail_use_ssl" id="mail_use_ssl" {% if content.mail_use_ssl %}checked{% endif %}>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -25,7 +25,7 @@
<tr> <tr>
<th>SMTP hostname</th> <th>SMTP hostname</th>
<th>SMTP port</th> <th>SMTP port</th>
<th>Server requires SSL</th> <th>SSL</th>
<th>SMTP login</th> <th>SMTP login</th>
<th>SMTP password</th> <th>SMTP password</th>
<th>From mail</th> <th>From mail</th>

View File

@ -2,6 +2,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import mimetypes import mimetypes
import logging
import sys
mimetypes.add_type('application/xhtml+xml','.xhtml') mimetypes.add_type('application/xhtml+xml','.xhtml')
from flask import Flask, render_template, session, request, Response, redirect, url_for, send_from_directory, make_response, g, flash, abort from flask import Flask, render_template, session, request, Response, redirect, url_for, send_from_directory, make_response, g, flash, abort
from cps import db, config, ub, helper from cps import db, config, ub, helper
@ -20,6 +22,15 @@ from sqlalchemy.sql import *
app = (Flask(__name__)) app = (Flask(__name__))
# Log only in production mode.
#if not app.debug:
file_handler = logging.StreamHandler(sys.stdout)
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger_name = 'calibre web'
app.logger.setLevel(logging.INFO)
app.logger.info('Starting Calibre Web...')
Principal(app) Principal(app)
lm = LoginManager(app) lm = LoginManager(app)
@ -41,8 +52,6 @@ def load_user_from_header(header_val):
header_val = base64.b64decode(header_val) header_val = base64.b64decode(header_val)
basic_username = header_val.split(':')[0] basic_username = header_val.split(':')[0]
basic_password = header_val.split(':')[1] basic_password = header_val.split(':')[1]
#print basic_username
#print basic_password
except TypeError: except TypeError:
pass pass
user = ub.session.query(ub.User).filter(ub.User.nickname == basic_username).first() user = ub.session.query(ub.User).filter(ub.User.nickname == basic_username).first()
@ -212,14 +221,7 @@ def get_opds_download_link(book_id, format):
file_name = author+'-'+file_name file_name = author+'-'+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.DB_ROOT, book.path), data.name + "." +format)) response = make_response(send_from_directory(os.path.join(config.DB_ROOT, 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)
response.headers["Content-Disposition"] = \
"attachment; " \
"filename={utf_filename}.{suffix};" \
"filename*=UTF-8''{utf_filename}.{suffix}".format(
utf_filename=file_name.encode('utf-8'),
suffix=format
)
return response return response
@app.route("/", defaults={'page': 1}) @app.route("/", defaults={'page': 1})
@ -238,12 +240,6 @@ def index(page):
@app.route('/hot/page/<int:page>') @app.route('/hot/page/<int:page>')
def hot_books(page): def hot_books(page):
random = db.session.query(db.Books).filter(false()) random = db.session.query(db.Books).filter(false())
# if page == 1:
# entries = db.session.query(db.Books).filter(db.Books.ratings.any(db.Ratings.rating > 9)).order_by(db.Books.last_modified.desc()).limit(config.NEWEST_BOOKS)
# else:
# off = int(int(config.NEWEST_BOOKS) * (page - 1))
# entries = db.session.query(db.Books).filter(db.Books.ratings.any(db.Ratings.rating > 9)).order_by(db.Books.last_modified.desc()).offset(60).limit(config.NEWEST_BOOKS)
off = int(int(6) * (page - 1)) off = int(int(6) * (page - 1))
all_books = ub.session.query(ub.Downloads, ub.func.count(ub.Downloads.book_id)).order_by(ub.func.count(ub.Downloads.book_id).desc()).group_by(ub.Downloads.book_id) all_books = ub.session.query(ub.Downloads, ub.func.count(ub.Downloads.book_id)).order_by(ub.func.count(ub.Downloads.book_id).desc()).group_by(ub.Downloads.book_id)
hot_books = all_books.offset(off).limit(config.NEWEST_BOOKS) hot_books = all_books.offset(off).limit(config.NEWEST_BOOKS)
@ -370,7 +366,6 @@ def get_download_link(book_id, format):
file_name = author+'-'+file_name file_name = author+'-'+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.DB_ROOT, book.path), data.name + "." +format)) response = make_response(send_from_directory(os.path.join(config.DB_ROOT, book.path), data.name + "." +format))
#response.headers["Content-Disposition"] = "attachment; filename=%s.%s" % (file_name, format)
response.headers["Content-Disposition"] = \ response.headers["Content-Disposition"] = \
"attachment; " \ "attachment; " \
"filename={utf_filename}.{suffix};" \ "filename={utf_filename}.{suffix};" \
@ -544,7 +539,6 @@ def profile():
downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first()) downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first())
if request.method == "POST": if request.method == "POST":
to_save = request.form.to_dict() to_save = request.form.to_dict()
#print to_save
if to_save["password"]: if to_save["password"]:
content.password = generate_password_hash(to_save["password"]) content.password = generate_password_hash(to_save["password"])
if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail: if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail:
@ -660,7 +654,6 @@ def edit_book(book_id):
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()
if request.method == 'POST': if request.method == 'POST':
to_save = request.form.to_dict() to_save = request.form.to_dict()
#print to_save
book.title = to_save["book_title"] book.title = to_save["book_title"]
book.authors[0].name = to_save["author_name"] book.authors[0].name = to_save["author_name"]
@ -679,7 +672,6 @@ def edit_book(book_id):
for tag in to_save["tags"].split(","): for tag in to_save["tags"].split(","):
if tag.strip(): if tag.strip():
#print tag
is_tag = db.session.query(db.Tags).filter(db.Tags.name.like('%' + tag.strip() + '%')).first() is_tag = db.session.query(db.Tags).filter(db.Tags.name.like('%' + tag.strip() + '%')).first()
if is_tag: if is_tag:
book.tags.append(is_tag) book.tags.append(is_tag)
@ -707,11 +699,3 @@ def edit_book(book_id):
return render_template('edit_book.html', book=book) return render_template('edit_book.html', book=book)
else: else:
return render_template('edit_book.html', book=book) return render_template('edit_book.html', book=book)
# @app.route('/admin/delete/<int:book_id>')
# def delete_book(book_id):
# to_delete = db.session.query(db.Books).filter(db.Books.id == book_id).first()
# print to_delete
# db.session.delete(to_delete)
# db.session.commit()
# return redirect(url_for('index'))