Files
safari-hunt/src/sidebar.js
Vahagn Khachatryan 68f43a2a50 First cut.
2018-11-20 18:24:14 +00:00

305 lines
9.2 KiB
JavaScript

document.body.style.border = "5px solid red";
function onError(error) {
console.error(`Error: ${error}`);
$('#error-message').text(`Error: ${error}`);
$('#error-message').show();
$('#loading').hide();
$('#book-info').hide();
}
function getCurrentTab() {
console.debug("Querying active tab.");
var queryInfo = {
active: true,
currentWindow: true
};
return browser.tabs.query(queryInfo)
.then(function(tabs) {
if (tabs.length == 1){
let url = tabs[0].url;
console.info(`Active URL: ${url}`);
return url;
} else {
console.error(`Expected 1 active tab, received: ${tabs}`);
throw 'Failed to get active tab.';
}
}, onError);
}
function extractBookId(url){
console.debug(`Extracting book id from ${url}`);
// match a url like:
// https://www.safaribooksonline.com/library/view/startup-opportunities-2nd/9781119378181/
// https://www.safaribooksonline.com/library/view/startup-growth-engines/77961SEM00001/
let match = url.match(/\/library\/view\/[^\/]+\/(\w+)\//);
let bookId = match && match[1];
if (bookId) {
console.debug(`Extracted book id: ${bookId}`);
return bookId;
}else{
console.error('Could not extract book id from url, only '
+'domain "www.safaribooksonline.com“ is supported.');
throw 'Failed to extract book id.';
}
}
// class MiniWebServer{
// constructor() {
// this.url = "http://127.0.0.1:8080/test.zip"
// }
// downloadTestZip(){
// console.info(`Downloading ${this.url}`)
// return fetch(this.url, {
// credentials: 'include'
// }).then((res) => {
// console.log(`Getting blob.`)
// return res.blob()
// }).then(JSZip.loadAsync)
// .then((zip) => {
// this.zip = zip
// })
// }
// fetchUrl(url){
// let name = "meta/"+url.replace(/[^a-z0-9]/gi, '_').toLowerCase()
// this.zip.file(name)
// .
// }
// }
class Book{
constructor(book_id, epub) {
this.book_id = book_id;
this.raw_book = {};
this.chapter_list = [];
this.book_files = {}
this.book_info = null
this.book_toc = null
this.book_flattoc = null
}
downloadResource(url){
console.info(`Downloading ${url}`)
return fetch(url, {
credentials: 'include'
}).then((res) => {
console.log(`Downloaded.`)
return res;
}, onError)
}
downloadJson(url){
return this.downloadResource(url)
.then((res) => {
return res.json();
}, onError);
}
downloadBookInfo(){
console.info(`Downloading book info for ${this.book_id}`);
let url = `https://www.safaribooksonline.com/api/v1/book/${this.book_id}/`;
return this.downloadJson(url)
.then((book_info)=>{
this.book_info = book_info;
}, 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(){
let downloads = []
this.insertBookFile({
url: this.book_info.cover,
file: "cover.img",
context: null,
mime: null
})
downloads.push(
this.downloadJson(this.book_info.toc)
.then((json)=>{
this.book_toc=json
}))
downloads.push(
this.downloadJson(this.book_info.flat_toc)
.then((json)=>{
this.book_flattoc=json
}))
downloads.push(
Promise.map(this.book_info.chapters, (chapter) => {
return this.downloadJson(chapter)
.then((json) => {
return this.extractChapterAssets(json)
})
},{concurrency: 1}))
return Promise.all(downloads)
}
downloadMetaContent(){
let downloads = []
// downloads.push(this.downloadResource(this.book_info.cover))
downloads.push(
this.downloadJson(this.book_info.toc)
.then((json)=>{
this.book_toc=json
}))
downloads.push(
this.downloadJson(this.book_info.flat_toc)
.then((json)=>{
this.book_flattoc=json
}))
downloads.push(
Promise.map(this.book_info.chapters, (chapter) => {
return this.downloadJson(chapter)
.then((json) => {
return this.extractChapterAssets(json)
})
},{concurrency: 1}))
return Promise.all(downloads)
}
extractChapterAssets(json){
if (!json.asset_base_url
|| !json.content){
throw "Missing data."
}
// Html
this.insertBookFile({
url: json.content,
file: json.full_path,
context: null,
mime: null
})
// List of images.
for (let idx in json.images){
this.insertBookFile({
url: json.asset_base_url + json.images[idx],
file: json.images[idx],
context: null,
mime: null
})
}
// List of stylesheets.
for (let idx in json.stylesheets){
this.insertBookFile({
url: json.stylesheets[idx].original_url,
file: json.stylesheets[idx].full_path,
context: null,
mime: null
})
}
}
insertBookFile(obj){
this.book_files[obj.url] = obj
}
}
function renderInfo(book){
$("#book-name").text(book.book_info.title);
$("#book-cover").attr("src", book.book_info.cover);
$('#book-info').show();
}
function renderChapterList(book){
// Add chapters to UI
for (let chapter_idx in book.chapter_list) {
console.log(book.chapter_list[chapter_idx])
let chapter = book.chapter_list[chapter_idx];
var chapter_dom = $("<li></li>")
.addClass("list-group-item")
.html(chapter.title)
.attr("chapterIndex", chapter_idx);
$("#book-chapter-list").append(chapter_dom);
}
$('#loading').hide();
}
function createEpub(book, epub){
for (let url in book.raw_book){
let name = "meta/"+book.raw_book[url].url.replace(/[^a-z0-9]/gi, '_').toLowerCase()
epub.addFile(name, book.raw_book[url].clone().blob())
}
// epub.addFile("book_info.json", JSON.stringify(book.book_info))
// epub.addFile("book_files.json", JSON.stringify(book.book_files))
// epub.addFile("book_toc.json", JSON.stringify(book.book_toc))
// epub.addFile("book_flattoc.json", JSON.stringify(book.book_flattoc))
epub.addFile("book.json", JSON.stringify(book, null, '\t'))
}
function onDownloadBookClicked(){
console.info("Begin book download.");
$('#loading').show();
$('#error-message').hide();
$('#book-info').hide();
getCurrentTab()
.then(extractBookId, onError)
.then((book_id) => {
epub = new EpubWriter();
book = new Book(book_id);
book.downloadBookInfo()
.then(() => { renderInfo(book); })
.then(() => { return book.downloadChapterList(); })
.then(() => { return renderChapterList(book); })
.then(() => { return book.downloadContent(); })
.then(() => { return createEpub(book, epub); })
.then(() => { return epub.generateAsync(); })
.then((file) => {
let filename = "books/" + "test" + ".zip"
// book.filename.replace(/[^a-z0-9]/gi, '_').toLowerCase()
let url = window.URL.createObjectURL(file)
browser.downloads.download({ "filename" : filename, url : url})
})
}, onError);
}
document.addEventListener('DOMContentLoaded', function() {
console.log("Start safari book hunter.");
$('#loading').hide();
$('#error-message').hide();
$('#book-info').hide();
$('#download-book-button').click(() => {
onDownloadBookClicked();
});
$('#deselect-all-button').show()
$('#download-button').show()
$('#download-section').hide();
// let bookInfo = new BookInfo();
})