spamreport is using the new storage. see #675
This commit is contained in:
parent
b30da27c84
commit
55240868dd
3 changed files with 106 additions and 26 deletions
|
|
@ -16,11 +16,20 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { taStorage } from './mzta-storage.js';
|
||||
|
||||
export const taSpamReport = {
|
||||
logger: console,
|
||||
do_debug: false,
|
||||
_data_prefix: 'mzta-spam-report-',
|
||||
_processing_prefix: 'mzta-spam-processing-',
|
||||
_max_reports: 100,
|
||||
_storage: null,
|
||||
|
||||
_getStorage() {
|
||||
if (!this._storage) this._storage = new taStorage(this.do_debug);
|
||||
return this._storage;
|
||||
},
|
||||
|
||||
async setProcessing(data_id) {
|
||||
const key = this._processing_prefix + data_id;
|
||||
|
|
@ -34,8 +43,7 @@ export const taSpamReport = {
|
|||
},
|
||||
|
||||
async saveReportData(data, data_id) {
|
||||
const key = this._data_prefix + data_id;
|
||||
await browser.storage.session.set({ [key]: data });
|
||||
await this._getStorage().writeSpam(data_id, data, true);
|
||||
await browser.storage.session.remove(this._processing_prefix + data_id);
|
||||
},
|
||||
|
||||
|
|
@ -51,47 +59,53 @@ export const taSpamReport = {
|
|||
},
|
||||
|
||||
async loadReportData(data_id) {
|
||||
const key = this._data_prefix + data_id;
|
||||
let output = await browser.storage.session.get(key);
|
||||
return output[key] || null;
|
||||
let record = await this._getStorage().getRecord(data_id);
|
||||
if (!record || !this._getStorage().hasField(record, 'spam')) return null;
|
||||
let spam = record.spam;
|
||||
return {
|
||||
headerMessageId: data_id,
|
||||
spamValue: spam.spamValue,
|
||||
explanation: spam.explanation,
|
||||
report_date: new Date(spam.ts),
|
||||
subject: spam.subject,
|
||||
from: spam.from,
|
||||
message_date: spam.message_date,
|
||||
moved: spam.moved,
|
||||
SpamThreshold: spam.SpamThreshold,
|
||||
};
|
||||
},
|
||||
|
||||
async removeReportData(data_id) {
|
||||
const key = this._data_prefix + data_id;
|
||||
await browser.storage.session.remove(key);
|
||||
await this._getStorage().deleteSpamField(data_id);
|
||||
await browser.storage.session.remove(this._processing_prefix + data_id);
|
||||
},
|
||||
|
||||
async getAllReportData() {
|
||||
let allData = await browser.storage.session.get(null);
|
||||
let reportData = {};
|
||||
|
||||
for (const [key, value] of Object.entries(allData)) {
|
||||
if (key.startsWith(this._data_prefix)) {
|
||||
reportData[key.replace(this._data_prefix, '')] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return reportData;
|
||||
return await this._getStorage().getAllSpamRecords();
|
||||
},
|
||||
|
||||
async clearReportData() {
|
||||
let allData = await browser.storage.session.get(null);
|
||||
let keysToDelete = Object.keys(allData).filter(key => key.startsWith(this._data_prefix) || key.startsWith(this._processing_prefix));
|
||||
|
||||
let storage = this._getStorage();
|
||||
let allSpam = await storage.getAllSpamRecords();
|
||||
for (let messageId of Object.keys(allSpam)) {
|
||||
await storage.deleteSpamField(messageId);
|
||||
}
|
||||
let allSession = await browser.storage.session.get(null);
|
||||
let keysToDelete = Object.keys(allSession).filter(k => k.startsWith(this._processing_prefix));
|
||||
for (let key of keysToDelete) {
|
||||
await browser.storage.session.remove(key);
|
||||
}
|
||||
},
|
||||
|
||||
async truncReportData() {
|
||||
let data = await this.getAllReportData();
|
||||
let data = await this._getStorage().getAllSpamRecords();
|
||||
let sortedData = this.sortReportsByDate(data);
|
||||
let keys = Object.keys(sortedData);
|
||||
|
||||
if (keys.length > this._max_reports) {
|
||||
let storage = this._getStorage();
|
||||
for (let i = this._max_reports; i < keys.length; i++) {
|
||||
await browser.storage.session.remove(this._data_prefix + keys[i]);
|
||||
await storage.deleteSpamField(keys[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -72,11 +72,11 @@ export class taStorage {
|
|||
/**
|
||||
* Write the spam field for a given Message-ID.
|
||||
* @param {string} messageId - The Message-ID header string.
|
||||
* @param {number} score - Spam score (float 0-1).
|
||||
* @param {string} reason - Textual motivation for the score.
|
||||
* @param {object} report_data - The full spam report object with fields:
|
||||
* spamValue, explanation, subject, from, message_date, moved, SpamThreshold.
|
||||
* @param {boolean} [force=true] - If true, overwrite existing spam data.
|
||||
*/
|
||||
async writeSpam(messageId, score, reason, force = true) {
|
||||
async writeSpam(messageId, report_data, force = true) {
|
||||
try {
|
||||
let key = this._buildKey(messageId);
|
||||
let record = await this.getRecord(messageId) || { v: taStorage.SCHEMA_VERSION };
|
||||
|
|
@ -84,7 +84,18 @@ export class taStorage {
|
|||
return;
|
||||
}
|
||||
let now = Date.now();
|
||||
record.spam = { score: score, reason: reason, ts: now };
|
||||
record.spam = {
|
||||
spamValue: report_data.spamValue,
|
||||
explanation: report_data.explanation,
|
||||
subject: report_data.subject,
|
||||
from: report_data.from,
|
||||
message_date: report_data.message_date instanceof Date
|
||||
? report_data.message_date.toISOString()
|
||||
: report_data.message_date,
|
||||
moved: report_data.moved,
|
||||
SpamThreshold: report_data.SpamThreshold,
|
||||
ts: now,
|
||||
};
|
||||
record.ts = now;
|
||||
await messenger.storage.local.set({ [key]: record });
|
||||
} catch (e) {
|
||||
|
|
@ -92,6 +103,60 @@ export class taStorage {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all records that contain a spam field.
|
||||
* @returns {Promise<object>} Map of messageId -> spam data object (legacy shape).
|
||||
*/
|
||||
async getAllSpamRecords() {
|
||||
try {
|
||||
let all = await messenger.storage.local.get(null);
|
||||
let result = {};
|
||||
for (let [key, record] of Object.entries(all)) {
|
||||
if (!key.startsWith(taStorage.STORAGE_KEY_PREFIX)) continue;
|
||||
if (!this.hasField(record, 'spam')) continue;
|
||||
let messageId = key.slice(taStorage.STORAGE_KEY_PREFIX.length);
|
||||
let spam = record.spam;
|
||||
result[messageId] = {
|
||||
headerMessageId: messageId,
|
||||
spamValue: spam.spamValue,
|
||||
explanation: spam.explanation,
|
||||
report_date: new Date(spam.ts),
|
||||
subject: spam.subject,
|
||||
from: spam.from,
|
||||
message_date: spam.message_date,
|
||||
moved: spam.moved,
|
||||
SpamThreshold: spam.SpamThreshold,
|
||||
};
|
||||
}
|
||||
return result;
|
||||
} catch (e) {
|
||||
this.taLog.error('getAllSpamRecords error: ' + e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete only the spam field from a record.
|
||||
* Deletes the entire record if no other data fields remain.
|
||||
* @param {string} messageId - The Message-ID header string.
|
||||
*/
|
||||
async deleteSpamField(messageId) {
|
||||
try {
|
||||
let key = this._buildKey(messageId);
|
||||
let record = await this.getRecord(messageId);
|
||||
if (!record || !('spam' in record)) return;
|
||||
delete record.spam;
|
||||
const remainingFields = Object.keys(record).filter(k => k !== 'v' && k !== 'ts');
|
||||
if (remainingFields.length === 0) {
|
||||
await messenger.storage.local.remove(key);
|
||||
} else {
|
||||
await messenger.storage.local.set({ [key]: record });
|
||||
}
|
||||
} catch (e) {
|
||||
this.taLog.error('deleteSpamField error: ' + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the summary field for a given Message-ID.
|
||||
* @param {string} messageId - The Message-ID header string.
|
||||
|
|
|
|||
|
|
@ -1043,6 +1043,7 @@ const newEmailListener = (folder, messagesList) => {
|
|||
let messages = getMessages(messagesList);
|
||||
|
||||
taSpamReport.logger = taLog;
|
||||
taSpamReport.do_debug = prefs_init.do_debug;
|
||||
|
||||
let add_tags_auto_enabled = prefs_init.add_tags && prefs_init.add_tags_auto;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue