This commit is contained in:
Nemo 2020-02-10 18:33:33 +05:30
parent cf381e5687
commit 2d0bbaf4a9
4 changed files with 157 additions and 129 deletions

View File

@ -17,4 +17,8 @@ E.write(filepath, ISBN);
## License ## License
Licensed under the [MIT License](https://nemo.mit-license.org/). See LICENSE file for details. Licensed under the [MIT License](https://nemo.mit-license.org/). See LICENSE file for details.
## Credits
Some of the code in `openlibrary.js` is based on the [node-isbn-catalogue](https://www.npmjs.com/package/node-isbn-catalogue) package, which was based on [palmerabollo/node-isbn](https://github.com/palmerabollo/node-isbn). Both are under AGPL.

View File

@ -1,26 +1,36 @@
const OL = require("./openlibrary"); const OL = require("./openlibrary");
const fs = require('fs'); const fs = require("fs");
const XML = require('xmlbuilder'); const XML = require("xmlbuilder");
function _convert(data, pretty) { function _convert(data, pretty) {
let contents =XML.create('metadata', {"xmlns:dc": "http://purl.org/dc/elements/1.1/"}) let contents = XML.create("metadata", {
for(let key in data.industryIdentifiers) { "xmlns:dc": "http://purl.org/dc/elements/1.1/"
});
for (let key in data.industryIdentifiers) {
let d = data.industryIdentifiers[key]; let d = data.industryIdentifiers[key];
contents.ele('dc:identifier', {'opf:scheme': d['type']}, d['identifier'][0]) contents.ele(
"dc:identifier",
{ "opf:scheme": d["type"] },
d["identifier"][0]
);
} }
for(let i in data.authors) { for (let i in data.authors) {
contents.ele('dc:creator', {'opf:role': 'aut'}, data.authors[i]) contents.ele("dc:creator", { "opf:role": "aut" }, data.authors[i]);
} }
contents.ele('dc:title', {id: 'title'}, data.title) contents.ele("dc:title", { id: "title" }, data.title);
contents.ele('dc:title', {id: 'subtitle'}, data.description) contents.ele("dc:title", { id: "subtitle" }, data.description);
contents.ele('meta', {refines:"#subtitle",property: "title-type"}, 'subtitle'); contents.ele(
"meta",
{ refines: "#subtitle", property: "title-type" },
"subtitle"
);
contents.ele('dc:language', {}, data.language) contents.ele("dc:language", {}, data.language);
contents.ele('dc:publisher', {}, data.publisher) contents.ele("dc:publisher", {}, data.publisher);
let blob = contents.end({pretty: pretty}) let blob = contents.end({ pretty: pretty });
return blob; return blob;
} }
@ -28,7 +38,7 @@ module.exports = {
write: function(filepath, isbn) { write: function(filepath, isbn) {
OL.lookup(isbn, function(err, data) { OL.lookup(isbn, function(err, data) {
fs.writeFileSync(filepath, _convert(data)); fs.writeFileSync(filepath, _convert(data));
}) });
}, },
_convert: _convert _convert: _convert
}; };

View File

@ -1,99 +1,116 @@
'use strict'; "use strict";
const https = require('https'); const https = require("https");
const OPENLIBRARY_API_BASE = 'openlibrary.org'; const OPENLIBRARY_API_BASE = "openlibrary.org";
const OPENLIBRARY_API_BOOK = '/api/books'; const OPENLIBRARY_API_BOOK = "/api/books";
module.exports = { module.exports = {
lookup: function(isbn, callback) { lookup: function(isbn, callback) {
var standardize = function standardize(book) { var standardize = function standardize(book) {
var standardBook = { var standardBook = {
'title': book.details.title, title: book.details.title,
'publishedDate': book.details.publish_date, publishedDate: book.details.publish_date,
'authors': [], authors: [],
'description': book.details.subtitle, description: book.details.subtitle,
'industryIdentifiers': [], industryIdentifiers: [],
'pageCount': book.details.number_of_pages, pageCount: book.details.number_of_pages,
'printType': 'BOOK', printType: "BOOK",
'categories': [], categories: [],
'imageLinks': { imageLinks: {
'smallThumbnail': book.thumbnail_url, smallThumbnail: book.thumbnail_url,
'thumbnail': book.thumbnail_url thumbnail: book.thumbnail_url
}, },
'previewLink': book.preview_url, previewLink: book.preview_url,
'infoLink': book.info_url infoLink: book.info_url
}; };
if (undefined !== book.details.isbn_13) { if (undefined !== book.details.isbn_13) {
standardBook.industryIdentifiers.push({type: 'ISBN-13', identifier: book.details.isbn_13}); standardBook.industryIdentifiers.push({
} type: "ISBN-13",
if (undefined !== book.details.isbn_10) { identifier: book.details.isbn_13
standardBook.industryIdentifiers.push({type: 'ISBN-10', identifier: book.details.isbn_10}); });
} }
if (undefined !== book.details.isbn_10) {
standardBook.industryIdentifiers.push({
type: "ISBN-10",
identifier: book.details.isbn_10
});
}
if (undefined !== book.details.goodreads) { if (undefined !== book.details.goodreads) {
standardBook.industryIdentifiers.push({type: 'Goodreads', identifier: book.details.goodreads}); standardBook.industryIdentifiers.push({
} type: "Goodreads",
if (undefined !== book.details.librarything) { identifier: book.details.goodreads
standardBook.industryIdentifiers.push({type: 'LibraryThing', identifier: book.details.librarything}); });
} }
if (undefined !== book.details.librarything) {
standardBook.industryIdentifiers.push({
type: "LibraryThing",
identifier: book.details.librarything
});
}
if (book.details.publishers) { if (book.details.publishers) {
standardBook.publisher = book.details.publishers[0]; standardBook.publisher = book.details.publishers[0];
} else { } else {
standardBook.publisher = ''; standardBook.publisher = "";
} }
if (book.details.authors) { if (book.details.authors) {
book.details.authors.forEach(function (author) { book.details.authors.forEach(function(author) {
standardBook.authors.push(author.name); standardBook.authors.push(author.name);
}); });
} }
if (book.details.languages) { if (book.details.languages) {
book.details.languages.forEach(function (language) { book.details.languages.forEach(function(language) {
standardBook.language = language.key.replace("/languages/", ""); standardBook.language = language.key.replace("/languages/", "");
}); });
} else { } else {
standardBook.language = 'unknown'; standardBook.language = "unknown";
} }
return standardBook; return standardBook;
}; };
var requestOptions = { var requestOptions = {
host: OPENLIBRARY_API_BASE, host: OPENLIBRARY_API_BASE,
path: OPENLIBRARY_API_BOOK + '?bibkeys=ISBN:' + isbn + '&format=json&jscmd=details' path:
OPENLIBRARY_API_BOOK +
"?bibkeys=ISBN:" +
isbn +
"&format=json&jscmd=details"
}; };
var request = https.request(requestOptions, function (response) { var request = https.request(requestOptions, function(response) {
if (response.statusCode !== 200) { if (response.statusCode !== 200) {
return callback(new Error('wrong response code: ' + response.statusCode)); return callback(
new Error("wrong response code: " + response.statusCode)
);
}
var body = "";
response.on("data", function(chunk) {
body += chunk;
});
response.on("end", function() {
var books = JSON.parse(body);
var book = books["ISBN:" + isbn];
if (!book) {
return callback(new Error("no books found with isbn: " + isbn));
} }
var body = ''; return callback(null, standardize(book));
response.on('data', function (chunk) { });
body += chunk;
})
response.on('end', function () {
var books = JSON.parse(body);
var book = books['ISBN:' + isbn];
if (!book) {
return callback(new Error('no books found with isbn: ' + isbn));
}
return callback(null, standardize(book));
})
}); });
request.on('error', function (err) { request.on("error", function(err) {
return callback(err); return callback(err);
}) });
request.end(); request.end();
} }
} };

73
test.js
View File

@ -1,42 +1,39 @@
const generator = require('./index') const generator = require("./index");
generator.write('/tmp/filename.xml', '0596101198') generator.write("/tmp/filename.xml", "0596101198");
test('the xml generator to work', () => { test("the xml generator to work", () => {
let input = { let input = {
"title": "Open Source for the Enterprise", title: "Open Source for the Enterprise",
"publishedDate": "July 27, 2005", publishedDate: "July 27, 2005",
"authors": [ authors: ["Dan Woods", "Gautam Guliani"],
"Dan Woods", description: "Managing Risks, Reaping Rewards",
"Gautam Guliani" industryIdentifiers: [
], {
"description": "Managing Risks, Reaping Rewards", type: "ISBN-13",
"industryIdentifiers": [ identifier: ["9780596101190"]
{ },
"type": "ISBN-13", {
"identifier": [ type: "ISBN-10",
"9780596101190" identifier: ["0596101198"]
] }
],
pageCount: 234,
printType: "BOOK",
categories: [],
imageLinks: {
smallThumbnail: "https://covers.openlibrary.org/b/id/389214-S.jpg",
thumbnail: "https://covers.openlibrary.org/b/id/389214-S.jpg"
}, },
{ previewLink:
"type": "ISBN-10", "https://openlibrary.org/books/OL7581318M/Open_Source_for_the_Enterprise",
"identifier": [ infoLink:
"0596101198" "https://openlibrary.org/books/OL7581318M/Open_Source_for_the_Enterprise",
] publisher: "O'Reilly Media, Inc.",
} language: "eng"
], };
"pageCount": 234, let xml = generator._convert(input, false);
"printType": "BOOK", expect(xml).toBe(
"categories": [], `<?xml version="1.0"?><metadata><dc:identifier opf:scheme="ISBN-13">9780596101190</dc:identifier><dc:identifier opf:scheme="ISBN-10">0596101198</dc:identifier><dc:creator opf:role="aut">Dan Woods</dc:creator><dc:creator opf:role="aut">Gautam Guliani</dc:creator><dc:title id="title">Open Source for the Enterprise</dc:title><dc:title id="subtitle">Managing Risks, Reaping Rewards</dc:title><meta refines="#subtitle" property="title-type">subtitle</meta><dc:language>eng</dc:language><dc:publisher>O'Reilly Media, Inc.</dc:publisher></metadata>`
"imageLinks": { );
"smallThumbnail": "https://covers.openlibrary.org/b/id/389214-S.jpg", });
"thumbnail": "https://covers.openlibrary.org/b/id/389214-S.jpg"
},
"previewLink": "https://openlibrary.org/books/OL7581318M/Open_Source_for_the_Enterprise",
"infoLink": "https://openlibrary.org/books/OL7581318M/Open_Source_for_the_Enterprise",
"publisher": "O'Reilly Media, Inc.",
"language": "eng"
}
let xml = generator._convert(input, false)
expect(xml).toBe(`<?xml version="1.0"?><metadata><dc:identifier opf:scheme="ISBN-13">9780596101190</dc:identifier><dc:identifier opf:scheme="ISBN-10">0596101198</dc:identifier><dc:creator opf:role="aut">Dan Woods</dc:creator><dc:creator opf:role="aut">Gautam Guliani</dc:creator><dc:title id="title">Open Source for the Enterprise</dc:title><dc:title id="subtitle">Managing Risks, Reaping Rewards</dc:title><meta refines="#subtitle" property="title-type">subtitle</meta><dc:language>eng</dc:language><dc:publisher>O'Reilly Media, Inc.</dc:publisher></metadata>`);
})