Merge pull request #358 from micz/account_selector_auto_feature

Accounts selector auto feature
This commit is contained in:
Mic 2025-04-22 19:29:58 +02:00 committed by GitHub
commit 945598d5fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 237 additions and 27 deletions

View file

@ -1123,6 +1123,10 @@
"message": "If checked, the AI will automatically add tags to newly received emails.",
"description": ""
},
"prefs_OptionText_add_tags_auto_Info2": {
"message": "Choose which account to activate this feature for at the bottom of this page.",
"description": ""
},
"prefs_OptionText_add_tags_auto_force_existing": {
"message": "Force existing tags when autotagging",
"description": ""
@ -1350,5 +1354,17 @@
"ask_chatgptweb_permission_ok": {
"message": "Permission granted. You can click here to close this tab and return to the main window.",
"description": ""
},
"AccountSelector_AutoTags": {
"message": "Choose the accounts where auto-tagging is enabled",
"description": ""
},
"AccountSelector_AutoTags_infoline": {
"message": "Each change is saved immediately.",
"description": ""
},
"AccountSelector_Spamfilter": {
"message": "Choose the accounts where the spam filter is enabled",
"description": ""
}
}

View file

@ -43,6 +43,17 @@ function fixMsgHeader(msgHeader) {
return msgHeader;
}
export async function getAccountsList() {
let accounts = await browser.accounts.list();
let accounts_array = [];
for (let account of accounts) {
let account_id = account.id;
let account_name = account.name;
accounts_array.push({id: account_id, name: account_name});
}
return accounts_array;
}
export async function getCurrentIdentity(msgHeader, getFull = false) {
let identities_array = [];
let fallback_identity = '';

View file

@ -845,6 +845,9 @@ const newEmailListener = (folder, messagesList) => {
async function processEmails(messages, addTagsAuto, spamFilter) {
taWorkingStatus.startWorking();
let prefs_aats = await browser.storage.sync.get({ add_tags_maxnum: prefs_default.add_tags_maxnum, connection_type: prefs_default.connection_type, add_tags_force_lang: prefs_default.add_tags_force_lang, default_chatgpt_lang: prefs_default.default_chatgpt_lang, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing, add_tags_enabled_accounts: prefs_default.add_tags_enabled_accounts, spamfilter_enabled_accounts: prefs_default.spamfilter_enabled_accounts });
for await (let message of messages) {
let curr_fullMessage = null;
let msg_text = null;
@ -857,12 +860,18 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
}
if (addTagsAuto) {
if(prefs_aats.add_tags_enabled_accounts.length > 0){
let accountId = message.folder.accountId;
if(!prefs_aats.add_tags_enabled_accounts.includes(accountId)){
taLog.log("Account " + accountId + " not enabled for add_tags, skipping...");
continue;
}
}
let specialFullPrompt_add_tags = '';
let curr_prompt_add_tags = menus.allPrompts.find(p => p.id === 'prompt_add_tags');
let tags_full_list = await getTagsList();
let chatgpt_lang = await taPromptUtils.getDefaultLang(curr_prompt_add_tags);
specialFullPrompt_add_tags = await taPromptUtils.preparePrompt(curr_prompt_add_tags, message, chatgpt_lang, '', body_text, curr_fullMessage.headers.subject, msg_text, '', tags_full_list);
let prefs_aat = await browser.storage.sync.get({ add_tags_maxnum: prefs_default.add_tags_maxnum, connection_type: prefs_default.connection_type, add_tags_force_lang: prefs_default.add_tags_force_lang, default_chatgpt_lang: prefs_default.default_chatgpt_lang, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing });
specialFullPrompt_add_tags = taPromptUtils.finalizePrompt_add_tags(specialFullPrompt_add_tags, prefs_aat.add_tags_maxnum, prefs_aat.add_tags_force_lang, prefs_aat.default_chatgpt_lang);
taLog.log("Special prompt: " + specialFullPrompt_add_tags);
let cmd_addTags = new mzta_specialCommand(specialFullPrompt_add_tags, prefs_aat.connection_type, prefs_init.do_debug);
@ -879,6 +888,13 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
}
if (spamFilter) {
if(prefs_aats.spamfilter_enabled_accounts.length > 0){
let accountId = message.folder.accountId;
if(!prefs_aats.spamfilter_enabled_accounts.includes(accountId)){
taLog.log("Account " + accountId + " not enabled for spamfilter, skipping...");
continue;
}
}
let curr_prompt_spamfilter = await getSpamFilterPrompt();
let chatgpt_lang = await taPromptUtils.getDefaultLang(curr_prompt_spamfilter);
let specialFullPrompt_spamfilter = await taPromptUtils.preparePrompt(curr_prompt_spamfilter, message, chatgpt_lang, '', body_text, curr_fullMessage.headers.subject, msg_text, '', '');

View file

@ -51,6 +51,7 @@ export const prefs_default = {
add_tags_auto_force_existing: false,
add_tags_auto_only_inbox: true,
add_tags_context_menu: true,
add_tags_enabled_accounts: [],
get_calendar_event: true,
get_task: true,
calendar_enforce_timezone: false,
@ -58,4 +59,5 @@ export const prefs_default = {
spamfilter: false,
spamfilter_threshold: 70,
spamfilter_context_menu: true,
spamfilter_enabled_accounts: [],
}

View file

@ -12,7 +12,7 @@
font-style: italic;
}
#addtags_excl_list_container{
#addtags_excl_list_container, #account_selector_container{
width: 90%;
margin: 40px auto;
}
@ -21,6 +21,22 @@
width: 30em;
}
#account_selector_container{
display: none;
}
#account_selector_checkboxes{
padding: 10px;
border: 1px solid gray;
width: 24em;
margin-bottom: 10px;
margin-top: 10px;
}
.add_tags_auto{
background-color: #e9ffdf;
}
.btn_div{
width: 100%;
display: flex;
@ -129,4 +145,8 @@ table#miczPrefs tr:last-child td {
.autocomplete-list li.active {
background-color: #4c4e58;
}
.add_tags_auto{
background-color: #415c35;
}
}

View file

@ -49,8 +49,9 @@
</label>
</td>
</tr>
<tr class="add_tags_tr">
<td><span>__MSG_prefs_OptionText_add_tags_auto__</span></td>
<tr class="add_tags_tr add_tags_auto">
<td><span>__MSG_prefs_OptionText_add_tags_auto__</span>
<span class="infoline" id="add_tags_auto_infoline"><br>__MSG_prefs_OptionText_add_tags_auto_Info2__</span></td>
<td>
<label>
<input type="checkbox" id="add_tags_auto" name="add_tags_auto" class="option-input" />
@ -58,7 +59,7 @@
</label>
</td>
</tr>
<tr class="add_tags_tr" id="add_tags_auto_force_existing_tr">
<tr class="add_tags_tr add_tags_auto" id="add_tags_auto_force_existing_tr">
<td><span>__MSG_prefs_OptionText_add_tags_auto_force_existing__</span></td>
<td>
<label>
@ -67,7 +68,7 @@
</label>
</td>
</tr>
<tr class="add_tags_tr" id="add_tags_auto_only_inbox_tr">
<tr class="add_tags_tr add_tags_auto" id="add_tags_auto_only_inbox_tr">
<td><span>__MSG_prefs_OptionText_add_tags_auto_only_inbox__</span></td>
<td>
<label>
@ -106,6 +107,13 @@
<br><textarea id="addtags_excl_list" rows="15"></textarea>
<div class="btn_div"><button id="btn_save_excl_list" disabled>__MSG_save__</button></div>
</div>
<div id="account_selector_container">
<div id="account_selector_info"><span class="section_title">__MSG_AccountSelector_AutoTags__</span>
<br><span class="infoline">__MSG_AccountSelector_AutoTags_infoline__</span></div>
<div id="account_selector_checkboxes"></div>
<button type="button" id="accounts_select_all">Select All</button>
<button type="button" id="accounts_deselect_all">Deselect All</button>
</div>
<script src="mzta-add-tags.js" type="module"></script>
<script src="../../js/mzta-i18n.js"></script>
</body>

View file

@ -22,7 +22,7 @@ import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
import { getPlaceholders } from "../../js/mzta-placeholders.js";
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
import { addTags_getExclusionList, addTags_setExclusionList } from "../../js/mzta-addatags-exclusion-list.js";
import { getAccountsList } from "../../js/mzta-utils.js";
let autocompleteSuggestions = [];
let taLog = new taLogger("mzta-addtags-page",true);
@ -56,12 +56,18 @@ document.addEventListener('DOMContentLoaded', async () => {
let add_tags_auto_el = document.getElementById('add_tags_auto');
let add_tags_auto_force_existing_tr = document.getElementById('add_tags_auto_force_existing_tr');
let add_tags_auto_only_inbox_tr = document.getElementById('add_tags_auto_only_inbox_tr');
let account_selector_container = document.getElementById('account_selector_container');
let add_tags_auto_infoline = document.getElementById('add_tags_auto_infoline');
add_tags_auto_el.addEventListener('click', (event) => {
add_tags_auto_force_existing_tr.style.display = event.target.checked ? 'table-row' : 'none';
add_tags_auto_only_inbox_tr.style.display = event.target.checked ? 'table-row' : 'none';
account_selector_container.style.display = event.target.checked ? 'block' : 'none';
add_tags_auto_infoline.style.display = event.target.checked ? 'inline' : 'none';
});
add_tags_auto_force_existing_tr.style.display = add_tags_auto_el.checked ? 'table-row' : 'none';
add_tags_auto_only_inbox_tr.style.display = add_tags_auto_el.checked ? 'table-row' : 'none';
account_selector_container.style.display = add_tags_auto_el.checked ? 'block' : 'none';
add_tags_auto_infoline.style.display = add_tags_auto_el.checked ? 'inline' : 'none';
addtags_reset_btn.addEventListener('click', () => {
addtags_textarea.value = browser.i18n.getMessage('prompt_add_tags_full_text');
@ -118,6 +124,60 @@ document.addEventListener('DOMContentLoaded', async () => {
document.getElementById('excl_list_unsaved').classList.add('hidden');
});
//Accounts manager
let accounts = await getAccountsList();
const accountsContainer = document.getElementById('account_selector_checkboxes');
accounts.forEach(account => {
const accountLabel = document.createElement('label');
const accountCheckbox = document.createElement('input');
accountCheckbox.type = 'checkbox';
accountCheckbox.classList.add('accountCheckbox');
accountCheckbox.value = account.id;
accountLabel.appendChild(accountCheckbox);
accountLabel.appendChild(document.createTextNode(account.name));
accountsContainer.appendChild(accountLabel);
accountsContainer.appendChild(document.createElement('br'));
});
let prefs_add_tags = await browser.storage.sync.get({ add_tags_enabled_accounts: [] });
let add_tags_enabled_accounts = prefs_add_tags.add_tags_enabled_accounts;
taLog.log("add_tags_enabled_accounts = " + JSON.stringify(add_tags_enabled_accounts) + ".");
document.querySelectorAll('.accountCheckbox').forEach(checkbox => {
if (add_tags_enabled_accounts.length === 0 || add_tags_enabled_accounts.includes(checkbox.value)) {
checkbox.checked = true;
} else {
checkbox.checked = false;
}
});
document.querySelectorAll('.accountCheckbox').forEach(checkbox => {
checkbox.addEventListener('change', () => {
let selectedAccounts = Array.from(document.querySelectorAll('.accountCheckbox:checked')).map(checkbox => checkbox.value);
if (selectedAccounts.length === 0) {
checkbox.checked = true; // Prevent deselecting the last selected checkbox
taLog.log("At least one account must be selected.");
return;
}
if (selectedAccounts.length === document.querySelectorAll('.accountCheckbox').length) {
browser.storage.sync.set({ add_tags_enabled_accounts: [] });
taLog.log("All accounts selected, saving add_tags_enabled_accounts = [].");
} else {
browser.storage.sync.set({ add_tags_enabled_accounts: selectedAccounts });
taLog.log("Saving add_tags_enabled_accounts = " + JSON.stringify(selectedAccounts) + ".");
}
});
});
document.getElementById('accounts_select_all').addEventListener('click', () => {
let checkboxes = document.querySelectorAll('.accountCheckbox');
checkboxes.forEach(checkbox => checkbox.checked = true);
});
document.getElementById('accounts_deselect_all').addEventListener('click', () => {
let checkboxes = document.querySelectorAll('.accountCheckbox');
checkboxes.forEach(checkbox => checkbox.checked = false);
});
});

View file

@ -1,4 +1,4 @@
#spamfilter_prompt_container{
#spamfilter_container, #account_selector_container, #spamfitler_reports_container{
width: 90%;
margin: 20px auto;
}
@ -7,6 +7,19 @@
width: 100%;
}
#account_selector_container{
margin-top: 40px;
margin-bottom: 40px;
}
#account_selector_checkboxes{
padding: 10px;
border: 1px solid gray;
width: 24em;
margin-bottom: 10px;
margin-top: 10px;
}
.infoline{
font-size: 0.8em;
font-style: italic;

View file

@ -44,24 +44,33 @@
<div id="spamfilter_info_additional_statements"></div>
<div class="btn_div"><button id="btn_reset_prompt" disabled>__MSG_reset_default__</button><button id="btn_save_prompt" disabled>__MSG_save__</button></div>
</div>
<h2>__MSG_SpamReport_Title__</h2>
<table id="report_data">
<thead>
<tr>
<th>Message_ID</th>
<th>__MSG_Date__</th>
<th>__MSG_From__</th>
<th>__MSG_Subject__</th>
<th>__MSG_Spam_Value__</th>
<th>__MSG_Moved_to_Spam__</th>
<th>__MSG_Explanation__</th>
<th>__MSG_Report_Date__</th>
</tr>
</thead>
<tbody id="report_data_body">
<!-- Rows will be inserted dynamically -->
</tbody>
</table>
<div id="account_selector_container">
<div id="account_selector_info"><span class="section_title">__MSG_AccountSelector_Spamfilter__</span>
<br><span class="infoline">__MSG_AccountSelector_AutoTags_infoline__</span></div>
<div id="account_selector_checkboxes"></div>
<button type="button" id="accounts_select_all">Select All</button>
<button type="button" id="accounts_deselect_all">Deselect All</button>
</div>
<div id="spamfitler_reports_container">
<h2>__MSG_SpamReport_Title__</h2>
<table id="report_data">
<thead>
<tr>
<th>Message_ID</th>
<th>__MSG_Date__</th>
<th>__MSG_From__</th>
<th>__MSG_Subject__</th>
<th>__MSG_Spam_Value__</th>
<th>__MSG_Moved_to_Spam__</th>
<th>__MSG_Explanation__</th>
<th>__MSG_Report_Date__</th>
</tr>
</thead>
<tbody id="report_data_body">
<!-- Rows will be inserted dynamically -->
</tbody>
</table>
</div>
<script src="mzta-spamfilter.js" type="module"></script>
<script src="../../js/mzta-i18n.js"></script>
</body>

View file

@ -22,6 +22,7 @@ import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
import { getPlaceholders } from "../../js/mzta-placeholders.js";
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
import { taSpamReport } from '../../js/mzta-spamreport.js';
import { getAccountsList } from "../../js/mzta-utils.js";
let autocompleteSuggestions = [];
let taLog = new taLogger("mzta-spamfilter-page",true);
@ -80,7 +81,61 @@ document.addEventListener('DOMContentLoaded', async () => {
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
textareaAutocomplete(spamfilter_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
loadSpamReport()
//Accounts manager
let accounts = await getAccountsList();
const accountsContainer = document.getElementById('account_selector_checkboxes');
accounts.forEach(account => {
const accountLabel = document.createElement('label');
const accountCheckbox = document.createElement('input');
accountCheckbox.type = 'checkbox';
accountCheckbox.classList.add('accountCheckbox');
accountCheckbox.value = account.id;
accountLabel.appendChild(accountCheckbox);
accountLabel.appendChild(document.createTextNode(account.name));
accountsContainer.appendChild(accountLabel);
accountsContainer.appendChild(document.createElement('br'));
});
let prefs_spamfilter = await browser.storage.sync.get({ spamfilter_enabled_accounts: [] });
let spamfilter_enabled_accounts = prefs_spamfilter.spamfilter_enabled_accounts;
taLog.log("spamfilter_enabled_accounts: " + JSON.stringify(spamfilter_enabled_accounts));
document.querySelectorAll('.accountCheckbox').forEach(checkbox => {
if (spamfilter_enabled_accounts.length === 0 || spamfilter_enabled_accounts.includes(checkbox.value)) {
checkbox.checked = true;
} else {
checkbox.checked = false;
}
});
document.querySelectorAll('.accountCheckbox').forEach(checkbox => {
checkbox.addEventListener('change', () => {
let selectedAccounts = Array.from(document.querySelectorAll('.accountCheckbox:checked')).map(checkbox => checkbox.value);
if (selectedAccounts.length === 0) {
checkbox.checked = true; // Prevent deselecting the last selected checkbox
taLog.log("At least one account must be selected.");
return;
}
if (selectedAccounts.length === document.querySelectorAll('.accountCheckbox').length) {
browser.storage.sync.set({ spamfilter_enabled_accounts: [] });
taSpamReport.logger.log("All accounts selected, saving spamfilter_enabled_accounts = [].");
} else {
browser.storage.sync.set({ spamfilter_enabled_accounts: selectedAccounts });
taSpamReport.logger.log("Saving spamfilter_enabled_accounts = " + JSON.stringify(selectedAccounts) + ".");
}
});
});
document.getElementById('accounts_select_all').addEventListener('click', () => {
let checkboxes = document.querySelectorAll('.accountCheckbox');
checkboxes.forEach(checkbox => checkbox.checked = true);
});
document.getElementById('accounts_deselect_all').addEventListener('click', () => {
let checkboxes = document.querySelectorAll('.accountCheckbox');
checkboxes.forEach(checkbox => checkbox.checked = false);
});
loadSpamReport();
});
function check_spamfilter_threshold(event) {