Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
188
gaia/apps/email/js/ext/pop3/jobs.js
Executable file
188
gaia/apps/email/js/ext/pop3/jobs.js
Executable file
|
|
@ -0,0 +1,188 @@
|
|||
define(['module', 'exports', 'logic', '../allback', 'mix',
|
||||
'../jobmixins', '../drafts/jobs', './pop3'],
|
||||
function(module, exports, logic, allback, mix,
|
||||
jobmixins, draftsJobs, pop3) {
|
||||
|
||||
/**
|
||||
* Manage the jobs for a POP3 account. POP3 does not support
|
||||
* server-side folders, so many of these operations are local-only.
|
||||
* Operations not implemented in the Pop3JobDriver are ignored and
|
||||
* assumed unsupported. For instance, issuing a "move" command will
|
||||
* execute local_do_move, but not do_move. It is assumed that unit
|
||||
* tests will ensure we've implemented all required jobs.
|
||||
*/
|
||||
function Pop3JobDriver(account, state) {
|
||||
this.account = account;
|
||||
this.resilientServerIds = true; // once assigned, the server never changes IDs
|
||||
this._heldMutexReleasers = [];
|
||||
|
||||
logic.defineScope(this, 'Pop3JobDriver', { accountId: account.id });
|
||||
|
||||
// For tracking state as used in jobmixins:
|
||||
this._stateDelta = {};
|
||||
this._state = state;
|
||||
if (!state.hasOwnProperty('suidToServerId')) {
|
||||
state.suidToServerId = {};
|
||||
state.moveMap = {};
|
||||
}
|
||||
}
|
||||
exports.Pop3JobDriver = Pop3JobDriver;
|
||||
Pop3JobDriver.prototype = {
|
||||
|
||||
/**
|
||||
* Request access to a POP3 folder for mutation. This acquires a
|
||||
* write mutex on the FolderStorage. The callback will be invoked
|
||||
* with the folder and the raw connection.
|
||||
*
|
||||
* There is no need to explicitly release the connection when done;
|
||||
* it will be automatically released when the mutex is released if
|
||||
* desirable.
|
||||
*
|
||||
* This function is used by jobmixins.
|
||||
*/
|
||||
_accessFolderForMutation: function(
|
||||
folderId, needConn, callback, deathback, label) {
|
||||
var storage = this.account.getFolderStorageForFolderId(folderId);
|
||||
storage.runMutexed(label, function(releaseMutex) {
|
||||
this._heldMutexReleasers.push(releaseMutex);
|
||||
try {
|
||||
// The folderSyncer is like IMAP/ActiveSync's folderConn.
|
||||
callback(storage.folderSyncer, storage);
|
||||
} catch (ex) {
|
||||
logic(this, 'callbackErr', { ex: ex });
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a folder locally. (Again, no remote folders, so
|
||||
* do_createFolder is not implemented.)
|
||||
*/
|
||||
local_do_createFolder: function(op, callback) {
|
||||
var path, delim, parentFolderId = null, depth = 0;
|
||||
|
||||
if (op.parentFolderId) {
|
||||
if (!this.account._folderInfos.hasOwnProperty(op.parentFolderId)) {
|
||||
throw new Error("No such folder: " + op.parentFolderId);
|
||||
}
|
||||
var parentFolder = this.account._folderInfos[op.parentFolderId];
|
||||
delim = parentFolder.$meta.delim;
|
||||
path = parentFolder.$meta.path + delim;
|
||||
parentFolderId = parentFolder.$meta.id;
|
||||
depth = parentFolder.depth + 1;
|
||||
}
|
||||
else {
|
||||
path = '';
|
||||
delim = '/';
|
||||
}
|
||||
|
||||
if (typeof(op.folderName) === 'string')
|
||||
path += op.folderName;
|
||||
else
|
||||
path += op.folderName.join(delim);
|
||||
if (op.containOnlyOtherFolders) {
|
||||
path += delim;
|
||||
}
|
||||
|
||||
if (this.account.getFolderByPath(path)) {
|
||||
callback(null);
|
||||
} else {
|
||||
var folderMeta = self.account._learnAboutFolder(
|
||||
op.folderName, path, parentFolderId, 'normal', delim, depth);
|
||||
callback(null, folderMeta);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete old messages from disk. Since we currently leave mail on
|
||||
* the server, we won't incur permanent data loss.
|
||||
*/
|
||||
local_do_purgeExcessMessages: function(op, callback) {
|
||||
this._accessFolderForMutation(
|
||||
op.folderId, false,
|
||||
function withMutex(_ignoredConn, storage) {
|
||||
storage.purgeExcessMessages(function(numDeleted, cutTS) {
|
||||
// Indicate that we want a save performed if any messages got deleted.
|
||||
callback(null, null, numDeleted > 0);
|
||||
});
|
||||
},
|
||||
null,
|
||||
'purgeExcessMessages');
|
||||
},
|
||||
|
||||
local_do_saveSentDraft: function(op, callback) {
|
||||
var self = this;
|
||||
this._accessFolderForMutation(
|
||||
op.folderId, /* needConn*/ false,
|
||||
function(nullFolderConn, folderStorage) {
|
||||
var latch = allback.latch();
|
||||
|
||||
folderStorage.addMessageHeader(op.headerInfo, op.bodyInfo,
|
||||
latch.defer());
|
||||
folderStorage.addMessageBody(op.headerInfo, op.bodyInfo, latch.defer());
|
||||
|
||||
latch.then(function(results) {
|
||||
// header/body insertion can't fail
|
||||
callback(null, null, /* save */ true);
|
||||
});
|
||||
},
|
||||
/* no conn => no deathback required */ null,
|
||||
'saveSentDraft');
|
||||
},
|
||||
|
||||
do_syncFolderList: function(op, doneCallback) {
|
||||
this.account.meta.lastFolderSyncAt = Date.now();
|
||||
doneCallback(null);
|
||||
},
|
||||
|
||||
/** No-op to silence warnings. Perhaps implement someday. */
|
||||
do_modtags: function(op, doneCallback) {
|
||||
doneCallback(null);
|
||||
},
|
||||
|
||||
/** No-op to silence warnings. Perhaps implement someday. */
|
||||
undo_modtags: function(op, doneCallback) {
|
||||
doneCallback(null);
|
||||
},
|
||||
|
||||
// Local modifications (move, delete, and modtags) simply reuse the
|
||||
// jobmixins implementation. No server-side implementations are
|
||||
// necessary here, so they are omitted.
|
||||
local_do_modtags: jobmixins.local_do_modtags,
|
||||
local_undo_modtags: jobmixins.local_undo_modtags,
|
||||
local_do_move: jobmixins.local_do_move,
|
||||
local_undo_move: jobmixins.local_undo_move,
|
||||
local_do_delete: jobmixins.local_do_delete,
|
||||
local_undo_delete: jobmixins.local_undo_delete,
|
||||
|
||||
// Download operations (for attachments) are irrelevant because
|
||||
// downloading the bodies always fetches the attachments too.
|
||||
|
||||
local_do_downloadBodies: jobmixins.local_do_downloadBodies,
|
||||
do_downloadBodies: jobmixins.do_downloadBodies,
|
||||
check_downloadBodies: jobmixins.check_downloadBodies,
|
||||
|
||||
check_downloadBodyReps: jobmixins.check_downloadBodyReps,
|
||||
do_downloadBodyReps: jobmixins.do_downloadBodyReps,
|
||||
local_do_downloadBodyReps: jobmixins.local_do_downloadBodyReps,
|
||||
|
||||
|
||||
local_do_sendOutboxMessages: jobmixins.local_do_sendOutboxMessages,
|
||||
do_sendOutboxMessages: jobmixins.do_sendOutboxMessages,
|
||||
check_sendOutboxMessages: jobmixins.check_sendOutboxMessages,
|
||||
local_undo_sendOutboxMessages: jobmixins.local_undo_sendOutboxMessages,
|
||||
undo_sendOutboxMessages: jobmixins.undo_sendOutboxMessages,
|
||||
local_do_setOutboxSyncEnabled: jobmixins.local_do_setOutboxSyncEnabled,
|
||||
|
||||
local_do_upgradeDB: jobmixins.local_do_upgradeDB,
|
||||
|
||||
// These utility functions are necessary.
|
||||
postJobCleanup: jobmixins.postJobCleanup,
|
||||
allJobsDone: jobmixins.allJobsDone,
|
||||
_partitionAndAccessFoldersSequentially:
|
||||
jobmixins._partitionAndAccessFoldersSequentially
|
||||
};
|
||||
|
||||
mix(Pop3JobDriver.prototype, draftsJobs.draftsMixins);
|
||||
|
||||
}); // end define
|
||||
Loading…
Reference in a new issue