bbf6d9b026
Bugfix for feeds - removed categories related and up - load new books now working - category random now working login page is free of non accessible elements boolean custom column is vivible in UI books with only with certain languages can be shown book shelfs can be deleted from UI Anonymous user view is more resticted Added browse of series in sidebar Dependencys in vendor folder are updated to newer versions (licencs files are now present) Bugfix editing Authors names Made upload on windows working
208 lines
7.1 KiB
Python
Executable File
208 lines
7.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import db, ub
|
|
import config
|
|
from flask import current_app as app
|
|
|
|
import smtplib
|
|
import socket
|
|
import sys
|
|
import os
|
|
import traceback
|
|
import re
|
|
import unicodedata
|
|
from StringIO import StringIO
|
|
from email import encoders
|
|
from email.MIMEBase import MIMEBase
|
|
from email.MIMEMultipart import MIMEMultipart
|
|
from email.MIMEText import MIMEText
|
|
from email.generator import Generator
|
|
from flask_babel import gettext as _
|
|
import subprocess
|
|
|
|
def update_download(book_id, user_id):
|
|
check = ub.session.query(ub.Downloads).filter(ub.Downloads.user_id == user_id).filter(ub.Downloads.book_id == book_id).first()
|
|
|
|
if not check:
|
|
new_download = ub.Downloads(user_id=user_id, book_id=book_id)
|
|
ub.session.add(new_download)
|
|
ub.session.commit()
|
|
|
|
def make_mobi(book_id):
|
|
kindlegen = os.path.join(config.MAIN_DIR, "vendor", "kindlegen")
|
|
if not os.path.exists(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:
|
|
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)
|
|
|
|
if os.path.exists(file_path + ".epub"):
|
|
check = subprocess.call([kindlegen, file_path + ".epub"], stdout=subprocess.PIPE)
|
|
if not check or check < 2:
|
|
book.data.append(db.Data(
|
|
name=book.data[0].name,
|
|
format="MOBI",
|
|
book=book.id,
|
|
uncompressed_size=os.path.getsize(file_path + ".mobi")
|
|
))
|
|
db.session.commit()
|
|
return file_path + ".mobi"
|
|
else:
|
|
app.logger.error("make_mobi: kindlegen failed with error while converting book")
|
|
return None
|
|
else:
|
|
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
|
|
is_epub = False
|
|
is_pdf = False
|
|
file_path = None
|
|
settings = ub.get_mail_settings()
|
|
# create MIME message
|
|
msg = MIMEMultipart()
|
|
msg['From'] = settings["mail_from"]
|
|
msg['To'] = kindle_mail
|
|
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)
|
|
|
|
# attach files
|
|
#msg.attach(self.get_attachment(file_path))
|
|
|
|
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)
|
|
|
|
formats = {}
|
|
|
|
for entry in data:
|
|
if entry.format == "MOBI":
|
|
formats["mobi"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".mobi")
|
|
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:
|
|
return _("Could not find any formats suitable for sending by email")
|
|
|
|
if 'mobi' in formats:
|
|
msg.attach(get_attachment(formats['mobi']))
|
|
elif 'epub' in formats:
|
|
filepath = make_mobi(book.id)
|
|
if filepath is not None:
|
|
msg.attach(get_attachment(filepath))
|
|
elif filepath is None:
|
|
return _("Could not convert epub to mobi")
|
|
elif 'pdf' in formats:
|
|
msg.attach(get_attachment(formats['pdf']))
|
|
elif 'pdf' in formats:
|
|
msg.attach(get_attachment(formats['pdf']))
|
|
else:
|
|
return _("Could not find any formats suitable for sending by email")
|
|
|
|
# convert MIME message to string
|
|
fp = StringIO()
|
|
gen = Generator(fp, mangle_from_=False)
|
|
gen.flatten(msg)
|
|
msg = fp.getvalue()
|
|
|
|
# send email
|
|
try:
|
|
mailserver = smtplib.SMTP(settings["mail_server"],settings["mail_port"])
|
|
mailserver.set_debuglevel(0)
|
|
|
|
if int(use_ssl) == 1:
|
|
mailserver.ehlo()
|
|
mailserver.starttls()
|
|
mailserver.ehlo()
|
|
|
|
if settings["mail_password"]:
|
|
mailserver.login(settings["mail_login"], settings["mail_password"])
|
|
mailserver.sendmail(settings["mail_login"], kindle_mail, msg)
|
|
mailserver.quit()
|
|
except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException), e:
|
|
app.logger.error(traceback.print_exc())
|
|
return _("Failed to send mail: %s" % str(e))
|
|
|
|
return None
|
|
|
|
|
|
def get_attachment(file_path):
|
|
'''Get file as MIMEBase message'''
|
|
|
|
try:
|
|
file_ = open(file_path, 'rb')
|
|
attachment = MIMEBase('application', 'octet-stream')
|
|
attachment.set_payload(file_.read())
|
|
file_.close()
|
|
encoders.encode_base64(attachment)
|
|
|
|
attachment.add_header('Content-Disposition', 'attachment',
|
|
filename=os.path.basename(file_path))
|
|
return attachment
|
|
except IOError:
|
|
traceback.print_exc()
|
|
message = (_('The requested file could not be read. Maybe wrong '\
|
|
'permissions?'))
|
|
return None
|
|
|
|
def get_valid_filename(value, replace_whitespace=True):
|
|
"""
|
|
Returns the given string converted to a string that can be used for a clean
|
|
filename. Limits num characters to 128 max.
|
|
"""
|
|
value = value[:128]
|
|
re_slugify = re.compile('[^\w\s-]', re.UNICODE)
|
|
value = unicodedata.normalize('NFKD', value)
|
|
re_slugify = re.compile('[^\w\s-]', re.UNICODE)
|
|
value = unicode(re_slugify.sub('', value).strip())
|
|
if replace_whitespace:
|
|
value = re.sub('[\s]+', '_', value, flags=re.U)
|
|
value = value.replace(u"\u00DF", "ss")
|
|
return value
|
|
|
|
def get_normalized_author(value):
|
|
"""
|
|
Normalizes sorted author name
|
|
"""
|
|
value = unicodedata.normalize('NFKD', value)
|
|
value = re.sub('[^\w,\s]', '', value, flags=re.U)
|
|
value = " ".join(value.split(", ")[::-1])
|
|
return value
|
|
|
|
def update_dir_stucture(book_id):
|
|
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).first()
|
|
path = os.path.join(config.DB_ROOT, book.path)
|
|
|
|
authordir = book.path.split("/")[0]
|
|
new_authordir=get_valid_filename(book.authors[0].name, False)
|
|
titledir = book.path.split("/")[1]
|
|
new_titledir = get_valid_filename(book.title, False) + " (" + str(book_id) + ")"
|
|
|
|
if titledir != new_titledir:
|
|
new_title_path = os.path.join(os.path.dirname(path), new_titledir)
|
|
os.rename(path, new_title_path)
|
|
path = new_title_path
|
|
book.path = book.path.split("/")[0] + "/" + new_titledir
|
|
|
|
if authordir != new_authordir:
|
|
new_author_path = os.path.join(os.path.join(config.DB_ROOT, new_authordir), os.path.basename(path))
|
|
os.renames(path, new_author_path)
|
|
book.path = new_authordir + "/" + book.path.split("/")[1]
|
|
db.session.commit()
|
|
|