Generating epub.

This commit is contained in:
Vahagn Khachatryan
2019-01-10 22:58:31 +00:00
parent d050d282ba
commit 510d8c083a
4 changed files with 366 additions and 309 deletions

View File

@@ -1,13 +1,12 @@
var isNode=new Function("try {return this===global;}catch(e){return false;}"); // var JSZip = require('jszip');
if (isNode()){ // var StringDecoder = require('string_decoder').StringDecoder;
var JSZip = require('jszip'); // let html = new StringDecoder("utf-8").write(content)
var StringDecoder = require('string_decoder').StringDecoder; var textDecoder = new TextDecoder("utf-8");
var XMLSerializer = require('xmlserializer') // var xmlSerializer = require('xmlserializer')
var DOMParser = require('xmldom').DOMParser var xmlSerializer = new XMLSerializer();
var generatedBufferType = 'uint8array' // var DOMParser = require('xmldom').DOMParser
} else { var domParser = new DOMParser();
var generatedBufferType = 'uint8array' var generatedBufferType = 'blob'
}
class EpubXhtml{ class EpubXhtml{
constructor(filename) { constructor(filename) {
@@ -18,9 +17,9 @@ class EpubXhtml{
} }
convert(content){ convert(content){
let html = new StringDecoder("utf-8").write(content) let html = textDecoder.decode(content);
let dom = new DOMParser().parseFromString(html, 'text/html'); let dom = domParser.parseFromString(html, 'text/html');
let xml = XMLSerializer.serializeToString(dom); let xml = xmlSerializer.serializeToString(dom);
// let cnt = `<?xml version="1.0" encoding="utf-8" standalone="no"?> // let cnt = `<?xml version="1.0" encoding="utf-8" standalone="no"?>
// <!DOCTYPE html> // <!DOCTYPE html>
let cnt = `<?xml version="1.0" encoding="utf-8" standalone="no"?> let cnt = `<?xml version="1.0" encoding="utf-8" standalone="no"?>
@@ -159,8 +158,6 @@ class EpubNav{
class EpubMeta{ class EpubMeta{
constructor() { constructor() {
this.zip = new JSZip();
this.metadata = { this.metadata = {
book_id: 'book_id', book_id: 'book_id',
title: 'title', title: 'title',
@@ -201,7 +198,7 @@ class EpubMeta{
addManifest(filename, mime){ addManifest(filename, mime){
let key = filename let key = filename
if (mime.startsWith('text/html')){ if (mime && mime.startsWith('text/html')){
let o = new EpubXhtml(filename) let o = new EpubXhtml(filename)
this.override[key] = o this.override[key] = o
filename = o.filename filename = o.filename
@@ -253,7 +250,7 @@ class EpubMeta{
} }
class EpubWriter{ class EpubWriter{
constructor(book_id) { constructor() {
this.zip = new JSZip(); this.zip = new JSZip();
this.meta = new EpubMeta(); this.meta = new EpubMeta();
this.override = {} this.override = {}
@@ -272,6 +269,10 @@ class EpubWriter{
` ); ` );
} }
addMetaInfoFile(filename, content){
this.zip.file("META-INF/"+filename, content)
}
addFile(filename, content){ addFile(filename, content){
console.log(`epub ${filename}:`) console.log(`epub ${filename}:`)
@@ -294,6 +295,4 @@ class EpubWriter{
} }
} }
if (isNode()){ // module.exports = EpubWriter
module.exports = EpubWriter
}

View File

@@ -16,7 +16,8 @@
"activeTab", "activeTab",
"tabs", "tabs",
"downloads", "downloads",
"*://*.safaribooksonline.com/*" "*://*.safaribooksonline.com/*",
"*://*.oreilly.com/*"
], ],
"browser_action": { "browser_action": {

View File

@@ -52,7 +52,8 @@ class Book{
downloadResource(url){ downloadResource(url){
console.info(`Downloading ${url}`) console.info(`Downloading ${url}`)
return fetch(url, { return fetch(url, {
credentials: 'include' credentials: 'include',
mode: "no-cors" // no-cors, cors, *same-origin
}).then((res) => { }).then((res) => {
// console.log(`Downloaded.`) // console.log(`Downloaded.`)
return res; return res;
@@ -68,33 +69,13 @@ class Book{
downloadBookInfo(){ downloadBookInfo(){
console.info(`Downloading book info for ${this.book_id}`); console.info(`Downloading book info for ${this.book_id}`);
let url = `https://www.safaribooksonline.com/api/v1/book/${this.book_id}/`; let url = `https://learning.oreilly.com/api/v1/book/${this.book_id}/`;
return this.downloadJson(url) return this.downloadJson(url)
.then((book_info) => { .then((book_info) => {
this.book_info = book_info; this.book_info = book_info;
}, onError); }, onError);
} }
downloadChapterList(){
function helper(book, url){
console.info(`Downloading chapter list ${url}`);
return book.downloadJson(url)
.then((chapter_list) => {
book.chapter_list
= book.chapter_list.concat(chapter_list.results);
if (chapter_list.next != null){
return helper(book, chapter_list.next);
}
}, onError);
}
return helper(this, this.book_info.chapter_list)
.then(() => {
console.info(`Chapter List Downloaded.`);
}, onError);
}
downloadMetaContent(){ downloadMetaContent(){
let downloads = [] let downloads = []
@@ -156,7 +137,9 @@ class Book{
if (res.ok){ if (res.ok){
this.book_files[url].headers = res.headers this.book_files[url].headers = res.headers
this.book_files[url].mime = res.headers.get('Content-Type') this.book_files[url].mime = res.headers.get('Content-Type')
this.book_files[url].body = res.blob() return res.arrayBuffer().then((arrBuffer)=>{
this.book_files[url].body = arrBuffer
})
} }
}) })
},{concurrency: 10}) },{concurrency: 10})
@@ -223,15 +206,85 @@ function renderProgress(txt){
} }
function fillMetadata(epub, book)
{
epub.meta.addTitle(book.book_info.title)
epub.meta.addLanguage(book.book_info.language)
epub.meta.addBookId(book.book_info.isbn)
for (let i in book.book_info.authors){
let author = book.book_info.authors[i]
epub.meta.addAuthor(author)
}
for (let i in book.book_info.publishers){
let publisher = book.book_info.publishers[i]
epub.meta.addPublisher(publisher.name)
}
// # The metadata element or deprecated dc-metadata element contains
// # at least one identifier element, at least one title element,
// # and at least one language element drawn from the Dublin Core tag
// # set.
// epub.set_title('Test Title')
// epub.set_language('en')
// epub.set_direction('ltr')
// # epub.set_cover(file_name, content, create_page=True):
// # epub.add_author(author, file_as=None, role=None, uid='creator'):
// # epub.add_metadata(namespace, name, value, others=None):
// # epub.set_unique_metadata(namespace, name, value, others=None):
}
function fillManifest(epub, book)
{
for (let key in book.book_files){
let f = book.book_files[key]
epub.meta.addManifest(f.filename, f.mime)
}
let f = book.book_files[book.book_info.cover]
epub.meta.addCover(f.filename)
}
function fillToc(epub, book)
{
for (let i in book.book_toc){
let toc_item = book.book_toc[i]
epub.meta.addToc(
toc_item.filename,
toc_item.label,
toc_item.depth)
}
}
function fillSpine(epub, book)
{
for (let i in book.book_info.chapters){
let url = book.book_info.chapters[i]
let full_path = book.chapter_info[url].full_path
epub.meta.addSpine(full_path)
}
}
function fillGuide(epub, book)
{}
function createEpub(book, epub){ function createEpub(book, epub){
epub.addFile("book.json", JSON.stringify(book, null, '\t')) epub.addMetaInfoFile("book.json", JSON.stringify(book, null, '\t'))
// OPF file info.
fillManifest(epub, book)
fillSpine(epub, book)
fillGuide(epub, book)
fillMetadata(epub, book)
// NCX and NAV files.
fillToc(epub, book)
for (let url in book.book_files){ for (let url in book.book_files){
file = book.book_files[url] file = book.book_files[url]
epub.addFile(file.filename, file.body) epub.addFile(file.filename, file.body)
} }
} }
function onDownloadBookClicked(){ function onDownloadBookClicked(){
console.info("Begin book download."); console.info("Begin book download.");
page = new SidebarPage() page = new SidebarPage()
@@ -253,7 +306,7 @@ function onDownloadBookClicked(){
let title = book.book_info.title let title = book.book_info.title
let filename = "books/" let filename = "books/"
+ title.replace(/[^a-z0-9]/gi, '_').toLowerCase() + title.replace(/[^a-z0-9]/gi, '_').toLowerCase()
+ ".zip" + ".epub"
console.log(`Zip file name ${filename}`) console.log(`Zip file name ${filename}`)
renderProgress(`Saved to ${filename}`) renderProgress(`Saved to ${filename}`)
let url = window.URL.createObjectURL(file) let url = window.URL.createObjectURL(file)

View File

@@ -1,6 +1,7 @@
let fs = require("fs"); var fs = require("fs");
let JSZip = require('jszip'); var JSZip = require('jszip');
let EpubWriter = require('../src/epub') var EpubWriter = require('../src/epub')
let zip = new JSZip() let zip = new JSZip()
let epub = new EpubWriter() let epub = new EpubWriter()
@@ -134,6 +135,9 @@ function fillSpine(epub, book_info)
for (let i in book_info.book_info.chapters){ for (let i in book_info.book_info.chapters){
let s = book_info.book_info.chapters[i].split('/') let s = book_info.book_info.chapters[i].split('/')
epub.meta.addSpine(s[s.length-1]) epub.meta.addSpine(s[s.length-1])
// let url = book_info.book_info.chapters[i]
// let full_name = book_info.chapter_info[url].full_name
// epub.meta.addSpine(full_name)
} }
} }