#!/usr/bin/env python # -*- coding: utf-8 -*- from cps import db, ub from cps import config import smtplib 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 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): print "make_mobie: 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: print "make_mobie: epub format not found for book id: %d" % book_id return None file_path = os.path.join(config.DB_ROOT, book.path, data.name) # print os.path.getsize(file_path + ".epub") if os.path.exists(file_path + ".epub"): # print u"conversion started for %s" % book.title 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: print "make_mobie: kindlegen failed to convert book" return None else: print "make_mobie: epub not found: " + file_path + ".epub" 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'] = 'Sent to Kindle' text = 'This email has been sent via calibre web.' msg.attach(MIMEText(text)) use_ssl = settings.get('mail_use_ssl', 0) print "use ssl: %d" % use_ssl # 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 == "AZW": formats["azw"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".azw") if entry.format == "AZW3": formats["azw3"] = os.path.join(config.DB_ROOT, book.path, entry.name + ".azw3") 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: print "no formats found" return "Could not find any formats that can be send by email" if 'azw3' in formats: msg.attach(get_attachment(formats['azw3'])) elif 'azw' in formats: msg.attach(get_attachment(formats['azw'])) elif '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 '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 that can be send 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() mailserver.login(settings["mail_login"], settings["mail_password"]) mailserver.sendmail(settings["mail_login"], kindle_mail, msg) mailserver.quit() except smtplib.SMTPException: traceback.print_exc() return "Error communicating with the mail server, please check the logs for details." 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): """ 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()) value = re.sub('[\s]+', '_', value, flags=re.U) 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