Split Inventaire book methods into sepate class

This commit is contained in:
Robbie Antenesse 2020-02-04 15:31:58 -07:00
parent a596e685d6
commit abbc8b5591
3 changed files with 122 additions and 111 deletions

View File

@ -1,70 +1,13 @@
const fetch = require('node-fetch'); const fetch = require('node-fetch');
class BooksController { class Inventaire {
constructor(bookSource, bookURI, language) { constructor(bookURI, language) {
this.source = bookSource; this.url = 'https://inventaire.io';
this.inventaire = 'https://inventaire.io';
this.openLibrary = 'https://openlibrary.org';
this.bookBrainz = 'https://bookbrainz.org';
this.uri = bookURI; this.uri = bookURI;
this.lang = language; this.lang = language;
} }
getBookData() { handleQuickEntity(entityObject) {
const bookData = this.getBookDataFromInventaire();
const communityData = this.getCommunityData();
return {
...bookData,
...communityData,
}
}
getCommunityData(maxReviews) {
if (process.NODE_ENV !== 'production') {
return this.getFakeData(maxReviews);
}
return {};
}
getFakeData(maxReviews) {
const faker = require('faker');
const numberOfReviews = Math.floor(Math.random() * 100);
const reviews = [];
for (let i = 0; i < numberOfReviews; i++) {
const reviewerName = Math.random() < 0.5
? faker.fake('{{name.firstName}} {{name.lastName}}')
: faker.fake('{{hacker.adjective}}{{hacker.noun}}');
reviews.push({
reviewer: {
name: reviewerName,
handle: faker.fake('@{{internet.userName}}@{{internet.domainName}}'),
},
date: faker.date.past(),
rating: parseFloat((Math.random() * 5).toFixed(1)),
review: faker.lorem.paragraph(),
hearts: Math.floor(Math.random() * 1000),
});
}
const averageRating = parseFloat((reviews.reduce((total, review) => {
return total + review.rating;
}, 0) / numberOfReviews).toFixed(1));
reviews.sort((a, b) => {
if (a.hearts === b.hearts) return 0;
return a.hearts > b.hearts ? -1 : 1;
});
return {
averageRating,
numberOfReviews,
reviews: typeof maxReviews !== 'undefined' ? reviews.slice(0, maxReviews - 1) : reviews,
}
}
handleQuickInventaireEntity(entityObject) {
return { return {
name: ( name: (
typeof entityObject.label !== 'undefined' typeof entityObject.label !== 'undefined'
@ -78,7 +21,7 @@ class BooksController {
), ),
link: ( link: (
typeof entityObject.uri !== 'undefined' typeof entityObject.uri !== 'undefined'
? `${this.inventaire}/entity/${entityObject.uri}` ? `${this.url}/entity/${entityObject.uri}`
: null : null
), ),
uri: ( uri: (
@ -91,7 +34,7 @@ class BooksController {
? entityObject.image.map(imageId => { ? entityObject.image.map(imageId => {
return { return {
uri: imageId.toString(), uri: imageId.toString(),
url: `${this.inventaire}/img/entities/${imageId}`, url: `${this.url}/img/entities/${imageId}`,
} }
}) })
: [] : []
@ -99,7 +42,7 @@ class BooksController {
}; };
} }
handleInventaireEntity(entityObject) { handleEntity(entityObject) {
const hasLabels = typeof entityObject.labels !== 'undefined'; const hasLabels = typeof entityObject.labels !== 'undefined';
const hasDescriptions = typeof entityObject.descriptions !== 'undefined'; const hasDescriptions = typeof entityObject.descriptions !== 'undefined';
@ -124,7 +67,7 @@ class BooksController {
), ),
link: ( link: (
typeof entityObject.uri !== 'undefined' typeof entityObject.uri !== 'undefined'
? `${this.inventaire}/entity/${entityObject.uri}` ? `${this.url}/entity/${entityObject.uri}`
: null : null
), ),
uri: ( uri: (
@ -135,39 +78,9 @@ class BooksController {
}; };
} }
handleOpenLibraryEntity(entityObject) { async getBookData(uri) {
return { if (uri) {
name: ( const request = fetch(`${this.url}/api/entities?action=by-uris&uris=${encodeURIComponent(uri)}`)
typeof entityObject.title_suggest !== 'undefined'
? entityObject.title_suggest
: null
),
description: (
typeof entityObject.author_name !== 'undefined'
? `${entityObject.type} by ${entityObject.author_name.map(name => name.trim()).join(', ')}`
: null
),
link: (
typeof entityObject.key !== 'undefined'
? `${this.openLibrary}${entityObject.key}`
: null
),
uri: (
typeof entityObject.key !== 'undefined'
? entityObject.key.substr(entityObject.key.lastIndexOf('/') + 1)
: null
),
coverId: (
typeof entityObject.cover_i !== 'undefined'
? entityObject.cover_i.toString()
: false
),
};
}
async getBookDataFromInventaire() {
if (this.uri) {
const request = fetch(`${this.inventaire}/api/entities?action=by-uris&uris=${encodeURIComponent(this.uri)}`)
request.catch(exception => { request.catch(exception => {
console.error(exception); console.error(exception);
return { return {
@ -186,9 +99,9 @@ class BooksController {
const bookData = await json; const bookData = await json;
if (typeof bookData.entities !== 'undefined' && typeof bookData.entities[this.uri] !== 'undefined') { if (typeof bookData.entities !== 'undefined' && typeof bookData.entities[uri] !== 'undefined') {
const bookData = this.handleInventaireEntity(bookData.entities[this.uri], this.lang); const bookData = this.handleEntity(bookData.entities[uri], this.lang);
bookData['covers'] = await this.getInventaireCovers(); bookData['covers'] = await this.getCovers();
return bookData; return bookData;
} }
@ -199,18 +112,18 @@ class BooksController {
}; };
} }
async getInventaireCovers() { async getCovers(uri) {
if (!this.uri) { if (!uri) {
return Promise.resolve([]); return Promise.resolve([]);
} }
// Note: property `wdt:P629` is a given entity (uri)'s list of editions (ISBNs). // Note: property `wdt:P629` is a given entity (uri)'s list of editions (ISBNs).
const editionsRequest = fetch(`${this.inventaire}/api/entities?action=reverse-claims&uri=${encodeURIComponent(this.uri)}&property=wdt:P629`) const editionsRequest = fetch(`${this.url}/api/entities?action=reverse-claims&uri=${encodeURIComponent(uri)}&property=wdt:P629`)
editionsRequest.catch(exception => { editionsRequest.catch(exception => {
console.error(exception); console.error(exception);
return { return {
error: exception, error: exception,
message: `An error occurred when trying to reach the Inventaire API for URI ${this.uri}.`, message: `An error occurred when trying to reach the Inventaire API for URI ${uri}.`,
} }
}); });
@ -230,12 +143,12 @@ class BooksController {
return Promise.resolve([]); return Promise.resolve([]);
} }
const isbnsRequest = fetch(`${this.inventaire}/api/entities?action=by-uris&uris=${encodeURIComponent(editionURIs)}`); const isbnsRequest = fetch(`${this.url}/api/entities?action=by-uris&uris=${encodeURIComponent(editionURIs)}`);
isbnsRequest.catch(exception => { isbnsRequest.catch(exception => {
console.error(exception); console.error(exception);
return { return {
error: exception, error: exception,
message: `An error occurred when trying to reach the Inventaire API for URI ${this.uri}.`, message: `An error occurred when trying to reach the Inventaire API for URI ${uri}.`,
} }
}); });
@ -260,7 +173,7 @@ class BooksController {
const entity = responseJSON.entities[key]; const entity = responseJSON.entities[key];
return { return {
uri: entity.uri, uri: entity.uri,
url: typeof entity.claims['invp:P2'] !== 'undefined' ? `${this.inventaire}/img/entities/${entity.claims['invp:P2'][0]}` : null, url: typeof entity.claims['invp:P2'] !== 'undefined' ? `${this.url}/img/entities/${entity.claims['invp:P2'][0]}` : null,
publishDate: typeof entity.claims['wdt:P577'] !== 'undefined' ? entity.claims['wdt:P577'][0] : null, publishDate: typeof entity.claims['wdt:P577'] !== 'undefined' ? entity.claims['wdt:P577'][0] : null,
} }
}); });
@ -277,4 +190,4 @@ class BooksController {
} }
} }
module.exports = BooksController; module.exports = Inventaire;

View File

@ -0,0 +1,98 @@
const Inventaire = require('./Inventaire');
class BooksController {
constructor(bookSource, bookURI, language) {
this.source = bookSource;
this.Inventaire = new Inventaire(bookURI, language);
this.openLibrary = 'https://openlibrary.org';
this.bookBrainz = 'https://bookbrainz.org';
this.uri = bookURI;
this.lang = language;
}
getBookData() {
const bookData = this.getBookDataFromInventaire();
const communityData = this.getCommunityData();
return {
...bookData,
...communityData,
}
}
getCommunityData(maxReviews) {
if (process.NODE_ENV !== 'production') {
return this.getFakeData(maxReviews);
}
return {};
}
getFakeData(maxReviews) {
const faker = require('faker');
const numberOfReviews = Math.floor(Math.random() * 100);
const reviews = [];
for (let i = 0; i < numberOfReviews; i++) {
const reviewerName = Math.random() < 0.5
? faker.fake('{{name.firstName}} {{name.lastName}}')
: faker.fake('{{hacker.adjective}}{{hacker.noun}}');
reviews.push({
reviewer: {
name: reviewerName,
handle: faker.fake('@{{internet.userName}}@{{internet.domainName}}'),
},
date: faker.date.past(),
rating: parseFloat((Math.random() * 5).toFixed(1)),
review: faker.lorem.paragraph(),
hearts: Math.floor(Math.random() * 1000),
});
}
const averageRating = parseFloat((reviews.reduce((total, review) => {
return total + review.rating;
}, 0) / numberOfReviews).toFixed(1));
reviews.sort((a, b) => {
if (a.hearts === b.hearts) return 0;
return a.hearts > b.hearts ? -1 : 1;
});
return {
averageRating,
numberOfReviews,
reviews: typeof maxReviews !== 'undefined' ? reviews.slice(0, maxReviews - 1) : reviews,
}
}
handleOpenLibraryEntity(entityObject) {
return {
name: (
typeof entityObject.title_suggest !== 'undefined'
? entityObject.title_suggest
: null
),
description: (
typeof entityObject.author_name !== 'undefined'
? `${entityObject.type} by ${entityObject.author_name.map(name => name.trim()).join(', ')}`
: null
),
link: (
typeof entityObject.key !== 'undefined'
? `${this.openLibrary}${entityObject.key}`
: null
),
uri: (
typeof entityObject.key !== 'undefined'
? entityObject.key.substr(entityObject.key.lastIndexOf('/') + 1)
: null
),
coverId: (
typeof entityObject.cover_i !== 'undefined'
? entityObject.cover_i.toString()
: false
),
};
}
}
module.exports = BooksController;

View File

@ -34,7 +34,7 @@ class SearchController {
const booksController = new BooksController('inventaire', undefined, this.lang); const booksController = new BooksController('inventaire', undefined, this.lang);
return responseJSON.results.map(work => { return responseJSON.results.map(work => {
const bookData = booksController.handleQuickInventaireEntity(work); const bookData = booksController.Inventaire.handleQuickEntity(work);
booksController.uri = bookData.uri; // Update booksController.uri for each book when fetching community data. booksController.uri = bookData.uri; // Update booksController.uri for each book when fetching community data.
const communityData = booksController.getCommunityData(5); const communityData = booksController.getCommunityData(5);
@ -68,7 +68,7 @@ class SearchController {
return json.then(responseJSON => { return json.then(responseJSON => {
const booksController = new BooksController('inventaire', undefined, this.lang); const booksController = new BooksController('inventaire', undefined, this.lang);
return responseJSON.works.map(work => { return responseJSON.works.map(work => {
const bookData = booksController.handleInventaireEntity(work); const bookData = booksController.Inventaire.handleEntity(work);
const communityData = booksController.getCommunityData(5); const communityData = booksController.getCommunityData(5);
return { return {