UNPKG

libzotero

Version:
234 lines (208 loc) 7.3 kB
'use strict'; var log = require('./Log.js').Logger('libZotero:Collections'); module.exports = function (jsonBody) { var collections = this; this.instance = 'Zotero.Collections'; this.version = 0; this.syncState = { earliestVersion: null, latestVersion: null }; this.collectionObjects = {}; this.collectionsArray = []; this.objectMap = this.collectionObjects; this.objectArray = this.collectionsArray; this.dirty = false; this.loaded = false; if (jsonBody) { this.addCollectionsFromJson(jsonBody); this.initSecondaryData(); } }; module.exports.prototype = new Zotero.Container(); //build up secondary data necessary to rendering and easy operations but that //depend on all collections already being present module.exports.prototype.initSecondaryData = function () { log.debug('Zotero.Collections.initSecondaryData', 3); var collections = this; //rebuild collectionsArray collections.collectionsArray = []; Object.keys(collections.collectionObjects).forEach(function (key) { var collection = collections.collectionObjects[key]; collections.collectionsArray.push(collection); }); collections.collectionsArray.sort(Zotero.ApiObject.prototype.fieldComparer('name')); collections.nestCollections(); collections.assignDepths(0, collections.collectionsArray); }; //take Collection XML and insert a Collection object module.exports.prototype.addCollection = function (collection) { this.addObject(collection); return this; }; module.exports.prototype.addCollectionsFromJson = function (jsonBody) { log.debug('addCollectionsFromJson', 3); var collections = this; var collectionsAdded = []; jsonBody.forEach(function (collectionObj) { var collection = new Zotero.Collection(collectionObj); collections.addObject(collection); collectionsAdded.push(collection); }); return collectionsAdded; }; module.exports.prototype.assignDepths = function (depth, cArray) { log.debug('Zotero.Collections.assignDepths', 3); var collections = this; var insertchildren = function insertchildren(depth, children) { children.forEach(function (col) { col.nestingDepth = depth; if (col.hasChildren) { insertchildren(depth + 1, col.children); } }); }; collections.collectionsArray.forEach(function (collection) { if (collection.topLevel) { collection.nestingDepth = 1; if (collection.hasChildren) { insertchildren(2, collection.children); } } }); }; module.exports.prototype.nestedOrderingArray = function () { log.debug('Zotero.Collections.nestedOrderingArray', 3); var collections = this; var nested = []; var insertchildren = function insertchildren(a, children) { children.forEach(function (col) { a.push(col); if (col.hasChildren) { insertchildren(a, col.children); } }); }; collections.collectionsArray.forEach(function (collection) { if (collection.topLevel) { nested.push(collection); if (collection.hasChildren) { insertchildren(nested, collection.children); } } }); log.debug('Done with nestedOrderingArray', 3); return nested; }; module.exports.prototype.getCollection = function (key) { return this.getObject(key); }; module.exports.prototype.remoteDeleteCollection = function (collectionKey) { var collections = this; return collections.removeLocalCollection(collectionKey); }; module.exports.prototype.removeLocalCollection = function (collectionKey) { var collections = this; return collections.removeLocalCollections([collectionKey]); }; module.exports.prototype.removeLocalCollections = function (collectionKeys) { var collections = this; //delete Collection from collectionObjects for (var i = 0; i < collectionKeys.length; i++) { delete collections.collectionObjects[collectionKeys[i]]; } //rebuild collectionsArray collections.initSecondaryData(); }; //reprocess all collections to add references to children inside their parents module.exports.prototype.nestCollections = function () { var collections = this; //clear out all child references so we don't duplicate collections.collectionsArray.forEach(function (collection) { collection.children = []; }); collections.collectionsArray.sort(Zotero.ApiObject.prototype.fieldComparer('name')); collections.collectionsArray.forEach(function (collection) { collection.nestCollection(collections.collectionObjects); }); }; module.exports.prototype.writeCollections = function (collectionsArray) { log.debug('Zotero.Collections.writeCollections', 3); var collections = this; var library = collections.owningLibrary; var i; var config = { 'target': 'collections', 'libraryType': collections.owningLibrary.libraryType, 'libraryID': collections.owningLibrary.libraryID }; //add collectionKeys to collections if they don't exist yet for (i = 0; i < collectionsArray.length; i++) { var collection = collectionsArray[i]; //generate a collectionKey if the collection does not already have one var collectionKey = collection.get('key'); if (collectionKey === '' || collectionKey === null) { var newCollectionKey = Zotero.utils.getKey(); collection.set('key', newCollectionKey); collection.set('version', 0); } } var writeChunks = collections.chunkObjectsArray(collectionsArray); var rawChunkObjects = collections.rawChunks(writeChunks); //update collections with server response if successful var writeCollectionsSuccessCallback = function writeCollectionsSuccessCallback(response) { log.debug('writeCollections successCallback', 3); var library = this.library; var writeChunk = this.writeChunk; library.collections.updateObjectsFromWriteResponse(this.writeChunk, response); //save updated collections to collections for (var i = 0; i < writeChunk.length; i++) { var collection = writeChunk[i]; if (collection.synced && !collection.writeFailure) { library.collections.addCollection(collection); //save updated collections to IDB if (Zotero.config.useIndexedDB) { log.debug('updating indexedDB collections'); library.idbLibrary.updateCollections(writeChunk); } } } response.returnCollections = writeChunk; return response; }; log.debug('collections.version: ' + collections.version, 3); log.debug('collections.libraryVersion: ' + collections.libraryVersion, 3); var requestObjects = []; for (i = 0; i < writeChunks.length; i++) { var successContext = { writeChunk: writeChunks[i], library: library }; var requestData = JSON.stringify(rawChunkObjects[i]); requestObjects.push({ url: config, type: 'POST', data: requestData, processData: false, headers: { //'If-Unmodified-Since-Version': collections.version, //'Content-Type': 'application/json' }, success: writeCollectionsSuccessCallback.bind(successContext) }); } return library.sequentialRequests(requestObjects).then(function (responses) { log.debug('Done with writeCollections sequentialRequests promise', 3); collections.initSecondaryData(); responses.forEach(function (response) { if (response.isError || response.data.hasOwnProperty('failed') && Object.keys(response.data.failed).length > 0) { throw new Error('failure when writing collections'); } }); return responses; }).catch(function (err) { log.error(err); //rethrow so widget doesn't report success throw err; }); };