Fixing for send to kindle after uploading
codecleaning
pull/722/head
Ozzieisaacs 6 years ago
parent b78130e3b1
commit 863b77a5d7

@ -114,9 +114,9 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
return return
def check_send_to_kindle(entry): def check_send_to_kindle(entry):
''' """
returns all available book formats for sending to Kindle returns all available book formats for sending to Kindle
''' """
if len(entry.data): if len(entry.data):
bookformats=list() bookformats=list()
if ub.config.config_ebookconverter == 0: if ub.config.config_ebookconverter == 0:
@ -156,6 +156,18 @@ def check_send_to_kindle(entry):
return None return None
# Check if a reader is existing for any of the book formats, if not, return empty list, otherwise return
# list with supported formats
def check_read_formats(entry):
EXTENSIONS_READER = {'TXT', 'PDF', 'EPUB', 'ZIP', 'CBZ', 'TAR', 'CBT', 'RAR', 'CBR'}
bookformats = list()
if len(entry.data):
for ele in iter(entry.data):
if ele.format in EXTENSIONS_READER:
bookformats.append(ele.format.lower())
return bookformats
# Files are processed in the following order/priority: # Files are processed in the following order/priority:
# 1: If Mobi file is existing, it's directly send to kindle email, # 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, # 2: If Epub file is existing, it's converted and send to kindle email,
@ -336,6 +348,7 @@ def delete_book_gdrive(book, book_format):
error =_(u'Book path %(path)s not found on Google Drive', path=book.path) # file not found error =_(u'Book path %(path)s not found on Google Drive', path=book.path) # file not found
return error return error
def generate_random_password(): def generate_random_password():
s = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*()?" s = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*()?"
passlen = 8 passlen = 8
@ -349,12 +362,14 @@ def update_dir_stucture(book_id, calibrepath):
else: else:
return update_dir_structure_file(book_id, calibrepath) return update_dir_structure_file(book_id, calibrepath)
def delete_book(book, calibrepath, book_format): def delete_book(book, calibrepath, book_format):
if ub.config.config_use_google_drive: if ub.config.config_use_google_drive:
return delete_book_gdrive(book, book_format) return delete_book_gdrive(book, book_format)
else: else:
return delete_book_file(book, calibrepath, book_format) return delete_book_file(book, calibrepath, book_format)
def get_book_cover(cover_path): def get_book_cover(cover_path):
if ub.config.config_use_google_drive: if ub.config.config_use_google_drive:
try: try:
@ -372,6 +387,7 @@ def get_book_cover(cover_path):
else: else:
return send_from_directory(os.path.join(ub.config.config_calibre_dir, cover_path), "cover.jpg") return send_from_directory(os.path.join(ub.config.config_calibre_dir, cover_path), "cover.jpg")
# saves book cover to gdrive or locally # saves book cover to gdrive or locally
def save_cover(url, book_path): def save_cover(url, book_path):
img = requests.get(url) img = requests.get(url)
@ -384,7 +400,7 @@ def save_cover(url, book_path):
f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb") f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb")
f.write(img.content) f.write(img.content)
f.close() f.close()
uploadFileToEbooksFolder(os.path.join(book_path, 'cover.jpg'), os.path.join(tmpDir, f.name)) gd.uploadFileToEbooksFolder(os.path.join(book_path, 'cover.jpg'), os.path.join(tmpDir, f.name))
web.app.logger.info("Cover is saved on Google Drive") web.app.logger.info("Cover is saved on Google Drive")
return True return True
@ -394,6 +410,7 @@ def save_cover(url, book_path):
web.app.logger.info("Cover is saved") web.app.logger.info("Cover is saved")
return True return True
def do_download_file(book, book_format, data, headers): def do_download_file(book, book_format, data, headers):
if ub.config.config_use_google_drive: if ub.config.config_use_google_drive:
startTime = time.time() startTime = time.time()
@ -621,6 +638,7 @@ def get_current_version_info():
return {'hash': content[0], 'datetime': content[1]} return {'hash': content[0], 'datetime': content[1]}
return False return False
def json_serial(obj): def json_serial(obj):
"""JSON serializer for objects not serializable by default json code""" """JSON serializer for objects not serializable by default json code"""
@ -628,6 +646,7 @@ def json_serial(obj):
return obj.isoformat() return obj.isoformat()
raise TypeError ("Type %s not serializable" % type(obj)) raise TypeError ("Type %s not serializable" % type(obj))
def render_task_status(tasklist): def render_task_status(tasklist):
#helper function to apply localize status information in tasklist entries #helper function to apply localize status information in tasklist entries
renderedtasklist=list() renderedtasklist=list()

@ -57,17 +57,15 @@
</div> </div>
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if entry.data|length %} {% if reader_list %}
<div class="btn-group" role="group"> <div class="btn-group" role="group">
<button id="read-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button id="read-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-eye-open"></span> {{_('Read in browser')}} <span class="glyphicon glyphicon-eye-open"></span> {{_('Read in browser')}}
<span class="caret"></span> <span class="caret"></span>
</button> </button>
<ul class="dropdown-menu" aria-labelledby="read-in-browser"> <ul class="dropdown-menu" aria-labelledby="read-in-browser">
{% for format in entry.data %} {% for format in reader_list %}
{%if format.format|lower == 'epub' or format.format|lower == 'txt' or format.format|lower == 'pdf' or format.format|lower == 'cbr' or format.format|lower == 'cbt' or format.format|lower == 'cbz' %} <li><a target="_blank" href="{{ url_for('read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
<li><a target="_blank" href="{{ url_for('read_book', book_id=entry.id, book_format=format.format|lower) }}">{{format.format}}</a></li>
{% endif %}
{%endfor%} {%endfor%}
</ul> </ul>
</div> </div>

@ -56,7 +56,6 @@ import tempfile
from redirect import redirect_back from redirect import redirect_back
import time import time
import server import server
# import copy
from reverseproxy import ReverseProxied from reverseproxy import ReverseProxied
try: try:
@ -116,8 +115,6 @@ EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz',
'fb2', 'html', 'rtf', 'odt'} 'fb2', 'html', 'rtf', 'odt'}
EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'html', 'rtf', 'odt'} EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'html', 'rtf', 'odt'}
# EXTENSIONS_READER = set(['txt', 'pdf', 'epub', 'zip', 'cbz', 'tar', 'cbt'] + (['rar','cbr'] if rar_support else []))
# Main code # Main code
mimetypes.init() mimetypes.init()
@ -733,7 +730,8 @@ def feed_hot():
# ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete() # ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete()
# ub.session.commit() # ub.session.commit()
numBooks = entries.__len__() numBooks = entries.__len__()
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, numBooks) pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1),
config.config_books_per_page, numBooks)
return render_xml_template('feed.xml', entries=entries, pagination=pagination) return render_xml_template('feed.xml', entries=entries, pagination=pagination)
@ -773,7 +771,8 @@ def feed_publisherindex():
def feed_publisher(book_id): def feed_publisher(book_id):
off = request.args.get("offset") or 0 off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.publishers.any(db.Publishers.id == book_id), [db.Books.timestamp.desc()]) db.Books, db.Books.publishers.any(db.Publishers.id == book_id),
[db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination) return render_xml_template('feed.xml', entries=entries, pagination=pagination)
@ -872,7 +871,8 @@ def get_opds_download_link(book_id, book_format):
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)
headers = Headers() headers = Headers()
headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf8')), book_format) headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf8')),
book_format)
try: try:
headers["Content-Type"] = mimetypes.types_map['.' + book_format] headers["Content-Type"] = mimetypes.types_map['.' + book_format]
except KeyError: except KeyError:
@ -895,32 +895,8 @@ def get_metadata_calibre_companion(uuid):
@app.route("/ajax/emailstat") @app.route("/ajax/emailstat")
@login_required @login_required
def get_email_status_json(): def get_email_status_json():
answer=list()
# UIanswer = list()
tasks=helper.global_WorkerThread.get_taskstatus() tasks=helper.global_WorkerThread.get_taskstatus()
'''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'] = ""
else:
if 'starttime' not in task:
task['starttime'] = ""
answer.append(task)
else:
for task in tasks:
if task['formStarttime']:
task['starttime'] = format_datetime(task['formStarttime'], format='short', locale=get_locale())
task['formStarttime'] = ""
else:
if 'starttime' not in task:
task['starttime'] = ""
answer = tasks'''
# UIanswer = copy.deepcopy(answer)
answer = helper.render_task_status(tasks) answer = helper.render_task_status(tasks)
js=json.dumps(answer, default=helper.json_serial) js=json.dumps(answer, default=helper.json_serial)
response = make_response(js) response = make_response(js)
response.headers["Content-Type"] = "application/json; charset=utf-8" response.headers["Content-Type"] = "application/json; charset=utf-8"
@ -1464,7 +1440,8 @@ def publisher_list():
def publisher(book_id, page): def publisher(book_id, page):
publisher = db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first() publisher = db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first()
if publisher: if publisher:
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.publishers.any(db.Publishers.id == book_id), entries, random, pagination = fill_indexpage(page, db.Books,
db.Books.publishers.any(db.Publishers.id == book_id),
(db.Series.name, db.Books.series_index), db.books_series_link, db.Series) (db.Series.name, db.Books.series_index), db.books_series_link, db.Series)
return render_title_template('index.html', random=random, entries=entries, pagination=pagination, return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
title=_(u"Publisher: %(name)s", name=publisher.name), page="publisher") title=_(u"Publisher: %(name)s", name=publisher.name), page="publisher")
@ -1675,10 +1652,11 @@ def show_book(book_id):
entries.tags = sort(entries.tags, key = lambda tag: tag.name) entries.tags = sort(entries.tags, key = lambda tag: tag.name)
kindle_list = helper.check_send_to_kindle(entries) kindle_list = helper.check_send_to_kindle(entries)
reader_list = helper.check_read_formats(entries)
return render_title_template('detail.html', entry=entries, cc=cc, is_xhr=request.is_xhr, return render_title_template('detail.html', entry=entries, cc=cc, is_xhr=request.is_xhr,
title=entries.title, books_shelfs=book_in_shelfs, title=entries.title, books_shelfs=book_in_shelfs,
have_read=have_read, kindle_list=kindle_list, page="book") have_read=have_read, kindle_list=kindle_list, reader_list=reader_list, page="book")
else: else:
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error") flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
return redirect(url_for("index")) return redirect(url_for("index"))
@ -1795,7 +1773,8 @@ def delete_book(book_id, book_format):
getattr(book, cc_string).remove(del_cc) getattr(book, cc_string).remove(del_cc)
db.session.delete(del_cc) db.session.delete(del_cc)
else: else:
modify_database_object([u''], getattr(book, cc_string), db.cc_classes[c.id], db.session, 'custom') modify_database_object([u''], getattr(book, cc_string), db.cc_classes[c.id],
db.session, 'custom')
db.session.query(db.Books).filter(db.Books.id == book_id).delete() db.session.query(db.Books).filter(db.Books.id == book_id).delete()
else: else:
db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == book_format).delete() db.session.query(db.Data).filter(db.Data.book == book.id).filter(db.Data.format == book_format).delete()
@ -1871,7 +1850,8 @@ def revoke_watch_gdrive():
last_watch_response = config.config_google_drive_watch_changes_response last_watch_response = config.config_google_drive_watch_changes_response
if last_watch_response: if last_watch_response:
try: try:
gdriveutils.stopChannel(gdriveutils.Gdrive.Instance().drive, last_watch_response['id'], last_watch_response['resourceId']) gdriveutils.stopChannel(gdriveutils.Gdrive.Instance().drive, last_watch_response['id'],
last_watch_response['resourceId'])
except HttpError: except HttpError:
pass pass
settings = ub.session.query(ub.Settings).first() settings = ub.session.query(ub.Settings).first()
@ -2467,7 +2447,8 @@ def send_to_kindle(book_id, book_format, convert):
if settings.get("mail_server", "mail.example.com") == "mail.example.com": if settings.get("mail_server", "mail.example.com") == "mail.example.com":
flash(_(u"Please configure the SMTP mail settings first..."), category="error") flash(_(u"Please configure the SMTP mail settings first..."), category="error")
elif current_user.kindle_mail: elif current_user.kindle_mail:
result = helper.send_mail(book_id, book_format, convert, 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: if result is None:
flash(_(u"Book successfully queued for sending to %(kindlemail)s", kindlemail=current_user.kindle_mail), flash(_(u"Book successfully queued for sending to %(kindlemail)s", kindlemail=current_user.kindle_mail),
category="success") category="success")
@ -2625,7 +2606,8 @@ def remove_from_shelf(shelf_id, book_id):
else: else:
app.logger.info("Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name) app.logger.info("Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name)
if not request.is_xhr: if not request.is_xhr:
flash(_(u"Sorry you are not allowed to remove a book from this shelf: %(sname)s", sname=shelf.name), category="error") flash(_(u"Sorry you are not allowed to remove a book from this shelf: %(sname)s", sname=shelf.name),
category="error")
return redirect(url_for('index')) return redirect(url_for('index'))
return "Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name, 403 return "Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name, 403
@ -3111,9 +3093,9 @@ def configuration_helper(origin):
content.config_rarfile_location = to_save["config_rarfile_location"].strip() content.config_rarfile_location = to_save["config_rarfile_location"].strip()
else: else:
flash(check[1], category="error") flash(check[1], category="error")
return render_title_template("config_edit.html", content=config, origin=origin, gdrive=gdriveutils.gdrive_support, return render_title_template("config_edit.html", content=config, origin=origin,
goodreads=goodreads_support, rarfile_support=rar_support, gdrive=gdriveutils.gdrive_support, goodreads=goodreads_support,
title=_(u"Basic Configuration")) rarfile_support=rar_support, title=_(u"Basic Configuration"))
try: try:
if content.config_use_google_drive and is_gdrive_ready() and not os.path.exists(config.config_calibre_dir + "/metadata.db"): if content.config_use_google_drive and is_gdrive_ready() and not os.path.exists(config.config_calibre_dir + "/metadata.db"):
gdriveutils.downloadFile(None, "metadata.db", config.config_calibre_dir + "/metadata.db") gdriveutils.downloadFile(None, "metadata.db", config.config_calibre_dir + "/metadata.db")
@ -3128,15 +3110,17 @@ def configuration_helper(origin):
logging.getLogger("book_formats").setLevel(config.config_log_level) logging.getLogger("book_formats").setLevel(config.config_log_level)
except Exception as e: except Exception as e:
flash(e, category="error") flash(e, category="error")
return render_title_template("config_edit.html", content=config, origin=origin, gdrive=gdriveutils.gdrive_support, return render_title_template("config_edit.html", content=config, origin=origin,
gdriveError=gdriveError, goodreads=goodreads_support, rarfile_support=rar_support, gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError,
goodreads=goodreads_support, rarfile_support=rar_support,
title=_(u"Basic Configuration"), page="config") title=_(u"Basic Configuration"), page="config")
if db_change: if db_change:
reload(db) reload(db)
if not db.setup_db(): if not db.setup_db():
flash(_(u'DB location is not valid, please enter correct path'), category="error") flash(_(u'DB location is not valid, please enter correct path'), category="error")
return render_title_template("config_edit.html", content=config, origin=origin, gdrive=gdriveutils.gdrive_support, return render_title_template("config_edit.html", content=config, origin=origin,
gdriveError=gdriveError, goodreads=goodreads_support, rarfile_support=rar_support, gdrive=gdriveutils.gdrive_support,gdriveError=gdriveError,
goodreads=goodreads_support, rarfile_support=rar_support,
title=_(u"Basic Configuration"), page="config") title=_(u"Basic Configuration"), page="config")
if reboot_required: if reboot_required:
# stop Server # stop Server
@ -3150,8 +3134,9 @@ def configuration_helper(origin):
else: else:
gdrivefolders=list() gdrivefolders=list()
return render_title_template("config_edit.html", origin=origin, success=success, content=config, return render_title_template("config_edit.html", origin=origin, success=success, content=config,
show_authenticate_google_drive=not is_gdrive_ready(), gdrive=gdriveutils.gdrive_support, show_authenticate_google_drive=not is_gdrive_ready(),
gdriveError=gdriveError, gdrivefolders=gdrivefolders, rarfile_support=rar_support, gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError,
gdrivefolders=gdrivefolders, rarfile_support=rar_support,
goodreads=goodreads_support, title=_(u"Basic Configuration"), page="config") goodreads=goodreads_support, title=_(u"Basic Configuration"), page="config")
@ -3581,7 +3566,8 @@ def upload_single_file(request, book, book_id):
return redirect(url_for('show_book', book_id=book.id)) return redirect(url_for('show_book', book_id=book.id))
file_size = os.path.getsize(saved_filename) file_size = os.path.getsize(saved_filename)
is_format = db.session.query(db.Data).filter(db.Data.book == book_id).filter(db.Data.format == file_ext.upper()).first() is_format = db.session.query(db.Data).filter(db.Data.book == book_id).\
filter(db.Data.format == file_ext.upper()).first()
# Format entry already exists, no need to update the database # Format entry already exists, no need to update the database
if is_format: if is_format:
@ -3611,7 +3597,8 @@ def upload_cover(request, book):
try: try:
os.makedirs(filepath) os.makedirs(filepath)
except OSError: except OSError:
flash(_(u"Failed to create path for cover %(path)s (Permission denied).", cover=filepath), category="error") flash(_(u"Failed to create path for cover %(path)s (Permission denied).", cover=filepath),
category="error")
return redirect(url_for('show_book', book_id=book.id)) return redirect(url_for('show_book', book_id=book.id))
try: try:
requested_file.save(saved_filename) requested_file.save(saved_filename)
@ -3826,11 +3813,13 @@ def upload():
try: try:
os.unlink(meta.file_path) os.unlink(meta.file_path)
except OSError: except OSError:
flash(_(u"Failed to delete file %(file)s (Permission denied).", file= meta.file_path), category="warning") flash(_(u"Failed to delete file %(file)s (Permission denied).", file= meta.file_path),
category="warning")
if meta.cover is None: if meta.cover is None:
has_cover = 0 has_cover = 0
copyfile(os.path.join(config.get_main_dir, "cps/static/generic_cover.jpg"), os.path.join(filepath, "cover.jpg")) copyfile(os.path.join(config.get_main_dir, "cps/static/generic_cover.jpg"),
os.path.join(filepath, "cover.jpg"))
else: else:
has_cover = 1 has_cover = 1
move(meta.cover, os.path.join(filepath, "cover.jpg")) move(meta.cover, os.path.join(filepath, "cover.jpg"))
@ -3896,8 +3885,7 @@ def upload():
# save data to database, reread data # save data to database, reread data
db.session.commit() db.session.commit()
db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort) db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort)
book = db.session.query(db.Books) \ book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
.filter(db.Books.id == book_id).filter(common_filters()).first()
# upload book to gdrive if nesseccary and add "(bookid)" to folder name # upload book to gdrive if nesseccary and add "(bookid)" to folder name
if config.config_use_google_drive: if config.config_use_google_drive:
@ -3919,14 +3907,18 @@ def upload():
for author in db_book.authors: for author in db_book.authors:
author_names.append(author.name) author_names.append(author.name)
if len(request.files.getlist("btn-upload")) < 2: if len(request.files.getlist("btn-upload")) < 2:
cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.
datatype.notin_(db.cc_exceptions)).all()
if current_user.role_edit() or current_user.role_admin(): if current_user.role_edit() or current_user.role_admin():
return render_title_template('book_edit.html', book=book, authors=author_names, return render_title_template('book_edit.html', book=book, authors=author_names,
cc=cc, title=_(u"edit metadata"), page="upload") cc=cc, title=_(u"edit metadata"), page="upload")
book_in_shelfs = [] book_in_shelfs = []
flg_send_to_kindle = helper.chk_send_to_kindle(book_id) kindle_list = helper.check_send_to_kindle(book)
reader_list = helper.check_read_formats(book)
return render_title_template('detail.html', entry=book, cc=cc, return render_title_template('detail.html', entry=book, cc=cc,
title=book.title, books_shelfs=book_in_shelfs, flg_kindle=flg_send_to_kindle, page="upload") title=book.title, books_shelfs=book_in_shelfs, kindle_list=kindle_list,
reader_list=reader_list, page="upload")
return redirect(url_for("index")) return redirect(url_for("index"))

Loading…
Cancel
Save