Merge remote-tracking branch 'bbb/295---Send-AZW-to-Kindle'

Changed function for 295, azw3 is preferred format for sending to kindle
This commit is contained in:
Ozzieisaacs 2018-11-18 17:09:13 +01:00
commit dfa17956c9
4 changed files with 95 additions and 44 deletions

View file

@ -17,6 +17,7 @@ from flask import send_from_directory, make_response, redirect, abort
from flask_babel import gettext as _
from flask_login import current_user
from babel.dates import format_datetime
from datetime import datetime
import threading
import shutil
import requests
@ -112,42 +113,68 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
e_mail, user_name, _(u"Registration e-mail for user: %(name)s", name=user_name), text)
return
def check_send_to_kindle(entry):
'''
returns all available book formats for sending to Kindle
'''
if len(entry.data):
bookformats=list()
if ub.config.config_ebookconverter == 0:
# no converter - only for mobi and pdf formats
for ele in iter(entry.data):
if 'MOBI' in ele.format:
bookformats.append({'format':'Mobi','text':_('Send %(format)s to Kindle',format='Mobi')})
if 'PDF' in ele.format:
bookformats.append({'format':'Pdf','text':_('Send %(format)s to Kindle',format='Pdf')})
if 'AZW' in ele.format:
bookformats.append({'format':'Azw','text':_('Send %(format)s to Kindle',format='Azw')})
if 'AZW3' in ele.format:
bookformats.append({'format':'Azw3','text':_('Send %(format)s to Kkindle',format='Azw3')})
else:
formats = list()
for ele in iter(entry.data):
formats.append(ele.format)
if 'MOBI' in formats:
bookformats.append({'format': 'Mobi','convert':0,'text':_('Send %(format)s to Kindle',format='Mobi')})
if 'AZW' in formats:
bookformats.append({'format': 'Azw','convert':0,'text':_('Send %(format)s to Kindle',format='Azw')})
if 'AZW3' in formats:
bookformats.append({'format': 'Azw3','convert':0,'text':_('Send %(format)s to Kindle',format='Azw3')})
if 'PDF' in formats:
bookformats.append({'format': 'Pdf','convert':0,'text':_('Send %(format)s to Kindle',format='Pdf')})
if ub.config.config_ebookconverter >= 1:
if 'EPUB' in formats and not 'MOBI' in formats:
bookformats.append({'format': 'Mobi','convert':1,
'text':_('Convert %(orig)s to %(format)s and send to Kindle',orig='Epub',format='Mobi')})
if ub.config.config_ebookconverter == 2:
if 'EPUB' in formats and not 'AZW3' in formats:
bookformats.append({'format': 'Azw3','convert':1,
'text':_('Convert %(orig)s to %(format)s and send to Kindle',orig='Epub',format='Azw3')})
return bookformats
else:
app.logger.error(u'Cannot find book entry %d', entry.id)
return None
# Files are processed in the following order/priority:
# 1: If Mobi file is exisiting, it's directly send to kindle email,
# 2: If Epub file is exisiting, it's converted and send to kindle email
# 3: If Pdf file is exisiting, it's directly send to kindle email,
def send_mail(book_id, kindle_mail, calibrepath, user_id):
# 1: If Mobi file is existing, it's directly send to kindle email,
# 2: If Epub file is existing, it's converted and send to kindle email,
# 3: If Pdf file is existing, it's directly send to kindle email
def send_mail(book_id, book_format, convert, kindle_mail, calibrepath, user_id):
"""Send email with attachments"""
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).all()
formats = {}
for entry in data:
if entry.format == "MOBI":
formats["mobi"] = entry.name + ".mobi"
if entry.format == "EPUB":
formats["epub"] = entry.name + ".epub"
if entry.format == "PDF":
formats["pdf"] = entry.name + ".pdf"
if len(formats) == 0:
return _(u"Could not find any formats suitable for sending by e-mail")
if 'mobi' in formats:
result = formats['mobi']
elif 'epub' in formats:
if convert:
# returns None if success, otherwise errormessage
return convert_book_format(book_id, calibrepath, u'epub', u'mobi', user_id, kindle_mail)
elif 'pdf' in formats:
result = formats['pdf'] # worker.get_attachment()
return convert_book_format(book_id, calibrepath, u'epub', book_format.lower(), user_id, kindle_mail)
else:
return _(u"Could not find any formats suitable for sending by e-mail")
if result:
global_WorkerThread.add_email(_(u"Send to Kindle"), book.path, result, ub.get_mail_settings(),
for entry in iter(book.data):
if entry.format.upper() == book_format.upper():
result = entry.name + '.' + book_format.lower()
global_WorkerThread.add_email(_(u"Send to Kindle"), book.path, result, ub.get_mail_settings(),
kindle_mail, user_id, _(u"E-mail: %(book)s", book=book.title),
_(u'This e-mail has been sent via Calibre-Web.'))
else:
return
return _(u"The requested file could not be read. Maybe wrong permissions?")
@ -594,16 +621,23 @@ def get_current_version_info():
return {'hash': content[0], 'datetime': content[1]}
return False
def json_serial(obj):
"""JSON serializer for objects not serializable by default json code"""
if isinstance(obj, (datetime)):
return obj.isoformat()
raise TypeError ("Type %s not serializable" % type(obj))
def render_task_status(tasklist):
#helper function to apply localize status information in tasklist entries
renderedtasklist=list()
# task2 = task
for task in tasklist:
if task['user'] == current_user.nickname or current_user.role_admin():
# task2 = copy.deepcopy(task) # = task
if task['formStarttime']:
task['starttime'] = format_datetime(task['formStarttime'], format='short', locale=web.get_locale())
task['formStarttime'] = ""
# task2['formStarttime'] = ""
else:
if 'starttime' not in task:
task['starttime'] = ""

View file

@ -40,8 +40,22 @@
</div>
{% endif %}
{% endif %}
{% if g.user.kindle_mail and g.user.is_authenticated %}
<a href="{{url_for('send_to_kindle', book_id=entry.id)}}" id="sendbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-send"></span> {{_('Send to Kindle')}}</a>
{% if g.user.kindle_mail and g.user.is_authenticated and kindle_list %}
{% if kindle_list.__len__() == 1 %}
<a href="{{url_for('send_to_kindle', book_id=entry.id, book_format=kindle_list[0]['format'], convert=kindle_list[0]['convert'])}}" id="sendbtn" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-send"></span> {{kindle_list[0]['text']}}</a>
{% else %}
<div class="btn-group" role="group">
<button id="sendbtn2" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-send"></span>{{_('Send to Kindle')}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="send-to-kindle">
{% for format in kindle_list %}
<li><a href="{{url_for('send_to_kindle', book_id=entry.id, book_format=format['format'], convert=format['convert'])}}">{{format['text']}}</a></li>
{%endfor%}
</ul>
</div>
{% endif %}
{% endif %}
{% if entry.data|length %}
<div class="btn-group" role="group">

View file

@ -903,12 +903,12 @@ def get_email_status_json():
answer=list()
# UIanswer = list()
tasks=helper.global_WorkerThread.get_taskstatus()
if not current_user.role_admin():
'''if not current_user.role_admin():
for task in tasks:
if task['user'] == current_user.nickname:
if task['formStarttime']:
task['starttime'] = format_datetime(task['formStarttime'], format='short', locale=get_locale())
task['formStarttime'] = ""
# task['formStarttime'] = ""
else:
if 'starttime' not in task:
task['starttime'] = ""
@ -921,12 +921,12 @@ def get_email_status_json():
else:
if 'starttime' not in task:
task['starttime'] = ""
answer = tasks
answer = tasks'''
# UIanswer = copy.deepcopy(answer)
answer = helper.render_task_status(answer)
answer = helper.render_task_status(tasks)
js=json.dumps(answer)
js=json.dumps(answer, default=helper.json_serial)
response = make_response(js)
response.headers["Content-Type"] = "application/json; charset=utf-8"
return response
@ -1679,9 +1679,11 @@ def show_book(book_id):
entries.tags = sort(entries.tags, key = lambda tag: tag.name)
kindle_list = helper.check_send_to_kindle(entries)
return render_title_template('detail.html', entry=entries, cc=cc, is_xhr=request.is_xhr,
title=entries.title, books_shelfs=book_in_shelfs,
have_read=have_read, page="book")
have_read=have_read, kindle_list=kindle_list, page="book")
else:
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
return redirect(url_for("index"))
@ -2462,15 +2464,15 @@ def token_verified():
return response
@app.route('/send/<int:book_id>')
@app.route('/send/<int:book_id>/<book_format>/<int:convert>')
@login_required
@download_required
def send_to_kindle(book_id):
def send_to_kindle(book_id, book_format, convert):
settings = ub.get_mail_settings()
if settings.get("mail_server", "mail.example.com") == "mail.example.com":
flash(_(u"Please configure the SMTP mail settings first..."), category="error")
elif current_user.kindle_mail:
result = helper.send_mail(book_id, current_user.kindle_mail, config.config_calibre_dir, current_user.nickname)
result = helper.send_mail(book_id, book_format, convert, current_user.kindle_mail, config.config_calibre_dir, current_user.nickname)
if result is None:
flash(_(u"Book successfully queued for sending to %(kindlemail)s", kindlemail=current_user.kindle_mail),
category="success")
@ -3911,7 +3913,7 @@ def upload():
gdriveutils.updateGdriveCalibreFromLocal()
if error:
flash(error, category="error")
uploadText=_(u"File %(file)s uploaded", file=book.title)
uploadText=(u"File %s" % book.title)
helper.global_WorkerThread.add_upload(current_user.nickname,
"<a href=\"" + url_for('show_book', book_id=book.id) + "\">" + uploadText + "</a>")
@ -3927,8 +3929,9 @@ def upload():
return render_title_template('book_edit.html', book=book, authors=author_names,
cc=cc, title=_(u"edit metadata"), page="upload")
book_in_shelfs = []
flg_send_to_kindle = helper.chk_send_to_kindle(book_id)
return render_title_template('detail.html', entry=book, cc=cc,
title=book.title, books_shelfs=book_in_shelfs, page="upload")
title=book.title, books_shelfs=book_in_shelfs, flg_kindle=flg_send_to_kindle, page="upload")
return redirect(url_for("index"))

View file

@ -71,7 +71,7 @@ def get_attachment(bookpath, filename):
file_ = open(os.path.join(calibrepath, bookpath, filename), 'rb')
data = file_.read()
file_.close()
except IOError:
except IOError as e:
web.app.logger.exception(e) # traceback.print_exc()
web.app.logger.error(u'The requested file could not be read. Maybe wrong permissions?')
return None
@ -320,7 +320,7 @@ class WorkerThread(threading.Thread):
cur_book = web.db.session.query(web.db.Books).filter(web.db.Books.id == bookid).first()
if os.path.isfile(file_path + format_new_ext):
new_format = web.db.Data(name=cur_book.data[0].name,
book_format=self.queue[self.current]['settings']['new_book_format'],
book_format=self.queue[self.current]['settings']['new_book_format'].upper(),
book=bookid, uncompressed_size=os.path.getsize(file_path + format_new_ext))
cur_book.data.append(new_format)
web.db.session.commit()