VulpesOS/gaia/apps/email/js/ext/pop3/jobs.js
OverSu b38dea0597 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.
2026-09-30 23:13:03 +02:00

188 lines
6.4 KiB
JavaScript
Executable file

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