mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-11-03 19:08:50 +03:00
Get a working Sieve scripts manager
This commit is contained in:
parent
a31834458b
commit
e3125ebfff
24 changed files with 439 additions and 304 deletions
|
|
@ -326,6 +326,17 @@ class ManageSieveClient extends \MailSo\Net\NetClient
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \MailSo\Net\Exceptions\Exception
|
||||
* @throws \MailSo\Sieve\Exceptions\NegativeResponseException
|
||||
*/
|
||||
public function RenameScript(string $sOldName, string $sNewName) : self
|
||||
{
|
||||
$this->sendRequestWithCheck('RENAMESCRIPT "'.$sOldName.'" "'.$sNewName.'"');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \MailSo\Net\Exceptions\Exception
|
||||
* @throws \MailSo\Sieve\Exceptions\NegativeResponseException
|
||||
|
|
|
|||
|
|
@ -76,6 +76,64 @@ trait Filters
|
|||
$aFilters, $sRaw, $bRawIsActive));
|
||||
}
|
||||
|
||||
public function DoFiltersScriptSave() : array
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
$sName = $this->GetActionParam('name', '');
|
||||
|
||||
$aFilters = array();
|
||||
if (\RainLoop\Providers\Filters\SieveStorage::SIEVE_FILE_NAME === $sName) {
|
||||
$aIncFilters = $this->GetActionParam('filters', array());
|
||||
foreach ($aIncFilters as $aFilter) {
|
||||
if (\is_array($aFilter)) {
|
||||
$oFilter = new \RainLoop\Providers\Filters\Classes\Filter();
|
||||
if ($oFilter->FromJSON($aFilter)) {
|
||||
$aFilters[] = $oFilter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->GetActionParam('active', false)) {
|
||||
// $this->FiltersProvider()->ActivateScript($oAccount, $sName);
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->Save(
|
||||
$oAccount, $sName, $aFilters, $this->GetActionParam('body', '')
|
||||
));
|
||||
}
|
||||
|
||||
public function DoFiltersScriptActivate() : array
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->ActivateScript(
|
||||
$oAccount, $this->GetActionParam('name', '')
|
||||
));
|
||||
}
|
||||
|
||||
public function DoFiltersScriptDelete() : array
|
||||
{
|
||||
$oAccount = $this->getAccountFromToken();
|
||||
|
||||
if (!$this->GetCapa(false, false, Capa::FILTERS, $oAccount)) {
|
||||
return $this->FalseResponse(__FUNCTION__);
|
||||
}
|
||||
|
||||
return $this->DefaultResponse(__FUNCTION__, $this->FiltersProvider()->DeleteScript(
|
||||
$oAccount, $this->GetActionParam('name', '')
|
||||
));
|
||||
}
|
||||
|
||||
protected function FiltersProvider() : \RainLoop\Providers\Filters
|
||||
{
|
||||
if (!$this->oFiltersProvider) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class Notifications
|
|||
|
||||
const CantSaveFilters = 351;
|
||||
const CantGetFilters = 352;
|
||||
const CantActivateFiltersScript = 351; // TODO: 353
|
||||
const CantDeleteFiltersScript = 351; // TODO: 354
|
||||
const FiltersAreNotCorrect = 355;
|
||||
|
||||
const CantCreateFolder = 400;
|
||||
|
|
|
|||
|
|
@ -14,47 +14,73 @@ class Filters extends \RainLoop\Providers\AbstractProvider
|
|||
$this->oDriver = $oDriver;
|
||||
}
|
||||
|
||||
private static function handleException(\Throwable $oException, int $defNotification) : void
|
||||
{
|
||||
if ($oException instanceof \MailSo\Net\Exceptions\SocketCanNotConnectToHostException) {
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
||||
}
|
||||
|
||||
if ($oException instanceof \MailSo\Sieve\Exceptions\NegativeResponseException) {
|
||||
throw new \RainLoop\Exceptions\ClientException(
|
||||
\RainLoop\Notifications::ClientViewError, $oException, \implode("\r\n", $oException->GetResponses())
|
||||
);
|
||||
}
|
||||
|
||||
throw new \RainLoop\Exceptions\ClientException($defNotification, $oException);
|
||||
}
|
||||
|
||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->IsActive() ? $this->oDriver->Load($oAccount, $bAllowRaw) : array();
|
||||
}
|
||||
catch (\MailSo\Net\Exceptions\SocketCanNotConnectToHostException $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException);
|
||||
}
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetFilters, $oException);
|
||||
static::handleException($oException, \RainLoop\Notifications::CantGetFilters);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters, string $sRaw = '', bool $bRawIsActive = false) : bool
|
||||
public function Save(\RainLoop\Model\Account $oAccount, string $sScriptName, array $aFilters, string $sRaw = '') : bool
|
||||
{
|
||||
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 (\MailSo\Sieve\Exceptions\NegativeResponseException $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(
|
||||
\RainLoop\Notifications::ClientViewError, $oException,
|
||||
\implode("\r\n", $oException->GetResponses()));
|
||||
return $this->IsActive()
|
||||
? $this->oDriver->Save($oAccount, $sScriptName, $aFilters, $sRaw)
|
||||
: false;
|
||||
}
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSaveFilters, $oException);
|
||||
static::handleException($oException. \RainLoop\Notifications::CantSaveFilters);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
public function ActivateScript(\RainLoop\Model\Account $oAccount, string $sScriptName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->IsActive()
|
||||
? $this->oDriver->Activate($oAccount, $sScriptName)
|
||||
: false;
|
||||
}
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
static::handleException($oException. \RainLoop\Notifications::CantActivateFiltersScript);
|
||||
}
|
||||
}
|
||||
|
||||
public function DeleteScript(\RainLoop\Model\Account $oAccount, string $sScriptName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->IsActive()
|
||||
? $this->oDriver->Delete($oAccount, $sScriptName)
|
||||
: false;
|
||||
}
|
||||
catch (\Throwable $oException)
|
||||
{
|
||||
static::handleException($oException. \RainLoop\Notifications::CantDeleteFiltersScript);
|
||||
}
|
||||
}
|
||||
|
||||
public function IsActive() : bool
|
||||
|
|
|
|||
|
|
@ -6,5 +6,9 @@ interface FiltersInterface
|
|||
{
|
||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array;
|
||||
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters) : bool;
|
||||
public function Save(\RainLoop\Model\Account $oAccount, string $sScriptName, array $aFilters, string $sRaw = '') : bool;
|
||||
|
||||
public function Activate(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool;
|
||||
|
||||
public function Delete(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,52 +39,67 @@ class SieveStorage implements FiltersInterface
|
|||
$this->bUtf8FolderName = !!$this->oConfig->Get('labs', 'sieve_utf8_folder_name', true);
|
||||
}
|
||||
|
||||
protected function getConnection(\RainLoop\Model\Account $oAccount) : ?\MailSo\Sieve\ManageSieveClient
|
||||
{
|
||||
$oSieveClient = new \MailSo\Sieve\ManageSieveClient();
|
||||
$oSieveClient->SetLogger($this->oLogger);
|
||||
$oSieveClient->SetTimeOuts(10, (int) \RainLoop\Api::Config()->Get('labs', 'sieve_timeout', 10));
|
||||
return $oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig)
|
||||
? $oSieveClient
|
||||
: null;
|
||||
}
|
||||
|
||||
public function Load(\RainLoop\Model\Account $oAccount, bool $bAllowRaw = false) : array
|
||||
{
|
||||
$aModules = array();
|
||||
$aFilters = array();
|
||||
$aScripts = array();
|
||||
|
||||
$oSieveClient = new \MailSo\Sieve\ManageSieveClient();
|
||||
$oSieveClient->SetLogger($this->oLogger);
|
||||
$oSieveClient->SetTimeOuts(10, (int) $this->oConfig->Get('labs', 'sieve_timeout', 10));
|
||||
|
||||
if ($oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig)) {
|
||||
$oSieveClient = $this->getConnection($oAccount);
|
||||
if ($oSieveClient) {
|
||||
$aModules = $oSieveClient->Modules();
|
||||
\sort($aModules);
|
||||
|
||||
$aList = $oSieveClient->ListScripts();
|
||||
|
||||
if (!empty($aList[self::SIEVE_FILE_NAME])) {
|
||||
$sS = $oSieveClient->GetScript(self::SIEVE_FILE_NAME);
|
||||
if ($sS) {
|
||||
$aFilters = $this->fileStringToCollection($sS);
|
||||
}
|
||||
}
|
||||
|
||||
if ($bAllowRaw) {
|
||||
foreach ($aList as $name => $active) {
|
||||
if ($name != self::SIEVE_FILE_NAME) {
|
||||
foreach ($aList as $name => $active) {
|
||||
if ($name != self::SIEVE_FILE_NAME) {
|
||||
if ($bAllowRaw) {
|
||||
$aScripts[$name] = array(
|
||||
'@Object' => 'Object/SieveScript',
|
||||
'name' => $name,
|
||||
'active' => $active,
|
||||
'body' => $oSieveClient->GetScript($name) // \trim() ?
|
||||
);
|
||||
} else {
|
||||
$aScripts[$name] = array(
|
||||
'@Object' => 'Object/SieveScript',
|
||||
'name' => $name,
|
||||
'active' => $active,
|
||||
'body' => $oSieveClient->GetScript($name), // \trim() ?
|
||||
'filters' => $aFilters
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$sS = $oSieveClient->GetScript(self::SIEVE_FILE_NAME);
|
||||
if ($sS) {
|
||||
$aFilters = $this->fileStringToCollection($sS);
|
||||
}
|
||||
$aScripts[$name] = array(
|
||||
'@Object' => 'Object/SieveScript',
|
||||
'name' => $name,
|
||||
'active' => $active,
|
||||
'body' => $oSieveClient->GetScript($name), // \trim() ?
|
||||
'filters' => $aFilters
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$oSieveClient->LogoutAndDisconnect();
|
||||
}
|
||||
|
||||
if (!isset($aList[self::SIEVE_FILE_NAME_RAW])) {
|
||||
if (!isset($aList[self::SIEVE_FILE_NAME])) {
|
||||
$aScripts[$name] = array(
|
||||
'@Object' => 'Object/SieveScript',
|
||||
'name' => self::SIEVE_FILE_NAME,
|
||||
'active' => false,
|
||||
'body' => '',
|
||||
'filters' => []
|
||||
);
|
||||
}
|
||||
|
||||
if ($bAllowRaw && !isset($aList[self::SIEVE_FILE_NAME_RAW])) {
|
||||
$aScripts[$name] = array(
|
||||
'@Object' => 'Object/SieveScript',
|
||||
'name' => self::SIEVE_FILE_NAME_RAW,
|
||||
|
|
@ -96,55 +111,52 @@ class SieveStorage implements FiltersInterface
|
|||
\ksort($aScripts);
|
||||
|
||||
return array(
|
||||
'RawIsAllow' => $bAllowRaw,
|
||||
'Filters' => $aFilters,
|
||||
'Capa' => $aModules,
|
||||
'Scripts' => $aScripts
|
||||
);
|
||||
}
|
||||
|
||||
public function Save(\RainLoop\Model\Account $oAccount, array $aFilters, string $sRaw = '', bool $bRawIsActive = false) : bool
|
||||
public function Save(\RainLoop\Model\Account $oAccount, string $sScriptName, array $aFilters, string $sRaw = '') : bool
|
||||
{
|
||||
$oSieveClient = new \MailSo\Sieve\ManageSieveClient();
|
||||
$oSieveClient->SetLogger($this->oLogger);
|
||||
$oSieveClient->SetTimeOuts(10, (int) \RainLoop\Api::Config()->Get('labs', 'sieve_timeout', 10));
|
||||
|
||||
if ($oAccount->SieveConnectAndLoginHelper($this->oPlugins, $oSieveClient, $this->oConfig))
|
||||
{
|
||||
$aList = $oSieveClient->ListScripts();
|
||||
|
||||
if ($bRawIsActive)
|
||||
{
|
||||
if (!empty($sRaw))
|
||||
{
|
||||
$oSieveClient->PutScript(self::SIEVE_FILE_NAME_RAW, $sRaw);
|
||||
$oSieveClient->SetActiveScript(self::SIEVE_FILE_NAME_RAW);
|
||||
}
|
||||
else if (isset($aList[self::SIEVE_FILE_NAME_RAW]))
|
||||
{
|
||||
$oSieveClient->DeleteScript(self::SIEVE_FILE_NAME_RAW);
|
||||
if (self::SIEVE_FILE_NAME === $sScriptName) {
|
||||
$sRaw = $this->collectionToFileString($aFilters);
|
||||
}
|
||||
$oSieveClient = $this->getConnection($oAccount);
|
||||
if ($oSieveClient) {
|
||||
if (empty($sRaw)) {
|
||||
$aList = $oSieveClient->ListScripts();
|
||||
if (isset($aList[$sScriptName])) {
|
||||
$oSieveClient->DeleteScript($sScriptName);
|
||||
}
|
||||
} else {
|
||||
$oSieveClient->PutScript($sScriptName, $sRaw);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sUserFilter = $this->collectionToFileString($aFilters);
|
||||
|
||||
if (!empty($sUserFilter))
|
||||
{
|
||||
$oSieveClient->PutScript(self::SIEVE_FILE_NAME, $sUserFilter);
|
||||
$oSieveClient->SetActiveScript(self::SIEVE_FILE_NAME);
|
||||
}
|
||||
else if (isset($aList[self::SIEVE_FILE_NAME]))
|
||||
{
|
||||
$oSieveClient->DeleteScript(self::SIEVE_FILE_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
$oSieveClient->LogoutAndDisconnect();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If $sScriptName is the empty string (i.e., ""), then any active script is disabled.
|
||||
*/
|
||||
public function Activate(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool
|
||||
{
|
||||
$oSieveClient = $this->getConnection($oAccount);
|
||||
if ($oSieveClient) {
|
||||
$oSieveClient->SetActiveScript(\trim($sScriptName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function Delete(\RainLoop\Model\Account $oAccount, string $sScriptName) : bool
|
||||
{
|
||||
$oSieveClient = $this->getConnection($oAccount);
|
||||
if ($oSieveClient) {
|
||||
$oSieveClient->DeleteScript(\trim($sScriptName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -349,6 +349,15 @@ en:
|
|||
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
||||
REJECT_MESSAGE_LABEL: "Reject message"
|
||||
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Create Script"
|
||||
TITLE_EDIT: "Edit Script"
|
||||
SCRIPT_NAME: "Name"
|
||||
BUTTON_ADD_FILTER: "Add a Filter"
|
||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||
BUTTON_SAVE: "Save"
|
||||
CAPABILITY_LABEL: "Capabilities"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
||||
SELECT_CHOOSE_ONE: "Choose one"
|
||||
|
|
@ -431,21 +440,15 @@ en:
|
|||
BUTTON_BACK: "Back"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filters"
|
||||
LEGEND_SIEVE_SCRIPT: "Sieve Script"
|
||||
BUTTON_SAVE: "Save"
|
||||
BUTTON_ADD_FILTER: "Add a Filter"
|
||||
BUTTON_DELETE: "Delete"
|
||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||
SUBNAME_NONE: "None"
|
||||
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Reject"
|
||||
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
||||
SUBNAME_DISCARD: "Discard"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
LOADING_PROCESS: "Updating filter list"
|
||||
DELETING_ASK: "Are you sure?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identity"
|
||||
LABEL_DISPLAY_NAME: "Name"
|
||||
|
|
|
|||
|
|
@ -348,6 +348,15 @@ de_DE:
|
|||
VACATION_RECIPIENTS_LABEL: "Empfänger (durch Komma getrennt)"
|
||||
REJECT_MESSAGE_LABEL: "Ablehnnachricht"
|
||||
ALL_INCOMING_MESSAGES_DESC: "Alle eingehenden Nachrichten"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Skript erstellen"
|
||||
TITLE_EDIT: "Skript bearbeiten"
|
||||
SCRIPT_NAME: "Name"
|
||||
BUTTON_ADD_FILTER: "Filter hinzufügen"
|
||||
BUTTON_RAW_SCRIPT: "Benutzerdefiniertes Skript verwenden"
|
||||
BUTTON_SAVE: "Speichern"
|
||||
CAPABILITY_LABEL: "Unterstützte Module"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Die Änderungen müssen auf dem Server gespeichert werden."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Wählen Sie die Systemordner aus"
|
||||
SELECT_CHOOSE_ONE: "Wählen Sie einen aus"
|
||||
|
|
@ -431,20 +440,15 @@ de_DE:
|
|||
BUTTON_BACK: "Zurück"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filter"
|
||||
BUTTON_SAVE: "Speichern"
|
||||
BUTTON_ADD_FILTER: "Filter hinzufügen"
|
||||
BUTTON_DELETE: "Löschen"
|
||||
BUTTON_RAW_SCRIPT: "Benutzerdefiniertes Skript verwenden"
|
||||
SUBNAME_NONE: "Keine"
|
||||
SUBNAME_MOVE_TO: "Verschieben nach \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Weiterleiten nach \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Ablehnen"
|
||||
SUBNAME_VACATION_MESSAGE: "Urlaubsbenachrichtigung"
|
||||
SUBNAME_DISCARD: "Verwerfen"
|
||||
CAPABILITY_LABEL: "Unterstützte Module"
|
||||
LOADING_PROCESS: "Aktualisiere Filterliste"
|
||||
DELETING_ASK: "Sind Sie sicher?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Die Änderungen müssen auf dem Server gespeichert werden."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identität"
|
||||
LABEL_DISPLAY_NAME: "Name"
|
||||
|
|
|
|||
|
|
@ -349,6 +349,15 @@ en_GB:
|
|||
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
||||
REJECT_MESSAGE_LABEL: "Reject message"
|
||||
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Create Script"
|
||||
TITLE_EDIT: "Edit Script"
|
||||
SCRIPT_NAME: "Name"
|
||||
BUTTON_ADD_FILTER: "Add a Filter"
|
||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||
BUTTON_SAVE: "Save"
|
||||
CAPABILITY_LABEL: "Capabilities"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
||||
SELECT_CHOOSE_ONE: "Choose one"
|
||||
|
|
@ -431,20 +440,15 @@ en_GB:
|
|||
BUTTON_BACK: "Back"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filters"
|
||||
BUTTON_SAVE: "Save"
|
||||
BUTTON_ADD_FILTER: "Add a Filter"
|
||||
BUTTON_DELETE: "Delete"
|
||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||
SUBNAME_NONE: "None"
|
||||
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Reject"
|
||||
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
||||
SUBNAME_DISCARD: "Discard"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
LOADING_PROCESS: "Updating filter list"
|
||||
DELETING_ASK: "Are you sure?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identity"
|
||||
LABEL_DISPLAY_NAME: "Name"
|
||||
|
|
|
|||
|
|
@ -349,6 +349,15 @@ en_US:
|
|||
VACATION_RECIPIENTS_LABEL: "Recipients (comma separated)"
|
||||
REJECT_MESSAGE_LABEL: "Reject message"
|
||||
ALL_INCOMING_MESSAGES_DESC: "All incoming messages"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Create Script"
|
||||
TITLE_EDIT: "Edit Script"
|
||||
SCRIPT_NAME: "Name"
|
||||
BUTTON_ADD_FILTER: "Add a Filter"
|
||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||
BUTTON_SAVE: "Save"
|
||||
CAPABILITY_LABEL: "Capabilities"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Select system folders"
|
||||
SELECT_CHOOSE_ONE: "Choose one"
|
||||
|
|
@ -431,20 +440,15 @@ en_US:
|
|||
BUTTON_BACK: "Back"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filters"
|
||||
BUTTON_SAVE: "Save"
|
||||
BUTTON_ADD_FILTER: "Add a Filter"
|
||||
BUTTON_DELETE: "Delete"
|
||||
BUTTON_RAW_SCRIPT: "Use Custom User Script"
|
||||
SUBNAME_NONE: "None"
|
||||
SUBNAME_MOVE_TO: "Move to \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Forward to \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Reject"
|
||||
SUBNAME_VACATION_MESSAGE: "Vacation message"
|
||||
SUBNAME_DISCARD: "Discard"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
LOADING_PROCESS: "Updating filter list"
|
||||
DELETING_ASK: "Are you sure?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "These changes need to be saved to the server."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identity"
|
||||
LABEL_DISPLAY_NAME: "Name"
|
||||
|
|
|
|||
|
|
@ -348,6 +348,15 @@ es_ES:
|
|||
VACATION_RECIPIENTS_LABEL: "Destinatarios (separados por coma)"
|
||||
REJECT_MESSAGE_LABEL: "Rechazar mensaje"
|
||||
ALL_INCOMING_MESSAGES_DESC: "Todos los mensajes entrantes"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Create Script"
|
||||
TITLE_EDIT: "Edit Script"
|
||||
SCRIPT_NAME: "Nombre"
|
||||
BUTTON_ADD_FILTER: "Añadir un Filtro"
|
||||
BUTTON_RAW_SCRIPT: "Usar Script Personalizado"
|
||||
BUTTON_SAVE: "Guardar"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Estos cambios deben ser cambiados en el servidor."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Seleccione las carpetas del sistema"
|
||||
SELECT_CHOOSE_ONE: "Elija una"
|
||||
|
|
@ -432,20 +441,15 @@ es_ES:
|
|||
BUTTON_BACK: "Atrás"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filtros"
|
||||
BUTTON_SAVE: "Guardar"
|
||||
BUTTON_ADD_FILTER: "Añadir un Filtro"
|
||||
BUTTON_DELETE: "Borrar"
|
||||
BUTTON_RAW_SCRIPT: "Usar Script Personalizado"
|
||||
SUBNAME_NONE: "Ninguno"
|
||||
SUBNAME_MOVE_TO: "Mover a \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Reenviar a \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Rechazar"
|
||||
SUBNAME_VACATION_MESSAGE: "Mensaje de vacaciones"
|
||||
SUBNAME_DISCARD: "Descartar"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
LOADING_PROCESS: "Actualizando lista de filtros"
|
||||
DELETING_ASK: "¿Está seguro?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Estos cambios deben ser cambiados en el servidor."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identidad"
|
||||
LABEL_DISPLAY_NAME: "Nombre"
|
||||
|
|
|
|||
|
|
@ -349,6 +349,15 @@ fr_FR:
|
|||
VACATION_RECIPIENTS_LABEL: "Destinataires (séparés par des virgules)"
|
||||
REJECT_MESSAGE_LABEL: "Message rejeté"
|
||||
ALL_INCOMING_MESSAGES_DESC: "Tous les messages entrants"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Create Script"
|
||||
TITLE_EDIT: "Edit Script"
|
||||
SCRIPT_NAME: "Nom"
|
||||
BUTTON_ADD_FILTER: "Ajouter un filtre"
|
||||
BUTTON_RAW_SCRIPT: "Utiliser le script d'un utilisateur"
|
||||
BUTTON_SAVE: "Enregistrer"
|
||||
CAPABILITY_LABEL: "Capacité"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Ces changements doivent être enregistrés sur le serveur."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Sélectionner les dossiers systèmes"
|
||||
SELECT_CHOOSE_ONE: "Faites un choix"
|
||||
|
|
@ -432,20 +441,15 @@ fr_FR:
|
|||
BUTTON_BACK: "Retour"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filtres"
|
||||
BUTTON_SAVE: "Enregistrer"
|
||||
BUTTON_ADD_FILTER: "Ajouter un filtre"
|
||||
BUTTON_DELETE: "Effacer"
|
||||
BUTTON_RAW_SCRIPT: "Utiliser le script d'un utilisateur"
|
||||
SUBNAME_NONE: "Aucun"
|
||||
SUBNAME_MOVE_TO: "Déplacer vers \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Faire suivre à \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Rejeter"
|
||||
SUBNAME_VACATION_MESSAGE: "Message d'absence"
|
||||
SUBNAME_DISCARD: "Exclure"
|
||||
CAPABILITY_LABEL: "Capacité"
|
||||
LOADING_PROCESS: "Mise à jour de la liste de filtres"
|
||||
DELETING_ASK: "Êtes-vous sûr ?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Ces changements doivent être enregistrés sur le serveur."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identité"
|
||||
LABEL_DISPLAY_NAME: "Nom"
|
||||
|
|
|
|||
|
|
@ -348,6 +348,15 @@ nl_NL:
|
|||
VACATION_RECIPIENTS_LABEL: "Ontvangers (comma gescheiden)"
|
||||
REJECT_MESSAGE_LABEL: "Afwijsbericht"
|
||||
ALL_INCOMING_MESSAGES_DESC: "Alle inkomende berichten"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Script toevoegen"
|
||||
TITLE_EDIT: "Script aanpassen"
|
||||
SCRIPT_NAME: "Naam"
|
||||
BUTTON_ADD_FILTER: "Filter toevoegen"
|
||||
BUTTON_RAW_SCRIPT: "Maak een custom script"
|
||||
BUTTON_SAVE: "Opslaan"
|
||||
CAPABILITY_LABEL: "Mogelijkheden"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Wijzigingen moeten nog opgeslagen worden op de server."
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "Selecteer systeem mappen"
|
||||
SELECT_CHOOSE_ONE: "Kies één"
|
||||
|
|
@ -430,20 +439,15 @@ nl_NL:
|
|||
BUTTON_BACK: "Terug"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "Filters"
|
||||
BUTTON_SAVE: "Opslaan"
|
||||
BUTTON_ADD_FILTER: "Filter toevoegen"
|
||||
BUTTON_DELETE: "Verwijder"
|
||||
BUTTON_RAW_SCRIPT: "Maak een custom script"
|
||||
SUBNAME_NONE: "Geen"
|
||||
SUBNAME_MOVE_TO: "Verplaats naar map \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "Doorsturen naar \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "Afwijzen"
|
||||
SUBNAME_VACATION_MESSAGE: "Afwezigheidsbericht"
|
||||
SUBNAME_DISCARD: "Gooi weg"
|
||||
CAPABILITY_LABEL: "Mogelijkheden"
|
||||
LOADING_PROCESS: "Bezig met updaten van de filter lijst"
|
||||
DELETING_ASK: "Weet u het zeker?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "Wijzigingen moeten nog opgeslagen worden op de server."
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "Identiteit"
|
||||
LABEL_DISPLAY_NAME: "Naam"
|
||||
|
|
|
|||
|
|
@ -348,6 +348,15 @@ zh_CN:
|
|||
VACATION_RECIPIENTS_LABEL: "收件人 (半角逗号“,”分隔)"
|
||||
REJECT_MESSAGE_LABEL: "拒收邮件"
|
||||
ALL_INCOMING_MESSAGES_DESC: "所有来信"
|
||||
POPUPS_SIEVE_SCRIPT:
|
||||
TITLE_CREATE: "Create Script"
|
||||
TITLE_EDIT: "Edit Script"
|
||||
SCRIPT_NAME: "名称"
|
||||
BUTTON_ADD_FILTER: "添加筛选条件"
|
||||
BUTTON_RAW_SCRIPT: "使用自定义脚本"
|
||||
BUTTON_SAVE: "保存"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "这些更改需要保存。"
|
||||
POPUPS_SYSTEM_FOLDERS:
|
||||
TITLE_SYSTEM_FOLDERS: "选择系统文件夹"
|
||||
SELECT_CHOOSE_ONE: "选择一个"
|
||||
|
|
@ -429,20 +438,15 @@ zh_CN:
|
|||
BUTTON_BACK: "返回"
|
||||
SETTINGS_FILTERS:
|
||||
LEGEND_FILTERS: "筛选器"
|
||||
BUTTON_SAVE: "保存"
|
||||
BUTTON_ADD_FILTER: "添加筛选条件"
|
||||
BUTTON_DELETE: "删除"
|
||||
BUTTON_RAW_SCRIPT: "使用自定义脚本"
|
||||
SUBNAME_NONE: "无"
|
||||
SUBNAME_MOVE_TO: "移动到 \"%FOLDER%\""
|
||||
SUBNAME_FORWARD_TO: "转发到 \"%EMAIL%\""
|
||||
SUBNAME_REJECT: "拒绝"
|
||||
SUBNAME_VACATION_MESSAGE: "假期自动回复"
|
||||
SUBNAME_DISCARD: "取消"
|
||||
CAPABILITY_LABEL: "Capability"
|
||||
LOADING_PROCESS: "正在更新筛选规则列表"
|
||||
DELETING_ASK: "确定删除?"
|
||||
CHANGES_NEED_TO_BE_SAVED_DESC: "这些更改需要保存。"
|
||||
SETTINGS_IDENTITY:
|
||||
LEGEND_IDENTITY: "身份"
|
||||
LABEL_DISPLAY_NAME: "名称"
|
||||
|
|
|
|||
|
|
@ -1,51 +1,65 @@
|
|||
<div class="modal fade b-filter-script g-ui-user-select-none" data-bind="modal: modalVisibility">
|
||||
<div>
|
||||
<div data-bind="with: script">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-bind="command: cancelCommand">×</button>
|
||||
<h3 class="i18n" data-i18n="POPUPS_FILTER/LEGEND_SIEVE_SCRIPT"></h3>
|
||||
<button type="button" class="close" data-bind="command: $root.cancelCommand">×</button>
|
||||
<h3>
|
||||
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/TITLE_CREATE" data-bind="visible: $root.isNew"></span>
|
||||
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/TITLE_EDIT" data-bind="visible: !$root.isNew()"></span>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row" data-bind="visible: haveChanges">
|
||||
|
||||
<div class="control-group" data-bind="css: {'error': nameError}">
|
||||
<div class="controls">
|
||||
<input type="text" class="i18n span5"
|
||||
data-bind="value: name, hasFocus: $root.isNew, visible: $root.isNew"
|
||||
autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-i18n="[placeholder]POPUPS_SIEVE_SCRIPT/SCRIPT_NAME"
|
||||
/>
|
||||
<span data-bind="text: name, visible: !$root.isNew()"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" data-bind="visible: hasChanges">
|
||||
<div class="span8 width100-on-mobile">
|
||||
<br />
|
||||
<div class="alert g-ui-user-select-none" style="margin-bottom: 0">
|
||||
<div class="alert g-ui-user-select-none">
|
||||
<i class="icon-warning"></i>
|
||||
|
||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/CHANGES_NEED_TO_BE_SAVED_DESC"></span>
|
||||
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/CHANGES_NEED_TO_BE_SAVED_DESC"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" data-bind="visible: serverError">
|
||||
<div class="row" data-bind="visible: $root.saveError">
|
||||
<div class="span8 width100-on-mobile">
|
||||
<div class="alert alert-error g-ui-user-select-none" style="margin-bottom: 0">
|
||||
<div class="alert alert-error g-ui-user-select-none">
|
||||
<i class="icon-warning"></i>
|
||||
|
||||
<span data-bind="text: serverErrorDesc"></span>
|
||||
<span data-bind="text: $root.saveErrorText"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="row">
|
||||
<!--
|
||||
<div class="row" data-bind="visible: allowFilters">
|
||||
<div class="span5 width100-on-mobile">
|
||||
<a class="btn" data-bind="click: function () { filterRaw.active(!filterRaw.active()) },
|
||||
css: {'active': filterRaw.active }, tooltip: 'SETTINGS_FILTERS/BUTTON_RAW_SCRIPT'">
|
||||
<a class="btn" data-bind="click: function () { $root.rawActive(!$root.rawActive()) },
|
||||
css: {'active': $root.rawActive }, tooltip: 'POPUPS_SIEVE_SCRIPT/BUTTON_RAW_SCRIPT'">
|
||||
<i class="icon-file-code"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="row">
|
||||
<div class="span8 width100-on-mobile">
|
||||
<div class="control-group" data-bind="css: {'error': filterRaw.error}, visible: filterRaw.active()">
|
||||
<div class="control-group" data-bind="visible: $root.rawActive">
|
||||
<div class="controls">
|
||||
<pre style="word-break: break-word;" data-bind="visible: '' !== filterRaw.capa()">
|
||||
<b class="i18n" data-i18n="SETTINGS_FILTERS/CAPABILITY_LABEL"></b>:
|
||||
<span data-bind="text: filterRaw.capa"></span>
|
||||
<pre>
|
||||
<b class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/CAPABILITY_LABEL"></b>:
|
||||
<span data-bind="text: $root.sieveCapabilities"></span>
|
||||
</pre>
|
||||
<textarea class="span8" style="height: 300px; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;"
|
||||
data-bind="value: filterRaw, valueUpdate: 'afterkeydown'"></textarea>
|
||||
<textarea class="span8" data-bind="value: body, valueUpdate: 'afterkeydown'"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div data-bind="visible: !filterRaw.active()">
|
||||
<div data-bind="visible: !$root.rawActive()">
|
||||
<table class="table table-hover list-table filters-list g-ui-user-select-none"
|
||||
data-bind="i18nUpdate: filters">
|
||||
<colgroup>
|
||||
|
|
@ -55,10 +69,10 @@
|
|||
<col style="width: 140px" />
|
||||
<col style="width: 1%" />
|
||||
</colgroup>
|
||||
<tbody data-bind="foreach: filters" style="width: 600px">
|
||||
<tbody data-bind="foreach: filters">
|
||||
<tr class="filter-item" draggable="true" data-bind="sortableItem: { list: $root.filters }">
|
||||
<td>
|
||||
<span class="disabled-filter" data-bind="click: function () { $root.haveChanges(true); enabled(!enabled()); }">
|
||||
<span class="disabled-filter" data-bind="click: function () { $parent.hasChanges(true); enabled(!enabled()); }">
|
||||
<i data-bind="css: {'icon-checkbox-checked': enabled, 'icon-checkbox-unchecked': !enabled()}"></i>
|
||||
</span>
|
||||
</td>
|
||||
|
|
@ -83,20 +97,20 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<a class="btn" data-bind="click: addFilter">
|
||||
<a class="btn" data-bind="click: $root.addFilter">
|
||||
<i class="icon-plus"></i>
|
||||
|
||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/BUTTON_ADD_FILTER"></span>
|
||||
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/BUTTON_ADD_FILTER"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a class="btn buttonSave" data-bind="command: saveScriptCommand, tooltipErrorTip: saveErrorText, css: {'btn-danger': '' !== saveErrorText()}">
|
||||
<i data-bind="css: {'icon-floppy': !script.saving(), 'icon-spinner animated': script.saving()}"></i>
|
||||
<a class="btn buttonSave" data-bind="visible: hasChanges, click: function() { $root.saveScriptCommand(); }, css: {'btn-danger': $root.saveError}">
|
||||
<i data-bind="css: {'icon-floppy': !$root.saving, 'icon-spinner animated': $root.saving}"></i>
|
||||
|
||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/BUTTON_SAVE"></span>
|
||||
<span class="i18n" data-i18n="POPUPS_SIEVE_SCRIPT/BUTTON_SAVE"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div class="legend">
|
||||
<span class="i18n" data-i18n="SETTINGS_FILTERS/LEGEND_FILTERS"></span>
|
||||
|
||||
<i class="icon-spinner animated" style="margin-top: 5px" data-bind="visible: filters.loading"></i>
|
||||
<i class="icon-spinner animated" style="margin-top: 5px" data-bind="visible: loading"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" data-bind="visible: serverError">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue