UNPKG

@openveo/portal

Version:

OpenVeo Portal gives access to medias exposed by OpenVeo server associated to an OpenVeo Publish plugin

294 lines (245 loc) 10.7 kB
'use strict'; /** * @module portal/providers/OpenVeoProvider */ const querystring = require('querystring'); const openVeoApi = require('@openveo/api'); const Cache = process.require('app/server/Cache.js'); const ResourceFilter = openVeoApi.storages.ResourceFilter; class OpenVeoProvider extends openVeoApi.providers.Provider { /** * Defines an OpenVeoProvider to interact with OpenVeo web service. * * @extends OpenVeoProvider * @constructor * @param {Storage} storage The storage to interact with * @param {Cache} [cache] The cache to use. If not specified a 10 seconds cache is created * @see {@link https://github.com/veo-labs/openveo-api|OpenVeo API documentation} for more information about Storage */ constructor(storage, cache) { super(storage); Object.defineProperties(this, /** @lends module:portal/providers/OpenVeoProvider~OpenVeoProvider */ { /** * The OpenVeo cache. * * @type {Cache} * @instance */ cache: { value: cache || new Cache({stdTTL: 10, checkperiod: 10}) } } ); this.cache.on('expired', (key, value) => { this.cache.del(key); }); } /** * Fetches a document. * * @param {String} location The location of the documents in the storage * @param {String} id The id of the document to fetch * @param {Object} [fields] Fields to be included or excluded from the resulting documents, by default all * fields are returned. Only "exclude" or "include" can be specified, not both * @param {Array} [fields.include] The list of fields to include in the response, all other fields are excluded * @param {Array} [fields.exclude] The list of fields to exclude from response, all other fields are included. Ignored * if include is also specified. * @param {Number} [ttl] The duration of the cache for this request (in seconds) * @param {module:portal/providers/OpenVeoProvider~OpenVeoProvider~getOneCallback} callback The function to call when * it's done */ getOne(location, id, fields, ttl, callback) { new Promise((resolve, reject) => { let cacheId = `getOne-${location}-${id}-${querystring.stringify(fields)}`; let document = this.cache.get(cacheId); if (document) return resolve(document); this.storage.getOne(location, new ResourceFilter().equal('id', id), fields, (error, fetchedDocument) => { if (error) return reject(error); this.cache.set(cacheId, fetchedDocument, (ttl === null || ttl === undefined) ? undefined : ttl); resolve(fetchedDocument); }); }).then((document) => { callback(null, document); }).catch((error) => { callback(error); }); } /** * Fetches documents. * * @param {String} location The location of the documents in the storage * @param {ResourceFilter} [filter] Rules to filter documents * @param {Object} [fields] Fields to be included or excluded from the resulting documents, by default all * fields are returned. Only "exclude" or "include" can be specified, not both * @param {Array} [fields.include] The list of fields to include in the response, all other fields are excluded * @param {Array} [fields.exclude] The list of fields to exclude from response, all other fields are included. Ignored * if include is also specified. * @param {Number} [limit] A limit number of documents to retrieve (10 by default) * @param {Number} [page] The page number started at 0 for the first page * @param {Object} sort The list of fields to sort by with the field name as key and the sort order as * value (e.g. {field1: 'asc'}). Sort can be made only on one field * @param {Number} [ttl] The duration of the cache for this request (in seconds) * @param {module:portal/providers/OpenVeoProvider~OpenVeoProvider~getCallback} callback The function to call when * it's done */ get(location, filter, fields, limit, page, sort, ttl, callback) { new Promise((resolve, reject) => { let fieldsString = querystring.stringify(fields); let operationsString = querystring.stringify(this.storage.buildFilter(filter)); let sortString = querystring.stringify(sort || {}); let cacheId = `get-${location}-${operationsString}-${fieldsString}-${limit}-${page}-${sortString}`; let cacheValue = this.cache.get(cacheId); if (cacheValue) return resolve(cacheValue); this.storage.get(location, filter, fields, limit, page, sort, (error, fetchedDocuments, pagination) => { if (error) return reject(error); let result = { documents: fetchedDocuments, pagination: pagination }; this.cache.set(cacheId, result, (ttl === null || ttl === undefined) ? undefined : ttl); resolve(result); }); }).then((result) => { callback(null, result.documents, result.pagination); }).catch((error) => { callback(error); }); } /** * Gets all documents from storage iterating on all pages. * * @param {String} location The location of the documents in the storage * @param {ResourceFilter} [filter] Rules to filter documents * @param {Object} [fields] Fields to be included or excluded from the resulting documents, by default all * fields are returned. Only "exclude" or "include" can be specified, not both * @param {Array} [fields.include] The list of fields to include in the response, all other fields are excluded * @param {Array} [fields.exclude] The list of fields to exclude from response, all other fields are included. Ignored * if include is also specified. * @param {Object} sort The list of fields to sort by with the field name as key and the sort order as * value (e.g. {field1: 'asc'}). Sort can be made only on one field * @param {Number} [ttl] The duration of the cache for this request (in seconds) * @param {module:portal/providers/OpenVeoProvider~OpenVeoProvider~getAllCallback} callback The function to call when * it's done */ getAll(location, filter, fields, sort, ttl, callback) { let allDocuments = []; let page = 0; const getDocuments = (callback) => { this.get(location, filter, fields, null, page, sort, ttl, function(error, documents, pagination) { if (error) return callback(error); allDocuments = allDocuments.concat(documents); if (page < pagination.pages - 1) { // There are other pages // Get next page page++; getDocuments(callback); } else { // No more pages // End it callback(null); } }); }; getDocuments(function(error) { callback(error, allDocuments); }); } /** * Updates a document. * * @param {String} location The location of the document in the storage * @param {String} id The id of the document to update * @param {Object} data The modifications to perform * @param {module:portal/providers/OpenVeoProvider~OpenVeoProvider~updateOneCallback} callback The function to call * when it's done */ updateOne(location, id, data, callback) { this.storage.updateOne(location, new ResourceFilter().equal('id', id), data, (error, total) => { this.executeCallback(callback, error, total); }); } /** * Convert a video Point of Interest * * @param {String} videoId The id of the video to convert * @param {Number} duration The duration of the video in ms * @param {module:portal/providers/OpenVeoProvider~OpenVeoProvider~convertVideoPoiCallback} callback The function to * call when it's done */ convertVideoPoi(videoId, duration, callback) { this.storage.convertVideoPoi(videoId, duration, (error, video) => { this.executeCallback(callback, error, video); }); } /** * Deletes cache of a document. * * @param {String} location The location of the document in the storage * @param {String} id The id of the document to remove from cache * @param {Boolean} alsoRemoveFromPages Also remove cache entries containing the document (paginated results) * @return {Number} The number of removed entries */ deleteDocumentCache(location, id, alsoRemoveFromPages) { let deleteCount = 0; if (!location || !id) return deleteCount; deleteCount += this.cache.del(`getOne-${location}-${id}-*`); if (alsoRemoveFromPages) { // Find cache entries referencing the document const cacheValues = this.cache.mget([`get-${location}-*`]); for (let cacheId in cacheValues) { let result = cacheValues[cacheId]; for (let document of result.documents) { if (document.id === id) deleteCount += this.cache.del(cacheId); } } } return deleteCount; } /** * Deletes all cache entries associated to a location. * * @param {String} location The location of the documents in the storage * @return {Number} The number of removed entries */ deleteLocationCache(location) { let deleteCount = 0; if (!location) return deleteCount; deleteCount += this.cache.del(`get-${location}-*`); deleteCount += this.cache.del(`getOne-${location}-*`); return deleteCount; } } module.exports = OpenVeoProvider; /** * @callback module:portal/providers/OpenVeoProvider~OpenVeoProvider~getOneCallback * @param {(Error|undefined)} error The error if an error occurred * @param {Object} result The document */ /** * @callback module:portal/providers/OpenVeoProvider~OpenVeoProvider~getCallback * @param {(Error|undefined)} error The error if an error occurred * @param {Array} result The list of retrieved documents * @param {Object} pagination Pagination information * @param {Number} pagination.limit The specified limit * @param {Number} pagination.page The actual page * @param {Number} pagination.pages The total number of pages * @param {Number} pagination.size The total number of documents */ /** * @callback module:portal/providers/OpenVeoProvider~OpenVeoProvider~getAllCallback * @param {(Error|undefined)} error The error if an error occurred * @param {Array} result The list of documents */ /** * @callback module:portal/providers/OpenVeoProvider~OpenVeoProvider~updateOneCallback * @param {(Error|undefined)} error The error if an error occurred * @param {Number} total 1 if everything went fine */ /** * @callback module:portal/providers/OpenVeoProvider~OpenVeoProvider~convertVideoPoiCallback * @param {(Error|undefined)} error The error if an error occurred * @param {Object} video The video with converted POI */