Compare commits
4 Commits
ae8694a6b4
...
03a939b643
Author | SHA1 | Date |
---|---|---|
Robbie Antenesse | 03a939b643 | |
Robbie Antenesse | abbc8b5591 | |
Robbie Antenesse | a596e685d6 | |
Robbie Antenesse | b99bdfc562 |
|
@ -31,7 +31,7 @@ export class ShelvesController extends ViewController {
|
|||
}
|
||||
|
||||
getUserShelves () {
|
||||
return fetch('/api/shelves/get').then(response => response.json()).then(shelves => {
|
||||
return fetch('/api/shelf/getAll').then(response => response.json()).then(shelves => {
|
||||
this.state.myShelves = shelves;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,70 +1,13 @@
|
|||
const fetch = require('node-fetch');
|
||||
|
||||
class BooksController {
|
||||
constructor(bookSource, bookURI, language) {
|
||||
this.source = bookSource;
|
||||
this.inventaire = 'https://inventaire.io';
|
||||
this.openLibrary = 'https://openlibrary.org';
|
||||
this.bookBrainz = 'https://bookbrainz.org';
|
||||
class Inventaire {
|
||||
constructor(bookURI, language) {
|
||||
this.url = 'https://inventaire.io';
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
handleQuickInventaireEntity(entityObject) {
|
||||
handleQuickEntity(entityObject) {
|
||||
return {
|
||||
name: (
|
||||
typeof entityObject.label !== 'undefined'
|
||||
|
@ -78,7 +21,7 @@ class BooksController {
|
|||
),
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${this.inventaire}/entity/${entityObject.uri}`
|
||||
? `${this.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
uri: (
|
||||
|
@ -91,7 +34,7 @@ class BooksController {
|
|||
? entityObject.image.map(imageId => {
|
||||
return {
|
||||
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 hasDescriptions = typeof entityObject.descriptions !== 'undefined';
|
||||
|
||||
|
@ -124,7 +67,7 @@ class BooksController {
|
|||
),
|
||||
link: (
|
||||
typeof entityObject.uri !== 'undefined'
|
||||
? `${this.inventaire}/entity/${entityObject.uri}`
|
||||
? `${this.url}/entity/${entityObject.uri}`
|
||||
: null
|
||||
),
|
||||
uri: (
|
||||
|
@ -135,39 +78,9 @@ class BooksController {
|
|||
};
|
||||
}
|
||||
|
||||
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
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
async getBookDataFromInventaire() {
|
||||
if (this.uri) {
|
||||
const request = fetch(`${this.inventaire}/api/entities?action=by-uris&uris=${encodeURIComponent(this.uri)}`)
|
||||
async getBookData(uri) {
|
||||
if (uri) {
|
||||
const request = fetch(`${this.url}/api/entities?action=by-uris&uris=${encodeURIComponent(uri)}`)
|
||||
request.catch(exception => {
|
||||
console.error(exception);
|
||||
return {
|
||||
|
@ -186,9 +99,9 @@ class BooksController {
|
|||
|
||||
const bookData = await json;
|
||||
|
||||
if (typeof bookData.entities !== 'undefined' && typeof bookData.entities[this.uri] !== 'undefined') {
|
||||
const bookData = this.handleInventaireEntity(bookData.entities[this.uri], this.lang);
|
||||
bookData['covers'] = await this.getInventaireCovers();
|
||||
if (typeof bookData.entities !== 'undefined' && typeof bookData.entities[uri] !== 'undefined') {
|
||||
const bookData = this.handleEntity(bookData.entities[uri], this.lang);
|
||||
bookData['covers'] = await this.getCovers();
|
||||
|
||||
return bookData;
|
||||
}
|
||||
|
@ -199,18 +112,18 @@ class BooksController {
|
|||
};
|
||||
}
|
||||
|
||||
async getInventaireCovers() {
|
||||
if (!this.uri) {
|
||||
async getCovers(uri) {
|
||||
if (!uri) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
// 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 => {
|
||||
console.error(exception);
|
||||
return {
|
||||
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([]);
|
||||
}
|
||||
|
||||
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 => {
|
||||
console.error(exception);
|
||||
return {
|
||||
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];
|
||||
return {
|
||||
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,
|
||||
}
|
||||
});
|
||||
|
@ -277,4 +190,4 @@ class BooksController {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports = BooksController;
|
||||
module.exports = Inventaire;
|
|
@ -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;
|
|
@ -34,7 +34,7 @@ class SearchController {
|
|||
const booksController = new BooksController('inventaire', undefined, this.lang);
|
||||
|
||||
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.
|
||||
const communityData = booksController.getCommunityData(5);
|
||||
|
||||
|
@ -68,7 +68,7 @@ class SearchController {
|
|||
return json.then(responseJSON => {
|
||||
const booksController = new BooksController('inventaire', undefined, this.lang);
|
||||
return responseJSON.works.map(work => {
|
||||
const bookData = booksController.handleInventaireEntity(work);
|
||||
const bookData = booksController.Inventaire.handleEntity(work);
|
||||
const communityData = booksController.getCommunityData(5);
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
const fetch = require('node-fetch');
|
||||
|
||||
class ShelfController {
|
||||
constructor (shelfModel, shelfItemModel) {
|
||||
this.model = shelfModel;
|
||||
this.itemModel = shelfItemModel;
|
||||
constructor (sequelizeModels) {
|
||||
this.model = sequelizeModels.Shelf;
|
||||
this.itemModel = sequelizeModels.ShelfItem;
|
||||
}
|
||||
|
||||
static newShelfNameIsValid (name, existingNames = []) {
|
||||
|
|
|
@ -7,7 +7,7 @@ async function routes(fastify, options) {
|
|||
return false;
|
||||
});
|
||||
|
||||
fastify.get('/api/shelves/get', async (request, reply) => {
|
||||
fastify.get('/api/shelf/getAll', async (request, reply) => {
|
||||
if (!request.isLoggedInUser) {
|
||||
return reply.code(400).send({
|
||||
error: true,
|
||||
|
@ -15,7 +15,7 @@ async function routes(fastify, options) {
|
|||
});
|
||||
}
|
||||
|
||||
const shelfController = new ShelfController(fastify.models.Shelf, fastify.models.ShelfItem);
|
||||
const shelfController = new ShelfController(fastify.models);
|
||||
|
||||
const shelves = await request.user.getShelves({
|
||||
attributes: ['id', 'name', 'isDeletable', 'isPublic', 'updatedAt'],
|
||||
|
@ -45,7 +45,7 @@ async function routes(fastify, options) {
|
|||
return ShelfController.CheckExternalDomainForShelf(request.params.domain.trim(), request.params.shelfId);
|
||||
}
|
||||
|
||||
const shelfController = new ShelfController(fastify.models.Shelf, fastify.models.ShelfItem);
|
||||
const shelfController = new ShelfController(fastify.models);
|
||||
|
||||
const shelf = await shelfController.getShelfById(request.params.shelfId);
|
||||
if (typeof shelf.error !== 'undefined') {
|
||||
|
@ -88,7 +88,7 @@ async function routes(fastify, options) {
|
|||
return reply.code(400).send(shelfNameIsValid);
|
||||
}
|
||||
|
||||
const shelfController = new ShelfController(fastify.models.Shelf, fastify.models.ShelfItem);
|
||||
const shelfController = new ShelfController(fastify.models);
|
||||
|
||||
const newShelf = shelfController.createShelf(request.user, request.body.shelfName);
|
||||
if (typeof newShelf.error !== 'undefined' && newShelf.error !== false) {
|
||||
|
@ -136,7 +136,7 @@ async function routes(fastify, options) {
|
|||
return reply.code(400).send(shelfNameIsValid);
|
||||
}
|
||||
|
||||
const shelfController = new ShelfController(fastify.models.Shelf, fastify.models.ShelfItem);
|
||||
const shelfController = new ShelfController(fastify.models);
|
||||
|
||||
const newShelf = shelfController.renameShelf(request.user, request.body.shelfId, request.body.shelfName);
|
||||
if (typeof newShelf.error !== 'undefined' && newShelf.error !== false) {
|
||||
|
|
18
yarn.lock
18
yarn.lock
|
@ -4610,22 +4610,6 @@ node-libs-browser@^2.0.0:
|
|||
util "^0.11.0"
|
||||
vm-browserify "^1.0.1"
|
||||
|
||||
node-pre-gyp@*:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83"
|
||||
integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==
|
||||
dependencies:
|
||||
detect-libc "^1.0.2"
|
||||
mkdirp "^0.5.1"
|
||||
needle "^2.2.1"
|
||||
nopt "^4.0.1"
|
||||
npm-packlist "^1.1.6"
|
||||
npmlog "^4.0.2"
|
||||
rc "^1.2.7"
|
||||
rimraf "^2.6.1"
|
||||
semver "^5.3.0"
|
||||
tar "^4.4.2"
|
||||
|
||||
node-pre-gyp@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054"
|
||||
|
@ -6902,7 +6886,7 @@ tar-stream@^2.0.0:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
tar@^4, tar@^4.4.2:
|
||||
tar@^4:
|
||||
version "4.4.13"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
||||
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
|
||||
|
|
Loading…
Reference in New Issue