Example #1
0
    def get_byte_book(self):
        if not self.has_content:
            return None

        toc_thumbnails = {"c": "https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"}

        InsertToc(self.oeb, self.sections, toc_thumbnails, self.insertHtmlToc, self.insertThumbnail)

        byte_book = byteStringIO()

        self.book.convert(self.oeb, byte_book, self.opts, log)

        return byte_book.getvalue()
Example #2
0
    def get_byte_book(self):
        if not self.has_content:
            return None

        toc_thumbnails = {
            "c":
            "https://www.google.com.hk/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
        }

        InsertToc(self.oeb, self.sections, toc_thumbnails, self.insertHtmlToc,
                  self.insertThumbnail)

        byte_book = byteStringIO()

        self.book.convert(self.oeb, byte_book, self.opts, log)

        return byte_book.getvalue()
Example #3
0
	def make(self):
		self._oeb = self._create_oeb()
	
		itemcnt, imgindex = 0, 0
		sections = OrderedDict()

		sections.setdefault('test', [])
		sections['test'].append(('test title', 'test brief', 'article content'))
		sections.setdefault('test2', [])
		sections['test2'].append(('test2 title', 'test2 brief', 'article2 content'))

		for k in self._metadata:
			self._oeb.metadata.add(k, self._metadata[k])

		self._toc(sections)

		io = byteStringIO()
		o = MOBIOutput()

		o.convert(self._oeb, io, self._opts, log)

		f = open('test.mobi', 'wb')
		f.write(str(io.getvalue()))
		f.close()
Example #4
0
    def ProcessComicRSS(self, username, user, feed):
        opts = None
        oeb = None

        # 创建 OEB
        #global log
        opts = getOpts(user.device, 'comic')
        oeb = CreateOeb(main.log, None, opts)
        pubtype = 'book:book:KindleEar'
        language = 'zh-cn'

        setMetaData(oeb,
                    feed.title,
                    language,
                    local_time("%Y-%m-%d", user.timezone),
                    pubtype=pubtype)
        oeb.container = ServerContainer(main.log)

        #guide
        id_, href = oeb.manifest.generate('masthead',
                                          DEFAULT_MASTHEAD)  # size:600*60
        oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_MASTHEAD))
        oeb.guide.add('masthead', 'Masthead Image', href)

        id_, href = oeb.manifest.generate('cover', DEFAULT_COVER)
        item = oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_COVER))

        oeb.guide.add('cover', 'Cover', href)
        oeb.metadata.add('cover', id_)

        itemcnt, imgindex = 0, 0
        sections = OrderedDict()
        toc_thumbnails = {}  #map img-url -> manifest-href

        if feed.url.startswith(("http://ac.qq.com", "http://m.ac.qq.com")):
            book = TencentBaseBook(imgindex=imgindex, opts=opts, user=user)
        elif feed.url.startswith("http://www.cartoonmad.com"):
            book = CartoonMadBaseBook(imgindex=imgindex, opts=opts, user=user)
        else:
            return "Failed to push book <%s>!" % title

        book.title = feed.title
        book.description = feed.title
        book.language = language
        book.keep_image = True
        book.oldest_article = 7
        book.fulltext_by_readability = True
        book.feeds = [(feed.title, feed.url)]
        book.url_filters = [flt.url for flt in user.urlfilter]

        try:  #书的质量可能不一,一本书的异常不能影响其他书籍的推送
            for sec_or_media, url, title, content, brief, thumbnail in book.Items(
            ):
                if not sec_or_media or not title or not content:
                    continue

                if sec_or_media.startswith(r'image/'):
                    id_, href = oeb.manifest.generate(id='img', href=title)
                    item = oeb.manifest.add(id_,
                                            href,
                                            sec_or_media,
                                            data=content)
                    if thumbnail:
                        toc_thumbnails[url] = href
                    imgindex += 1
                else:
                    #id, href = oeb.manifest.generate(id='feed', href='feed%d.html'%itemcnt)
                    #item = oeb.manifest.add(id, href, 'application/xhtml+xml', data=content)
                    #oeb.spine.add(item, True)
                    sections.setdefault(sec_or_media, [])
                    sections[sec_or_media].append(
                        (title, brief, thumbnail, content))
                    itemcnt += 1
        except Exception as e:
            excFileName, excFuncName, excLineNo = get_exc_location()
            main.log.warn(
                "Failed to push <%s> : %s, in file '%s', %s (line %d)" %
                (book.title, str(e), excFileName, excFuncName, excLineNo))
            return "Failed to push book <%s>!" % title

        volumeTitle = ''
        if itemcnt > 0:
            insertHtmlToc = False
            insertThumbnail = False
            volumeTitle = book.LastDeliveredVolume()
            oeb.metadata.clear('title')
            oeb.metadata.add('title', feed.title + volumeTitle)

            InsertToc(oeb, sections, toc_thumbnails, insertHtmlToc,
                      insertThumbnail)
            oIO = byteStringIO()
            o = EPUBOutput() if user.book_type == "epub" else MOBIOutput()
            o.convert(oeb, oIO, opts, main.log)
            try:
                ultima_log = DeliverLog.all().order('-time').get()
            except:
                ultima_log = sorted(DeliverLog.all(),
                                    key=attrgetter('time'),
                                    reverse=True)
                ultima_log = ultima_log[0] if ultima_log else None

            if ultima_log:
                diff = datetime.datetime.utcnow() - ultima_log.datetime
                if diff.days * 86400 + diff.seconds < 10:
                    time.sleep(8)

            self.SendToKindle(username, user.kindle_email,
                              feed.title + volumeTitle, user.book_type,
                              str(oIO.getvalue()), user.timezone)
            rs = "%s(%s).%s Sent!" % (feed.title, local_time(tz=user.timezone),
                                      user.book_type)
            main.log.info(rs)
            return rs
        else:
            self.deliverlog(username,
                            str(user.kindle_email),
                            feed.title + volumeTitle,
                            0,
                            status='nonews',
                            tz=user.timezone)
            rs = "No new feeds."
            main.log.info(rs)
            return rs
Example #5
0
    def GET(self):
        username = web.input().get("u")
        bookid = web.input().get("id")

        user = KeUser.all().filter("name = ", username).get()
        if not user:
            return "User not exist!<br />"

        to = user.kindle_email
        if (';' in to) or (',' in to):
            to = to.replace(',', ';').replace(' ', '').split(';')

        booktype = user.book_type  #mobi,epub
        bookmode = user.book_mode or 'periodical'  #periodical,comic
        titlefmt = user.titlefmt
        tz = user.timezone

        bookid = bookid.split(',') if ',' in bookid else [bookid]
        bks = []
        for id_ in bookid:
            try:
                bks.append(Book.get_by_id(int(id_)))
            except:
                continue
                #return "id of book is invalid or book not exist!<br />"

        book4meta = None
        if len(bks) == 0:
            return "No have book to push!"
        elif len(bks) == 1:
            if bks[0].builtin:
                book4meta = BookClass(bks[0].title)
                mhfile = book4meta.mastheadfile
                coverfile = book4meta.coverfile
                if issubclass(book4meta, BaseComicBook
                              ):  #如果单独推送一个继承自BaseComicBook的书籍,则自动设置为漫画模式
                    bookmode = 'comic'
            else:  #单独的推送自定义RSS
                book4meta = bks[0]
                mhfile = DEFAULT_MASTHEAD
                coverfile = DEFAULT_COVER
        else:  #多本书合并推送时使用“自定义RSS”的元属性
            book4meta = user.ownfeeds
            mhfile = DEFAULT_MASTHEAD
            coverfile = DEFAULT_COVER_BV if user.merge_books else DEFAULT_COVER

        if not book4meta:
            return "No have book to push.<br />"

        opts = None
        oeb = None

        # 创建 OEB
        #global log
        opts = getOpts(user.device, bookmode)
        oeb = CreateOeb(main.log, None, opts)
        bookTitle = "%s %s" % (book4meta.title, local_time(
            titlefmt, tz)) if titlefmt else book4meta.title

        if bookmode == 'comic':
            pubtype = 'book:book:KindleEar'
        else:
            pubtype = 'periodical:magazine:KindleEar'

        setMetaData(oeb,
                    bookTitle,
                    book4meta.language,
                    local_time("%Y-%m-%d", tz),
                    pubtype=pubtype)
        oeb.container = ServerContainer(main.log)

        #guide
        if mhfile:
            id_, href = oeb.manifest.generate('masthead',
                                              mhfile)  # size:600*60
            oeb.manifest.add(id_, href, MimeFromFilename(mhfile))
            oeb.guide.add('masthead', 'Masthead Image', href)

        if coverfile:
            imgData = None
            imgMime = ''
            #使用保存在数据库的用户上传的封面
            if coverfile == DEFAULT_COVER and user.cover:
                imgData = user.cover
                imgMime = 'image/jpeg'  #保存在数据库中的只可能是jpeg格式
            elif callable(coverfile):  #如果封面需要回调的话
                try:
                    imgData = book4meta().coverfile()
                    if imgData:
                        imgType = imghdr.what(None, imgData)
                        if imgType:  #如果是合法图片
                            imgMime = r"image/" + imgType
                        else:
                            main.log.warn(
                                'content of cover is invalid : [%s].' %
                                bookTitle)
                            imgData = None
                except Exception as e:
                    main.log.warn(
                        'Failed to fetch cover for book [%s]. [Error: %s]' %
                        (bookTitle, str(e)))
                    coverfile = DEFAULT_COVER
                    imgData = None
                    imgMime = ''

            if imgData and imgMime:
                id_, href = oeb.manifest.generate('cover', 'cover.jpg')
                item = oeb.manifest.add(id_, href, imgMime, data=imgData)
            else:
                id_, href = oeb.manifest.generate('cover', coverfile)
                item = oeb.manifest.add(id_, href, MimeFromFilename(coverfile))
            oeb.guide.add('cover', 'Cover', href)
            oeb.metadata.add('cover', id_)
        elif len(bks) > 1 and DEFAULT_COVER:
            #将所有书籍的封面拼贴成一个
            #如果DEFAULT_COVER=None说明用户不需要封面
            id_, href = oeb.manifest.generate('cover', 'cover.jpg')
            item = oeb.manifest.add(id_,
                                    href,
                                    'image/jpeg',
                                    data=self.MergeCovers(bks, opts, user))
            oeb.guide.add('cover', 'Cover', href)
            oeb.metadata.add('cover', id_)

        itemcnt, imgindex = 0, 0
        sections = OrderedDict()
        toc_thumbnails = {}  #map img-url -> manifest-href
        for bk in bks:
            if bk.builtin:
                cbook = BookClass(bk.title)
                if not cbook:
                    main.log.warn('not exist book <%s>' % bk.title)
                    continue
                book = cbook(imgindex=imgindex, opts=opts, user=user)
                book.url_filters = [flt.url for flt in user.urlfilter]
                if bk.needs_subscription:  #需要登录
                    subs_info = user.subscription_info(bk.title)
                    if subs_info:
                        book.account = subs_info.account
                        book.password = subs_info.password
            else:  # 自定义RSS
                if bk.feedscount == 0:
                    continue  #return "the book has no feed!<br />"

                book = BaseFeedBook(imgindex=imgindex, opts=opts, user=user)
                book.title = bk.title
                book.description = bk.description
                book.language = bk.language
                book.keep_image = bk.keep_image
                book.oldest_article = bk.oldest_article
                book.fulltext_by_readability = True
                feeds = bk.feeds
                book.feeds = []
                for feed in feeds:
                    if feed.url.startswith(
                        ("http://www.cartoonmad.com", "http://ac.qq.com",
                         "http://m.ac.qq.com")):
                        self.ProcessComicRSS(username, user, feed)
                    else:
                        book.feeds.append(
                            (feed.title, feed.url, feed.isfulltext))
                book.url_filters = [flt.url for flt in user.urlfilter]

            # 对于html文件,变量名字自文档,thumbnail为文章第一个img的url
            # 对于图片文件,section为图片mime,url为原始链接,title为文件名,content为二进制内容,
            #    img的thumbail仅当其为article的第一个img为True
            try:  #书的质量可能不一,一本书的异常不能影响其他书籍的推送
                for sec_or_media, url, title, content, brief, thumbnail in book.Items(
                ):
                    if not sec_or_media or not title or not content:
                        continue

                    if sec_or_media.startswith(r'image/'):
                        id_, href = oeb.manifest.generate(id='img', href=title)
                        item = oeb.manifest.add(id_,
                                                href,
                                                sec_or_media,
                                                data=content)
                        if thumbnail:
                            toc_thumbnails[url] = href
                        imgindex += 1
                    else:
                        #id, href = oeb.manifest.generate(id='feed', href='feed%d.html'%itemcnt)
                        #item = oeb.manifest.add(id, href, 'application/xhtml+xml', data=content)
                        #oeb.spine.add(item, True)
                        sections.setdefault(sec_or_media, [])
                        sections[sec_or_media].append(
                            (title, brief, thumbnail, content))
                        itemcnt += 1
            except Exception as e:
                excFileName, excFuncName, excLineNo = get_exc_location()
                main.log.warn(
                    "Failed to push <%s> : %s, in file '%s', %s (line %d)" %
                    (book.title, str(e), excFileName, excFuncName, excLineNo))
                continue

        volumeTitle = ''
        if itemcnt > 0:
            #漫画模式不需要TOC和缩略图
            if bookmode == 'comic':
                insertHtmlToc = False
                insertThumbnail = False
                if len(bks) == 1 and book:  #因为漫画模式没有目录,所以在标题中添加卷号
                    volumeTitle = book.LastDeliveredVolume()
                    oeb.metadata.clear('title')
                    oeb.metadata.add('title', bookTitle + volumeTitle)
            else:
                insertHtmlToc = GENERATE_HTML_TOC
                insertThumbnail = GENERATE_TOC_THUMBNAIL

            InsertToc(oeb, sections, toc_thumbnails, insertHtmlToc,
                      insertThumbnail)
            oIO = byteStringIO()
            o = EPUBOutput() if booktype == "epub" else MOBIOutput()
            o.convert(oeb, oIO, opts, main.log)
            try:
                ultima_log = DeliverLog.all().order('-time').get()
            except:
                ultima_log = sorted(DeliverLog.all(),
                                    key=attrgetter('time'),
                                    reverse=True)
                ultima_log = ultima_log[0] if ultima_log else None
            if ultima_log:
                diff = datetime.datetime.utcnow() - ultima_log.datetime
                if diff.days * 86400 + diff.seconds < 10:
                    time.sleep(8)
            self.SendToKindle(username, to, book4meta.title + volumeTitle,
                              booktype, str(oIO.getvalue()), tz)
            rs = "%s(%s).%s Sent!" % (book4meta.title, local_time(tz=tz),
                                      booktype)
            main.log.info(rs)
            return rs
        else:
            self.deliverlog(username,
                            str(to),
                            book4meta.title + volumeTitle,
                            0,
                            status='nonews',
                            tz=tz)
            rs = "No new feeds."
            main.log.info(rs)
            return rs
Example #6
0
    def push_comic_book(self, username, user, book, opts=None):
        if not opts:
            opts = getOpts(user.device, "comic")
        oeb = CreateOeb(main.log, None, opts)
        pubtype = 'book:book:KindleEar'
        language = 'zh-cn'

        setMetaData(
            oeb,
            book.title,
            language,
            local_time("%Y-%m-%d", user.timezone),
            pubtype=pubtype,
        )
        oeb.container = ServerContainer(main.log)

        #guide
        id_, href = oeb.manifest.generate('masthead',
                                          DEFAULT_MASTHEAD)  # size:600*60
        oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_MASTHEAD))
        oeb.guide.add('masthead', 'Masthead Image', href)

        id_, href = oeb.manifest.generate('cover', DEFAULT_COVER)
        item = oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_COVER))

        oeb.guide.add('cover', 'Cover', href)
        oeb.metadata.add('cover', id_)

        itemcnt, imgindex = 0, 0
        sections = OrderedDict()
        toc_thumbnails = {}  #map img-url -> manifest-href

        chapters = book.ParseFeedUrls()
        if not chapters:
            self.deliverlog(
                username,
                str(user.kindle_email),
                book.title,
                0,
                status="nonews",
                tz=user.timezone,
            )
            return
        for (
                bookname,
                chapter_title,
                img_list,
                chapter_url,
                next_chapter_index,
        ) in chapters:
            try:
                image_count = 0
                for (
                        mime_or_section,
                        url,
                        filename,
                        content,
                        brief,
                        thumbnail,
                ) in book.gen_image_items(img_list, chapter_url):
                    if not mime_or_section or not filename or not content:
                        continue

                    if mime_or_section.startswith(r"image/"):
                        id_, href = oeb.manifest.generate(id="img",
                                                          href=filename)
                        item = oeb.manifest.add(id_,
                                                href,
                                                mime_or_section,
                                                data=content)
                        if thumbnail:
                            toc_thumbnails[url] = href
                    else:
                        sections.setdefault(mime_or_section, [])
                        sections[mime_or_section].append(
                            (filename, brief, thumbnail, content))
                        image_count += 1

                title = book.title + " " + chapter_title
                if not image_count:
                    self.deliverlog(
                        username,
                        str(user.kindle_email),
                        title,
                        0,
                        status="can't download image",
                        tz=user.timezone,
                    )
                    rs = "No new feeds."
                    main.log.info(rs)
                    continue
                insertHtmlToc = False
                insertThumbnail = False
                oeb.metadata.clear("title")
                oeb.metadata.add("title", title)

                InsertToc(oeb, sections, toc_thumbnails, insertHtmlToc,
                          insertThumbnail)
                oIO = byteStringIO()
                o = EPUBOutput() if user.book_type == "epub" else MOBIOutput()
                o.convert(oeb, oIO, opts, main.log)
                try:
                    ultima_log = DeliverLog.all().order("-time").get()
                except:
                    ultima_log = sorted(DeliverLog.all(),
                                        key=attrgetter("time"),
                                        reverse=True)
                    ultima_log = ultima_log[0] if ultima_log else None

                if ultima_log:
                    diff = datetime.datetime.utcnow() - ultima_log.datetime
                    if diff.days * 86400 + diff.seconds < 10:
                        time.sleep(8)

                self.SendToKindle(
                    username,
                    user.kindle_email,
                    title,
                    user.book_type,
                    str(oIO.getvalue()),
                    user.timezone,
                )
                book.UpdateLastDelivered(bookname, chapter_title,
                                         next_chapter_index)
                rs = "%s(%s).%s Sent!" % (
                    title,
                    local_time(tz=user.timezone),
                    user.book_type,
                )
                main.log.info(rs)
            except:
                main.log.exception(u"Failed to push {} {}".format(
                    bookname, chapter_title))
Example #7
0
    def ProcessComicRSS(self, username, user, feed):
        opts = None
        oeb = None

        # 创建 OEB
        #global log
        opts = getOpts(user.device, 'comic')
        oeb = CreateOeb(main.log, None, opts)
        pubtype = 'book:book:KindleEar'
        language = 'zh-cn'

        setMetaData(oeb, feed.title, language, local_time("%Y-%m-%d", user.timezone), pubtype=pubtype)
        oeb.container = ServerContainer(main.log)

        #guide
        id_, href = oeb.manifest.generate('masthead', DEFAULT_MASTHEAD) # size:600*60
        oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_MASTHEAD))
        oeb.guide.add('masthead', 'Masthead Image', href)
        
        id_, href = oeb.manifest.generate('cover', DEFAULT_COVER)
        item = oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_COVER))

        oeb.guide.add('cover', 'Cover', href)
        oeb.metadata.add('cover', id_)
            
        itemcnt, imgindex = 0, 0
        sections = OrderedDict()
        toc_thumbnails = {} #map img-url -> manifest-href

        book = CartoonMadBaseBook(imgindex=imgindex, opts=opts, user=user)
        book.title = feed.title
        book.description = feed.title
        book.language = language
        book.keep_image = True
        book.oldest_article = 7
        book.fulltext_by_readability = True
        book.feeds = [(feed.title, feed.url)]
        book.url_filters = [flt.url for flt in user.urlfilter]

        try: #书的质量可能不一,一本书的异常不能影响其他书籍的推送
            for sec_or_media, url, title, content, brief, thumbnail in book.Items():
                if not sec_or_media or not title or not content:
                    continue
                
                if sec_or_media.startswith(r'image/'):
                    id_, href = oeb.manifest.generate(id='img', href=title)
                    item = oeb.manifest.add(id_, href, sec_or_media, data=content)
                    if thumbnail:
                        toc_thumbnails[url] = href
                    imgindex += 1
                else:
                    #id, href = oeb.manifest.generate(id='feed', href='feed%d.html'%itemcnt)
                    #item = oeb.manifest.add(id, href, 'application/xhtml+xml', data=content)
                    #oeb.spine.add(item, True)
                    sections.setdefault(sec_or_media, [])
                    sections[sec_or_media].append((title, brief, thumbnail, content))
                    itemcnt += 1
        except Exception as e:
            excFileName, excFuncName, excLineNo = get_exc_location()
            main.log.warn("Failed to push <%s> : %s, in file '%s', %s (line %d)" % (
                book.title, str(e), excFileName, excFuncName, excLineNo))
            return "Failed to push book <%s>!"%title 
        
        volumeTitle = ''
        if itemcnt > 0:
            insertHtmlToc = False
            insertThumbnail = False
            volumeTitle = book.LastDeliveredVolume()
            oeb.metadata.clear('title')
            oeb.metadata.add('title', feed.title + volumeTitle)
            
            InsertToc(oeb, sections, toc_thumbnails, insertHtmlToc, insertThumbnail)
            oIO = byteStringIO()
            o = EPUBOutput() if user.book_type == "epub" else MOBIOutput()
            o.convert(oeb, oIO, opts, main.log)
            try:
                ultima_log = DeliverLog.all().order('-time').get()
            except:
                ultima_log = sorted(DeliverLog.all(), key=attrgetter('time'), reverse=True)
                ultima_log = ultima_log[0] if ultima_log else None

            if ultima_log:
                diff = datetime.datetime.utcnow() - ultima_log.datetime
                if diff.days * 86400 + diff.seconds < 10:
                    time.sleep(8)

            self.SendToKindle(username, user.kindle_email, feed.title + volumeTitle, user.book_type, str(oIO.getvalue()), user.timezone)
            rs = "%s(%s).%s Sent!"%(feed.title, local_time(tz=user.timezone), user.book_type)
            main.log.info(rs)
            return rs
        else:
            self.deliverlog(username, str(user.kindle_email), feed.title + volumeTitle, 0, status='nonews', tz=user.timezone)
            rs = "No new feeds."
            main.log.info(rs)
            return rs
Example #8
0
 def GET(self):
     username = web.input().get("u")
     bookid = web.input().get("id")
     
     user = KeUser.all().filter("name = ", username).get()
     if not user:
         return "User not exist!<br />"
     
     to = user.kindle_email
     if (';' in to) or (',' in to):
         to = to.replace(',', ';').replace(' ', '').split(';')
     
     booktype = user.book_type #mobi,epub
     bookmode = user.book_mode or 'periodical' #periodical,comic
     titlefmt = user.titlefmt
     tz = user.timezone
     
     bookid = bookid.split(',') if ',' in bookid else [bookid]
     bks = []
     for id_ in bookid:
         try:
             bks.append(Book.get_by_id(int(id_)))
         except:
             continue
             #return "id of book is invalid or book not exist!<br />"
     
     book4meta = None
     if len(bks) == 0:
         return "No have book to push!"
     elif len(bks) == 1:
         if bks[0].builtin:
             book4meta = BookClass(bks[0].title)
             mhfile = book4meta.mastheadfile
             coverfile = book4meta.coverfile
             if issubclass(book4meta, BaseComicBook): #如果单独推送一个继承自BaseComicBook的书籍,则自动设置为漫画模式
                 bookmode = 'comic'
         else: #单独的推送自定义RSS
             book4meta = bks[0]
             mhfile = DEFAULT_MASTHEAD
             coverfile = DEFAULT_COVER
     else: #多本书合并推送时使用“自定义RSS”的元属性
         book4meta = user.ownfeeds
         mhfile = DEFAULT_MASTHEAD
         coverfile = DEFAULT_COVER_BV if user.merge_books else DEFAULT_COVER
     
     if not book4meta:
         return "No have book to push.<br />"
         
     opts = None
     oeb = None
     
     # 创建 OEB
     #global log
     opts = getOpts(user.device, bookmode)
     oeb = CreateOeb(main.log, None, opts)
     bookTitle = "%s %s" % (book4meta.title, local_time(titlefmt, tz)) if titlefmt else book4meta.title
     
     if bookmode == 'comic':
         pubtype = 'book:book:KindleEar'
     else:
         pubtype = 'periodical:magazine:KindleEar'
         
     setMetaData(oeb, bookTitle, book4meta.language, local_time("%Y-%m-%d",tz), pubtype=pubtype)
     oeb.container = ServerContainer(main.log)
     
     #guide
     if mhfile:
         id_, href = oeb.manifest.generate('masthead', mhfile) # size:600*60
         oeb.manifest.add(id_, href, MimeFromFilename(mhfile))
         oeb.guide.add('masthead', 'Masthead Image', href)
     
     if coverfile:
         imgData = None
         imgMime = ''
         #使用保存在数据库的用户上传的封面
         if coverfile == DEFAULT_COVER and user.cover:
             imgData = user.cover
             imgMime = 'image/jpeg' #保存在数据库中的只可能是jpeg格式
         elif callable(coverfile): #如果封面需要回调的话
             try:
                 imgData = book4meta().coverfile()
                 if imgData:
                     imgType = imghdr.what(None, imgData)
                     if imgType: #如果是合法图片
                         imgMime = r"image/" + imgType
                     else:
                         main.log.warn('content of cover is invalid : [%s].' % bookTitle)
                         imgData = None
             except Exception as e:
                 main.log.warn('Failed to fetch cover for book [%s]. [Error: %s]' % (bookTitle, str(e)))
                 coverfile = DEFAULT_COVER
                 imgData = None
                 imgMime = ''
         
         if imgData and imgMime:
             id_, href = oeb.manifest.generate('cover', 'cover.jpg')
             item = oeb.manifest.add(id_, href, imgMime, data=imgData)
         else:
             id_, href = oeb.manifest.generate('cover', coverfile)
             item = oeb.manifest.add(id_, href, MimeFromFilename(coverfile))
         oeb.guide.add('cover', 'Cover', href)
         oeb.metadata.add('cover', id_)
     elif len(bks) > 1 and DEFAULT_COVER:
         #将所有书籍的封面拼贴成一个
         #如果DEFAULT_COVER=None说明用户不需要封面
         id_, href = oeb.manifest.generate('cover', 'cover.jpg')
         item = oeb.manifest.add(id_, href, 'image/jpeg', data=self.MergeCovers(bks, opts, user))
         oeb.guide.add('cover', 'Cover', href)
         oeb.metadata.add('cover', id_)
         
     itemcnt, imgindex = 0, 0
     sections = OrderedDict()
     toc_thumbnails = {} #map img-url -> manifest-href
     for bk in bks:
         if bk.builtin:
             cbook = BookClass(bk.title)
             if not cbook:
                 main.log.warn('not exist book <%s>' % bk.title)
                 continue
             book = cbook(imgindex=imgindex, opts=opts, user=user)
             book.url_filters = [flt.url for flt in user.urlfilter]
             if bk.needs_subscription: #需要登录
                 subs_info = user.subscription_info(bk.title)
                 if subs_info:
                     book.account = subs_info.account
                     book.password = subs_info.password
         else: # 自定义RSS
             if bk.feedscount == 0:
                 continue  #return "the book has no feed!<br />"
                 
             book = BaseFeedBook(imgindex=imgindex, opts=opts, user=user)
             book.title = bk.title
             book.description = bk.description
             book.language = bk.language
             book.keep_image = bk.keep_image
             book.oldest_article = bk.oldest_article
             book.fulltext_by_readability = True
             feeds = bk.feeds
             book.feeds = []
             for feed in feeds:
                 if feed.url.startswith("http://www.cartoonmad.com"):
                     self.ProcessComicRSS(username, user, feed)
                 else:
                     book.feeds.append((feed.title, feed.url, feed.isfulltext))
             book.url_filters = [flt.url for flt in user.urlfilter]
             
         # 对于html文件,变量名字自文档,thumbnail为文章第一个img的url
         # 对于图片文件,section为图片mime,url为原始链接,title为文件名,content为二进制内容,
         #    img的thumbail仅当其为article的第一个img为True
         try: #书的质量可能不一,一本书的异常不能影响其他书籍的推送
             for sec_or_media, url, title, content, brief, thumbnail in book.Items():
                 if not sec_or_media or not title or not content:
                     continue
                 
                 if sec_or_media.startswith(r'image/'):
                     id_, href = oeb.manifest.generate(id='img', href=title)
                     item = oeb.manifest.add(id_, href, sec_or_media, data=content)
                     if thumbnail:
                         toc_thumbnails[url] = href
                     imgindex += 1
                 else:
                     #id, href = oeb.manifest.generate(id='feed', href='feed%d.html'%itemcnt)
                     #item = oeb.manifest.add(id, href, 'application/xhtml+xml', data=content)
                     #oeb.spine.add(item, True)
                     sections.setdefault(sec_or_media, [])
                     sections[sec_or_media].append((title, brief, thumbnail, content))
                     itemcnt += 1
         except Exception as e:
             excFileName, excFuncName, excLineNo = get_exc_location()
             main.log.warn("Failed to push <%s> : %s, in file '%s', %s (line %d)" % (
                 book.title, str(e), excFileName, excFuncName, excLineNo))
             continue
     
     volumeTitle = ''
     if itemcnt > 0:
         #漫画模式不需要TOC和缩略图
         if bookmode == 'comic':
             insertHtmlToc = False
             insertThumbnail = False
             if len(bks) == 1 and book: #因为漫画模式没有目录,所以在标题中添加卷号
                 volumeTitle = book.LastDeliveredVolume()
                 oeb.metadata.clear('title')
                 oeb.metadata.add('title', bookTitle + volumeTitle)
         else:
             insertHtmlToc = GENERATE_HTML_TOC
             insertThumbnail = GENERATE_TOC_THUMBNAIL
         
         InsertToc(oeb, sections, toc_thumbnails, insertHtmlToc, insertThumbnail)
         oIO = byteStringIO()
         o = EPUBOutput() if booktype == "epub" else MOBIOutput()
         o.convert(oeb, oIO, opts, main.log)
         try:
             ultima_log = DeliverLog.all().order('-time').get()
         except:
             ultima_log = sorted(DeliverLog.all(), key=attrgetter('time'), reverse=True)
             ultima_log = ultima_log[0] if ultima_log else None
         if ultima_log:
             diff = datetime.datetime.utcnow() - ultima_log.datetime
             if diff.days * 86400 + diff.seconds < 10:
                 time.sleep(8)
         self.SendToKindle(username, to, book4meta.title + volumeTitle, booktype, str(oIO.getvalue()), tz)
         rs = "%s(%s).%s Sent!"%(book4meta.title, local_time(tz=tz), booktype)
         main.log.info(rs)
         return rs
     else:
         self.deliverlog(username, str(to), book4meta.title + volumeTitle, 0, status='nonews', tz=tz)
         rs = "No new feeds."
         main.log.info(rs)
         return rs
Example #9
0
    def push_comic_book(self, username, user, book, opts=None):
        if not opts:
            opts = getOpts(user.device, "comic")
        oeb = CreateOeb(main.log, None, opts)
        pubtype = 'book:book:KindleEar'
        language = 'zh-cn'

        setMetaData(
            oeb,
            book.title,
            language,
            local_time("%Y-%m-%d", user.timezone),
            pubtype=pubtype,
        )
        oeb.container = ServerContainer(main.log)

        #guide
        id_, href = oeb.manifest.generate('masthead', DEFAULT_MASTHEAD) # size:600*60
        oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_MASTHEAD))
        oeb.guide.add('masthead', 'Masthead Image', href)

        id_, href = oeb.manifest.generate('cover', DEFAULT_COVER)
        item = oeb.manifest.add(id_, href, MimeFromFilename(DEFAULT_COVER))

        oeb.guide.add('cover', 'Cover', href)
        oeb.metadata.add('cover', id_)

        itemcnt, imgindex = 0, 0
        sections = OrderedDict()
        toc_thumbnails = {} #map img-url -> manifest-href

        chapters = book.ParseFeedUrls()
        if not chapters:
            self.deliverlog(
                username,
                str(user.kindle_email),
                book.title,
                0,
                status="nonews",
                tz=user.timezone,
            )
            return
        for (
            bookname,
            chapter_title,
            img_list,
            chapter_url,
            next_chapter_index,
        ) in chapters:
            try:
                image_count = 0
                for (
                    mime_or_section,
                    url,
                    filename,
                    content,
                    brief,
                    thumbnail,
                ) in book.gen_image_items(img_list, chapter_url):
                    if not mime_or_section or not filename or not content:
                        continue

                    if mime_or_section.startswith(r"image/"):
                        id_, href = oeb.manifest.generate(id="img", href=filename)
                        item = oeb.manifest.add(
                            id_, href, mime_or_section, data=content
                        )
                        if thumbnail:
                            toc_thumbnails[url] = href
                    else:
                        sections.setdefault(mime_or_section, [])
                        sections[mime_or_section].append(
                            (filename, brief, thumbnail, content)
                        )
                        image_count += 1

                title = book.title + " " + chapter_title
                if not image_count:
                    self.deliverlog(
                        username,
                        str(user.kindle_email),
                        title,
                        0,
                        status="can't download image",
                        tz=user.timezone,
                    )
                    rs = "No new feeds."
                    main.log.info(rs)
                    continue
                insertHtmlToc = False
                insertThumbnail = False
                oeb.metadata.clear("title")
                oeb.metadata.add("title", title)

                InsertToc(oeb, sections, toc_thumbnails, insertHtmlToc, insertThumbnail)
                oIO = byteStringIO()
                o = EPUBOutput() if user.book_type == "epub" else MOBIOutput()
                o.convert(oeb, oIO, opts, main.log)
                try:
                    ultima_log = DeliverLog.all().order("-time").get()
                except:
                    ultima_log = sorted(
                        DeliverLog.all(), key=attrgetter("time"), reverse=True
                    )
                    ultima_log = ultima_log[0] if ultima_log else None

                if ultima_log:
                    diff = datetime.datetime.utcnow() - ultima_log.datetime
                    if diff.days * 86400 + diff.seconds < 10:
                        time.sleep(8)

                self.SendToKindle(
                    username,
                    user.kindle_email,
                    title,
                    user.book_type,
                    str(oIO.getvalue()),
                    user.timezone,
                )
                book.UpdateLastDelivered(bookname, chapter_title, next_chapter_index)
                rs = "%s(%s).%s Sent!" % (
                    title,
                    local_time(tz=user.timezone),
                    user.book_type,
                )
                main.log.info(rs)
            except:
                main.log.exception(
                    u"Failed to push {} {}".format(bookname, chapter_title)
                )
def createMobi(bk):
    opts = makeoeb.getOpts('kindlepw')
    oeb = makeoeb.CreateOeb(default_log, None, opts)

    title = bk.title

    makeoeb.setMetaData(oeb, title)
    oeb.container = makeoeb.ServerContainer()

    # cover
    mhfile = bk.masthead_path
    coverfile = bk.cover_path

    if mhfile:
        id_, href = oeb.manifest.generate('masthead', mhfile)  # size:600*60
        oeb.manifest.add(id_, href, makeoeb.MimeFromFilename(mhfile))
        oeb.guide.add('masthead', 'Masthead Image', href)

    if coverfile:
        id_, href = oeb.manifest.generate('cover', coverfile)
        item = oeb.manifest.add(id_, href, makeoeb.MimeFromFilename(coverfile))
        oeb.guide.add('cover', 'Cover', href)
        oeb.metadata.add('cover', id_)

    itemcnt, imgindex = 0, 0
    from collections import OrderedDict
    sections = OrderedDict()
    toc_thumbnails = {}  # map img-url -> manifest-href
    if not bk:
        default_log.warn('not exist book <%s>' % bk.title)


    book = base.BaseFeedBook(imgindex=imgindex)
    book.title = bk.title
    book.description = bk.desc
    book.language = bk.lang
    book.oldest_article = bk.oldest_article
    book.fulltext_by_readability = True
    feeds = bk.feeds
    book.feeds = [(feed["title"], feed["url"], feed["fulltext"]) for feed in feeds]

    try:
        for sec_or_media, url, title, content, brief, thumbnail in book.Items(opts):
            if not sec_or_media or not title or not content:
                continue

            if sec_or_media.startswith(r'image/'):
                id_, href = oeb.manifest.generate(id='img', href=title)
                item = oeb.manifest.add(id_, href, sec_or_media, data=content)
                if thumbnail:
                    toc_thumbnails[url] = href
                imgindex += 1
            else:
                # id, href = oeb.manifest.generate(id='feed', href='feed%d.html'%itemcnt)
                # item = oeb.manifest.add(id, href, 'application/xhtml+xml', data=content)
                # oeb.spine.add(item, True)
                sections.setdefault(sec_or_media, [])
                sections[sec_or_media].append((title, brief, thumbnail, content))
                itemcnt += 1
    except Exception as e:
        default_log.warn("Failure in pushing book '%s' : %s" % (book.title, str(e)))
    print itemcnt
    if itemcnt > 0:
        from utils import InsertToc
        InsertToc(oeb, sections, toc_thumbnails)
        oIO = byteStringIO()
        o = MOBIOutput()
        o.convert(oeb, oIO, opts, default_log)

        of_name = "/tmp/"+ time.strftime("%Y-%m-%d_%H%M%S", time.localtime()) + ".mobi"
        with open(of_name, "w") as f:
            f.write(str(oIO.getvalue()))
        return of_name
    return ""
def createMobi(bk):
    opts = makeoeb.getOpts('kindlepw')
    oeb = makeoeb.CreateOeb(default_log, None, opts)

    title = bk.title

    makeoeb.setMetaData(oeb, title)
    oeb.container = makeoeb.ServerContainer()

    # cover
    mhfile = bk.masthead_path
    coverfile = bk.cover_path

    if mhfile:
        id_, href = oeb.manifest.generate('masthead', mhfile)  # size:600*60
        oeb.manifest.add(id_, href, makeoeb.MimeFromFilename(mhfile))
        oeb.guide.add('masthead', 'Masthead Image', href)

    if coverfile:
        id_, href = oeb.manifest.generate('cover', coverfile)
        item = oeb.manifest.add(id_, href, makeoeb.MimeFromFilename(coverfile))
        oeb.guide.add('cover', 'Cover', href)
        oeb.metadata.add('cover', id_)

    itemcnt, imgindex = 0, 0
    from collections import OrderedDict
    sections = OrderedDict()
    toc_thumbnails = {}  # map img-url -> manifest-href
    if not bk:
        default_log.warn('not exist book <%s>' % bk.title)

    book = base.BaseFeedBook(imgindex=imgindex)
    book.title = bk.title
    book.description = bk.desc
    book.language = bk.lang
    book.oldest_article = bk.oldest_article
    book.fulltext_by_readability = True
    feeds = bk.feeds
    book.feeds = [(feed["title"], feed["url"], feed["fulltext"])
                  for feed in feeds]

    try:
        for sec_or_media, url, title, content, brief, thumbnail in book.Items(
                opts):
            if not sec_or_media or not title or not content:
                continue

            if sec_or_media.startswith(r'image/'):
                id_, href = oeb.manifest.generate(id='img', href=title)
                item = oeb.manifest.add(id_, href, sec_or_media, data=content)
                if thumbnail:
                    toc_thumbnails[url] = href
                imgindex += 1
            else:
                # id, href = oeb.manifest.generate(id='feed', href='feed%d.html'%itemcnt)
                # item = oeb.manifest.add(id, href, 'application/xhtml+xml', data=content)
                # oeb.spine.add(item, True)
                sections.setdefault(sec_or_media, [])
                sections[sec_or_media].append(
                    (title, brief, thumbnail, content))
                itemcnt += 1
    except Exception as e:
        default_log.warn("Failure in pushing book '%s' : %s" %
                         (book.title, str(e)))
    print itemcnt
    if itemcnt > 0:
        from utils import InsertToc
        InsertToc(oeb, sections, toc_thumbnails)
        oIO = byteStringIO()
        o = MOBIOutput()
        o.convert(oeb, oIO, opts, default_log)

        of_name = "/tmp/" + time.strftime("%Y-%m-%d_%H%M%S",
                                          time.localtime()) + ".mobi"
        with open(of_name, "w") as f:
            f.write(str(oIO.getvalue()))
        return of_name
    return ""