2013-05-26 22:59:03 +00:00
|
|
|
define([
|
|
|
|
"jquery",
|
2013-05-27 19:45:33 +00:00
|
|
|
"underscore",
|
2013-05-26 22:59:03 +00:00
|
|
|
"utils",
|
2013-11-05 23:03:38 +00:00
|
|
|
"storage",
|
2013-07-30 08:46:36 +00:00
|
|
|
"eventMgr",
|
2013-06-10 21:22:32 +00:00
|
|
|
"fileSystem",
|
|
|
|
"fileMgr",
|
2013-06-22 23:48:57 +00:00
|
|
|
"classes/Provider",
|
2013-06-10 21:22:32 +00:00
|
|
|
"providers/dropboxProvider",
|
2013-12-16 00:31:40 +00:00
|
|
|
"providers/gdriveProvider",
|
2013-12-23 22:40:13 +00:00
|
|
|
"providers/gdrivesecProvider",
|
|
|
|
"providers/gdriveterProvider"
|
2013-11-05 23:03:38 +00:00
|
|
|
], function($, _, utils, storage, eventMgr, fileSystem, fileMgr, Provider) {
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
var synchronizer = {};
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Create a map with providerId: providerModule
|
|
|
|
var providerMap = _.chain(arguments).map(function(argument) {
|
2013-06-22 23:48:57 +00:00
|
|
|
return argument instanceof Provider && [
|
2013-05-29 19:55:23 +00:00
|
|
|
argument.providerId,
|
|
|
|
argument
|
|
|
|
];
|
|
|
|
}).compact().object().value();
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-11-05 23:03:38 +00:00
|
|
|
// Retrieve sync locations from storage
|
2014-04-10 23:22:30 +00:00
|
|
|
(function() {
|
|
|
|
var syncIndexMap = {};
|
|
|
|
_.each(fileSystem, function(fileDesc) {
|
|
|
|
utils.retrieveIndexArray(fileDesc.fileIndex + ".sync").forEach(function(syncIndex) {
|
|
|
|
try {
|
|
|
|
var syncAttributes = JSON.parse(storage[syncIndex]);
|
|
|
|
// Store syncIndex
|
|
|
|
syncAttributes.syncIndex = syncIndex;
|
|
|
|
// Replace provider ID by provider module in attributes
|
|
|
|
var provider = providerMap[syncAttributes.provider];
|
|
|
|
if(!provider) {
|
|
|
|
throw new Error("Invalid provider ID: " + syncAttributes.provider);
|
|
|
|
}
|
|
|
|
syncAttributes.provider = provider;
|
|
|
|
fileDesc.syncLocations[syncIndex] = syncAttributes;
|
|
|
|
syncIndexMap[syncIndex] = syncAttributes;
|
2013-06-13 23:25:32 +00:00
|
|
|
}
|
2014-04-10 23:22:30 +00:00
|
|
|
catch(e) {
|
|
|
|
// storage can be corrupted
|
|
|
|
eventMgr.onError(e);
|
|
|
|
// Remove sync location
|
|
|
|
utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncIndex);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// Clean fields from deleted files in local storage
|
|
|
|
Object.keys(storage).forEach(function(key) {
|
2014-04-12 22:30:18 +00:00
|
|
|
var match = key.match(/sync\.\S+/);
|
|
|
|
if(match && !syncIndexMap.hasOwnProperty(match[0])) {
|
2014-04-10 23:22:30 +00:00
|
|
|
storage.removeItem(key);
|
2013-06-03 22:19:52 +00:00
|
|
|
}
|
2013-05-29 19:55:23 +00:00
|
|
|
});
|
2014-04-10 23:22:30 +00:00
|
|
|
})();
|
2014-03-28 00:49:49 +00:00
|
|
|
|
2014-02-09 17:50:40 +00:00
|
|
|
// AutoSync configuration
|
|
|
|
_.each(providerMap, function(provider) {
|
|
|
|
provider.autosyncConfig = utils.retrieveIgnoreError(provider.providerId + ".autosyncConfig") || {};
|
|
|
|
});
|
2014-03-28 00:49:49 +00:00
|
|
|
|
2013-07-21 14:38:53 +00:00
|
|
|
// Returns true if at least one file has synchronized location
|
2013-07-30 08:46:36 +00:00
|
|
|
synchronizer.hasSync = function(provider) {
|
|
|
|
return _.some(fileSystem, function(fileDesc) {
|
|
|
|
return _.some(fileDesc.syncLocations, function(syncAttributes) {
|
|
|
|
return provider === undefined || syncAttributes.provider === provider;
|
|
|
|
});
|
2013-07-21 14:38:53 +00:00
|
|
|
});
|
|
|
|
};
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-07-20 01:08:17 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* Standard synchronization
|
|
|
|
**************************************************************************/
|
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Recursive function to upload a single file on multiple locations
|
|
|
|
var uploadSyncAttributesList = [];
|
2013-11-05 23:03:38 +00:00
|
|
|
var uploadContent;
|
|
|
|
var uploadContentCRC;
|
|
|
|
var uploadTitle;
|
|
|
|
var uploadTitleCRC;
|
2014-03-28 00:49:49 +00:00
|
|
|
var uploadDiscussionList;
|
|
|
|
var uploadDiscussionListCRC;
|
2013-05-29 19:55:23 +00:00
|
|
|
function locationUp(callback) {
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// No more synchronized location for this document
|
|
|
|
if(uploadSyncAttributesList.length === 0) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return fileUp(callback);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
2013-05-22 21:54:14 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Dequeue a synchronized location
|
|
|
|
var syncAttributes = uploadSyncAttributesList.pop();
|
2013-06-16 18:29:54 +00:00
|
|
|
|
2014-04-13 10:45:31 +00:00
|
|
|
syncAttributes.provider.syncUp(
|
2014-03-28 00:49:49 +00:00
|
|
|
uploadContent,
|
|
|
|
uploadContentCRC,
|
|
|
|
uploadTitle,
|
|
|
|
uploadTitleCRC,
|
|
|
|
uploadDiscussionList,
|
|
|
|
uploadDiscussionListCRC,
|
2014-03-30 01:44:51 +00:00
|
|
|
syncAttributes,
|
2014-03-28 00:49:49 +00:00
|
|
|
function(error, uploadFlag) {
|
|
|
|
if(uploadFlag === true) {
|
|
|
|
// If uploadFlag is true, request another upload cycle
|
|
|
|
uploadCycle = true;
|
|
|
|
}
|
|
|
|
if(error) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return callback(error);
|
2014-03-28 00:49:49 +00:00
|
|
|
}
|
|
|
|
if(uploadFlag) {
|
|
|
|
// Update syncAttributes in storage
|
|
|
|
utils.storeAttributes(syncAttributes);
|
|
|
|
}
|
|
|
|
locationUp(callback);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
2014-03-28 00:49:49 +00:00
|
|
|
);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
2013-04-10 18:14:59 +00:00
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Recursive function to upload multiple files
|
|
|
|
var uploadFileList = [];
|
|
|
|
function fileUp(callback) {
|
|
|
|
|
|
|
|
// No more fileDesc to synchronize
|
|
|
|
if(uploadFileList.length === 0) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return syncUp(callback);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Dequeue a fileDesc to synchronize
|
|
|
|
var fileDesc = uploadFileList.pop();
|
|
|
|
uploadSyncAttributesList = _.values(fileDesc.syncLocations);
|
|
|
|
if(uploadSyncAttributesList.length === 0) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return fileUp(callback);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get document title/content
|
|
|
|
uploadContent = fileDesc.content;
|
|
|
|
uploadContentCRC = utils.crc32(uploadContent);
|
|
|
|
uploadTitle = fileDesc.title;
|
|
|
|
uploadTitleCRC = utils.crc32(uploadTitle);
|
2014-03-28 00:49:49 +00:00
|
|
|
uploadDiscussionList = fileDesc.discussionListJSON;
|
|
|
|
uploadDiscussionListCRC = utils.crc32(uploadDiscussionList);
|
2013-05-29 19:55:23 +00:00
|
|
|
locationUp(callback);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Entry point for up synchronization (upload changes)
|
|
|
|
var uploadCycle = false;
|
|
|
|
function syncUp(callback) {
|
|
|
|
if(uploadCycle === true) {
|
|
|
|
// New upload cycle
|
|
|
|
uploadCycle = false;
|
|
|
|
uploadFileList = _.values(fileSystem);
|
|
|
|
fileUp(callback);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Recursive function to download changes from multiple providers
|
|
|
|
var providerList = [];
|
|
|
|
function providerDown(callback) {
|
|
|
|
if(providerList.length === 0) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return callback();
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
var provider = providerList.pop();
|
|
|
|
|
|
|
|
// Check that provider has files to sync
|
2013-07-30 08:46:36 +00:00
|
|
|
if(!synchronizer.hasSync(provider)) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return providerDown(callback);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Perform provider's syncDown
|
|
|
|
provider.syncDown(function(error) {
|
|
|
|
if(error) {
|
2014-03-30 01:44:51 +00:00
|
|
|
return callback(error);
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
providerDown(callback);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Entry point for down synchronization (download changes)
|
|
|
|
function syncDown(callback) {
|
|
|
|
providerList = _.values(providerMap);
|
|
|
|
providerDown(callback);
|
|
|
|
}
|
|
|
|
|
2013-08-04 00:53:46 +00:00
|
|
|
// Listen to offline status changes
|
|
|
|
var isOffline = false;
|
|
|
|
eventMgr.addListener("onOfflineChanged", function(isOfflineParam) {
|
|
|
|
isOffline = isOfflineParam;
|
|
|
|
});
|
|
|
|
|
2013-05-29 19:55:23 +00:00
|
|
|
// Main entry point for synchronization
|
|
|
|
var syncRunning = false;
|
|
|
|
synchronizer.sync = function() {
|
2013-06-10 22:32:34 +00:00
|
|
|
// If sync is already running or offline
|
2013-08-04 00:53:46 +00:00
|
|
|
if(syncRunning === true || isOffline === true) {
|
2013-06-10 22:32:34 +00:00
|
|
|
return false;
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
syncRunning = true;
|
2013-07-30 08:46:36 +00:00
|
|
|
eventMgr.onSyncRunning(true);
|
2013-05-29 19:55:23 +00:00
|
|
|
uploadCycle = true;
|
|
|
|
|
|
|
|
function isError(error) {
|
|
|
|
if(error !== undefined) {
|
|
|
|
syncRunning = false;
|
2013-07-30 08:46:36 +00:00
|
|
|
eventMgr.onSyncRunning(false);
|
2013-05-29 19:55:23 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
syncDown(function(error) {
|
|
|
|
if(isError(error)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
syncUp(function(error) {
|
|
|
|
if(isError(error)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
syncRunning = false;
|
2013-07-30 08:46:36 +00:00
|
|
|
eventMgr.onSyncRunning(false);
|
|
|
|
eventMgr.onSyncSuccess();
|
2013-05-29 19:55:23 +00:00
|
|
|
});
|
|
|
|
});
|
2013-06-10 22:32:34 +00:00
|
|
|
return true;
|
2013-05-29 19:55:23 +00:00
|
|
|
};
|
2013-07-18 23:30:28 +00:00
|
|
|
|
2013-07-20 01:08:17 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* Initialize module
|
|
|
|
**************************************************************************/
|
2013-05-29 19:55:23 +00:00
|
|
|
|
|
|
|
// Initialize the export dialog
|
|
|
|
function initExportDialog(provider) {
|
|
|
|
|
|
|
|
// Reset fields
|
|
|
|
utils.resetModalInputs();
|
|
|
|
|
|
|
|
// Load preferences
|
2013-06-03 22:19:52 +00:00
|
|
|
var exportPreferences = utils.retrieveIgnoreError(provider.providerId + ".exportPreferences");
|
|
|
|
if(exportPreferences) {
|
2013-05-29 19:55:23 +00:00
|
|
|
_.each(provider.exportPreferencesInputIds, function(inputId) {
|
2013-08-23 23:50:14 +00:00
|
|
|
var exportPreferenceValue = exportPreferences[inputId];
|
|
|
|
if(_.isBoolean(exportPreferenceValue)) {
|
|
|
|
utils.setInputChecked("#input-sync-export-" + inputId, exportPreferenceValue);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
utils.setInputValue("#input-sync-export-" + inputId, exportPreferenceValue);
|
|
|
|
}
|
2013-05-29 19:55:23 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-02-09 17:50:40 +00:00
|
|
|
// Open dialog
|
2013-08-11 00:52:05 +00:00
|
|
|
$(".modal-upload-" + provider.providerId).modal();
|
2013-05-29 19:55:23 +00:00
|
|
|
}
|
|
|
|
|
2014-02-09 17:50:40 +00:00
|
|
|
eventMgr.addListener("onFileCreated", function(fileDesc) {
|
|
|
|
if(_.size(fileDesc.syncLocations) === 0) {
|
|
|
|
_.each(providerMap, function(provider) {
|
2014-04-07 23:19:47 +00:00
|
|
|
provider.autosyncConfig.enabled && provider.autosyncFile(fileDesc.title, fileDesc.content, fileDesc.discussionListJSON, provider.autosyncConfig, function(error, syncAttributes) {
|
2014-02-09 17:50:40 +00:00
|
|
|
if(error) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
fileDesc.addSyncLocation(syncAttributes);
|
|
|
|
eventMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-08-04 00:53:46 +00:00
|
|
|
eventMgr.addListener("onReady", function() {
|
2013-05-29 19:55:23 +00:00
|
|
|
// Init each provider
|
|
|
|
_.each(providerMap, function(provider) {
|
|
|
|
// Provider's import button
|
|
|
|
$(".action-sync-import-" + provider.providerId).click(function(event) {
|
|
|
|
provider.importFiles(event);
|
|
|
|
});
|
|
|
|
// Provider's export action
|
|
|
|
$(".action-sync-export-dialog-" + provider.providerId).click(function() {
|
|
|
|
initExportDialog(provider);
|
|
|
|
});
|
2014-02-09 17:50:40 +00:00
|
|
|
// Provider's autosync action
|
|
|
|
$(".action-autosync-dialog-" + provider.providerId).click(function() {
|
|
|
|
// Reset fields
|
|
|
|
utils.resetModalInputs();
|
|
|
|
// Load config
|
|
|
|
provider.setAutosyncDialogConfig(provider);
|
|
|
|
// Open dialog
|
|
|
|
$(".modal-autosync-" + provider.providerId).modal();
|
|
|
|
});
|
2013-05-29 19:55:23 +00:00
|
|
|
$(".action-sync-export-" + provider.providerId).click(function(event) {
|
2013-06-19 20:33:46 +00:00
|
|
|
var fileDesc = fileMgr.currentFile;
|
2013-07-18 23:30:28 +00:00
|
|
|
|
2014-04-13 10:45:31 +00:00
|
|
|
provider.exportFile(event, fileDesc.title, fileDesc.content, fileDesc.discussionListJSON, function(error, syncAttributes) {
|
|
|
|
if(error) {
|
2013-07-18 23:30:28 +00:00
|
|
|
return;
|
2013-07-20 01:08:17 +00:00
|
|
|
}
|
2014-04-13 10:45:31 +00:00
|
|
|
fileDesc.addSyncLocation(syncAttributes);
|
|
|
|
eventMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
|
|
|
});
|
2013-05-29 19:55:23 +00:00
|
|
|
|
|
|
|
// Store input values as preferences for next time we open the
|
|
|
|
// export dialog
|
|
|
|
var exportPreferences = {};
|
|
|
|
_.each(provider.exportPreferencesInputIds, function(inputId) {
|
2013-08-23 23:50:14 +00:00
|
|
|
var inputElt = document.getElementById("input-sync-export-" + inputId);
|
|
|
|
if(inputElt.type == 'checkbox') {
|
|
|
|
exportPreferences[inputId] = inputElt.checked;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
exportPreferences[inputId] = inputElt.value;
|
|
|
|
}
|
2013-05-29 19:55:23 +00:00
|
|
|
});
|
2013-11-05 23:03:38 +00:00
|
|
|
storage[provider.providerId + ".exportPreferences"] = JSON.stringify(exportPreferences);
|
2013-05-29 19:55:23 +00:00
|
|
|
});
|
2014-02-09 17:50:40 +00:00
|
|
|
$(".action-autosync-" + provider.providerId).click(function(event) {
|
|
|
|
var config = provider.getAutosyncDialogConfig(event);
|
|
|
|
if(config !== undefined) {
|
|
|
|
storage[provider.providerId + ".autosyncConfig"] = JSON.stringify(config);
|
|
|
|
provider.autosyncConfig = config;
|
|
|
|
}
|
|
|
|
});
|
2013-05-29 19:55:23 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-07-30 08:46:36 +00:00
|
|
|
eventMgr.onSynchronizerCreated(synchronizer);
|
2013-05-29 19:55:23 +00:00
|
|
|
return synchronizer;
|
2013-04-02 18:42:47 +00:00
|
|
|
});
|