Skip to content

Commit

Permalink
Added: Show spam score in % in message detailed info
Browse files Browse the repository at this point in the history
Currently only for SpamAssassin and Rspamd
  • Loading branch information
djmaze committed Apr 8, 2021
1 parent 8ef00ed commit 168ee91
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 73 deletions.
6 changes: 6 additions & 0 deletions dev/Model/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ export class MessageModel extends AbstractModel {
this.addObservables({
subject: '',
size: 0,
spamScore: 0,
isSpam: false,
dateTimeStampInUTC: 0,
priority: MessagePriority.Normal,

Expand Down Expand Up @@ -116,6 +118,8 @@ export class MessageModel extends AbstractModel {
this._reset();
this.subject('');
this.size(0);
this.spamScore(0);
this.isSpam(false);
this.dateTimeStampInUTC(0);
this.priority(MessagePriority.Normal);

Expand Down Expand Up @@ -414,6 +418,8 @@ export class MessageModel extends AbstractModel {
this.subject(message.subject());

this.size(message.size());
this.spamScore(message.spamScore());
this.isSpam(message.isSpam());
this.dateTimeStampInUTC(message.dateTimeStampInUTC());
this.priority(message.priority());

Expand Down
4 changes: 4 additions & 0 deletions dev/View/User/MailBox/MessageView.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
viewReplyTo: '',
viewTimeStamp: 0,
viewSize: '',
viewSpamScore: 0,
viewSpamStatus: '',
viewLineAsCss: '',
viewViewLink: '',
viewUnsubscribeLink: '',
Expand Down Expand Up @@ -224,6 +226,8 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
this.viewReplyTo(message.replyToToLine());
this.viewTimeStamp(message.dateTimeStampInUTC());
this.viewSize(message.friendlySize());
this.viewSpamScore(message.spamScore());
this.viewSpamStatus(i18n(message.isSpam() ? 'GLOBAL/SPAM' : 'GLOBAL/NOT_SPAM'));
this.viewLineAsCss(message.lineAsCss());
this.viewViewLink(message.viewLink());
this.viewUnsubscribeLink(message.getFirstUnsubsribeLink());
Expand Down
3 changes: 3 additions & 0 deletions snappymail/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ private function getEnvelopeOrHeadersRequestString()
\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS,
\MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE,
// SPAM
\MailSo\Mime\Enumerations\Header::X_SPAM_STATUS,
\MailSo\Mime\Enumerations\Header::X_SPAMD_RESULT,
), true);
//
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
Expand Down
117 changes: 45 additions & 72 deletions snappymail/v/0.0.0/app/libraries/MailSo/Mail/Message.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,60 +17,20 @@
*/
class Message implements \JsonSerializable
{
/**
* @var string
*/
private $sFolder;

/**
* @var int
*/
private $iUid;

/**
* @var string
*/
private $sSubject;

/**
* @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;
private
$sFolder = '',
$iUid = 0,
$sSubject = '',
$sMessageId = '',
$sContentType = '',
$iSize = 0,
$iSpamScore = 0,
$bIsSpam = false,
$iInternalTimeStampInUTC = 0,
$iHeaderTimeStampInUTC = 0,
$sHeaderDate = '',
$aFlags = [],
$aFlagsLowerCase = [];

/**
* @var \MailSo\Mime\EmailCollection
Expand Down Expand Up @@ -189,23 +149,6 @@ class Message implements \JsonSerializable

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->oSender = null;
$this->oReplyTo = null;
Expand Down Expand Up @@ -300,6 +243,16 @@ public function Size() : int
return $this->iSize;
}

public function SpamScore() : int
{
return $this->iSpamScore;
}

public function IsSpam() : bool
{
return $this->bIsSpam;
}

public function InternalTimeStampInUTC() : int
{
return $this->iInternalTimeStampInUTC;
Expand Down Expand Up @@ -556,7 +509,7 @@ public function InitByFetchResponse(string $sFolder, \MailSo\Imap\FetchResponse
$this->sReadReceipt = \trim($oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO));
}

//Unsubscribe links
// Unsubscribe links
$this->aUnsubsribeLinks = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::LIST_UNSUBSCRIBE);
if (empty($this->aUnsubsribeLinks))
{
Expand All @@ -573,6 +526,24 @@ function ($link) {
);
}

$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);
if (0 < \strlen($sDraftInfo)) {
$sType = '';
Expand Down Expand Up @@ -751,6 +722,8 @@ public function jsonSerialize()
'Subject' => \trim(\MailSo\Base\Utils::Utf8Clear($this->Subject())),
'MessageId' => $this->MessageId(),
'Size' => $this->Size(),
'SpamScore' => $this->SpamScore(),
'IsSpam' => $this->IsSpam(),
'DateTimeStampInUTC' => $this->InternalTimeStampInUTC(),

// \MailSo\Mime\EmailCollection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@ abstract class Header
const DKIM_SIGNATURE = 'DKIM-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 DISPOSITION_NOTIFICATION_TO = 'Disposition-Notification-To';
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/_source.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ en:
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
SPAM_SCORE: "Spam Score"
READ_RECEIPT:
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/de_DE.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ de_DE:
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)"
LINK_DOWNLOAD_AS_ZIP: "Als ZIP-Datei herunterladen"
SPAM_SCORE: "Spam-Score"
READ_RECEIPT:
SUBJECT: "Empfangsbestätigung (angezeigt) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/en_GB.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ en_GB:
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
SPAM_SCORE: "Spam Score"
READ_RECEIPT:
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/en_US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ en_US:
PGP_SIGNED_MESSAGE_DESC: "OpenPGP signed message (click to verify)"
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP encrypted message (click to decrypt)"
LINK_DOWNLOAD_AS_ZIP: "Download as zip"
SPAM_SCORE: "Spam Score"
READ_RECEIPT:
SUBJECT: "Return Receipt (displayed) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/es_ES.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ es_ES:
PGP_SIGNED_MESSAGE_DESC: "Mensaje firmado mediante OpenPGP (click para verificar)"
PGP_ENCRYPTED_MESSAGE_DESC: "Mensaje cifrado mediante OpenPGP (click para desencriptar)"
LINK_DOWNLOAD_AS_ZIP: "Descargar todo (archivo ZIP)"
SPAM_SCORE: "Puntuación de spam"
READ_RECEIPT:
SUBJECT: "Acuse de recibo (se visualiza) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/fr_FR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ fr_FR:
PGP_SIGNED_MESSAGE_DESC: "Message signé par OpenPGP (cliquer pour vérifier)"
PGP_ENCRYPTED_MESSAGE_DESC: "Message chiffré par OpenPGP (cliquer pour déchiffrer)"
LINK_DOWNLOAD_AS_ZIP: "Télécharger le zip"
SPAM_SCORE: "Score de spam"
READ_RECEIPT:
SUBJECT: "Accusé de réception (affiché) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/nl_NL.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ nl_NL:
PGP_SIGNED_MESSAGE_DESC: "OpenPGP ondertekend bericht (klik om te verifiëren)"
PGP_ENCRYPTED_MESSAGE_DESC: "OpenPGP versleuteld bericht (klik om te ontsleutelen)"
LINK_DOWNLOAD_AS_ZIP: "Download als zip"
SPAM_SCORE: "Spamscore"
READ_RECEIPT:
SUBJECT: "Ontvangstbevestiging (weergegeven) - %SUBJECT%"
BODY: |
Expand Down
1 change: 1 addition & 0 deletions snappymail/v/0.0.0/app/localization/webmail/zh_CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ zh_CN:
PGP_SIGNED_MESSAGE_DESC: "由 OpenPGP 签名 (点击验证)"
PGP_ENCRYPTED_MESSAGE_DESC: "由 OpenPGP 加密 (点击解密)"
LINK_DOWNLOAD_AS_ZIP: "下载为zip压缩包"
SPAM_SCORE: "垃圾邮件分数"
READ_RECEIPT:
SUBJECT: "送达回执 - %SUBJECT%"
BODY: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,10 @@
(<time data-moment-format="FROMNOW" data-bind="moment: viewTimeStamp"></time>)
</td>
</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()">
<td data-i18n="POPUPS_FILTER/SELECT_FIELD_SIZE"></td>
<td class="size" data-bind="text: viewSize"></td>
Expand Down

0 comments on commit 168ee91

Please sign in to comment.