mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-30 21:40:00 +00:00
Add logging / Optimize CSS
This commit is contained in:
parent
34cd613e29
commit
13a024a77d
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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>
|
||||||
|
@ -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">
|
||||||
|
@ -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>
|
||||||
|
40
cps/web.py
40
cps/web.py
@ -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'))
|
|
||||||
|
Loading…
Reference in New Issue
Block a user