parent
b78130e3b1
commit
863b77a5d7
3 changed files with 73 additions and 64 deletions
|
@ -114,9 +114,9 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
|
|||
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:
|
||||
|
@ -156,6 +156,18 @@ def check_send_to_kindle(entry):
|
|||
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:
|
||||
# 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,
|
||||
|
@ -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
|
||||
return error
|
||||
|
||||
|
||||
def generate_random_password():
|
||||
s = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*()?"
|
||||
passlen = 8
|
||||
|
@ -349,12 +362,14 @@ def update_dir_stucture(book_id, calibrepath):
|
|||
else:
|
||||
return update_dir_structure_file(book_id, calibrepath)
|
||||
|
||||
|
||||
def delete_book(book, calibrepath, book_format):
|
||||
if ub.config.config_use_google_drive:
|
||||
return delete_book_gdrive(book, book_format)
|
||||
else:
|
||||
return delete_book_file(book, calibrepath, book_format)
|
||||
|
||||
|
||||
def get_book_cover(cover_path):
|
||||
if ub.config.config_use_google_drive:
|
||||
try:
|
||||
|
@ -372,6 +387,7 @@ def get_book_cover(cover_path):
|
|||
else:
|
||||
return send_from_directory(os.path.join(ub.config.config_calibre_dir, cover_path), "cover.jpg")
|
||||
|
||||
|
||||
# saves book cover to gdrive or locally
|
||||
def save_cover(url, book_path):
|
||||
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.write(img.content)
|
||||
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")
|
||||
return True
|
||||
|
||||
|
@ -394,6 +410,7 @@ def save_cover(url, book_path):
|
|||
web.app.logger.info("Cover is saved")
|
||||
return True
|
||||
|
||||
|
||||
def do_download_file(book, book_format, data, headers):
|
||||
if ub.config.config_use_google_drive:
|
||||
startTime = time.time()
|
||||
|
@ -621,6 +638,7 @@ 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"""
|
||||
|
||||
|
@ -628,6 +646,7 @@ def json_serial(obj):
|
|||
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()
|
||||
|
|
|
@ -57,17 +57,15 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if entry.data|length %}
|
||||
{% if reader_list %}
|
||||
<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">
|
||||
<span class="glyphicon glyphicon-eye-open"></span> {{_('Read in browser')}}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="read-in-browser">
|
||||
{% for format in entry.data %}
|
||||
{%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|lower) }}">{{format.format}}</a></li>
|
||||
{% endif %}
|
||||
{% for format in reader_list %}
|
||||
<li><a target="_blank" href="{{ url_for('read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
|
||||
{%endfor%}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
104
cps/web.py
104
cps/web.py
|
@ -56,7 +56,6 @@ import tempfile
|
|||
from redirect import redirect_back
|
||||
import time
|
||||
import server
|
||||
# import copy
|
||||
from reverseproxy import ReverseProxied
|
||||
|
||||
try:
|
||||
|
@ -116,8 +115,6 @@ EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz',
|
|||
'fb2', '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
|
||||
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.commit()
|
||||
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)
|
||||
|
||||
|
||||
|
@ -773,7 +771,8 @@ def feed_publisherindex():
|
|||
def feed_publisher(book_id):
|
||||
off = request.args.get("offset") or 0
|
||||
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)
|
||||
|
||||
|
||||
|
@ -872,7 +871,8 @@ def get_opds_download_link(book_id, book_format):
|
|||
file_name = book.authors[0].name + '_' + file_name
|
||||
file_name = helper.get_valid_filename(file_name)
|
||||
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:
|
||||
headers["Content-Type"] = mimetypes.types_map['.' + book_format]
|
||||
except KeyError:
|
||||
|
@ -895,32 +895,8 @@ def get_metadata_calibre_companion(uuid):
|
|||
@app.route("/ajax/emailstat")
|
||||
@login_required
|
||||
def get_email_status_json():
|
||||
answer=list()
|
||||
# UIanswer = list()
|
||||
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)
|
||||
|
||||
js=json.dumps(answer, default=helper.json_serial)
|
||||
response = make_response(js)
|
||||
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
||||
|
@ -1423,7 +1399,7 @@ def author_list():
|
|||
@login_required_if_no_ano
|
||||
def author(book_id, page):
|
||||
entries, __, pagination = fill_indexpage(page, db.Books, db.Books.authors.any(db.Authors.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)
|
||||
if entries is None:
|
||||
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
|
||||
return redirect(url_for("index"))
|
||||
|
@ -1464,8 +1440,9 @@ def publisher_list():
|
|||
def publisher(book_id, page):
|
||||
publisher = db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first()
|
||||
if publisher:
|
||||
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)
|
||||
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)
|
||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||
title=_(u"Publisher: %(name)s", name=publisher.name), page="publisher")
|
||||
else:
|
||||
|
@ -1675,10 +1652,11 @@ def show_book(book_id):
|
|||
entries.tags = sort(entries.tags, key = lambda tag: tag.name)
|
||||
|
||||
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,
|
||||
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:
|
||||
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
|
||||
return redirect(url_for("index"))
|
||||
|
@ -1795,7 +1773,8 @@ def delete_book(book_id, book_format):
|
|||
getattr(book, cc_string).remove(del_cc)
|
||||
db.session.delete(del_cc)
|
||||
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()
|
||||
else:
|
||||
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
|
||||
if last_watch_response:
|
||||
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:
|
||||
pass
|
||||
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":
|
||||
flash(_(u"Please configure the SMTP mail settings first..."), category="error")
|
||||
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:
|
||||
flash(_(u"Book successfully queued for sending to %(kindlemail)s", kindlemail=current_user.kindle_mail),
|
||||
category="success")
|
||||
|
@ -2625,7 +2606,8 @@ def remove_from_shelf(shelf_id, book_id):
|
|||
else:
|
||||
app.logger.info("Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name)
|
||||
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 "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()
|
||||
else:
|
||||
flash(check[1], category="error")
|
||||
return render_title_template("config_edit.html", content=config, origin=origin, gdrive=gdriveutils.gdrive_support,
|
||||
goodreads=goodreads_support, rarfile_support=rar_support,
|
||||
title=_(u"Basic Configuration"))
|
||||
return render_title_template("config_edit.html", content=config, origin=origin,
|
||||
gdrive=gdriveutils.gdrive_support, goodreads=goodreads_support,
|
||||
rarfile_support=rar_support, title=_(u"Basic Configuration"))
|
||||
try:
|
||||
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")
|
||||
|
@ -3128,15 +3110,17 @@ def configuration_helper(origin):
|
|||
logging.getLogger("book_formats").setLevel(config.config_log_level)
|
||||
except Exception as e:
|
||||
flash(e, category="error")
|
||||
return render_title_template("config_edit.html", content=config, origin=origin, gdrive=gdriveutils.gdrive_support,
|
||||
gdriveError=gdriveError, goodreads=goodreads_support, rarfile_support=rar_support,
|
||||
return render_title_template("config_edit.html", content=config, origin=origin,
|
||||
gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError,
|
||||
goodreads=goodreads_support, rarfile_support=rar_support,
|
||||
title=_(u"Basic Configuration"), page="config")
|
||||
if db_change:
|
||||
reload(db)
|
||||
if not db.setup_db():
|
||||
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,
|
||||
gdriveError=gdriveError, goodreads=goodreads_support, rarfile_support=rar_support,
|
||||
return render_title_template("config_edit.html", content=config, origin=origin,
|
||||
gdrive=gdriveutils.gdrive_support,gdriveError=gdriveError,
|
||||
goodreads=goodreads_support, rarfile_support=rar_support,
|
||||
title=_(u"Basic Configuration"), page="config")
|
||||
if reboot_required:
|
||||
# stop Server
|
||||
|
@ -3150,8 +3134,9 @@ def configuration_helper(origin):
|
|||
else:
|
||||
gdrivefolders=list()
|
||||
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,
|
||||
gdriveError=gdriveError, gdrivefolders=gdrivefolders, rarfile_support=rar_support,
|
||||
show_authenticate_google_drive=not is_gdrive_ready(),
|
||||
gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError,
|
||||
gdrivefolders=gdrivefolders, rarfile_support=rar_support,
|
||||
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))
|
||||
|
||||
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
|
||||
if is_format:
|
||||
|
@ -3611,7 +3597,8 @@ def upload_cover(request, book):
|
|||
try:
|
||||
os.makedirs(filepath)
|
||||
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))
|
||||
try:
|
||||
requested_file.save(saved_filename)
|
||||
|
@ -3826,11 +3813,13 @@ def upload():
|
|||
try:
|
||||
os.unlink(meta.file_path)
|
||||
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:
|
||||
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:
|
||||
has_cover = 1
|
||||
move(meta.cover, os.path.join(filepath, "cover.jpg"))
|
||||
|
@ -3896,8 +3885,7 @@ def upload():
|
|||
# save data to database, reread data
|
||||
db.session.commit()
|
||||
db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort)
|
||||
book = db.session.query(db.Books) \
|
||||
.filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
|
||||
|
||||
# upload book to gdrive if nesseccary and add "(bookid)" to folder name
|
||||
if config.config_use_google_drive:
|
||||
|
@ -3919,14 +3907,18 @@ def upload():
|
|||
for author in db_book.authors:
|
||||
author_names.append(author.name)
|
||||
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():
|
||||
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)
|
||||
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,
|
||||
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"))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue