1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 10:37:23 +00:00

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Cervinko Cera 2016-03-29 13:56:24 +02:00
commit c6500b7eca
6 changed files with 37 additions and 59 deletions

View File

@ -3,6 +3,7 @@
from cps import db, ub
from cps import config
from flask import current_app as app
import smtplib
import sys
@ -29,19 +30,17 @@ def update_download(book_id, user_id):
def make_mobi(book_id):
kindlegen = os.path.join(config.MAIN_DIR, "vendor", "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
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()
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
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"):
# print u"conversion started for %s" % book.title
check = subprocess.call([kindlegen, file_path + ".epub"], stdout=subprocess.PIPE)
if not check or check < 2:
book.data.append(db.Data(
@ -53,15 +52,14 @@ def make_mobi(book_id):
db.session.commit()
return file_path + ".mobi"
else:
print "make_mobie: kindlegen failed to convert book"
app.logger.error("make_mobi: kindlegen failed with error while converting book")
return None
else:
print "make_mobie: epub not found: " + file_path + ".epub"
app.logger.error("make_mobie: epub not found: %s.epub" % file_path)
return None
def send_mail(book_id, kindle_mail):
'''Send email with attachments'''
is_mobi = False
is_azw = False
is_azw3 = False
@ -73,14 +71,12 @@ def send_mail(book_id, kindle_mail):
msg = MIMEMultipart()
msg['From'] = settings["mail_from"]
msg['To'] = kindle_mail
msg['Subject'] = 'Sent to Kindle'
msg['Subject'] = 'Send to Kindle'
text = 'This email has been sent via calibre web.'
msg.attach(MIMEText(text))
use_ssl = settings.get('mail_use_ssl', 0)
print "use ssl: %d" % use_ssl
# attach files
#msg.attach(self.get_attachment(file_path))
@ -92,24 +88,15 @@ def send_mail(book_id, kindle_mail):
for entry in data:
if entry.format == "MOBI":
formats["mobi"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".mobi")
if entry.format == "AZW":
formats["azw"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".azw")
if entry.format == "AZW3":
formats["azw3"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".azw3")
if entry.format == "EPUB":
formats["epub"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".epub")
if entry.format == "PDF":
formats["pdf"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".pdf")
if len(formats) == 0:
print "no formats found"
return "Could not find any formats that can be send by email"
return "Could not find any formats suitable for sending by email"
if 'azw3' in formats:
msg.attach(get_attachment(formats['azw3']))
elif 'azw' in formats:
msg.attach(get_attachment(formats['azw']))
elif 'mobi' in formats:
if 'mobi' in formats:
msg.attach(get_attachment(formats['mobi']))
elif 'epub' in formats:
filepath = make_mobi(book.id)
@ -120,7 +107,7 @@ def send_mail(book_id, kindle_mail):
elif 'pdf' in formats:
msg.attach(get_attachment(formats['pdf']))
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
fp = StringIO()
@ -141,9 +128,9 @@ def send_mail(book_id, kindle_mail):
mailserver.login(settings["mail_login"], settings["mail_password"])
mailserver.sendmail(settings["mail_login"], kindle_mail, msg)
mailserver.quit()
except smtplib.SMTPException:
traceback.print_exc()
return "Error communicating with the mail server, please check the logs for details."
except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException), e:
app.logger.error(traceback.print_exc())
return "Failed to send mail: %s" % str(e)
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 .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 .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 .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 .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;}
@ -20,3 +20,11 @@ a{color: #45b29d}a:hover{color: #444;}
span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: text-top;}
.book-meta {padding-bottom: 20px;}
.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 %}
{% if g.user.role %}
</br>
<div class="btn-toolbar" role="toolbar">
<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>

View File

@ -8,11 +8,11 @@
<input type="text" class="form-control" name="mail_server" id="mail_server" value="{{content.mail_server}}">
</div>
<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}}">
</div>
<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 %}>
</div>
<div class="form-group">

View File

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

View File

@ -2,6 +2,8 @@
# -*- coding: utf-8 -*-
import mimetypes
import logging
import sys
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 cps import db, config, ub, helper
@ -21,6 +23,15 @@ import json
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)
lm = LoginManager(app)
@ -42,8 +53,6 @@ def load_user_from_header(header_val):
header_val = base64.b64decode(header_val)
basic_username = header_val.split(':')[0]
basic_password = header_val.split(':')[1]
#print basic_username
#print basic_password
except TypeError:
pass
user = ub.session.query(ub.User).filter(ub.User.nickname == basic_username).first()
@ -213,14 +222,7 @@ def get_opds_download_link(book_id, format):
file_name = author+'-'+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.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
)
response.headers["Content-Disposition"] = "attachment; filename=%s.%s" % (data.name, format)
return response
@app.route("/get_authors_json", methods = ['GET', 'POST'])
@ -247,12 +249,6 @@ def index(page):
@app.route('/hot/page/<int:page>')
def hot_books(page):
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))
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)
@ -379,7 +375,6 @@ def get_download_link(book_id, format):
file_name = author+'-'+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.headers["Content-Disposition"] = "attachment; filename=%s.%s" % (file_name, format)
response.headers["Content-Disposition"] = \
"attachment; " \
"filename={utf_filename}.{suffix};" \
@ -553,7 +548,6 @@ def profile():
downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first())
if request.method == "POST":
to_save = request.form.to_dict()
#print to_save
if to_save["password"]:
content.password = generate_password_hash(to_save["password"])
if to_save["kindle_mail"] and to_save["kindle_mail"] != content.kindle_mail:
@ -669,7 +663,6 @@ def edit_book(book_id):
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
if request.method == 'POST':
to_save = request.form.to_dict()
#print to_save
book.title = to_save["book_title"]
is_author = db.session.query(db.Authors).filter(db.Authors.name.like('%' + to_save["author_name"].strip() + '%')).first()
@ -701,7 +694,6 @@ def edit_book(book_id):
for tag in to_save["tags"].split(","):
if tag.strip():
#print tag
is_tag = db.session.query(db.Tags).filter(db.Tags.name.like('%' + tag.strip() + '%')).first()
if is_tag:
book.tags.append(is_tag)
@ -729,11 +721,3 @@ def edit_book(book_id):
return render_template('edit_book.html', book=book)
else:
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'))