mirror of
https://github.com/Foundry376/Mailspring.git
synced 2024-11-14 13:44:41 +08:00
108 lines
3 KiB
JavaScript
108 lines
3 KiB
JavaScript
const {Provider} = require('nylas-core');
|
|
|
|
const GMAIL_FOLDERS = ['[Gmail]/All Mail', '[Gmail]/Trash', '[Gmail]/Spam'];
|
|
|
|
class FetchFolderList {
|
|
constructor(provider) {
|
|
this._provider = provider;
|
|
}
|
|
|
|
description() {
|
|
return `FetchFolderList`;
|
|
}
|
|
|
|
_classForMailbox(boxName, box, {Folder, Label}) {
|
|
if (this._provider === Provider.Gmail) {
|
|
return GMAIL_FOLDERS.includes(boxName) ? Folder : Label;
|
|
}
|
|
return Folder;
|
|
}
|
|
|
|
_roleForMailbox(boxName, box) {
|
|
for (const attrib of (box.attribs || [])) {
|
|
const role = {
|
|
'\\Sent': 'sent',
|
|
'\\Drafts': 'drafts',
|
|
'\\Junk': 'junk',
|
|
'\\Trash': 'trash',
|
|
'\\All': 'all',
|
|
'\\Important': 'important',
|
|
'\\Flagged': 'flagged',
|
|
}[attrib];
|
|
if (role) {
|
|
return role;
|
|
}
|
|
}
|
|
if (boxName.toLowerCase().trim() === 'inbox') {
|
|
return 'inbox';
|
|
}
|
|
return null;
|
|
}
|
|
|
|
_updateCategoriesWithBoxes(categories, boxes) {
|
|
const stack = [];
|
|
const created = [];
|
|
const next = [];
|
|
|
|
Object.keys(boxes).forEach((boxName) => {
|
|
stack.push([boxName, boxes[boxName]]);
|
|
});
|
|
|
|
while (stack.length > 0) {
|
|
const [boxName, box] = stack.pop();
|
|
if (!box.attribs) {
|
|
// Some boxes seem to come back as partial objects. Not sure why, but
|
|
// I also can't access them via openMailbox. Possible node-imap i8n issue?
|
|
continue;
|
|
}
|
|
|
|
if (box.children && box.attribs.includes('\\HasChildren')) {
|
|
Object.keys(box.children).forEach((subname) => {
|
|
stack.push([`${boxName}${box.delimiter}${subname}`, box.children[subname]]);
|
|
});
|
|
}
|
|
|
|
let category = categories.find((cat) => cat.name === boxName);
|
|
if (!category) {
|
|
const Klass = this._classForMailbox(boxName, box, this._db);
|
|
category = Klass.build({
|
|
name: boxName,
|
|
accountId: this._db.accountId,
|
|
role: this._roleForMailbox(boxName, box),
|
|
});
|
|
created.push(category);
|
|
}
|
|
next.push(category);
|
|
}
|
|
|
|
// Todo: decide whether these are renames or deletes
|
|
const deleted = categories.filter(cat => !next.includes(cat));
|
|
|
|
return {next, created, deleted};
|
|
}
|
|
|
|
run(db, imap) {
|
|
this._db = db;
|
|
|
|
return imap.getBoxes().then((boxes) => {
|
|
const {Folder, Label, sequelize} = this._db;
|
|
|
|
return sequelize.transaction((transaction) => {
|
|
return Promise.props({
|
|
folders: Folder.findAll({transaction}),
|
|
labels: Label.findAll({transaction}),
|
|
}).then(({folders, labels}) => {
|
|
const all = [].concat(folders, labels);
|
|
const {created, deleted} = this._updateCategoriesWithBoxes(all, boxes);
|
|
|
|
let promises = [Promise.resolve()]
|
|
promises = promises.concat(created.map(cat => cat.save({transaction})))
|
|
promises = promises.concat(deleted.map(cat => cat.destroy({transaction})))
|
|
return Promise.all(promises)
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = FetchFolderList;
|