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
|
|
|
"core",
|
|
|
|
"utils",
|
|
|
|
"extension-manager",
|
2013-05-27 19:45:33 +00:00
|
|
|
"file-system",
|
|
|
|
"file-manager",
|
2013-05-26 22:59:03 +00:00
|
|
|
"dropbox-provider",
|
2013-05-27 19:45:33 +00:00
|
|
|
"gdrive-provider"
|
|
|
|
], function($, _, core, utils, extensionMgr, fileSystem, fileMgr) {
|
2013-05-26 22:59:03 +00:00
|
|
|
|
2013-04-01 16:46:48 +00:00
|
|
|
var synchronizer = {};
|
2013-04-01 23:12:28 +00:00
|
|
|
|
2013-05-27 19:45:33 +00:00
|
|
|
// Create a map with providerId: providerModule
|
|
|
|
var providerMap = _.chain(
|
|
|
|
arguments
|
|
|
|
).map(function(argument) {
|
|
|
|
return argument && argument.providerId && [argument.providerId, argument];
|
|
|
|
}).compact().object().value();
|
2013-04-10 23:13:31 +00:00
|
|
|
|
2013-05-27 19:45:33 +00:00
|
|
|
// Retrieve sync locations from localStorage
|
|
|
|
_.each(fileSystem, function(fileDesc) {
|
|
|
|
_.chain(
|
|
|
|
localStorage[fileDesc.fileIndex + ".sync"].split(";")
|
|
|
|
).compact().each(function(syncIndex) {
|
|
|
|
var syncAttributes = JSON.parse(localStorage[syncIndex]);
|
|
|
|
// Store syncIndex
|
|
|
|
syncAttributes.syncIndex = syncIndex;
|
|
|
|
// Replace provider ID by provider module in attributes
|
|
|
|
syncAttributes.provider = providerMap[syncAttributes.provider];
|
|
|
|
fileDesc.syncLocations[syncIndex] = syncAttributes;
|
|
|
|
});
|
|
|
|
});
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-10 23:13:31 +00:00
|
|
|
// Force the synchronization
|
|
|
|
synchronizer.forceSync = function() {
|
|
|
|
lastSync = 0;
|
|
|
|
synchronizer.sync();
|
|
|
|
};
|
|
|
|
|
2013-04-01 16:46:48 +00:00
|
|
|
// Recursive function to upload a single file on multiple locations
|
2013-05-26 22:59:03 +00:00
|
|
|
var uploadSyncAttributesList = [];
|
2013-04-10 18:14:59 +00:00
|
|
|
var uploadContent = undefined;
|
|
|
|
var uploadContentCRC = undefined;
|
|
|
|
var uploadTitle = undefined;
|
|
|
|
var uploadTitleCRC = undefined;
|
|
|
|
function locationUp(callback) {
|
|
|
|
|
|
|
|
// No more synchronized location for this document
|
2013-05-26 22:59:03 +00:00
|
|
|
if (uploadSyncAttributesList.length === 0) {
|
2013-04-10 18:14:59 +00:00
|
|
|
fileUp(callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dequeue a synchronized location
|
2013-05-26 22:59:03 +00:00
|
|
|
var syncAttributes = uploadSyncAttributesList.pop();
|
2013-04-20 17:40:05 +00:00
|
|
|
// Use the specified provider to perform the upload
|
2013-05-26 22:59:03 +00:00
|
|
|
syncAttributes.provider.syncUp(
|
2013-04-20 17:40:05 +00:00
|
|
|
uploadContent,
|
|
|
|
uploadContentCRC,
|
|
|
|
uploadTitle,
|
|
|
|
uploadTitleCRC,
|
|
|
|
syncAttributes,
|
|
|
|
function(error, uploadFlag) {
|
|
|
|
if(uploadFlag === true) {
|
|
|
|
// If uploadFlag is true, request another upload cycle
|
|
|
|
uploadCycle = true;
|
|
|
|
}
|
2013-04-20 00:14:20 +00:00
|
|
|
if(error) {
|
|
|
|
callback(error);
|
2013-04-07 15:22:13 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-04-20 17:40:05 +00:00
|
|
|
if(uploadFlag) {
|
|
|
|
// Update syncAttributes in localStorage
|
2013-05-27 23:39:07 +00:00
|
|
|
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
2013-04-01 16:46:48 +00:00
|
|
|
}
|
2013-04-16 15:02:24 +00:00
|
|
|
locationUp(callback);
|
2013-04-20 17:40:05 +00:00
|
|
|
}
|
|
|
|
);
|
2013-04-01 16:46:48 +00:00
|
|
|
}
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
// Recursive function to upload multiple files
|
2013-05-26 22:59:03 +00:00
|
|
|
var uploadFileList = [];
|
2013-04-10 18:14:59 +00:00
|
|
|
function fileUp(callback) {
|
|
|
|
|
2013-05-26 22:59:03 +00:00
|
|
|
// No more fileDesc to synchronize
|
|
|
|
if (uploadFileList.length === 0) {
|
2013-04-10 18:14:59 +00:00
|
|
|
syncUp(callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-05-26 22:59:03 +00:00
|
|
|
// Dequeue a fileDesc
|
|
|
|
var fileDesc = uploadFileList.pop();
|
|
|
|
uploadSyncAttributesList = _.values(fileDesc.syncLocations);
|
|
|
|
if(uploadSyncAttributesList.length === 0) {
|
2013-04-10 18:14:59 +00:00
|
|
|
fileUp(callback);
|
2013-04-01 16:46:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
// Get document title/content
|
2013-05-26 23:38:13 +00:00
|
|
|
uploadContent = localStorage[fileDesc.fileIndex + ".content"];
|
2013-05-25 18:13:59 +00:00
|
|
|
uploadContentCRC = utils.crc32(uploadContent);
|
2013-05-26 22:59:03 +00:00
|
|
|
uploadTitle = fileDesc.title;
|
2013-05-25 18:13:59 +00:00
|
|
|
uploadTitleCRC = utils.crc32(uploadTitle);
|
2013-04-10 18:14:59 +00:00
|
|
|
locationUp(callback);
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
// Entry point for up synchronization (upload changes)
|
2013-04-10 18:14:59 +00:00
|
|
|
var uploadCycle = false;
|
|
|
|
function syncUp(callback) {
|
|
|
|
if(uploadCycle === true) {
|
|
|
|
// New upload cycle
|
|
|
|
uploadCycle = false;
|
2013-05-27 22:13:41 +00:00
|
|
|
uploadFileList = _.values(fileSystem);
|
2013-04-10 18:14:59 +00:00
|
|
|
fileUp(callback);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-20 17:40:05 +00:00
|
|
|
// Recursive function to download changes from multiple providers
|
|
|
|
var providerList = [];
|
|
|
|
function providerDown(callback) {
|
|
|
|
if(providerList.length === 0) {
|
2013-04-07 15:22:13 +00:00
|
|
|
callback();
|
2013-04-21 00:07:27 +00:00
|
|
|
return;
|
2013-04-07 15:22:13 +00:00
|
|
|
}
|
2013-04-20 17:40:05 +00:00
|
|
|
var provider = providerList.pop();
|
2013-05-26 22:59:03 +00:00
|
|
|
|
|
|
|
// Check that provider has files to sync
|
2013-05-27 19:45:33 +00:00
|
|
|
if(!fileMgr.hasSync(provider)) {
|
2013-05-26 22:59:03 +00:00
|
|
|
providerDown(callback);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Perform provider's syncDown
|
2013-04-20 17:40:05 +00:00
|
|
|
provider.syncDown(function(error) {
|
|
|
|
if(error) {
|
2013-04-16 15:02:24 +00:00
|
|
|
callback(error);
|
2013-04-07 15:22:13 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-04-20 17:40:05 +00:00
|
|
|
providerDown(callback);
|
2013-04-07 15:22:13 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-04-21 00:07:27 +00:00
|
|
|
// Entry point for down synchronization (download changes)
|
2013-04-01 16:46:48 +00:00
|
|
|
function syncDown(callback) {
|
2013-04-20 17:40:05 +00:00
|
|
|
providerList = _.values(providerMap);
|
|
|
|
providerDown(callback);
|
2013-04-01 16:46:48 +00:00
|
|
|
};
|
2013-04-21 00:07:27 +00:00
|
|
|
|
|
|
|
// Main entry point for synchronization
|
2013-04-01 16:46:48 +00:00
|
|
|
var syncRunning = false;
|
|
|
|
var lastSync = 0;
|
|
|
|
synchronizer.sync = function() {
|
|
|
|
// If sync is already running or timeout is not reached or offline
|
2013-05-27 19:45:33 +00:00
|
|
|
if (syncRunning || lastSync + SYNC_PERIOD > utils.currentTime || core.isOffline) {
|
2013-04-01 16:46:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
syncRunning = true;
|
2013-05-27 19:45:33 +00:00
|
|
|
extensionMgr.onSyncRunning(true);
|
2013-04-10 18:14:59 +00:00
|
|
|
uploadCycle = true;
|
2013-05-27 19:45:33 +00:00
|
|
|
lastSync = utils.currentTime;
|
2013-04-10 18:14:59 +00:00
|
|
|
|
|
|
|
function isError(error) {
|
|
|
|
if(error !== undefined) {
|
|
|
|
syncRunning = false;
|
2013-05-27 19:45:33 +00:00
|
|
|
extensionMgr.onSyncRunning(false);
|
2013-04-10 18:14:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
syncDown(function(error) {
|
|
|
|
if(isError(error)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
syncUp(function(error) {
|
|
|
|
if(isError(error)) {
|
|
|
|
return;
|
|
|
|
}
|
2013-04-01 16:46:48 +00:00
|
|
|
syncRunning = false;
|
2013-05-27 19:45:33 +00:00
|
|
|
extensionMgr.onSyncRunning(false);
|
|
|
|
extensionMgr.onSyncSuccess();
|
2013-04-01 16:46:48 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
2013-04-21 14:36:53 +00:00
|
|
|
// Run sync function periodically
|
2013-05-04 00:05:58 +00:00
|
|
|
if(viewerMode === false) {
|
|
|
|
core.addPeriodicCallback(synchronizer.sync);
|
|
|
|
}
|
2013-04-01 23:12:28 +00:00
|
|
|
|
2013-05-22 21:54:14 +00:00
|
|
|
// Initialize the export dialog
|
|
|
|
function initExportDialog(provider) {
|
|
|
|
|
|
|
|
// Reset fields
|
2013-05-26 01:10:58 +00:00
|
|
|
utils.resetModalInputs();
|
2013-05-22 21:54:14 +00:00
|
|
|
|
|
|
|
// Load preferences
|
|
|
|
var serializedPreferences = localStorage[provider.providerId + ".exportPreferences"];
|
|
|
|
if(serializedPreferences) {
|
|
|
|
var exportPreferences = JSON.parse(serializedPreferences);
|
|
|
|
_.each(provider.exportPreferencesInputIds, function(inputId) {
|
2013-05-25 18:13:59 +00:00
|
|
|
utils.setInputValue("#input-sync-export-" + inputId, exportPreferences[inputId]);
|
2013-05-22 21:54:14 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Open dialog box
|
|
|
|
$("#modal-upload-" + provider.providerId).modal();
|
|
|
|
}
|
|
|
|
|
2013-04-22 01:04:12 +00:00
|
|
|
core.onReady(function() {
|
2013-04-20 00:14:20 +00:00
|
|
|
// Init each provider
|
|
|
|
_.each(providerMap, function(provider) {
|
|
|
|
// Provider's import button
|
|
|
|
$(".action-sync-import-" + provider.providerId).click(function(event) {
|
|
|
|
provider.importFiles(event);
|
|
|
|
});
|
2013-05-22 21:54:14 +00:00
|
|
|
// Provider's export action
|
|
|
|
$(".action-sync-export-dialog-" + provider.providerId).click(function() {
|
|
|
|
initExportDialog(provider);
|
|
|
|
});
|
2013-04-20 00:14:20 +00:00
|
|
|
$(".action-sync-export-" + provider.providerId).click(function(event) {
|
2013-05-22 21:54:14 +00:00
|
|
|
|
|
|
|
// Perform the provider's export
|
2013-05-27 19:45:33 +00:00
|
|
|
var fileDesc = fileMgr.getCurrentFile();
|
2013-05-26 22:59:03 +00:00
|
|
|
var title = fileDesc.title;
|
2013-05-26 23:38:13 +00:00
|
|
|
var content = localStorage[fileDesc.fileIndex + ".content"];
|
|
|
|
provider.exportFile(event, title, content, function(error, syncAttributes) {
|
2013-04-20 00:14:20 +00:00
|
|
|
if(error) {
|
|
|
|
return;
|
|
|
|
}
|
2013-05-27 19:45:33 +00:00
|
|
|
fileMgr.addSync(fileDesc, syncAttributes);
|
2013-04-20 00:14:20 +00:00
|
|
|
});
|
2013-05-22 21:54:14 +00:00
|
|
|
|
|
|
|
// Store input values as preferences for next time we open the export dialog
|
|
|
|
var exportPreferences = {};
|
|
|
|
_.each(provider.exportPreferencesInputIds, function(inputId) {
|
|
|
|
exportPreferences[inputId] = $("#input-sync-export-" + inputId).val();
|
|
|
|
});
|
|
|
|
localStorage[provider.providerId + ".exportPreferences"] = JSON.stringify(exportPreferences);
|
2013-04-20 00:14:20 +00:00
|
|
|
});
|
2013-05-22 21:54:14 +00:00
|
|
|
// Provider's manual export button
|
2013-04-20 00:14:20 +00:00
|
|
|
$(".action-sync-manual-" + provider.providerId).click(function(event) {
|
2013-05-27 19:45:33 +00:00
|
|
|
var fileDesc = fileMgr.getCurrentFile();
|
2013-05-26 22:59:03 +00:00
|
|
|
var title = fileDesc.title;
|
2013-05-26 23:38:13 +00:00
|
|
|
var content = localStorage[fileDesc.fileIndex + ".content"];
|
|
|
|
provider.exportManual(event, title, content, function(error, syncAttributes) {
|
2013-04-20 00:14:20 +00:00
|
|
|
if(error) {
|
|
|
|
return;
|
|
|
|
}
|
2013-05-27 19:45:33 +00:00
|
|
|
fileMgr.addSync(fileDesc, syncAttributes);
|
2013-04-20 00:14:20 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2013-04-10 18:14:59 +00:00
|
|
|
$(".action-force-sync").click(function() {
|
|
|
|
if(!$(this).hasClass("disabled")) {
|
|
|
|
synchronizer.forceSync();
|
|
|
|
}
|
|
|
|
});
|
2013-04-21 00:07:27 +00:00
|
|
|
});
|
2013-04-10 18:14:59 +00:00
|
|
|
|
2013-05-27 19:45:33 +00:00
|
|
|
extensionMgr.onSynchronizerCreated(synchronizer);
|
2013-04-01 16:46:48 +00:00
|
|
|
return synchronizer;
|
2013-04-02 18:42:47 +00:00
|
|
|
});
|