mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Added: Show spam score in % in message detailed info
Currently only for SpamAssassin and Rspamd
This commit is contained in:
parent
8ef00edb86
commit
168ee911b3
14 changed files with 84 additions and 73 deletions
|
|
@ -45,6 +45,8 @@ export class MessageModel extends AbstractModel {
|
||||||
this.addObservables({
|
this.addObservables({
|
||||||
subject: '',
|
subject: '',
|
||||||
size: 0,
|
size: 0,
|
||||||
|
spamScore: 0,
|
||||||
|
isSpam: false,
|
||||||
dateTimeStampInUTC: 0,
|
dateTimeStampInUTC: 0,
|
||||||
priority: MessagePriority.Normal,
|
priority: MessagePriority.Normal,
|
||||||
|
|
||||||
|
|
@ -116,6 +118,8 @@ export class MessageModel extends AbstractModel {
|
||||||
this._reset();
|
this._reset();
|
||||||
this.subject('');
|
this.subject('');
|
||||||
this.size(0);
|
this.size(0);
|
||||||
|
this.spamScore(0);
|
||||||
|
this.isSpam(false);
|
||||||
this.dateTimeStampInUTC(0);
|
this.dateTimeStampInUTC(0);
|
||||||
this.priority(MessagePriority.Normal);
|
this.priority(MessagePriority.Normal);
|
||||||
|
|
||||||
|
|
@ -414,6 +418,8 @@ export class MessageModel extends AbstractModel {
|
||||||
this.subject(message.subject());
|
this.subject(message.subject());
|
||||||
|
|
||||||
this.size(message.size());
|
this.size(message.size());
|
||||||
|
this.spamScore(message.spamScore());
|
||||||
|
this.isSpam(message.isSpam());
|
||||||
this.dateTimeStampInUTC(message.dateTimeStampInUTC());
|
this.dateTimeStampInUTC(message.dateTimeStampInUTC());
|
||||||
this.priority(message.priority());
|
this.priority(message.priority());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,8 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
||||||
viewReplyTo: '',
|
viewReplyTo: '',
|
||||||
viewTimeStamp: 0,
|
viewTimeStamp: 0,
|
||||||
viewSize: '',
|
viewSize: '',
|
||||||
|
viewSpamScore: 0,
|
||||||
|
viewSpamStatus: '',
|
||||||
viewLineAsCss: '',
|
viewLineAsCss: '',
|
||||||
viewViewLink: '',
|
viewViewLink: '',
|
||||||
viewUnsubscribeLink: '',
|
viewUnsubscribeLink: '',
|
||||||
|
|
@ -224,6 +226,8 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
|
||||||
this.viewReplyTo(message.replyToToLine());
|
this.viewReplyTo(message.replyToToLine());
|
||||||
this.viewTimeStamp(message.dateTimeStampInUTC());
|
this.viewTimeStamp(message.dateTimeStampInUTC());
|
||||||
this.viewSize(message.friendlySize());
|
this.viewSize(message.friendlySize());
|
||||||
|
this.viewSpamScore(message.spamScore());
|
||||||
|
this.viewSpamStatus(i18n(message.isSpam() ? 'GLOBAL/SPAM' : 'GLOBAL/NOT_SPAM'));
|
||||||
this.viewLineAsCss(message.lineAsCss());
|
this.viewLineAsCss(message.lineAsCss());
|
||||||
this.viewViewLink(message.viewLink());
|
this.viewViewLink(message.viewLink());
|
||||||
this.viewUnsubscribeLink(message.getFirstUnsubsribeLink());
|
this.viewUnsubscribeLink(message.getFirstUnsubsribeLink());
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,9 @@ class MailClient
|
||||||
\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
|
\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
|
||||||
\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS,
|
\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS,
|
||||||
\MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE,
|
\MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE,
|
||||||
|
// SPAM
|
||||||
|
\MailSo\Mime\Enumerations\Header::X_SPAM_STATUS,
|
||||||
|
\MailSo\Mime\Enumerations\Header::X_SPAMD_RESULT,
|
||||||
), true);
|
), true);
|
||||||
//
|
//
|
||||||
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
|
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
|
||||||
|
|
|
||||||
|
|
@ -17,60 +17,20 @@ namespace MailSo\Mail;
|
||||||
*/
|
*/
|
||||||
class Message implements \JsonSerializable
|
class Message implements \JsonSerializable
|
||||||
{
|
{
|
||||||
/**
|
private
|
||||||
* @var string
|
$sFolder = '',
|
||||||
*/
|
$iUid = 0,
|
||||||
private $sFolder;
|
$sSubject = '',
|
||||||
|
$sMessageId = '',
|
||||||
/**
|
$sContentType = '',
|
||||||
* @var int
|
$iSize = 0,
|
||||||
*/
|
$iSpamScore = 0,
|
||||||
private $iUid;
|
$bIsSpam = false,
|
||||||
|
$iInternalTimeStampInUTC = 0,
|
||||||
/**
|
$iHeaderTimeStampInUTC = 0,
|
||||||
* @var string
|
$sHeaderDate = '',
|
||||||
*/
|
$aFlags = [],
|
||||||
private $sSubject;
|
$aFlagsLowerCase = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $sMessageId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $sContentType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $iSize;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $iInternalTimeStampInUTC;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $iHeaderTimeStampInUTC;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $sHeaderDate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $aFlags;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $aFlagsLowerCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \MailSo\Mime\EmailCollection
|
* @var \MailSo\Mime\EmailCollection
|
||||||
|
|
@ -189,23 +149,6 @@ class Message implements \JsonSerializable
|
||||||
|
|
||||||
function __construct()
|
function __construct()
|
||||||
{
|
{
|
||||||
$this->Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function Clear() : self
|
|
||||||
{
|
|
||||||
$this->sFolder = '';
|
|
||||||
$this->iUid = 0;
|
|
||||||
$this->sSubject = '';
|
|
||||||
$this->sMessageId = '';
|
|
||||||
$this->sContentType = '';
|
|
||||||
$this->iSize = 0;
|
|
||||||
$this->iInternalTimeStampInUTC = 0;
|
|
||||||
$this->iHeaderTimeStampInUTC = 0;
|
|
||||||
$this->sHeaderDate = '';
|
|
||||||
$this->aFlags = array();
|
|
||||||
$this->aFlagsLowerCase = array();
|
|
||||||
|
|
||||||
$this->oFrom = null;
|
$this->oFrom = null;
|
||||||
$this->oSender = null;
|
$this->oSender = null;
|
||||||
$this->oReplyTo = null;
|
$this->oReplyTo = null;
|
||||||
|
|
@ -300,6 +243,16 @@ class Message implements \JsonSerializable
|
||||||
return $this->iSize;
|
return $this->iSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function SpamScore() : int
|
||||||
|
{
|
||||||
|
return $this->iSpamScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function IsSpam() : bool
|
||||||
|
{
|
||||||
|
return $this->bIsSpam;
|
||||||
|
}
|
||||||
|
|
||||||
public function InternalTimeStampInUTC() : int
|
public function InternalTimeStampInUTC() : int
|
||||||
{
|
{
|
||||||
return $this->iInternalTimeStampInUTC;
|
return $this->iInternalTimeStampInUTC;
|
||||||
|
|
@ -573,6 +526,24 @@ class Message implements \JsonSerializable
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$spam = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_SPAMD_RESULT);
|
||||||
|
if (\preg_match('/\\[([\\d\\.-]+)\\s*\\/\\s*([\\d\\.]+)\\];/', $spam, $match)) {
|
||||||
|
if ($threshold = \floatval($match[2])) {
|
||||||
|
$this->iSpamScore = \max(0, \min(100, 100 * \floatval($match[1]) / $threshold));
|
||||||
|
}
|
||||||
|
$this->bIsSpam = false !== \stripos($this->sSubject, '*** SPAM ***');
|
||||||
|
} else {
|
||||||
|
$spam = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_SPAM_STATUS);
|
||||||
|
if (\preg_match('/(?:hits|score)=([\\d\\.-]+)/', $spam, $value)
|
||||||
|
&& \preg_match('/required=([\\d\\.-]+)/', $spam, $threshold)) {
|
||||||
|
if ($threshold = \floatval($threshold[1])) {
|
||||||
|
$this->iSpamScore = \max(0, \min(100, 100 * \floatval($value[1]) / $threshold));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$spam = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_SPAM_FLAG);
|
||||||
|
$this->bIsSpam = false !== \stripos($spam, 'YES');
|
||||||
|
}
|
||||||
|
|
||||||
$sDraftInfo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO);
|
$sDraftInfo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO);
|
||||||
if (0 < \strlen($sDraftInfo)) {
|
if (0 < \strlen($sDraftInfo)) {
|
||||||
$sType = '';
|
$sType = '';
|
||||||
|
|
@ -751,6 +722,8 @@ class Message implements \JsonSerializable
|
||||||
'Subject' => \trim(\MailSo\Base\Utils::Utf8Clear($this->Subject())),
|
'Subject' => \trim(\MailSo\Base\Utils::Utf8Clear($this->Subject())),
|
||||||
'MessageId' => $this->MessageId(),
|
'MessageId' => $this->MessageId(),
|
||||||
'Size' => $this->Size(),
|
'Size' => $this->Size(),
|
||||||
|
'SpamScore' => $this->SpamScore(),
|
||||||
|
'IsSpam' => $this->IsSpam(),
|
||||||
'DateTimeStampInUTC' => $this->InternalTimeStampInUTC(),
|
'DateTimeStampInUTC' => $this->InternalTimeStampInUTC(),
|
||||||
|
|
||||||
// \MailSo\Mime\EmailCollection
|
// \MailSo\Mime\EmailCollection
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,20 @@ abstract class Header
|
||||||
const DKIM_SIGNATURE = 'DKIM-Signature';
|
const DKIM_SIGNATURE = 'DKIM-Signature';
|
||||||
const DOMAINKEY_SIGNATURE = 'DomainKey-Signature';
|
const DOMAINKEY_SIGNATURE = 'DomainKey-Signature';
|
||||||
|
|
||||||
const X_SPAM_STATUS = 'X-Spam-Status';
|
// SpamAssassin
|
||||||
|
const X_SPAM_FLAG = 'X-Spam-Flag'; // YES/NO
|
||||||
|
const X_SPAM_LEVEL = 'X-Spam-Level'; // *******
|
||||||
|
const X_SPAM_STATUS = 'X-Spam-Status'; // Yes|No
|
||||||
|
// Rspamd
|
||||||
|
const X_SPAMD_RESULT = 'X-Spamd-Result'; // default: False [7.13 / 9.00];
|
||||||
|
const X_SPAMD_BAR = 'X-Spamd-Bar'; // +++++++
|
||||||
|
// Unknown
|
||||||
|
const X_SPAM_CATEGORY = 'X-Spam-Category'; // SPAM|LEGIT
|
||||||
|
const X_SPAM_SCORE = 'X-Spam-Score'; // 0
|
||||||
|
const X_HAM_REPORT = 'X-Ham-Report';
|
||||||
|
const X_MICROSOFT_ANTISPAM = 'x-microsoft-antispam:';
|
||||||
|
|
||||||
|
const X_VIRUS = 'X-Virus';
|
||||||
|
|
||||||
const RETURN_RECEIPT_TO = 'Return-Receipt-To';
|
const RETURN_RECEIPT_TO = 'Return-Receipt-To';
|
||||||
const DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To';
|
const DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To';
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ en:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
|
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
|
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
|
||||||
|
SPAM_SCORE: "Spam Score"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
|
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ de_DE:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "OpenPGP-signierte Nachricht (klicken, um zu überprüfen)"
|
PGP_SIGNED_MESSAGE_DESC: "OpenPGP-signierte Nachricht (klicken, um zu überprüfen)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP-verschlüsselte Nachricht (klicken, um zu entschlüsseln)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP-verschlüsselte Nachricht (klicken, um zu entschlüsseln)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Als ZIP-Datei herunterladen"
|
LINK_DOWNLOAD_AS_ZIP: "Als ZIP-Datei herunterladen"
|
||||||
|
SPAM_SCORE: "Spam-Score"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Empfangsbestätigung (angezeigt) - %SUBJECT%"
|
SUBJECT: "Empfangsbestätigung (angezeigt) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ en_GB:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
|
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
|
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
|
||||||
|
SPAM_SCORE: "Spam Score"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
|
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ en_US:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
|
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
|
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
|
||||||
|
SPAM_SCORE: "Spam Score"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
|
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ es_ES:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "Mensaje firmado mediante OpenPGP (click para verificar)"
|
PGP_SIGNED_MESSAGE_DESC: "Mensaje firmado mediante OpenPGP (click para verificar)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "Mensaje cifrado mediante OpenPGP (click para desencriptar)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "Mensaje cifrado mediante OpenPGP (click para desencriptar)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Descargar todo (archivo ZIP)"
|
LINK_DOWNLOAD_AS_ZIP: "Descargar todo (archivo ZIP)"
|
||||||
|
SPAM_SCORE: "Puntuación de spam"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Acuse de recibo (se visualiza) - %SUBJECT%"
|
SUBJECT: "Acuse de recibo (se visualiza) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ fr_FR:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "Message signé par OpenPGP (cliquer pour vérifier)"
|
PGP_SIGNED_MESSAGE_DESC: "Message signé par OpenPGP (cliquer pour vérifier)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "Message chiffré par OpenPGP (cliquer pour déchiffrer)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "Message chiffré par OpenPGP (cliquer pour déchiffrer)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Télécharger le zip"
|
LINK_DOWNLOAD_AS_ZIP: "Télécharger le zip"
|
||||||
|
SPAM_SCORE: "Score de spam"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Accusé de réception (affiché) - %SUBJECT%"
|
SUBJECT: "Accusé de réception (affiché) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ nl_NL:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "OpenPGP ondertekend bericht (klik om te verifiëren)"
|
PGP_SIGNED_MESSAGE_DESC: "OpenPGP ondertekend bericht (klik om te verifiëren)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP versleuteld bericht (klik om te ontsleutelen)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP versleuteld bericht (klik om te ontsleutelen)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "Download als zip"
|
LINK_DOWNLOAD_AS_ZIP: "Download als zip"
|
||||||
|
SPAM_SCORE: "Spamscore"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "Ontvangstbevestiging (weergegeven) - %SUBJECT%"
|
SUBJECT: "Ontvangstbevestiging (weergegeven) - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ zh_CN:
|
||||||
PGP_SIGNED_MESSAGE_DESC: "由 OpenPGP 签名 (点击验证)"
|
PGP_SIGNED_MESSAGE_DESC: "由 OpenPGP 签名 (点击验证)"
|
||||||
PGP_ENCRYPTED_MESSAGE_DESC: "由 OpenPGP 加密 (点击解密)"
|
PGP_ENCRYPTED_MESSAGE_DESC: "由 OpenPGP 加密 (点击解密)"
|
||||||
LINK_DOWNLOAD_AS_ZIP: "下载为zip压缩包"
|
LINK_DOWNLOAD_AS_ZIP: "下载为zip压缩包"
|
||||||
|
SPAM_SCORE: "垃圾邮件分数"
|
||||||
READ_RECEIPT:
|
READ_RECEIPT:
|
||||||
SUBJECT: "送达回执 - %SUBJECT%"
|
SUBJECT: "送达回执 - %SUBJECT%"
|
||||||
BODY: |
|
BODY: |
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,10 @@
|
||||||
(<time data-moment-format="FROMNOW" data-bind="moment: viewTimeStamp"></time>)
|
(<time data-moment-format="FROMNOW" data-bind="moment: viewTimeStamp"></time>)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr data-bind="visible: 0 < viewSpamScore()">
|
||||||
|
<td data-i18n="MESSAGE/SPAM_SCORE"></td>
|
||||||
|
<td><span data-bind="text: viewSpamScore, title: viewSpamStatus"></span>%</td>
|
||||||
|
</tr>
|
||||||
<tr data-bind="visible: '' !== viewFrom()">
|
<tr data-bind="visible: '' !== viewFrom()">
|
||||||
<td data-i18n="POPUPS_FILTER/SELECT_FIELD_SIZE"></td>
|
<td data-i18n="POPUPS_FILTER/SELECT_FIELD_SIZE"></td>
|
||||||
<td class="size" data-bind="text: viewSize"></td>
|
<td class="size" data-bind="text: viewSize"></td>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue