calibre-web/cps/helper.py
OzzieIsaacs bbf6d9b026 Translation of UI (german and english)
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
2016-11-09 19:24:33 +01:00

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()