mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-03 14:37:02 +03:00
Sieve filters (beta)
This commit is contained in:
parent
94789632f0
commit
929bffccef
45 changed files with 1599 additions and 403 deletions
|
|
@ -1025,7 +1025,7 @@ class Actions
|
|||
*/
|
||||
private function UseSieve()
|
||||
{
|
||||
return false; // TODO
|
||||
return $this->Config()->Get('capa', 'filters', false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@ class Application extends \RainLoop\Config\AbstractConfig
|
|||
'capath' => array('', 'capath must be a correctly hashed certificate directory. (/etc/ssl/certs/)'),
|
||||
),
|
||||
|
||||
'capa' => array(
|
||||
'filters' => array(true)
|
||||
),
|
||||
|
||||
'login' => array(
|
||||
|
||||
'default_domain' => array('', ''),
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ class Notifications
|
|||
const CantSendMessage = 302;
|
||||
const InvalidRecipients = 303;
|
||||
|
||||
const CantSaveFilters = 351;
|
||||
const FiltersAreNotCorrect = 352;
|
||||
|
||||
const CantCreateFolder = 400;
|
||||
const CantRenameFolder = 401;
|
||||
const CantDeleteFolder = 402;
|
||||
|
|
@ -107,6 +110,9 @@ class Notifications
|
|||
self::CantSaveMessage => 'CantSaveMessage',
|
||||
self::CantSendMessage => 'CantSendMessage',
|
||||
self::InvalidRecipients => 'InvalidRecipients',
|
||||
self::CantSaveFilters => 'CantSaveFilters',
|
||||
self::FiltersAreNotCorrect => 'FiltersAreNotCorrect',
|
||||
|
||||
self::CantCreateFolder => 'CantCreateFolder',
|
||||
self::CantRenameFolder => 'CantRenameFolder',
|
||||
self::CantDeleteFolder => 'CantDeleteFolder',
|
||||
|
|
|
|||
|
|
@ -38,8 +38,21 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
*/
|
||||
public function Save($oAccount, $aFilters, $sRaw = '', $bRawIsActive = false)
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->Save($oAccount,
|
||||
$aFilters, $sRaw, $bRawIsActive) : false;
|
||||
try
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->Save(
|
||||
$oAccount, $aFilters, $sRaw, $bRawIsActive) : false;
|
||||
}
|
||||
catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSaveFilters, $oException);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@
|
|||
<div data-bind="component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'Use Sieve for this domain',
|
||||
label: 'Allow sieve scripts',
|
||||
value: useSieve
|
||||
}
|
||||
}"></div>
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
<div data-bind="component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'Allow custom raw script',
|
||||
label: 'Allow custom user script',
|
||||
value: sieveAllowRaw
|
||||
}
|
||||
}"></div>
|
||||
|
|
|
|||
|
|
@ -4,58 +4,50 @@
|
|||
<div class="modal-header">
|
||||
<button type="button" class="close" data-bind="command: cancelCommand">×</button>
|
||||
<h3>
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/TITLE_CREATE_FILTER" data-bind="visible: isNew"></span>
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/TITLE_EDIT_FILTER" data-bind="visible: !isNew()"></span>
|
||||
<span class="i18n" data-i18n-text="POPUPS_FILTER/TITLE_CREATE_FILTER" data-bind="visible: isNew"></span>
|
||||
<span class="i18n" data-i18n-text="POPUPS_FILTER/TITLE_EDIT_FILTER" data-bind="visible: !isNew()"></span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row filter" data-bind="with: filter">
|
||||
<div class="span9">
|
||||
<div class="row filter" data-bind="with: filter, i18nInit: filter">
|
||||
<div class="span9" data-bind="i18nInit: true">
|
||||
|
||||
<div class="control-group" data-bind="css: {'error': name.error}">
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" data-bind="value: name, hasFocus: name.focused" placeholder="Name @i18n"
|
||||
autocorrect="off" autocapitalize="off" spellcheck="false" />
|
||||
<input type="text" class="i18n span5" data-bind="value: name, hasFocus: name.focused"
|
||||
placeholder="" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-i18n-placeholder="POPUPS_FILTER/FILTER_NAME"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span>
|
||||
Conditions @i18n
|
||||
</span>
|
||||
</div>
|
||||
<div class="legend i18n" data-i18n-text="POPUPS_FILTER/LEGEND_CONDIFIONS"></div>
|
||||
<div>
|
||||
<div data-bind="visible: 1 < conditions().length">
|
||||
<select class="span4" data-bind="value: conditionsType">
|
||||
<option value="Any">
|
||||
Matching any of the following rules @i18n
|
||||
</option>
|
||||
<option value="All">
|
||||
Matching all of the following rules @i18n
|
||||
</option>
|
||||
<option value="Any" class="i18n"
|
||||
data-i18n-text="POPUPS_FILTER/SELECT_MATCH_ANY"></option>
|
||||
<option value="All" class="i18n"
|
||||
data-i18n-text="POPUPS_FILTER/SELECT_MATCH_ALL"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div data-bind="visible: 0 < conditions().length, foreach: conditions">
|
||||
<div data-bind="template: {'name': template(), 'data': $data}"></div>
|
||||
</div>
|
||||
<div data-bind="visible: 0 === conditions().length">
|
||||
All incoming messages @i18n
|
||||
<span class="i18n" data-i18n-text="POPUPS_FILTER/ALL_INCOMING_MESSAGES_DESC"></span>
|
||||
</div>
|
||||
<br />
|
||||
<a class="btn" data-bind="click: addCondition, i18nInit: true">
|
||||
<i class="icon-plus"></i>
|
||||
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_ADD_CONDITION"></span>
|
||||
<span class="i18n" data-i18n-text="POPUPS_FILTER/BUTTON_ADD_CONDITION"></span>
|
||||
</a>
|
||||
</div>
|
||||
<br />
|
||||
<div class="legend">
|
||||
<span>
|
||||
Actions @i18n
|
||||
</span>
|
||||
</div>
|
||||
<select data-bind="options: $root.actionTypeOptions, value: actionType, optionsText: 'name', optionsValue: 'id'"></select>
|
||||
<div data-bind="template: {'name': actionTemplate()}"></div>
|
||||
<div class="legend i18n" data-i18n-text="POPUPS_FILTER/LEGEND_ACTIONS"></div>
|
||||
<select class="span3" data-bind="options: $root.actionTypeOptions, value: actionType, optionsText: 'name', optionsValue: 'id'"></select>
|
||||
<div data-bind="template: {'name': actionTemplate()}, i18nUpdate: actionTemplate"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -63,7 +55,7 @@
|
|||
<a class="btn buttonSave" data-bind="command: saveFilter">
|
||||
<i class="icon-ok"></i>
|
||||
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_DONE"></span>
|
||||
<span class="i18n" data-i18n-text="POPUPS_FILTER/BUTTON_DONE"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,15 +13,17 @@
|
|||
</a>
|
||||
|
||||
<a class="btn" data-bind="visible: filterRaw.allow, click: function () { filterRaw.active(!filterRaw.active()) },
|
||||
css: {'active': filterRaw.active }">
|
||||
css: {'active': filterRaw.active }, tooltip: 'SETTINGS_FILTERS/BUTTON_RAW_SCRIPT'">
|
||||
<i class="icon-file-code"></i>
|
||||
</a>
|
||||
|
||||
<a class="btn" data-bind="command: saveChanges">
|
||||
<a class="btn hide-on-disabled-command" data-bind="command: saveChanges">
|
||||
<i data-bind="css: {'icon-floppy': !filters.saving(), 'icon-spinner animated': filters.saving()}"></i>
|
||||
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/BUTTON_SAVE"></span>
|
||||
</a>
|
||||
|
||||
<span data-bind="text: saveErrorText"style="color:red"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" data-bind="visible: haveChanges">
|
||||
|
|
@ -30,7 +32,7 @@
|
|||
<div class="alert g-ui-user-select-none" style="margin-bottom: 0">
|
||||
<i class="icon-warning"></i>
|
||||
|
||||
These changes need to be saved to the server. @i18n
|
||||
<span class="i18n" data-i18n-text="SETTINGS_FILTERS/CHACHES_NEED_TO_BE_SAVED_DESC"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -41,8 +43,15 @@
|
|||
|
||||
<span data-bind="text: processText"></span>
|
||||
</div>
|
||||
<div data-bind="visible: filterRaw.allow() && filterRaw.active()">
|
||||
<textarea class="span8" style="height: 300px" data-bind="value: filterRaw, valueUpdate: 'afterkeydown'"></textarea>
|
||||
<div class="control-group" data-bind="css: {'error': filterRaw.error}, visible: filterRaw.allow() && filterRaw.active()">
|
||||
<div class="controls">
|
||||
<pre style="word-break: break-word;" data-bind="visible: '' !== filterRaw.capa()">
|
||||
<b class="i18n" data-i18n-text="SETTINGS_FILTERS/CAPABILITY_LABEL"></b>:
|
||||
<span data-bind="text: filterRaw.capa"></span>
|
||||
</pre>
|
||||
<textarea class="span8" style="height: 300px; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;"
|
||||
data-bind="value: filterRaw, valueUpdate: 'afterkeydown'"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-hover list-table g-ui-user-select-none"
|
||||
data-bind="visible: !filterRaw.active() || !filterRaw.active(), i18nUpdate: filters">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<div class="control-group" data-bind="css: {'error': actionValue.error}">
|
||||
<div class="controls">
|
||||
<input type="text" data-bind="value: actionValue" placeholder="Email @i18n" />
|
||||
<input type="text" class="span3 i18n" data-bind="value: actionValue" placeholder=""
|
||||
data-i18n-placeholder="POPUPS_FILTER/EMAIL_LABEL" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
|
@ -8,14 +9,14 @@
|
|||
<div data-bind="component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'keep in INBOX @i18n',
|
||||
label: 'POPUPS_FILTER/KEEP_LABEL',
|
||||
value: actionKeep
|
||||
}
|
||||
}"></div>
|
||||
<div data-bind="visible: $root.allowMarkAsRead, component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'Mark as read @i18n',
|
||||
label: 'POPUPS_FILTER/MARK_AS_READ_LABEL',
|
||||
value: actionMarkAsRead
|
||||
}
|
||||
}"></div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<div class="control-group" data-bind="css: {'error': actionValue.error}">
|
||||
<div class="controls">
|
||||
<select data-bind="options: $root.folderSelectList, value: $root.selectedFolderValue,
|
||||
<select class="span3" data-bind="options: $root.folderSelectList, value: $root.selectedFolderValue,
|
||||
optionsText: 'name', optionsValue: 'id', optionsAfterRender: $root.defautOptionsAfterRender"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
<div data-bind="visible: $root.allowMarkAsRead, component: {
|
||||
name: 'Checkbox',
|
||||
params: {
|
||||
label: 'Mark as read @i18n',
|
||||
label: 'POPUPS_FILTER/MARK_AS_READ_LABEL',
|
||||
value: actionMarkAsRead
|
||||
}
|
||||
}"></div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<div class="control-group" data-bind="css: {'error': actionValue.error}" style="margin-bottom: 0">
|
||||
<div class="controls">
|
||||
<textarea class="span5" data-bind="value: actionValue" style="height: 100px;" placeholder="Reject message @i18n"></textarea>
|
||||
<textarea class="span5 i18n" data-bind="value: actionValue" style="height: 100px;"
|
||||
placeholder="" data-i18n-placeholder="POPUPS_FILTER/REJECT_MESSAGE_LABEL"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
<div class="control-group" style="margin-bottom: 0">
|
||||
<div class="controls">
|
||||
<input type="text" class="span5" data-bind="value: actionValueSecond" placeholder="Subject (optional) @i18n" />
|
||||
<input type="text" class="span5 i18n" data-bind="value: actionValueSecond" placeholder=""
|
||||
data-i18n-placeholder="POPUPS_FILTER/VACATION_SUBJECT_LABEL" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="css: {'error': actionValue.error}" style="margin-bottom: 0">
|
||||
<div class="controls">
|
||||
<textarea class="span5" data-bind="value: actionValue" style="height: 100px;" placeholder="Message @i18n"></textarea>
|
||||
<textarea class="span5 i18n" data-bind="value: actionValue" style="height: 100px;"
|
||||
placeholder="" data-i18n-placeholder="POPUPS_FILTER/VACATION_MESSAGE_LABEL"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue