Merge remote-tracking branch 'origin/develop' into feature/public_page

# Conflicts:
#	README.rst
#	config.php.sample
#	src/includes/psmconfig.inc.php
#	src/lang/en_US.lang.php
#	src/psm/Module/User/Controller/UserController.php
#	src/psm/Util/Install/Installer.php
This commit is contained in:
TimZ99 2020-08-24 22:27:51 +02:00
commit e599c18f0b
No known key found for this signature in database
GPG Key ID: 4D8268DC68E8339D
97 changed files with 3288 additions and 911 deletions

2
.github/FUNDING.yml vendored
View File

@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
custom: ["https://www.paypal.me/TimZandbergen99", "https://bunq.me/t"]

View File

@ -23,8 +23,9 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- Version [e.g. 3.3.5, develop]
**Version (please complete the following information):**
- Version [e.g. 3.3.5]
- PHP [e.g. 7.3]
**Additional context**
Add any other context about the problem here.

View File

@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: "[Feature Request]"
labels: ''
labels: 'Type: Feature'
assignees: ''
---

View File

@ -2,7 +2,7 @@
name: Question
about: Ask your questions
title: "[Question] "
labels: ''
labels: 'Type: Question'
assignees: ''
---

2
.gitignore vendored
View File

@ -10,3 +10,5 @@
*.bak
__MACOSX/
.DS_Store
.buildpath
.settings/

View File

@ -6,6 +6,23 @@ Not yet released
----------------
\-
v3.5.2 (released August 12, 2020)
-----------------------------
* Fixed missing version numbers.
* See https://github.com/phpservermon/phpservermon/compare/v3.5.1...v3.5.2
v3.5.1 (released August 12, 2020)
-----------------------------
* Security update regaring jQuery, see #972.
* See https://github.com/phpservermon/phpservermon/compare/v3.5.0...v3.5.1
v3.5.0 (released May 1, 2020)
-----------------------------
* See https://github.com/phpservermon/phpservermon/compare/v3.4.5...v3.5.0
v3.4.5 (released September 30, 2019)
------------------------------------

0
Makefile Executable file → Normal file
View File

27
README.rst Executable file → Normal file
View File

@ -5,7 +5,7 @@ PHP Server Monitor
:alt: Join the chat at https://gitter.im/erickrf/nlpnet
:target: https://gitter.im/phpservermon/phpservermon
Version 3.6.0
Version 3.6.0.beta2
PHP Server Monitor is a script that checks whether your websites and servers are up and running.
It comes with a web based user interface where you can manage your services and websites,
@ -16,7 +16,7 @@ Features:
---------
* Monitor services and websites (see below).
* Email, SMS, Pushover, Telegram notifications.
* Email, SMS, Discord, Pushover, Telegram and Jabber notifications.
* View history graphs of uptime and latency.
* User authentication with 2 levels (administrator and regular user).
* Logs of connection errors, outgoing emails and text messages.
@ -39,7 +39,7 @@ There are two different ways to monitor a server:
In both cases the script will return a "status offline", and will start sending out notifications.
Each server has its own settings regarding notification.
You can choose for email, text message (SMS), Pushover.net and Telegram notifications.
You can choose for email, text message (SMS), Pushover.net, Telegram and Jabber notifications.
The following SMS gateways are currently available:
* Clickatell - <https://www.clickatell.com>
@ -60,6 +60,8 @@ The following SMS gateways are currently available:
* SolutionsInfini - <https://solutionsinfini.com/>
* Plivo - <https://www.plivo.com/>
* Callr - <https://www.callr.com/>
* SMSAPI - <https://www.smsapi.com/en>
* OVH SMS PRO - <https://www.ovhtelecom.fr/sms/>
@ -79,10 +81,19 @@ Requirements
* MySQL database
* For PHP5: 5.5.9+
* For PHP7: 7.0.8+
* PHP cURL package
* PHP PDO mysql driver
* PHP-XML
* PHP Extensions (modules)
* ext-curl
* ext-ctype
* ext-filter
* ext-hash
* ext-json
* ext-libxml
* ext-openssl
* ext-pdo
* ext-pcre
* ext-sockets
* ext-xml
Install
-------
@ -105,7 +116,7 @@ If you are familiar with Vagrant (https://www.vagrantup.com)::
Documentation
-------------
The documentation is available in the docs folder or http://docs.phpservermonitor.org.
The documentation is available in the docs folder or https://docs.phpservermonitor.org.
License
@ -122,7 +133,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PHP Server Monitor. If not, see http://www.gnu.org/licenses/.
along with PHP Server Monitor. If not, see https://www.gnu.org/licenses/.
Docker
-------

6
composer.json Executable file → Normal file
View File

@ -6,6 +6,7 @@
"require": {
"php": "^5.5.9|>=7.0.8",
"ext-curl": "*",
"ext-json": "*",
"ext-pdo": "*",
"ext-xml": "*",
"phpmailer/phpmailer": ">=6.0.6 ~6.0",
@ -16,7 +17,8 @@
"symfony/filesystem": "~3.4",
"php-pushover/php-pushover": "dev-master",
"paragonie/random_compat": "^2.0",
"twig/twig": "~1.35"
"twig/twig": "~1.35",
"jaxl/jaxl": "^3.1"
},
"autoload": {
"files": [
@ -27,4 +29,4 @@
"psm\\": "src/psm/"
}
}
}
}

85
composer.lock generated
View File

@ -4,8 +4,81 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "b2a2bd93aeb6abf9b4e1905aa7ea4217",
"content-hash": "f78e950e2dfef7debe88d7b64e2b4aec",
"packages": [
{
"name": "jaxl/jaxl",
"version": "v3.1.0",
"source": {
"type": "git",
"url": "https://github.com/jaxl/JAXL.git",
"reference": "27aa43c4600b05809779428843d8d51db6ce6e0d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jaxl/JAXL/zipball/27aa43c4600b05809779428843d8d51db6ce6e0d",
"reference": "27aa43c4600b05809779428843d8d51db6ce6e0d",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-hash": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-openssl": "*",
"ext-pcre": "*",
"ext-sockets": "*",
"php": ">=5.2.4"
},
"require-dev": {
"phpunit/phpunit": "^3.7.0",
"squizlabs/php_codesniffer": "*"
},
"suggest": {
"ext-pcntl": "Interrupt JAXL with signals"
},
"bin": [
"jaxlctl"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1.x-dev"
}
},
"autoload": {
"classmap": [
"src/JAXL"
],
"exclude-from-classmap": [
"/tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Abhinavsingh",
"homepage": "https://abhinavsingh.com/"
}
],
"description": "Jaxl - Async, Non-Blocking, Event based Networking Library in PHP.",
"homepage": "http://jaxl.readthedocs.org/en/latest/index.html",
"keywords": [
"abhinavsingh",
"asynchronous",
"event loop",
"http",
"jabber",
"jaxl",
"non blocking",
"php",
"xmpp"
],
"time": "2016-09-13T01:59:35+00:00"
},
{
"name": "paragonie/random_compat",
"version": "v2.0.18",
@ -87,16 +160,16 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.1.3",
"version": "v6.1.6",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a25ae38e03de4ee4031725498a600012364787c7"
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a25ae38e03de4ee4031725498a600012364787c7",
"reference": "a25ae38e03de4ee4031725498a600012364787c7",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"reference": "c2796cb1cb99d7717290b48c4e6f32cb6c60b7b3",
"shasum": ""
},
"require": {
@ -145,7 +218,7 @@
}
],
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"time": "2019-11-21T09:37:46+00:00"
"time": "2020-05-27T12:24:03+00:00"
},
{
"name": "psr/container",

1
config.php.sample Executable file → Normal file
View File

@ -6,4 +6,5 @@ define('PSM_DB_NAME', 'db_name');
define('PSM_DB_HOST', 'localhost');
define('PSM_DB_PORT', '3306'); //3306 is the default port for MySQL. If no specfic port is used, leave it empty.
define('PSM_BASE_URL', '');
define('PSM_WEBCRON_KEY', '');
define('PSM_PUBLIC', true);

View File

@ -28,6 +28,9 @@
namespace {
// include main configuration and functionality
use psm\Router;
use psm\Util\Server\UpdateManager;
require_once __DIR__ . '/../src/bootstrap.php';
if (!psm_is_cli()) {
@ -41,7 +44,10 @@ namespace {
$data = @unserialize(PSM_CRON_ALLOW);
$allow = $data === false ? PSM_CRON_ALLOW : $data;
if (!in_array($_SERVER['REMOTE_ADDR'], $allow) && !in_array($_SERVER["HTTP_X_FORWARDED_FOR"], $allow)) {
if (!in_array($_SERVER['REMOTE_ADDR'], $allow) && !in_array($_SERVER["HTTP_X_FORWARDED_FOR"], $allow)
&& ! (array_key_exists ("webcron_key", $_GET) &&
$_GET["webcron_key"]==PSM_WEBCRON_KEY && (PSM_WEBCRON_KEY != ""))
) {
header('HTTP/1.0 403 Forbidden');
die('
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html>
@ -81,21 +87,79 @@ namespace {
// however if the cron has been running for X mins, we'll assume it died and run anyway
// if you want to change PSM_CRON_TIMEOUT, have a look in src/includes/psmconfig.inc.php.
// or you can provide the --timeout=x argument
$status = null;
if (PHP_SAPI === 'cli') {
$shortOptions = 's:'; // status
$longOptions = [
'status:'
];
$options = getopt($shortOptions, $longOptions);
$possibleValues = [
'on' => 'on',
'1' => 'on',
'up' => 'on',
'off' => 'off',
'0' => 'off',
'down' => 'off'
];
if (
true === array_key_exists('status', $options) &&
true === array_key_exists(strtolower($options['status']), $possibleValues)
) {
$status = $possibleValues[$options['status']];
} elseif (
true === array_key_exists('s', $options) &&
true === array_key_exists(strtolower($options['s']), $possibleValues)
) {
$status = $possibleValues[$options['s']];
}
}
if ($status === 'off') {
$confPrefix = 'cron_off_';
} else {
$confPrefix = 'cron_';
}
$time = time();
if (
psm_get_conf('cron_running') == 1
psm_get_conf($confPrefix . 'running') == 1
&& $cron_timeout > 0
&& ($time - psm_get_conf('cron_running_time') < $cron_timeout)
&& ($time - psm_get_conf($confPrefix . 'running_time') < $cron_timeout)
) {
die('Cron is already running. Exiting.');
}
if (!defined('PSM_DEBUG') || !PSM_DEBUG) {
psm_update_conf('cron_running', 1);
psm_update_conf($confPrefix . 'running', 1);
}
psm_update_conf('cron_running_time', $time);
psm_update_conf($confPrefix . 'running_time', $time);
/** @var Router $router */
/** @var UpdateManager $autorun */
$autorun = $router->getService('util.server.updatemanager');
$autorun->run(true);
psm_update_conf('cron_running', 0);
if ($status !== 'off') {
$autorun->run(true, $status);
} else {
set_time_limit(60);
if (false === defined('CRON_DOWN_INTERVAL')) {
define('CRON_DOWN_INTERVAL', 5); // every 5 second call update
}
$start = time();
$i = 0;
while ($i < 59) {
$autorun->run(true, $status);
if ($i < (59 - CRON_DOWN_INTERVAL)) {
time_sleep_until($start + $i + CRON_DOWN_INTERVAL);
}
$i += CRON_DOWN_INTERVAL;
}
}
psm_update_conf($confPrefix . 'running', 0);
}

View File

@ -51,9 +51,9 @@ copyright = u'2008-2017, Pepijn Over'
# built documents.
#
# The short X.Y version.
version = '3.4.5'
version = '3.6'
# The full version, including alpha/beta/rc tags.
release = version
release = '3.6.0.beta2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -85,6 +85,14 @@ The following people have contributed to the development of PHP Server Monitor:
* Nexmo SMS gateway
* Mateusz Małek - https://github.com/mateuszmalek
* SMSAPI gateway
* Daniel Krusky - https://github.com/dkrusky
* Discord webhook support
Translators
+++++++++++
@ -192,3 +200,4 @@ The following libraries are being used by PHP Server Monitor:
* PHP-Pushover - https://github.com/kryap/php-pushover
* Symfony - https://symfony.com
* Random_compat - https://github.com/paragonie/random_compat
* Hammer.js - https://github.com/hammerjs/hammer.js

View File

@ -61,7 +61,7 @@ The other way is to parse the access logs created by your webserver software, wh
When using tools such as Google Analytics, the monitor requests will not show up in your statistics, because the monitor does not execute any Javascript.
Tools that parse your raw access logs like Awstats, will include the requests made by the monitor.
To make sure these requests can be identified, the monitor uses a custom user agent, which you can usually filter out. The user agent of the monitor looks like::
To make sure these requests can be identified, the monitor uses a custom user agent, which you can usually filter out. The user agent can be modified in the config section, but bij default looks like::
Mozilla/5.0 (compatible; phpservermon/3.0.1; +http://www.phpservermonitor.org)
@ -169,3 +169,16 @@ What is the username of my bot?
1. Go to profile on the monitor.
2. Press activate.
3. A button will appear, this will direct you to your Telegram bot.
How do I setup Jabber notifications from Google account?
--------------------------------------------------------
A few steps are required to get Jabber notifications working for Google account.
You need to be an administrator for this part.
1. Go into you Google Account Security settings (https://myaccount.google.com/security).
2. Check that you have two factor auth enabled. If not, activate it.
3. Add new app password - copy it.
4. Login to PhpServerMonitor dashboard > config > Jabber and use password from step 3 with your Google account in PhpServerMonitor jabber settings.
5. As host use `talk.google.com`.
6. As username use your whole Google account (for example `example@google.com`).
7. As port use `5223` (really, not typo error ...).

View File

@ -50,6 +50,8 @@ For a regular upgrade, follow these steps:
* Follow the steps
* Enjoy
Alternatively you can use updater.sh script.
From 2.0
--------
@ -92,6 +94,16 @@ Please note that some distros have user-specific crontabs (e.g. Debian). If that
*/15 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php
If you want to check in different intervals online and offline servers you can use attribute `-s` (or `--status`) with value `on` or `off`.
So for example you want to check your servers which are online every 10 minutes and offline every 5 seconds. So configure two cron jobs::
*/10 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php -s on
*/1 * * * * /usr/bin/php /var/www/html/phpservermon/cron/status.cron.php -s off
By default `off` servers are checked every 5 seconds. If you want to change it add into your config file this constant with required value in seconds::
define('CRON_DOWN_INTERVAL', 1); // every 1 second call update
The update script has been designed to prevent itself from running multiple times. It has a maximum timeout of 10 minutes.
After that the script is assumed dead and the cronjob will run again.
If you want to change the 10 minutes timeout, find the constant "PSM_CRON_TIMEOUT" in src/includes/psmconfig.inc.php.
@ -136,6 +148,13 @@ In config.php add following line::
After that, you can hit the url http(s)://"yourmonitor.com"/cron/status.cron.php over the web from your allowed IP.
Alternatively, define a secret key to allow the update over the web:
In config.php add following line::
define('PSM_WEBCRON_KEY', 'YOURKEY');
After that, you can hit the url http(s)://"yourmonitor.com"/cron/status.cron.php?webcron_key=YOURKEY .
Troubleshooting
+++++++++++++++
@ -144,3 +163,4 @@ If you have problems setting up or accessing your monitor and do not know why, e
To enable debug mode, add the following line to your config.php file::
define('PSM_DEBUG', true);

View File

@ -15,7 +15,7 @@ Features
++++++++
* Monitor services and websites (see below).
* Email, SMS, Pushover and Telegram notifications.
* Email, SMS, Pushover, Telegram and Jabber notifications.
* View history graphs of uptime and latency.
* User authentication with 2 levels (administrator and regular user).
* Logs of connection errors, outgoing emails and text messages.
@ -44,7 +44,7 @@ There are two different ways to monitor a server:
Notifications
-------------
Each server has its own settings regarding notification.
You can choose for email, text message (SMS), Pushover.net and Telegram notifications.
You can choose for email, text message (SMS), Pushover.net, Telegram and Jabber notifications.
The following SMS gateways are currently available:
* Clickatell - <https://www.clickatell.com>

2
logs/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

0
manifest.json Executable file → Normal file
View File

0
phpservermon.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

2
service-worker.js Executable file → Normal file
View File

@ -1,7 +1,7 @@
var dataCacheName = 'PSM-v1';
var cacheName = 'PSM-PWA-final-1';
var filesToCache = [
'/',
'',
'index.php',
'src/templates/default/static/js/history.js',
'src/templates/default/static/js/scripts.js',

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@
/**
* Current PSM version
*/
define('PSM_VERSION', '3.6.0');
define('PSM_VERSION', '3.6.0.beta2');
/**
* URL to check for updates. Will not be checked if turned off on config page.
@ -130,3 +130,15 @@ if (!defined('PSM_MODULE_DEFAULT')) {
*/
define('PSM_MODULE_DEFAULT', 'server_status');
}
if (defined('PSM_JABBER_FORCE_TLS') === false) {
define('PSM_JABBER_FORCE_TLS', true);
}
if (defined('PSM_JABBER_AUTH_TYPE') === false) {
// possible values: PLAIN, X-OAUTH2, DIGEST-MD5, CRAM-MD5, SCRAM-SHA-1, ANONYMOUS, EXTERNAL
define('PSM_JABBER_AUTH_TYPE', 'PLAIN'); // default just plain because of google for example :(
}
if (defined('PSM_JABBER_DEBUG_LEVEL') === false) {
// possible values: ERROR, WARNING, NOTICE, INFO, DEBUG
define('PSM_JABBER_DEBUG_LEVEL', JAXLLogger::WARNING);
}

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'преди минута',
'seconds_ago' => 'преди %d секунди',
'a_second_ago' => 'преди секунда',
'seconds' => 'секунди',
),
'menu' => array(
'config' => 'Настройки',
@ -99,8 +100,8 @@ $sm_lang = array(
'pushover' => 'Pushover',
'pushover_description' => 'Pushover е услуга, която улеснява получаването на
известия в реално време. Посетете <a
href="https://pushover.net/">техния сайт</a> за повече
информация.',
href="https://pushover.net/" target="_blank">техния сайт</a> за
повече информация.',
'pushover_key' => 'Pushover Ключ',
'pushover_device' => 'Pushover Устройство',
'pushover_device_description' => 'Име на устройство, което да получава
@ -219,8 +220,6 @@ $sm_lang = array(
'email_smtp' => 'Активиране на SMTP',
'email_smtp_host' => 'SMTP сървър',
'email_smtp_port' => 'SMTP порт',
'email_smtp_security' => 'SMTP security',
'email_smtp_security_none' => 'None',
'email_smtp_username' => 'SMTP потребителско име',
'email_smtp_password' => 'SMTP парола',
'email_smtp_noauth' => 'Оставете празно за "без аутентикация"',
@ -232,8 +231,8 @@ $sm_lang = array(
'pushover_status' => 'Позволява изпращането на Pushover съобщения',
'pushover_description' => 'Pushover е услуга, която улеснява получаването на
известия в реално време. Посетете <a
href="https://pushover.net/">техния сайт</a> за повече
информация.',
href="https://pushover.net/" target="_blank">техния сайт</a> за
повече информация.',
'pushover_clone_app' => 'Кликнете тук за да създаване на вашият Pushover App',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Преди да използвате Pushover, трябва да <a
@ -267,7 +266,6 @@ $sm_lang = array(
системата',
'log_sms' => 'Да се пази ли лог на изпратените SMS съобщения от
системата',
'log_pushover' => 'Log pushover messages sent by the script',
'updated' => 'Настройките са обновени успешно.',
'tab_email' => 'Имейл',
'tab_sms' => 'SMS',

View File

@ -109,16 +109,17 @@ $sm_lang = array(
'email' => 'Correu',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover és un servei que fa fàcil obtenir notificacions en temps real. Veieu <a
href="https://pushover.net/">la seva web</a> per a més informació.',
href="https://pushover.net/" target="_blank">la seva web</a> per a més
informació.',
'pushover_key' => 'Clau Pushover',
'pushover_device' => 'Dispositiu Pushover',
'pushover_device_description' => 'Nom del dispositiu al qual enviar els missatges. Deixau en blanc per enviar
a tots els dispositius.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> és una app de missatgeria que
facilita el rebre notificacions en temps real. Consulteu la <a
href="http://docs.phpservermonitor.org/">documentació</a> per a més informació i
per saber com instal·lar-ho.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> és una app de
missatgeria que facilita el rebre notificacions en temps real. Consulteu la <a
href="http://docs.phpservermonitor.org/" target="_blank">documentació</a> per a
més informació i per saber com instal·lar-ho.',
'telegram_chat_id' => 'Codi ID del xat a Telegram',
'telegram_chat_id_description' => 'Els missatges seran enviats al xat de Telegram amb aquest ID.',
'telegram_get_chat_id' => 'Premeu aquí per a obtenir el codi ID del vostre xat',
@ -298,15 +299,14 @@ $sm_lang = array(
target="_blank">registrar una app</a> al seu portal web i introduïr
aquí el Token de la API.',
'telegram_status' => 'Permetre l\'enviament de missatges per Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> és una app de xat (mòbil i PC) que
facilita la recepció de notificacions en temps real. Veieu la <a
href="http://docs.phpservermonitor.org/">documentació</a> per saber més i saber
com activar-ho.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> és una app de xat
(mòbil i PC) que facilita la recepció de notificacions en temps real. Veieu la <a
href="http://docs.phpservermonitor.org/" target="_blank">documentació</a> per
saber més i saber com activar-ho.',
'telegram_api_token' => 'Token de l\'API de Telegram',
'telegram_api_token_description' => 'Abans de poder emprar Telegram necessiteu obtenir un token de l\'API.
Consulteu la <a
href="http://docs.phpservermonitor.org/">documentació</a> per saber
més.',
Consulteu la <a href="http://docs.phpservermonitor.org/"
target="_blank">documentació</a> per saber més.',
'alert_type' => 'Seleccioneu quan voleu ser notificats.',
'alert_type_description' => '<b>Canvi d\'estat:</b> Rebreu una notificació quan un servidor tingui un canvi
d\'estat. És a dir, passi d\'estar en línia a fora de línia o viceversa.<br
@ -347,7 +347,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-recàrrega',
'auto_refresh_description' => 'Recarregar automàticament la plana Servidors.<br/><span class="small">Temps en
segons, si poseu ZERO la plana no s\'auto-recarregarà.</span>',
'seconds' => 'segons',
'test' => 'Provar',
'test_email' => 'S\'enviarà un correu a l\'adreça que teniu al vostre perfil d\'usuari.',
'test_sms' => 'S\'enviarà un SMS al telèfon que teniu al vostre perfil d\'usuari.',

View File

@ -68,6 +68,7 @@ $sm_lang = array(
'a_minute_ago' => 'cca před minutou',
'seconds_ago' => 'před %d vteřinami',
'a_second_ago' => 'před chvílí',
'seconds' => 'sekunder',
),
'menu' => array(
'config' => 'Konfigurace',
@ -95,7 +96,7 @@ $sm_lang = array(
'email' => 'E-mail',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění.
Více na <a href="https://pushover.net/">webu Pushover</a>',
Více na <a href="https://pushover.net/" target="_blank">webu Pushover</a>',
'pushover_key' => 'Pushover Token',
'pushover_device' => 'Pushover Zařízení',
'pushover_device_description' => 'Název zařízení, na které být zráva odeslána. Ponechte prázdné
@ -227,7 +228,7 @@ $sm_lang = array(
'sms_from' => 'Telefonní číslo odesilatele',
'pushover_status' => 'Povolit zasílání Pushover zpráv',
'pushover_description' => 'Pushover je služba umožňující jednoduše zasílat real-time upozornění.
Více na <a href="https://pushover.net/">webu Pushover</a>',
Více na <a href="https://pushover.net/" target="_blank">webu Pushover</a>',
'pushover_clone_app' => 'Klikněte pro vytvoření Pushover aplikace',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Pře použitím Pushoveru se musíte <a href="%1$s" target="_blank"
@ -260,7 +261,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaticky obnovit',
'auto_refresh_description' => 'Automaticky obnovit stránku Servery.<br><span class="small">Čas v sekundách,
0 pro vypnutí automatického obnovení.</span>',
'seconds' => 'sekund',
'test' => 'Test',
'test_email' => 'E-mail bude odeslán na adresu uvedenou v uživatelském profilu.',
'test_sms' => 'SMS bude odeslána na telefonní číslo uvedené v uživatelském profilu.',

View File

@ -65,6 +65,7 @@ $sm_lang = array(
'a_minute_ago' => 'omkring et minut siden',
'seconds_ago' => '%d sekunder siden',
'a_second_ago' => 'et sekund siden',
'seconds' => 'sekunder',
),
'menu' => array(
'config' => 'Indstillinger',
@ -92,7 +93,8 @@ $sm_lang = array(
'email' => 'E-mail',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover er en service der gør det let at modtage real-time notifikationer. Se <a
href="https://pushover.net/">deres website</a> for mere information.',
href="https://pushover.net/" target="_blank">deres website</a> for mere
information.',
'pushover_key' => 'Pushover nøgle',
'pushover_device' => 'Pushover enhed',
'pushover_device_description' => 'Navnet enheden som beskeden skal sendes til. Lad denne være tom hvis
@ -208,7 +210,8 @@ $sm_lang = array(
'sms_from' => 'Afsenderens navn.',
'pushover_status' => 'Tillad at sende Pushover beskeder',
'pushover_description' => 'Pushover er en service det gør det nemt at modtage real-time notifikationer. Se <a
href="https://pushover.net/">deres website</a> for yderligere information.',
href="https://pushover.net/" target="_blank">deres website</a> for yderligere
information.',
'pushover_clone_app' => 'Klik her for at oprette din Pushover app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Før du kan benytte Pushover, skal du <a href="%1$s" target="_blank"
@ -243,7 +246,6 @@ $sm_lang = array(
'auto_refresh' => 'Genopfrisk automatisk',
'auto_refresh_description' => 'Genopfrisk automatisk serversider.<br><span class="small">Tid i sekunder. Hvis
0 vil siden ikke genopfriske automatisk</span>',
'seconds' => 'sekunder',
'test' => 'Test',
'test_email' => 'En e-mail vil blive sendt til den adresse, der er angivet i din brugerprofil.',
'test_sms' => 'En SMS vil blive sendt til det nummer, der er angivet i din brugerprofil.',

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'vor über einer Minute',
'seconds_ago' => 'vor %d Sekunden',
'a_second_ago' => 'vor über einer Sekunde',
'seconds' => 'Sekunden',
),
'menu' => array(
'config' => 'Einstellungen',
@ -93,8 +94,8 @@ $sm_lang = array(
'email' => 'E-Mail',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in
Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/">pushover.net</a>
für weitere Informationen.',
Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/"
target="_blank">pushover.net</a> für weitere Informationen.',
'pushover_key' => 'Pushover Key/Schlüssel',
'pushover_device' => 'Pushover Gerät',
'pushover_device_description' => 'Name des Gerätes, an das die Nachricht gesendet werden soll. Leer lassen,
@ -213,8 +214,8 @@ $sm_lang = array(
'sms_from' => 'SMS-Sendernummer',
'pushover_status' => 'Ermögliche das Senden von Pushover-Nachrichten',
'pushover_description' => 'Pushover ist ein Dienst, der es stark vereinfacht, Statusbenachrichtigungen in
Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/">pushover.net</a>
für weitere Informationen.',
Echtzeit zu erhalten. Besuchen Sie <a href="https://pushover.net/"
target="_blank">pushover.net</a> für weitere Informationen.',
'pushover_clone_app' => 'Klicken Sie hier, um Ihre Pushover-Anwendung zu erstellen',
'pushover_api_token' => 'Pushover-Anwendungs-API-Token',
'pushover_api_token_description' => 'Bevor Sie Pushover verwenden können, müssen Sie Ihre <a href="%1$s"
@ -249,7 +250,6 @@ $sm_lang = array(
'auto_refresh_description' => 'Automatische Aktualisierung der Server-Übersichtsseite<br><span
class="small">Zeit in Sekunden - die Ziffer \'0\' deaktiviert die automatische
Aktualisierung.</span>',
'seconds' => 'Sekunden',
'test' => 'Test',
'test_email' => 'Eine E-Mail wird an die E-Mail-Adresse gesendet, die in Ihrem Profil hinterlegt ist.',
'test_sms' => 'Eine SMS wird an die Telefonnummer gesendet, die in Ihrem Profil hinterlegt ist.',

View File

@ -50,9 +50,7 @@ $sm_lang = array(
'no' => 'No',
'insert' => 'Insert',
'add_new' => 'Add new',
'update_available' => 'A new version ({version}) is available. Click <a
href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank"
rel="noopener">here</a> to download the update.',
'update_available' => 'A new version ({version}) is available. Click <a href="https://github.com/phpservermon/phpservermon/releases/latest" target="_blank" rel="noopener">here</a> to download the update.',
'back_to_top' => 'Back to top',
'go_back' => 'Go back',
'ok' => 'OK',
@ -83,6 +81,8 @@ $sm_lang = array(
'minutes' => 'minutes',
'second' => 'second',
'seconds' => 'seconds',
'millisecond' => 'millisecond',
'milliseconds' => 'milliseconds',
'current' => 'current',
'settings' => 'Settings',
'search' => 'Search',
@ -113,27 +113,33 @@ $sm_lang = array(
'mobile' => 'Mobile',
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a
href="https://pushover.net/">their website</a> for more info.',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/" target="_blank">their website</a> for more info.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Device name to send the message to. Leave empty to send it to all devices.',
'discord' => 'Discord',
'discord_label' => 'Discord',
'discord_description' => 'Put your <a href="https://discordjs.guide/popular-topics/webhooks.html" target="_blank">webhook</a> here.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to
get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for more info and an
install guide.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> is a chat app that makes it easy to get real-time notifications. Visit the <a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for more info and an install guide.',
'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'The message will be send to the corresponding chat.',
'telegram_get_chat_id' => 'Click here to get your chat id',
'activate_telegram' => 'Activate Telegram notifications',
'activate_telegram_description' => 'Allow Telegram notifications to be sent to the specified chat id. Without
this permission, Telegram doesn\'t allow us to send notifications to you.',
'telegram_bot_username_found' => 'The bot was found!<br><a href="%s" target="_blank" rel="noopener"><button
class="btn btn-primary">Next step</button></a> <br>This will open a chat
with the bot. Here you need to press start of type /start.',
'activate_telegram_description' => 'Allow Telegram notifications to be sent to the specified chat id. Without this permission, Telegram doesn\'t allow us to send notifications to you.',
'telegram_bot_username_found' => 'The bot was found!<br><a href="%s" target="_blank" rel="noopener"><button class="btn btn-primary">Next step</button></a> <br>This will open a chat with the bot. Here you need to press start or type /start.',
'telegram_bot_username_error_token' => '401 - Unauthorized. Please make sure that the API token is valid.',
'telegram_bot_error' => 'An error has occurred while activating Telegram notification: %s',
'jabber' => 'Jabber',
'jabber_label' => 'Jabber',
'jabber_description' => 'You Jabber account',
'webhook' => 'Webhook',
'webhook_description' => 'Send a json webhook to a certain endpoint. <br/> The json can be customized, e.g. {
"text":"servermon: #message"}',
'webhook_url' => 'Webhook Url',
'webhook_url_description' => 'Webhook public endpoint url, should start with https://.',
'webhook_json' => 'Webhook JSON',
'webhook_json_description' => 'Define a custom json, use #message as message variable.',
'delete_title' => 'Delete User',
'delete_message' => 'Are you sure you want to delete user \'%1\'?',
'deleted' => 'User deleted.',
@ -142,8 +148,7 @@ $sm_lang = array(
'profile' => 'Profile',
'profile_updated' => 'Your profile has been updated.',
'error_user_name_bad_length' => 'Usernames must be between 2 and 64 characters.',
'error_user_name_invalid' => 'The username may only contain alphabetic characters (a-z, A-Z), digits (0-9),
dots (.) and underscores (_).',
'error_user_name_invalid' => 'The username may only contain alphabetic characters (a-z, A-Z), digits (0-9), dots (.) and underscores (_).',
'error_user_name_exists' => 'The given username already exists in the database.',
'error_user_email_bad_length' => 'Email addresses must be between 5 and 255 characters.',
'error_user_email_invalid' => 'The email address is invalid.',
@ -160,8 +165,11 @@ $sm_lang = array(
'status' => 'Status',
'email' => 'Email',
'sms' => 'SMS',
'discord' => 'Discord',
'pushover' => 'Pushover',
'webhook' => 'Webhook',
'telegram' => 'Telegram',
'jabber' => 'Jabber',
'no_logs' => 'No logs',
'clear' => 'Clear log',
'delete_title' => 'Delete log',
@ -197,17 +205,13 @@ $sm_lang = array(
'type_service' => 'Service',
'type_ping' => 'Ping',
'pattern' => 'Search string/pattern',
'pattern_description' => 'If this pattern is not found on the website, the server will be marked
online/offline. Regular expressions are allowed.',
'pattern_description' => 'If this pattern is not found on the website, the server will be marked online/offline. Regular expressions are allowed.',
'pattern_online' => 'Pattern indicates website is',
'pattern_online_description' => 'Online: If this pattern was found on the website, the server will be marked
online. Offline: If this pattern was not found on the website, the server
will be marked offline.',
'pattern_online_description' => 'Online: If this pattern was found on the website, the server will be marked online. Offline: If this pattern was not found on the website, the server will be marked offline.',
'redirect_check' => 'Redirecting to another domain is',
'redirect_check_description' => 'Redirect to another domain is usually a bad sign.',
'allow_http_status' => 'Allow HTTP status code',
'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as
online by default. Seperate with |.',
'allow_http_status_description' => 'Mark website as online. HTTP Status codes lower then 400 are marked as online by default. Seperate with |.',
'header_name' => 'Header name',
'header_value' => 'Header value',
'header_name_description' => 'Case-sensitive.',
@ -225,10 +229,16 @@ $sm_lang = array(
'send_email' => 'Send Email',
'sms' => 'SMS',
'send_sms' => 'Send SMS',
'discord' => 'Discord',
'send_discord' => 'Send Discord notification',
'webhook' => 'Webhook',
'send_webhook' => 'Send Webhook notification',
'pushover' => 'Pushover',
'send_pushover' => 'Send Pushover notification',
'telegram' => 'Telegram',
'send_telegram' => 'Send Telegram notification',
'jabber' => 'Jabber',
'send_jabber' => 'Send Jabber notification',
'users' => 'Users',
'delete_title' => 'Delete server',
'delete_message' => 'Are you sure you want to delete server \'%1\'?',
@ -249,6 +259,10 @@ $sm_lang = array(
'hour' => 'Hour',
'warning_threshold' => 'Warning threshold',
'warning_threshold_description' => 'Number of failed checks required before it is marked offline.',
'ssl_cert_expiry_days' => 'SSL Certificate Validity',
'ssl_cert_expiry_days_description' => 'The minimum remaining days the SSL certificate is still valid. Use 0 to disable check.',
'ssl_cert_expired' => 'SSL certificate expired since',
'ssl_cert_expiring' => 'SSL certificate expiring:',
'chart_last_week' => 'Last week',
'chart_history' => 'History',
'chart_day_format' => '%Y-%m-%d',
@ -257,8 +271,11 @@ $sm_lang = array(
'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => 'SMS notifications are disabled.',
'warning_notifications_disabled_email' => 'Email notifications are disabled.',
'warning_notifications_disabled_discord' => 'Discord notifications are disabled.',
'warning_notifications_disabled_webhook' => 'Webhook notifications are disabled.',
'warning_notifications_disabled_pushover' => 'Pushover notifications are disabled.',
'warning_notifications_disabled_telegram' => 'Telegram notifications are disabled.',
'warning_notifications_disabled_jabber' => 'Jabber notifications are disabled.',
'error_server_no_match' => 'Server not found.',
'error_server_label_bad_length' => 'The label must be between 1 and 255 characters.',
'error_server_ip_bad_length' => 'The domain / IP must be between 1 and 255 characters.',
@ -266,14 +283,15 @@ $sm_lang = array(
'error_server_ip_bad_website' => 'The website URL is not valid.',
'error_server_type_invalid' => 'The selected server type is invalid.',
'error_server_warning_threshold_invalid' => 'The warning threshold must be a valid integer greater than 0.',
'error_server_ssl_cert_expiry_days' => 'The remaining days for SSL certificate validity must be a valid integer greater than or equal to 0.',
),
'config' => array(
'general' => 'General',
'site_title' => 'Site title',
'language' => 'Language',
'show_update' => 'Check for updates?',
'password_encrypt_key' => 'The encryption key password',
'password_encrypt_key_note' => 'This key is used to encrypt passwords that are stored on servers for access to
websites. If the key will change the stored password is invalid!',
'password_encrypt_key_note' => 'This key is used to encrypt passwords that are stored on servers for access to websites. If the key will change the stored password is invalid!',
'proxy' => 'Enable proxy',
'proxy_url' => 'Proxy URL',
'proxy_user' => 'Proxy username',
@ -294,67 +312,84 @@ $sm_lang = array(
'sms_gateway_username' => 'Gateway username',
'sms_gateway_password' => 'Gateway password',
'sms_from' => 'Sender\'s phone number',
'discord_status' => 'Allow sending Discord messages',
'discord_description' => 'Discord is a service that makes it easy to get real-time notifications. See <a href="https://discord.com/" target="_blank">their website</a> for more info.',
'webhook_status' => 'Allow sending webhooks',
'webhook_description' => 'Allow sending webhooks to services like slack. The message payload end endpoint are defined in the profile settings.',
'webhook_url' => 'Webhook Url',
'webhook_url_description' => 'Url to webhook endpoint',
'webhook_json' => 'Webhook Json',
'webhook_json_description' => 'Customized Json, use #message as message variable.',
'pushover_status' => 'Allow sending Pushover messages',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a
href="https://pushover.net/">their website</a> for more info.',
'pushover_description' => 'Pushover is a service that makes it easy to get real-time notifications. See <a href="https://pushover.net/" target="_blank">their website</a> for more info.',
'pushover_clone_app' => 'Click here to create your Pushover app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank"
rel="noopener">register an App</a> at their website and enter the App API
Token here.',
'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank" rel="noopener">register an App</a> at their website and enter the App API Token here.',
'telegram_status' => 'Allow sending Telegram messages',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to
get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for more info and an
install guide.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> is a chat app that makes it easy to get real-time notifications. Visit the <a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for more info and an install guide.',
'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for help.',
'telegram_api_token_description' => 'Before you can use Telegram, you need to get a API token. Visit the <a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for help.',
'jabber_status' => 'Allow sending Jabber (XMPP) messages',
'jabber_description' => 'Visit the <a href="http://docs.phpservermonitor.org/">documentation</a> for more info and an install guide.',
'jabber_host' => 'Host',
'jabber_host_description' => 'Host of your Jabber account provider. For Google Account use talk.google.com.',
'jabber_port' => 'Port',
'jabber_port_description' => 'Port of your Jabber provider. Default 5222. For Google Account use 5223.',
'jabber_username' => 'Username',
'jabber_username_description' => 'For Google Account use incl. domain so for example example@google.com.',
'jabber_domain' => 'Domain',
'jabber_domain_description' => 'Domain of your Jabber provider. Left empty for Google Account.',
'jabber_password' => 'Password',
'jabber_password_description' => 'Fill only to set or change.',
'jabber_check' => 'Check your Jabber account if message was received.',
'alert_type' => 'Select when you\'d like to be notified.',
'alert_type_description' => '<b>Status change:</b> You will receive a notification when a server has a change
in status. So from online -> offline or offline -> online.<br><br><b>Offline:</b>
You will receive a notification when a server goes offline for the *FIRST TIME
ONLY*. For example, your cronjob is every 15 minutes and your server goes down at
1 am and stays down till 6 am. You will get 1 notification at 1 am and that\'s
it.<br><br><b>Always:</b> You will receive a notification every time the script
runs and a site is down, even if the site has been offline for hours.',
'alert_type_description' => '<b>Status change:</b> You will receive a notification when a server has a change in status. So from online -> offline or offline -> online.<br><br><b>Offline:</b> You will receive a notification when a server goes offline for the *FIRST TIME ONLY*. For example, your cronjob is every 15 minutes and your server goes down at 1 am and stays down till 6 am. You will get 1 notification at 1 am and that\'s it.<br><br><b>Always:</b> You will receive a notification every time the script runs and a site is down, even if the site has been offline for hours.',
'alert_type_status' => 'Status change',
'alert_type_offline' => 'Offline',
'alert_type_always' => 'Always',
'combine_notifications' => 'Combine notifications',
'combine_notifications_description' => 'Reduces the amount of notification by combining the notifications into
1 single notification. (This does not affect SMS notifications.)',
'combine_notifications_description' => 'Reduces the amount of notification by combining the notifications into 1 single notification. (This does not affect SMS notifications.)',
'alert_proxy' => 'Even if enabled, proxy is never used for services',
'alert_proxy_url' => 'Format: host:port',
'log_status' => 'Log status',
'log_status_description' => 'If log status is set to TRUE, the monitor will log the event whenever the
notification settings are passed.',
'log_status_description' => 'If log status is set to TRUE, the monitor will log the event whenever the notification settings are passed.',
'log_email' => 'Log emails sent by the script',
'log_sms' => 'Log text messages sent by the script',
'log_discord' => 'Log Discord messages sent by the script',
'log_pushover' => 'Log pushover messages sent by the script',
'log_webhook' => 'Log webhook messages sent by the script',
'log_telegram' => 'Log Telegram messages sent by the script',
'log_jabber' => 'Log Jabber messages sent by the script',
'updated' => 'The configuration has been updated.',
'tab_email' => 'Email',
'tab_sms' => 'SMS',
'tab_discord' => 'Discord',
'tab_pushover' => 'Pushover',
'tab_webhook' => 'Webhook',
'tab_telegram' => 'Telegram',
'tab_jabber' => 'Jabber',
'settings_email' => 'Email settings',
'settings_sms' => 'Text message settings',
'settings_discord' => 'Discord settings',
'settings_pushover' => 'Pushover settings',
'settings_webhook' => 'Webhook settings',
'settings_telegram' => 'Telegram settings',
'settings_jabber' => 'Jabber settings',
'settings_notification' => 'Notification settings',
'settings_log' => 'Log settings',
'settings_proxy' => 'Proxy settings',
'auto_refresh' => 'Auto-refresh',
'auto_refresh_description' => 'Auto-refresh servers page.<br><span class="small">Time in seconds, if 0 the
page won\'t refresh.</span>',
'seconds' => 'seconds',
'auto_refresh_description' => 'Auto-refresh servers page.<br><span class="small">Time in seconds, if 0 the page won\'t refresh.</span>',
'test' => 'Test',
'test_email' => 'An email will be sent to the address specified in your user profile.',
'test_sms' => 'An SMS will be sent to the phone number specified in your user profile.',
'test_discord' => 'A Discord notification will be sent to the webhook specified in your user profile.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user profile.',
'test_pushover' => 'A Pushover notification will be sent to the user key/device specified in your user
profile.',
'test_webhook' => 'A webhook notification will be sent to the given url endpoint.',
'test_telegram' => 'A Telegram notification will be sent to the chat id specified in your user profile.',
'test_jabber' => 'A Jabber notification will be sent to the jabber account specified in your user profile.',
'send' => 'Send',
'test_subject' => 'Test',
'test_message' => 'Test message',
@ -363,35 +398,55 @@ $sm_lang = array(
'sms_sent' => 'SMS sent',
'sms_error' => 'An error has occurred while sending the SMS: %s',
'sms_error_nomobile' => 'Unable to send test SMS: no valid phone number found in your profile.',
'discord_sent' => 'Discord notification sent',
'discord_error' => 'An error has occurred while sending the Discord notification: %s',
'discord_error_nowebhook' => 'Unable to send test Discord notification: no valid Discord webhook found in your user profile.',
'webhook_sent' => 'Webhook notification sent',
'webhook_error' => 'An error has occurred while sending the webhook notification: %s',
'webhook_error_nourl' => 'Unable to send test notification: no url found in user profile.',
'webhook_error_nojson' => 'Unable to send test notification: no json found in user profile.',
'pushover_sent' => 'Pushover notification sent',
'pushover_error' => 'An error has occurred while sending the Pushover notification: %s',
'pushover_error_noapp' => 'Unable to send test notification: no Pushover App API token found in the global
configuration.',
'pushover_error_noapp' => 'Unable to send test notification: no Pushover App API token found in the global configuration.',
'pushover_error_nokey' => 'Unable to send test notification: no Pushover key found in your profile.',
'telegram_sent' => 'Telegram notification sent',
'telegram_error' => 'An error has occurred while sending the Telegram notification: %s',
'telegram_error_notoken' => 'Unable to send test notification: no Telegram API token found in the global
configuration.',
'telegram_error_notoken' => 'Unable to send test notification: no Telegram API token found in the global configuration.',
'telegram_error_noid' => 'Unable to send test notification: no chat id found in your profile.',
'jabber_sent' => 'Telegram notification sent',
'jabber_error' => 'An error has occurred while sending the Telegram notification: %s',
'jabber_error_noconfig' => 'Unable to send test notification: no Jabber account set in the global configuration.',
'jabber_error_noaccount' => 'Unable to send test notification: no Jabber account found in your profile.',
'log_retention_period' => 'Log retention period',
'log_retention_period_description' => 'Number of days to keep logs of notifications and archives of server
uptime. Enter 0 to disable log cleanup.',
'log_retention_period_description' => 'Number of days to keep logs of notifications and archives of server uptime. Enter 0 to disable log cleanup.',
'log_retention_days' => 'days',
'user_agent' => 'User Agent',
'user_agent_key_note' => 'Custom user agent used by monitor within communication with external services.',
),
'notifications' => array(
'off_sms' => 'Server \'%LABEL%\' is DOWN: ip=%IP%, port=%PORT%. Error=%ERROR%',
'off_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is DOWN',
'off_email_body' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_discord_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_email_body' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port:
%PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_webhook_title' => 'Server \'%LABEL%\' is DOWN',
'off_webhook_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP:
%IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_pushover_title' => 'Server \'%LABEL%\' is DOWN',
'off_pushover_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP:
%IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_telegram_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP:
%IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_pushover_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_telegram_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'off_jabber_message' => 'Failed to connect to the following server:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Error: %ERROR%<br>Date: %DATE%',
'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%, it was down for %LAST_OFFLINE_DURATION%',
'on_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is RUNNING',
'on_email_body' => 'Server \'%LABEL%\' is running again, it was down for
%LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%',
'on_discord_message' => 'Server \'%LABEL%\' is running again, it was down for:
%LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date: %DATE%',
'on_webhook_title' => 'Server \'%LABEL%\' is RUNNING',
'on_webhook_message' => 'Server \'%LABEL%\' is running again, it was down for
%LAST_OFFLINE_DURATION%:<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%',
'on_pushover_title' => 'Server \'%LABEL%\' is RUNNING',
'on_pushover_message' => 'Server \'%LABEL%\' is running again, it was down for
@ -399,27 +454,50 @@ $sm_lang = array(
%DATE%',
'on_telegram_message' => 'Server \'%LABEL%\' is running again, it was down for:
%LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%',
'on_jabber_message' => 'Server \'%LABEL%\' is running again, it was down for:
%LAST_OFFLINE_DURATION%<br><br>Server: %LABEL%<br>IP: %IP%<br>Port: %PORT%<br>Date:
%DATE%',
'combi_off_email_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error:
%ERROR%</li><li>Date: %DATE%</li></ul>',
'combi_off_discord_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>-
Date: %DATE%<br><br>',
'combi_off_webhook_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error:
%ERROR%</li><li>Date: %DATE%</li></ul>',
'combi_off_pushover_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Error:
%ERROR%</li><li>Date: %DATE%</li></ul>',
'combi_off_telegram_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>-
Date: %DATE%<br><br>',
'combi_off_jabber_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Error: %ERROR%<br>-
Date: %DATE%<br><br>',
'combi_on_email_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port: %PORT%</li><li>Downtime:
%LAST_OFFLINE_DURATION%</li><li>Date: %DATE%</li></ul>',
'combi_on_webhook_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port:
%PORT%</li><li>Downtime: %LAST_OFFLINE_DURATION%</li><li>Date:
%DATE%</li></ul>',
'combi_on_discord_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>-
Downtime: %LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>',
'combi_on_pushover_message' => '<ul><li>Server: %LABEL%</li><li>IP: %IP%</li><li>Port:
%PORT%</li><li>Downtime: %LAST_OFFLINE_DURATION%</li><li>Date:
%DATE%</li></ul>',
'combi_on_telegram_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Downtime:
%LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>',
'combi_on_jabber_message' => '- Server: %LABEL%<br>- IP: %IP%<br>- Port: %PORT%<br>- Downtime:
%LAST_OFFLINE_DURATION%<br>- Date: %DATE%<br><br>',
'combi_email_subject' => 'IMPORTANT: \'%UP%\' servers UP again, \'%DOWN%\' servers DOWN',
'combi_webhook_subject' => '\'%UP%\' servers UP again, \'%DOWN%\' servers DOWN',
'combi_pushover_subject' => '\'%UP%\' servers UP again, \'%DOWN%\' servers DOWN',
'combi_email_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_discord_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_webhook_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_pushover_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_telegram_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
'combi_jabber_message' => '<b>The following servers went down:</b><br>%DOWN_SERVERS%<br><b>The following
servers are up again:</b><br>%UP_SERVERS%',
),
'login' => array(
@ -437,8 +515,7 @@ $sm_lang = array(
'password_forgot' => 'Forgot password?',
'password_reset' => 'Reset password',
'password_reset_email_subject' => 'Reset your password for PHP Server Monitor',
'password_reset_email_body' => 'Please use the following link to reset your password. Please note it expires
in 1 hour.<br><br>%link%',
'password_reset_email_body' => 'Please use the following link to reset your password. Please note it expires in 1 hour.<br><br>%link%',
'error_user_incorrect' => 'The provided username could not be found.',
'error_login_incorrect' => 'The information is incorrect.',
'error_login_passwords_nomatch' => 'The provided passwords do not match.',

View File

@ -116,17 +116,17 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo
real. Vea <a href="https://pushover.net/"> su página web </a> para más
información.',
real. Vea <a href="https://pushover.net/" target="_blank"> su página web </a> para
más información.',
'pushover_key' => 'Clave Pushover',
'pushover_device' => 'Dispositivo Pushover',
'pushover_device_description' => 'Nombre del dispositivo para enviar el mensaje. Dejar en blanco para enviarlo
a todos los dispositivos.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> is a chat app that makes it easy to
get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/">documentation</a> for more info and an
install guide.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> is a chat app that
makes it easy to get real-time notifications. Visit the <a
href="http://docs.phpservermonitor.org/" target="_blank">documentation</a> for more
info and an install guide.',
'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'El mensaje será enviado al chat correspondiente.',
'telegram_get_chat_id' => 'Haga click aquí para obtener su chat id',
@ -302,22 +302,22 @@ $sm_lang = array(
'sms_from' => 'Número origen del SMS',
'pushover_status' => '¿Habilitar el envío de mensajes Pushover?',
'pushover_description' => 'Pushover es un servicio que hace que sea fácil de obtener notificaciones en tiempo
real. Vea <a href="https://pushover.net/"> su página web </a> para más
información.',
real. Vea <a href="https://pushover.net/" target="_blank"> su página web </a> para
más información.',
'pushover_clone_app' => 'Haga clic aquí para crear tu aplicación Pushover',
'pushover_api_token' => 'Token API de Pushover',
'pushover_api_token_description' => 'Antes de poder utilizar Pushover, necesita <a href="%1$s" target="_blank"
rel="noopener"> registrar </a> su aplicación en la página web e
ingresar el token API.',
'telegram_status' => '¿Habilitar el envío de mensajes de Telegram?',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> es una aplicación de mensajería
instantánea que permite recibir notificaciones en tiempo real. Visite la <a
href="http://docs.phpservermonitor.org/">documentación</a> para una guía mas
detallada.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> es una aplicación de
mensajería instantánea que permite recibir notificaciones en tiempo real. Visite
la <a href="http://docs.phpservermonitor.org/" target="_blank">documentación</a>
para una guía mas detallada.',
'telegram_api_token' => 'Token API de Telegram',
'telegram_api_token_description' => 'Antes de utilizar Telegram, necesita un Token de API. Visite la <a
href="http://docs.phpservermonitor.org/">documentación</a> para más
información.',
href="http://docs.phpservermonitor.org/"
target="_blank">documentación</a> para más información.',
'alert_type' => '¿Cuándo desea recibir notificaciones?',
'alert_type_description' => '<b>Al cambiar el estado:</b> p.ej. en línea -> fuera de línea o fuera de línea
-> en línea.<br><br /><b>Fuera de Línea:</b> Recibirá una notificación cuando
@ -354,7 +354,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-actualizar',
'auto_refresh_description' => 'Auto-actualizar la página de servidores.<br><span class="small">Tiempo en
segundos, si se utiliza 0 la página no se actualizará.</span>',
'seconds' => 'segundos',
'test' => 'Prueba',
'test_email' => 'Un correo electrónico será enviado a la dirección especificada en su perfil de usuario.',
'test_sms' => 'Un SMS se enviará al número de teléfono especificado en su perfil de usuario.',

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'umbes minut aega tagasi',
'seconds_ago' => '%d sekundit tagasi',
'a_second_ago' => 'üks sekund tagasi',
'seconds' => 'sekundit',
),
'menu' => array(
'config' => 'Konfiguratsioon',
@ -93,7 +94,8 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata <a
href="https://pushover.net/">nende kodulehte</a> rohkema info jaoks.',
href="https://pushover.net/" target="_blank">nende kodulehte</a> rohkema info
jaoks.',
'pushover_key' => 'Pushoveri Võti',
'pushover_device' => 'Pushoveri Seade',
'pushover_device_description' => 'Seadme nimi, kuhu teavitus saata. Jäta tühjaks, et saata igale seadmele.',
@ -207,7 +209,8 @@ $sm_lang = array(
'sms_from' => 'Saatja telefoni number',
'pushover_status' => 'Luba Pushoveri sõnumite saatmine',
'pushover_description' => 'Pushover on teenus, mis teeb reaalaja teavitused imelihtsaks. Vaata <a
href="https://pushover.net/">nende kodulehte</a> rohkema info jaoks.',
href="https://pushover.net/" target="_blank">nende kodulehte</a> rohkema info
jaoks.',
'pushover_clone_app' => 'Kliki siia, et teha oma Pushover äpp',
'pushover_api_token' => 'Pushover Äppi API Žetoon',
'pushover_api_token_description' => 'Enne, kui saad Pushoverida pead sa <a href="%1$s" target="_blank"
@ -242,7 +245,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaatne värskendamine',
'auto_refresh_description' => 'Värskenda lehte automaatselt.<br><span class="small">Aeg sekundites, kui 0
siis lehte ei värskendata.</span>',
'seconds' => 'sekundit',
'test' => 'Test',
'test_email' => 'Email saadetakse profiilil märgitud aadressile.',
'test_sms' => 'SMS saadetakse profiilil märgitud numbrile.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'حدود یک دقیقه پیش',
'seconds_ago' => '%d ثانیه پیش',
'a_second_ago' => 'یک ثانیه پیش',
'seconds' => 'ثانیه',
),
'menu' => array(
'config' => 'تنظیم',
@ -97,7 +98,8 @@ $sm_lang = array(
'pushover' => 'Pushover',
'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ
را ساده می کند. برای اطلاعات بیشتر <a
href="https://pushover.net/">سایت آن ها</a> را ببینید.',
href="https://pushover.net/" target="_blank">سایت آن ها</a> را
ببینید.',
'pushover_key' => 'کلید Pushover',
'pushover_device' => 'دستگاه Pushover',
'pushover_device_description' => 'نام دستگاه برای ارسال پیام. برای ارسال به
@ -217,7 +219,8 @@ $sm_lang = array(
'pushover_status' => 'اجازه ارسال پیام های Pushover',
'pushover_description' => 'Pushover سرویسی است که دریافت اطلاعیه های بلادرنگ
را ساده می کند. برای اطلاعات بیشتر <a
href="https://pushover.net/">سایت آن ها</a> را ببینید.',
href="https://pushover.net/" target="_blank">سایت آن ها</a> را
ببینید.',
'pushover_clone_app' => 'برای ایجاد برنامه پوش آور خود اینجا را کلیک
کنید.',
'pushover_api_token' => 'رمز API برنامه پوش آور',
@ -261,7 +264,6 @@ $sm_lang = array(
'auto_refresh' => 'رفرش خودکار',
'auto_refresh_description' => 'رفرش خودکار صفحه سرورها.<br><span class="small">زمان
به ثنیه, اگر 0 باشد صفحه رفرش نخواهد شد.</span>',
'seconds' => 'ثانیه',
'test' => 'تست',
'test_email' => 'یک ایمیل به آدرس تعیین شده در پروفایل شما ارسال
خواهد شد.',

View File

@ -94,7 +94,7 @@ $sm_lang = array(
'email' => 'Sähköposti',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso
<a href="https://pushover.net/">verkkosivuilta</a> lisäinfoa.',
<a href="https://pushover.net/" target="_blank">verkkosivuilta</a> lisäinfoa.',
'pushover_key' => 'Pushover avain',
'pushover_device' => 'Pushover laite',
'pushover_device_description' => 'Laitteen nimi johon viesti lähetetään. Jätä tyhjäksi lähettääksesi
@ -209,7 +209,7 @@ $sm_lang = array(
'sms_from' => 'Lähettäjän puhelinnumero',
'pushover_status' => 'Salli Pushover-viestien lähetys',
'pushover_description' => 'Pushover on palvelu jolla on helppo lähettää reaaliaikaisia tilaviestejä. Katso
<a href="https://pushover.net/">verkkosivuilta</a> lisäinfoa.',
<a href="https://pushover.net/" target="_blank">verkkosivuilta</a> lisäinfoa.',
'pushover_clone_app' => 'Paina tästä luodaksesi Pushover-sovelluksesi',
'pushover_api_token' => 'Pushover API-avain',
'pushover_api_token_description' => 'Ennen kuin voit käyttää Pushoveria, sinun täytyy <a href="%1$s"
@ -244,7 +244,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaattipäivitys',
'auto_refresh_description' => 'Päivittää automaattisesti palvelimet-sivun.<br><span class="small">Aika
sekunteina, jos 0, sivu ei päivity automaattisesti.</span>',
'seconds' => 'sekuntia',
'test' => 'Testi',
'test_email' => 'Testisähköposti lähetetään profiilisi sähköpostiosoitteeseen.',
'test_sms' => 'Testitekstiviesti lähetetään profiilisi numeroon.',

View File

@ -113,16 +113,18 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir <a
href="https://pushover.net/">leur site web</a> pour plus d\'informations.',
href="https://pushover.net/" target="_blank">leur site web</a> pour plus
d\'informations.',
'pushover_key' => 'Clé Pushover',
'pushover_device' => 'Appareil Pushover',
'pushover_device_description' => 'Nom de l\'appareil auquel le message doit être envoyé. Laissez vide pour
l\'envoyer à tous les appareils.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> est une application de messagerie
instantanée qui facilite la réception de notification en temps réel. Lisez la <a
href="http://docs.phpservermonitor.org/">documentation</a> pour obtenir plus
d\'informations sur la configuration de ce service.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> est une application de
messagerie instantanée qui facilite la réception de notification en temps réel.
Lisez la <a href="http://docs.phpservermonitor.org/"
target="_blank">documentation</a> pour obtenir plus d\'informations sur la
configuration de ce service.',
'telegram_chat_id' => 'ID de conversation (Chat ID) Telegram',
'telegram_chat_id_description' => 'Les notifications seront envoyées à la conversation correspondante.',
'telegram_get_chat_id' => 'Cliquez ici pour obtenir votre ID de conversation (Chat ID)',
@ -302,22 +304,23 @@ $sm_lang = array(
'sms_from' => 'SMS de l\'expéditeur',
'pushover_status' => 'Autoriser l\'envoi des messages Pushover',
'pushover_description' => 'Pushover est un service qui simplifie les notifications en temps réel. Voir <a
href="https://pushover.net/">leur site web</a> pour plus d\'informations.',
href="https://pushover.net/" target="_blank">leur site web</a> pour plus
d\'informations.',
'pushover_clone_app' => 'Cliquez ici pour créer votre application Pushover',
'pushover_api_token' => 'Jeton application Pushover',
'pushover_api_token_description' => 'Avant de pouvoir utiliser Pushover, vous devez <a href="%1$s"
target="_blank" rel="noopener">créer une application</a> sur leur site
web et entrer ici le jeton (Token) de l\'application.',
'telegram_status' => 'Autorise l\'envoi de message Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> est une application de messagerie
instantanée qui facilite la réception de notification en temps réel. Lisez la <a
href="http://docs.phpservermonitor.org/">documentation</a> pour obtenir plus
d\'informations sur la configuration de ce service.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> est une application de
messagerie instantanée qui facilite la réception de notification en temps réel.
Lisez la <a href="http://docs.phpservermonitor.org/"
target="_blank">documentation</a> pour obtenir plus d\'informations sur la
configuration de ce service.',
'telegram_api_token' => 'Token API Telegram',
'telegram_api_token_description' => 'Afin de pouvoir utiliser Telegram, il vous faut obtenir un token api.
Consultez la <a
href="http://docs.phpservermonitor.org/">documentation</a> pour obtenir
de l\'aide.',
Consultez la <a href="http://docs.phpservermonitor.org/"
target="_blank">documentation</a> pour obtenir de l\'aide.',
'alert_type' => 'Choisissez quand vous souhaitez être notifié',
'alert_type_description' => '<b>Changement d\'état&nbsp;: </b>Vous recevez une notification chaque fois que
le serveur change d\'état. C\'est-à-dire passe de l\'état OK à HORS SERVICE
@ -358,7 +361,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-rachaîchissement',
'auto_refresh_description' => 'Auto-rachaîchissement de la page serveurs.<br><span class="small">Temps en
secondes. Si 0, la page n\'est pas rafraîchie.</span>',
'seconds' => 'secondes',
'test' => 'Tester',
'test_email' => 'Un email va vous être envoyé à l\'adresse définie dans votre profil utilisateur.',
'test_sms' => 'Un SMS va vous être envoyé au numéro défini dans votre profil utilisateur.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'circa un minuto fa',
'seconds_ago' => '%d secondi fa',
'a_second_ago' => 'un secondo fa',
'seconds' => 'secondi',
),
'menu' => array(
'config' => 'Configurazione',
@ -247,7 +248,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-Aggiornamento',
'auto_refresh_description' => 'Auto-Aggiornamento pagina servers.<br><span class="small">Tempo in secondi, se
impostato a 0 la pagina non si aggiornerà.</span>',
'seconds' => 'secondi',
'test' => 'Test',
'test_email' => 'Un Email verrà inviata all\'indirizzo specificato nel tuo profilo.',
'test_sms' => 'Un SMS verrà inviato al numero di telefono specificato nel tuo profilo.',

View File

@ -345,7 +345,6 @@ $sm_lang = array(
'auto_refresh' => '自動更新',
'auto_refresh_description' => 'サーバーページを自動更新します。<br><span
class="small">時間を秒で指定し、0に設定すると更新しません。</span>',
'seconds' => '秒',
'test' => 'テスト',
'test_email' => 'あなたのユーザープロフィールで指定されたアドレスに電子メールが送信されます。',
'test_sms' => 'あなたのユーザープロフィールで指定された電話番号にSMSが送信されます。',

View File

@ -81,6 +81,8 @@ $sm_lang = array(
'minutes' => 'minuten',
'second' => 'seconde',
'seconds' => 'seconden',
'millisecond' => 'milliseconde',
'milliseconds' => 'milliseconden',
'current' => 'huidig',
'settings' => 'Instellingen',
),
@ -110,8 +112,8 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te
ontvangen. Zie <a href="https://pushover.net/">hun website</a> voor meer
informatie.',
ontvangen. Zie <a href="https://pushover.net/" target="_blank">hun website</a> voor
meer informatie.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Apparaat waar de berichten naar toe gaan. Laat leeg voor alle apparaten.',
@ -244,6 +246,7 @@ $sm_lang = array(
),
'config' => array(
'general' => 'Algemeen',
'site_title' => 'Website titel',
'language' => 'Taal',
'show_update' => 'Controleer wekelijks voor updates?',
'email_status' => 'Sta email berichten toe?',
@ -264,8 +267,8 @@ $sm_lang = array(
'sms_from' => 'Telefoonnummer afzender',
'pushover_status' => 'Sta Pushover berichten toe?',
'pushover_description' => 'Pushover is een dienst die het gemakkelijk maakt om real-time notificaties te
ontvangen. Zie <a href="https://pushover.net/">hun website</a> voor meer
informatie.',
ontvangen. Zie <a href="https://pushover.net/" target="_blank">hun website</a> voor
meer informatie.',
'pushover_clone_app' => 'Klik hier om je Pushover app te maken',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Voordat je Pushover kunt gebruiken moet je een <a href="%1$s"
@ -308,7 +311,6 @@ $sm_lang = array(
'auto_refresh' => 'Herlaad automatisch',
'auto_refresh_description' => 'Auto-herladen servers pagina.<br><span class="small">Tijd in seconden, als de
tijd 0 is wordt de pagina niet ververst.</span>',
'seconds' => 'seconden',
'test' => 'Test',
'test_email' => 'Er zal een email verstuurd worden naar het email adres in je profiel.',
'test_sms' => 'Er zal een SMS verstuurd worden naar het telefoonnummer in je profiel.',
@ -336,6 +338,9 @@ $sm_lang = array(
'log_retention_period_description' => 'Aantal dagen dat logs van notificaties en archieven van server uptime
worden bewaard. Vul 0 in om log opruiming uit te zetten.',
'log_retention_days' => 'dagen',
'user_agent' => 'User Agent',
'user_agent_key_note' => 'Aangepaste user agent wordt door de monitor gebruikt bij de communicatie met externe
services.',
),
'notifications' => array(
'off_sms' => 'Server %LABEL% is DOWN: ip=%IP%, poort=%PORT%. Fout=%ERROR%',

View File

@ -107,16 +107,16 @@ $sm_lang = array(
'email' => 'E-post',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å meldinger i sanntid. Se <a
href="https://pushover.net/">deres nettside</a> for mer info.',
href="https://pushover.net/" target="_blank">deres nettside</a> for mer info.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Enhetsnavn for å sende meldingen til. La det være tomt for å sende det
til alle enheter.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> er en chat-app som gjør det enkelt å
meldinger i sanntid. til <a
href="http://docs.phpservermonitor.org/">dokumentasjonen</a> for mer informasjon og
en installasjonsguide. ',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> er en chat-app som
gjør det enkelt å meldinger i sanntid. til <a
href="http://docs.phpservermonitor.org/" target="_blank">dokumentasjonen</a> for
mer informasjon og en installasjonsguide. ',
'telegram_chat_id' => 'Telegram chat-ID',
'telegram_chat_id_description' => 'Meldingen vil bli sendt til tilhørende chat.',
'telegram_get_chat_id' => 'Klikk her for å få chat-ID',
@ -276,21 +276,21 @@ $sm_lang = array(
'sms_from' => 'Avsenderens telefonnummer',
'pushover_status' => 'Tillat sending av Pushover-meldinger',
'pushover_description' => 'Pushover er en tjeneste som gjør det enkelt å meldinger i sanntid. Se <a
href="https://pushover.net/">deres nettside</a> for mer info.',
href="https://pushover.net/" target="_blank">deres nettside</a> for mer info.',
'pushover_clone_app' => 'Klikk her for å lage din Pushover-app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Før du kan bruke Pushover, du <a href="%1$s" target="_blank"
rel="noopener"> registrere en app </a> deres nettside og angi App API
Token her.',
'telegram_status' => 'Tillat sending av Telegram-meldinger',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> er en chat-app som gjør det enkelt å
meldinger i sanntid. til <a
href="http://docs.phpservermonitor.org/">dokumentasjonen</a> for mer informasjon og
en installasjonsveiledning.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> er en chat-app som
gjør det enkelt å meldinger i sanntid. til <a
href="http://docs.phpservermonitor.org/" target="_blank">dokumentasjonen</a> for
mer informasjon og en installasjonsveiledning.',
'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Før du kan bruke Telegram, du en API-token. til <a
href="http://docs.phpservermonitor.org/">dokumentasjonen</a> for å
hjelp.',
href="http://docs.phpservermonitor.org/"
target="_blank">dokumentasjonen</a> for å hjelp.',
'alert_type' => 'Velg når du vil bli varslet.',
'alert_type_description' => '<b>Statusendring:</b> Du vil motta et varsel når en server har endret status.
fra online -> offline eller offline -> online.<br><br /><b>Offline:</b> Du
@ -326,7 +326,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-refresh',
'auto_refresh_description' => 'Auto-refresh server side.<br><span class="small">Tid i sekunder, hvis 0 siden
ikke blir oppdatert.</span>',
'seconds' => 'sekunder',
'test' => 'Test',
'test_email' => 'En e-post vil bli sendt til adressen spesifisert i brukerprofilen din.',
'test_sms' => 'En tekstmelding vil bli sendt til telefonnummeret som er angitt i brukerprofilen din.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'minutę temu',
'seconds_ago' => '%d sekund temu',
'a_second_ago' => 'sekundę temu',
'seconds' => 'sekund',
),
'menu' => array(
'config' => 'Konfiguracja',
@ -95,7 +96,7 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover jest usługą szybkich notyfikacji. Sprawdź <a
href="https://pushover.net/">ich stronę</a> po więcej informacji.',
href="https://pushover.net/" target="_blank">ich stronę</a> po więcej informacji.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Urządzenie dla Pushover',
'pushover_device_description' => 'Nazwa urządzenia do którego wysłać powiadomienie. Pozostaw puste aby
@ -191,6 +192,7 @@ $sm_lang = array(
),
'config' => array(
'general' => 'Ogólne',
'site_title' => 'Tytuł strony',
'language' => 'Język',
'show_update' => 'Sprawdzić aktualizacje?',
'email_status' => 'Pozwól na wysyłkę email',
@ -211,8 +213,8 @@ $sm_lang = array(
'sms_from' => 'Numer nadawcy',
'pushover_status' => 'Pozwól na wysyłkę notyfikacji Pushover',
'pushover_description' => 'Pushover jest usługą ułatwiającą otrzymywanie powiadomień w czasie
rzeczywistym. Sprawdź <a href="https://pushover.net/">ich stronę</a> aby uzyskać
więcej informacji.',
rzeczywistym. Sprawdź <a href="https://pushover.net/" target="_blank">ich
stronę</a> aby uzyskać więcej informacji.',
'pushover_clone_app' => 'Kliknij tutaj aby stworzyć aplikację korzystającą z Pushover',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Zanim zaczniesz używać Pushover, musisz <a href="%1$s" target="_blank"
@ -247,7 +249,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-odświeżanie',
'auto_refresh_description' => 'Auto-odświeżanie strony serwera.<br><span class="small">Czas w sekundach, dla
czasu 0 strona nie będzie odświeżana.</span>',
'seconds' => 'sekund',
'test' => 'Test',
'test_email' => 'Email zostanie wysłany na adres podany w Twoim profilu.',
'test_sms' => 'SMS zostanie wysłany na numer podany w Twoim profilu.',
@ -272,6 +273,8 @@ $sm_lang = array(
archiwizować uptime serwera. Wpisz 0 aby wyłączyć czyszczenie
logów.',
'log_retention_days' => 'dni',
'user_agent' => 'User Agent',
'user_agent_key_note' => 'Nazwa używana przez monitoring do identyfikacji ze sprawdzaną usługą.',
),
'notifications' => array(
'off_sms' => 'Serwer \'%LABEL%\' przestał odpowiadać: ip=%IP%, port=%PORT%. Błąd=%ERROR%',

View File

@ -66,6 +66,7 @@ $sm_lang = array(
'a_minute_ago' => 'cerca de um minuto atrás',
'seconds_ago' => '%d segundos atrás',
'a_second_ago' => 'um segundo atrás',
'seconds' => 'segundos',
),
'menu' => array(
'config' => 'Configuração',
@ -93,7 +94,7 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover para enviar notificações em real-tome. Veja <a
href="https://pushover.net/">o website</a> para mais informações.',
href="https://pushover.net/" target="_blank">o website</a> para mais informações.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Nome do Device para enviar a mensagem. Deixe em branco para enviar a todos
@ -209,7 +210,7 @@ $sm_lang = array(
'sms_from' => 'Número de telefone de envio',
'pushover_status' => 'Habilitar envio de mensagens Pushover',
'pushover_description' => 'Pushover é um serviço de notificações em tempo real. Veja <a
href="https://pushover.net/">o website</a> para mais informações.',
href="https://pushover.net/" target="_blank">o website</a> para mais informações.',
'pushover_clone_app' => 'Clique aqui para criar sua app Pushover',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Before you can use Pushover, you need to <a href="%1$s" target="_blank"
@ -245,7 +246,6 @@ $sm_lang = array(
'auto_refresh' => 'Atualizar automaticamente',
'auto_refresh_description' => 'Atualizar automaticamente a página de servidores.<br><span class="small">Tempo
em segundos, Se 0 a página não será atualizada.</span>',
'seconds' => 'segundos',
'test' => 'Teste',
'test_email' => 'Um e-mail será enviado para o endereço especificado em seu perfil de usuário.',
'test_sms' => 'Um SMS será enviado para o número de telefone especificado em seu perfil de usuário.',

View File

@ -113,7 +113,7 @@ $sm_lang = array(
'pushover_description' => 'Pushover - это сервис, который позволяет легко
получать уведомления в режиме реального
времени. Больше информации на <a
href="https://pushover.net/">их веб-сайте</a>.',
href="https://pushover.net/" target="_blank">их веб-сайте</a>.',
'pushover_key' => 'Pushover ключ',
'pushover_device' => 'Pushover устройство',
'pushover_device_description' => 'Имя устройства, на которое будут
@ -121,12 +121,12 @@ $sm_lang = array(
пустым, что бы отправлять уведомления на
все устройства.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> удобный мессенджер
для получения уведомлений в реальном
времени. Посетите <a
href="http://docs.phpservermonitor.org/">раздел документации</a>
для получения доп. информации и инструкций по
установке.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный
мессенджер для получения уведомлений в
реальном времени. Посетите <a
href="http://docs.phpservermonitor.org/" target="_blank">раздел
документации</a> для получения доп. информации
и инструкций по установке.',
'telegram_chat_id' => 'Telegram chat id',
'telegram_chat_id_description' => 'Сообщения будут отправляться на
указанный идентификатор чата.',
@ -304,7 +304,7 @@ $sm_lang = array(
'pushover_description' => 'Pushover - это сервис, который позволяет легко
получать уведомления в режиме реального
времени. Больше информации на <a
href="https://pushover.net/">их веб-сайте</a>.',
href="https://pushover.net/" target="_blank">их веб-сайте</a>.',
'pushover_clone_app' => 'Нажмите здесь чтобы создать ваш Pushover app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Прежде чем вы сможете начать
@ -313,17 +313,17 @@ $sm_lang = array(
rel="noopener">"App"</a> на их веб-сайте и ввести "App
API Token" сюда.',
'telegram_status' => 'Разрешить отправку уведомлений в Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> удобный мессенджер
для получения уведомлений в реальном
времени. Посетите <a
href="http://docs.phpservermonitor.org/">раздел документации</a>
для получения доп. информации и инструкций по
установке.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a> удобный
мессенджер для получения уведомлений в
реальном времени. Посетите <a
href="http://docs.phpservermonitor.org/" target="_blank">раздел
документации</a> для получения доп. информации
и инструкций по установке.',
'telegram_api_token' => 'Telegram API Token',
'telegram_api_token_description' => 'Прежде чем вы сможете начать
пользоваться Telegram, вам необходимо
получить API Token. Посетите <a
href="http://docs.phpservermonitor.org/">раздел
href="http://docs.phpservermonitor.org/" target="_blank">раздел
документации</a> для получения помощи.',
'alert_type' => 'Тип уведомлений',
'alert_type_description' => '<b>Изменение статуса:</b> Вы получите
@ -371,7 +371,6 @@ $sm_lang = array(
серверов.<br><span class="small">Время в секундах.
Если указано 0, то страница не будет
обновляться.</span>',
'seconds' => 'секунд',
'test' => 'Проверка',
'test_email' => 'Сообщение будет отправлено на адрес указаный в
профиле пользователя.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'cca pred minútou',
'seconds_ago' => 'pred %d sekundami',
'a_second_ago' => 'pred chvíľou',
'seconds' => 'sekúnd',
),
'menu' => array(
'config' => 'Konfigurácia',
@ -259,7 +260,6 @@ $sm_lang = array(
'auto_refresh' => 'Automaticky obnoviť',
'auto_refresh_description' => 'Automaticky obnoviť stránku Servery.<br><span class="small">Čas v
sekundách, 0 pre vypnutie automatického obnovenia.</span>',
'seconds' => 'sekúnd',
'test' => 'Test',
'test_email' => 'E-mail bude odoslaný na adresu uvedenú v užívateľskom profile.',
'test_sms' => 'SMS bude odoslaná na telefónne číslo uvedené v užívateľskom profile.',

View File

@ -65,6 +65,7 @@ $sm_lang = array(
'a_minute_ago' => 'pred približno minuto',
'seconds_ago' => 'pred %d sekundami',
'a_second_ago' => 'pred sekundo',
'seconds' => 'sekund',
),
'menu' => array(
'config' => 'Nastavitve',
@ -92,8 +93,8 @@ $sm_lang = array(
'email' => 'E-pošta',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času.
Več informacij je na voljo <a href="https://pushover.net/">na njihovi spletni
strani</a>.',
Več informacij je na voljo <a href="https://pushover.net/" target="_blank">na
njihovi spletni strani</a>.',
'pushover_key' => 'Pushover ključ',
'pushover_device' => 'Pushover naprava',
'pushover_device_description' => 'Ime naprave na katero naj se pošlje obvestilo. Če želite obvestilo
@ -209,8 +210,8 @@ $sm_lang = array(
'sms_from' => 'Telefonska številka pošiljatelja',
'pushover_status' => 'Dovolim pošiljanje Pushover sporočil',
'pushover_description' => 'Pushover je storitev, ki omogoča enostavno prejemanje obvestil v realnem času.
Več informacij je na voljo <a href="https://pushover.net/">na njihovi spletni
strani</a>.',
Več informacij je na voljo <a href="https://pushover.net/" target="_blank">na
njihovi spletni strani</a>.',
'pushover_clone_app' => 'Kliknite za ustvarjanje vaše Pushover aplikacije',
'pushover_api_token' => 'Pushover API žeton',
'pushover_api_token_description' => 'Pred uporabo storitve Pushover, morate na njihovi spletni strani <a
@ -247,7 +248,6 @@ $sm_lang = array(
'auto_refresh_description' => 'Samodejno posodabljanje pregleda statusa strežnikov.<br><span
class="small">Čas v sekundah. Če je vrednost 0 se stran ne bo samodejno
posodabljala.</span>',
'seconds' => 'sekund',
'test' => 'Test',
'test_email' => 'Na naslov, ki ste ga določili v vašem profilu, bo poslano e-sporočilo.',
'test_sms' => 'Na telefonsko številko, ki ste jo določili v vašem profilu, bo poslan SMS.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'ungefär en minut sen',
'seconds_ago' => '%d sekunder sedan',
'a_second_ago' => 'en sekund sedan',
'seconds' => 'sekunder',
),
'menu' => array(
'config' => 'Inställningar',
@ -94,7 +95,8 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover är en tjänst som skickar meddelande i realtid. Se <a
href="https://pushover.net/">deras webbsida</a> för mer information.',
href="https://pushover.net/" target="_blank">deras webbsida</a> för mer
information.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Enhetsnman att skicka meddelande till. Lämna tomt för att skicka till alla
@ -210,7 +212,7 @@ $sm_lang = array(
'sms_from' => 'Avsändarens telefonnummer',
'pushover_status' => 'Tillåt Pushover-meddelande',
'pushover_description' => 'Pushover är en tjänst som skickar meddelande i realtid. Se <a
href="https://pushover.net/">deras webbsida</a> för mer info.',
href="https://pushover.net/" target="_blank">deras webbsida</a> för mer info.',
'pushover_clone_app' => 'Klicka här för att skapa din Pushover app',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Innan du kan använda Pushover behöver du <a href="%1$s" target="_blank"
@ -245,7 +247,6 @@ $sm_lang = array(
'auto_refresh' => 'Auto-uppdatera',
'auto_refresh_description' => 'Auto-uppdatera status-sidan.<br><span class="small">Tid i sekunder, om "0"
uppdateras sidan inte automatiskt.</span>',
'seconds' => 'sekunder',
'test' => 'Test',
'test_email' => 'Ett emial kommer skickas till adressen i din profil.',
'test_sms' => 'Ett SMS kommer skickas till mobilnumret i din profil.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => 'yaklaşık bir dakika önce',
'seconds_ago' => '%d saniye önce',
'a_second_ago' => 'bir saniye önce',
'seconds' => 'saniye',
),
'menu' => array(
'config' => 'Ayarlar',
@ -95,7 +96,7 @@ $sm_lang = array(
'email' => 'E-posta',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi
için <a href="https://pushover.net/">sitesine</a> bakabilirsiniz.',
için <a href="https://pushover.net/" target="_blank">sitesine</a> bakabilirsiniz.',
'pushover_key' => 'Pushover Anahtarı',
'pushover_device' => 'Pushover Aracı',
'pushover_device_description' => 'Mesajın gönderileceği cihazın adı. Tüm cihazlara göndermek için boş
@ -211,7 +212,7 @@ $sm_lang = array(
'sms_from' => 'Gönderen numarası',
'pushover_status' => 'Pushover mesaj gönderimine izin ver',
'pushover_description' => 'Pushover gerçek zamanlı bildirim alabilmek için bir servistir. Daha fazla bilgi
için <a href="https://pushover.net/">sitesine</a> bakabilirsiniz.',
için <a href="https://pushover.net/" target="_blank">sitesine</a> bakabilirsiniz.',
'pushover_clone_app' => 'Pushover uygulaması oluşturmak için buraya tıklayınız.',
'pushover_api_token' => 'Pushover Uygulaması API Token Bilgisi',
'pushover_api_token_description' => 'Pushover kullanmadan önce, <a href="%1$s" target="_blank"
@ -248,7 +249,6 @@ $sm_lang = array(
'auto_refresh' => 'Otomatik Yenileme',
'auto_refresh_description' => 'Otomatik yenileme sunucu sayfası<br><span class="small">Eğer sayfa yenilenmez
ise.</span>',
'seconds' => 'saniye',
'test' => 'Test',
'test_email' => 'Profilinizde tanımladığınız e-posta adresinize bir e-posta gönderilecek.',
'test_sms' => 'Profilinizde tanımladığınız numaranıza bir SMS mesajı gönderilecek.',

View File

@ -116,7 +116,7 @@ $sm_lang = array(
'pushover' => 'Pushover',
'pushover_description' => 'Pushover сервіс, що дозволяє легко отримувати
сповіщення у реальному часі. За деталями
перейдіть на <a href="https://pushover.net/">їхній
перейдіть на <a href="https://pushover.net/" target="_blank">їхній
вебсайт</a>.',
'pushover_key' => 'Ключ Pushover',
'pushover_device' => 'Пристрій Pushover',
@ -124,11 +124,12 @@ $sm_lang = array(
повідомлення. Залиште пустим, щоб
надсилати на всі пристрої.',
'telegram' => 'Telegram',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> чат-застосунок, що
дозволяє легко отримувати сповіщення у
реальному часі. За деталями й інструкцією зі
встановлення зверніться до <a
href="http://docs.phpservermonitor.org/">документації</a>.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
чат-застосунок, що дозволяє легко отримувати
сповіщення у реальному часі. За деталями й
інструкцією зі встановлення зверніться до <a
href="http://docs.phpservermonitor.org/"
target="_blank">документації</a>.',
'telegram_chat_id' => 'Ідентифікатор чату Telegram',
'telegram_chat_id_description' => 'Повідомлення буде надіслане у
відповідний чат.',
@ -330,8 +331,8 @@ $sm_lang = array(
'pushover_status' => 'Дозволити надсилання Pushover-повідомлень',
'pushover_description' => 'Pushover сервіс, що дозволяє легко отримувати
сповіщення у реальному часі. За детальнішою
інформацію перейдіть на <a
href="https://pushover.net/">їхній вебсайт</a>.',
інформацію перейдіть на <a href="https://pushover.net/"
target="_blank">їхній вебсайт</a>.',
'pushover_clone_app' => 'Натисніть тут, щоб створити ваш Pushover-додаток',
'pushover_api_token' => 'Токен API Pushover-додатку',
'pushover_api_token_description' => 'Перед використанням Pushover ви маєте <a
@ -339,16 +340,17 @@ $sm_lang = array(
Додаток</a> на їхньому вебсайті та ввести
токен API Додатку тут.',
'telegram_status' => 'Дозволити надсилання Telegram-повідомлень',
'telegram_description' => '<a href="https://telegram.org/">Telegram</a> чат-застосунок, що
дозволяє легко отримувати сповіщення у
реальному часі. Детальніша інформація та
інструкція зі встановлення доступні у <a
href="http://docs.phpservermonitor.org/">документації</a>.',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
чат-застосунок, що дозволяє легко отримувати
сповіщення у реальному часі. Детальніша
інформація та інструкція зі встановлення
доступні у <a href="http://docs.phpservermonitor.org/"
target="_blank">документації</a>.',
'telegram_api_token' => 'Токен Telegram API',
'telegram_api_token_description' => 'Перед використанням Telegram ви маєте
отримати токен API. За довідкою
зверніться до <a
href="http://docs.phpservermonitor.org/">документації</a>.',
зверніться до <a href="http://docs.phpservermonitor.org/"
target="_blank">документації</a>.',
'alert_type' => 'Виберіть, коли б вам хотілося отримувати
сповіщення.',
'alert_type_description' => '<b>Зміна статусу:</b> Ви отримуватимете
@ -404,7 +406,6 @@ $sm_lang = array(
'auto_refresh_description' => 'Сторінка автооновлення серверів.<br><span
class="small">Час у секундах; якщо 0, сторінка не
оновлюватиметься.</span>',
'seconds' => 'секунд',
'test' => 'Тест',
'test_email' => 'Електронний лист буде надісланий на адресу,
вказану у вашому профілі користувача.',

View File

@ -64,6 +64,7 @@ $sm_lang = array(
'a_minute_ago' => 'khoảng một phút trước',
'seconds_ago' => '%d giây trước',
'a_second_ago' => 'một giây trước',
'seconds' => 'giây',
),
'menu' => array(
'config' => 'Cấu hình',
@ -91,8 +92,8 @@ $sm_lang = array(
'email' => 'Email',
'pushover' => 'Pushover',
'pushover_description' => 'Pushover một dịch vụ dễ dàng nhận các thông báo theo thời gian
thực. Xem <a href="https://pushover.net/">website của họ</a> để biết
thêm thông tin.',
thực. Xem <a href="https://pushover.net/" target="_blank">website của họ</a>
để biết thêm thông tin.',
'pushover_key' => 'Pushover Key',
'pushover_device' => 'Pushover Device',
'pushover_device_description' => 'Tên thiết bị để gửi tin nhắn đến. Để trống để gửi
@ -208,8 +209,8 @@ $sm_lang = array(
'sms_from' => 'Số điện thoại của người gửi',
'pushover_status' => 'Cho phép gửi tin nhắn bằng Pushover',
'pushover_description' => 'Pushover một dịch vụ dễ dàng nhận các thông báo theo thời gian
thực. Xem <a href="https://pushover.net/">website của họ</a> để biết
thêm thông tin.',
thực. Xem <a href="https://pushover.net/" target="_blank">website của họ</a>
để biết thêm thông tin.',
'pushover_clone_app' => 'Nhấn vào đây để tạo ứng dụng Pushover của bạn',
'pushover_api_token' => 'Pushover App API Token',
'pushover_api_token_description' => 'Trước khi bạn thể sử dụng Pushover, bạn cần phải <a
@ -246,7 +247,6 @@ $sm_lang = array(
'auto_refresh' => 'Tự động làm mới',
'auto_refresh_description' => 'Tự động làm mới servers page.<br><span class="small">Trong vài giây,
nếu 0 trang sẽ không làm mới.</span>',
'seconds' => 'giây',
'test' => 'Thử',
'test_email' => 'Một email sẽ được gửi đến địa chỉ được xác định trong hồ
người dùng của bạn.',

View File

@ -67,6 +67,7 @@ $sm_lang = array(
'a_minute_ago' => '1分钟前',
'seconds_ago' => '%d 秒前',
'a_second_ago' => '刚刚',
'seconds' => '秒',
),
'menu' => array(
'config' => '设置',
@ -124,9 +125,6 @@ $sm_lang = array(
'sms' => '短信',
'pushover' => 'Pushover',
'no_logs' => '没有日志',
'clear' => 'Clear log',
'delete_title' => 'Delete log',
'delete_message' => 'Are you sure you want to delete <b>all</b> logs?',
),
'servers' => array(
'server' => '业务',
@ -262,7 +260,6 @@ $sm_lang = array(
'auto_refresh' => '自动刷新',
'auto_refresh_description' => '自动刷新服务器页.<br><span class="small">单位为秒, 设置为 0
则不自动刷新.</span>',
'seconds' => '秒',
'test' => '测试',
'test_email' => '将发送一封邮件到您账户设置的邮件地址.',
'test_sms' => '将发送一封短信到您账户设置的手机号码.',

368
src/lang/zh_TW.lang.php Normal file
View File

@ -0,0 +1,368 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Jason Cheng <https://github.com/jasoncheng7115>
* @copyright Copyright (c) 2008-2014 Pepijn Over <pep@neanderthal-technology.com>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: v3.1.1
* @link http://www.phpservermonitor.org/
**/
$sm_lang = array(
'name' => '繁體中文 - Traditional Chinese',
'locale' => array(
'0' => 'zh_TW.UTF-8',
'1' => 'zh_TW',
'2' => 'chinese',
'3' => 'chinese-tw',
),
'locale_tag' => 'zh_TW',
'locale_dir' => 'ltr',
'system' => array(
'title' => 'Server Monitor',
'install' => '安裝',
'action' => '動作',
'save' => '儲存',
'edit' => '編輯',
'delete' => '刪除',
'date' => '日期',
'message' => '訊息',
'yes' => '是',
'no' => '否',
'insert' => '插入',
'add_new' => '增加',
'back_to_top' => '回到最上層',
'go_back' => '返回',
'ok' => '確定',
'cancel' => '取消',
'activate' => '啟用',
'short_day_format' => '%B %e',
'long_day_format' => '%B %e, %Y',
'yesterday_format' => '昨日 %k:%M',
'other_day_format' => '%A %k:%M',
'never' => '從未',
'hours_ago' => '%d小時前',
'an_hour_ago' => '1小時前',
'minutes_ago' => '%d分鐘前',
'a_minute_ago' => '1分鐘前',
'seconds_ago' => '%d秒前',
'a_second_ago' => '剛剛',
'year' => '年',
'years' => '年',
'month' => '月',
'months' => '月',
'day' => '日',
'days' => '日',
'hour' => '時',
'hours' => '時',
'minute' => '分',
'minutes' => '分',
'second' => '秒',
'seconds' => '秒',
),
'menu' => array(
'config' => '設定',
'server' => '伺服器',
'server_log' => '記錄',
'server_status' => '狀態',
'server_update' => '更新',
'user' => '使用者',
'help' => '說明',
),
'users' => array(
'user' => '使用者',
'name' => '顯示名稱',
'user_name' => '使用者名稱',
'password' => '密碼',
'password_repeat' => '再次輸入密碼',
'password_leave_blank' => '若密碼欄位保持空白,表示不做修改',
'level' => '等級',
'level_10' => '超級管理員',
'level_20' => '一般使用者',
'level_description' => '<b>超級管理員</b>
具備所有伺服器的管理權限,可管理使用者以及修改系統設定。<br/><b>一般使用者</b>
僅能查看以及更新自己所負責的伺服器。',
'mobile' => '行動電話',
'email' => '電子郵件',
'pushover' => 'Pushover 通知',
'pushover_description' => 'Pushover
是一種雲端服務,讓你可以很方便的收到即時訊息通知,您可以到<a
href="https://pushover.net/">網站</a>了解更多的內容。',
'pushover_key' => 'Pushover 金鑰',
'pushover_device' => 'Pushover 裝置',
'pushover_device_description' => '發送訊息的裝置名稱,若保留空白,將會發送到所有的裝置。',
'telegram' => 'Telegram 通知',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
是一種聊天應用程式,它提供很容易使用的的即時通知能力。您可以到
<a href="http://docs.phpservermonitor.org/" target="_blank">documentation</a>
了解更多的內容。',
'telegram_chat_id' => 'Telegram Chat ID',
'telegram_chat_id_description' => '將訊息發送到指定的聊天室',
'telegram_get_chat_id' => '點選這裡可以取得您的 Chat ID',
'activate_telegram' => '啟用 Telegram 通知',
'activate_telegram_description' => '允許 Telegram 將訊息發送到指定的 Chat
ID。若沒有啟用此項目Telegram
將不允許我們發送通知給您。',
'telegram_bot_username_error_token' => '401 - 未授權,請確認您的 API Token 是有效的。',
'telegram_bot_error' => '啟用 Telegram 通知時發生錯誤:%s',
'delete_title' => '刪除使用者',
'delete_message' => '您確定要刪除使用者 \'%1\'?',
'deleted' => '已刪除使用者。',
'updated' => '已更新使用者。',
'inserted' => '已增加使用者。',
'profile' => '個人資料',
'profile_updated' => '個人資料已經更新。',
'error_user_name_bad_length' => '使用者名稱長度必須為2-64個字元。',
'error_user_name_invalid' => '使用者名稱只允許英文字母(a-z、A-Z)、數字(0-9)以及底線(_)。',
'error_user_name_exists' => '這個使用者名稱已存在。',
'error_user_email_bad_length' => '電子郵件長度為5-255個字元。',
'error_user_email_invalid' => '無效的電子郵件。',
'error_user_level_invalid' => '無效的使用者等級。',
'error_user_no_match' => '這個使用者名稱不存在。',
'error_user_password_invalid' => '無效的密碼。',
'error_user_password_no_match' => '密碼不符。',
),
'log' => array(
'title' => '記錄概覽',
'type' => '類型',
'status' => '狀態',
'email' => '電子郵件通知',
'sms' => '簡訊通知',
'pushover' => 'Pushover 通知',
'telegram' => 'Telegram 通知',
'no_logs' => '沒有記錄',
'clear' => '清除記錄',
'delete_title' => '刪除記錄',
'delete_message' => '您確定要刪除 <b>所有</b> 記錄?',
),
'servers' => array(
'server' => '伺服器',
'status' => '狀態',
'label' => '標籤',
'domain' => '網域/IP',
'timeout' => '逾時',
'timeout_description' => '等待伺服器回應的秒數。',
'authentication_settings' => '驗證設定 (非必要)',
'website_username' => '使用者',
'website_username_description' => '存取這個網站的使用者。(只支援 Apache 驗證)',
'website_password' => '密碼',
'website_password_description' => '存取這個網站的使用者。(密碼將會以加密形式存放在資料庫)',
'fieldset_monitoring' => '監視',
'fieldset_permissions' => '權限',
'port' => '連接埠',
'custom_port' => '自訂連接埠',
'popular_ports' => '常用連接埠',
'please_select' => '請選擇',
'type' => '類型',
'type_website' => '網站',
'type_service' => '服務',
'type_ping' => 'Ping',
'pattern' => '字串',
'pattern_description' => '如果在網站上沒有找到符合的字串,則將網站標示為離線。',
'pattern_online' => '指明網站上的字串',
'pattern_online_description' => '線上:如果在網站上沒有找到符合的字串,則將網站標示為線上。',
'header_name_description' => '標頭名稱 (區分大小寫)',
'header_value_description' => '標頭的值,可以使用正則表示式。',
'last_check' => '最後一次檢查',
'last_online' => '最後一次上線',
'last_offline' => '最後一次離線',
'monitoring' => '監控中',
'no_monitoring' => '未監控',
'email' => '電子郵件通知',
'send_email' => '發送電子郵件',
'sms' => '簡訊通知',
'send_sms' => '發送簡訊',
'pushover' => 'Pushover 通知',
'send_pushover' => '發送 Pushover 通知',
'telegram' => 'Telegram 通知',
'send_telegram' => '發送 Telegram 通知',
'users' => '使用者',
'delete_title' => '刪除伺服器',
'delete_message' => '您確定要刪除這個伺服器 \'%1\'?',
'deleted' => '伺服器已刪除。',
'updated' => '伺服器已更新。',
'inserted' => '伺服器已增加。',
'latency' => '延遲',
'latency_max' => '延遲 (最大)',
'latency_min' => '延遲 (最小)',
'latency_avg' => '延遲 (平均)',
'uptime' => '上線時間',
'year' => '年',
'month' => '月',
'week' => '週',
'day' => '日',
'hour' => '小時',
'warning_threshold' => '警報臨界值',
'warning_threshold_description' => '失敗達到多少次數則標示為離線。',
'chart_last_week' => '上週',
'chart_history' => '更早',
'chart_day_format' => '%Y-%m-%d',
'chart_long_date_format' => '%Y-%m-%d %H:%M:%S',
'chart_short_date_format' => '%m/%d %H:%M',
'chart_short_time_format' => '%H:%M',
'warning_notifications_disabled_sms' => '簡訊通知已關閉。',
'warning_notifications_disabled_email' => '電子郵件通知已關閉。',
'warning_notifications_disabled_pushover' => 'Pushover 通知已關閉。',
'warning_notifications_disabled_telegram' => 'Telegram 通知已關閉。',
'error_server_no_match' => '找不到伺服器。',
'error_server_label_bad_length' => '標籤必須在1到255間的字元。',
'error_server_ip_bad_length' => '網域/IP必須在1到255間的字元。',
'error_server_ip_bad_service' => '無效的 IP 位址。',
'error_server_ip_bad_website' => '無效的網址。',
'error_server_type_invalid' => '無效的的伺服器型態',
'error_server_warning_threshold_invalid' => '警報臨界值必須是大於 0 的有效整數。',
),
'config' => array(
'general' => '一般',
'language' => '語言',
'show_update' => '檢查更新',
'password_encrypt_key' => '加密金鑰',
'password_encrypt_key_note' => '這個加密金鑰將用於保護您登入這個網站的密碼,如果修改了此金鑰,原本已經存在的密碼將無法使用!',
'proxy' => '啟用 Proxy',
'proxy_url' => 'Proxy URL',
'proxy_user' => 'Proxy 使用者名稱',
'proxy_password' => 'Proxy 密碼',
'email_status' => '啟用電子郵件通知',
'email_from_email' => '寄件者信箱',
'email_from_name' => '寄件者名稱',
'email_smtp' => '使用SMTP發信',
'email_smtp_host' => 'SMTP主機',
'email_smtp_port' => 'SMTP連接埠口',
'email_smtp_security' => 'SMTP安全性',
'email_smtp_security_none' => '無',
'email_smtp_username' => 'SMTP使用者名稱',
'email_smtp_password' => 'SMTP使用者密碼',
'email_smtp_noauth' => '留空白表示不做帳號驗證',
'sms_status' => '啟用簡訊通知',
'sms_gateway' => '簡訊服務提供者',
'sms_gateway_username' => '簡訊閘道使用者名稱',
'sms_gateway_password' => '簡訊閘道使用者密碼',
'sms_from' => '發送人電話號碼',
'pushover_status' => '啟用Pushover通知',
'pushover_description' => 'Pushover是線上服務讓您可以方便的收到即時通知請參考 <a
href="https://pushover.net/" target="_blank"> 網站</a>
可以得到更詳細的資訊。</a> ',
'pushover_clone_app' => '點選這裡可快速建立Pushover App',
'pushover_api_token_description' => '在您使用 Pushover 通知之前,需要先到這裡-><a href="%1$s"
target="_blank" rel="noopener">註冊Pushover App帳號</a>
接著在這個網頁輸入你的的Pushover App API Token號碼。',
'telegram_status' => '允許發送 Telegram 訊息',
'telegram_description' => '<a href="https://telegram.org/" target="_blank">Telegram</a>
是一種聊天應用程式,它提供很容易使用的即時通知服務。請參考
<a href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a>
可以取得更多資訊與安裝說明。',
'telegram_api_token_description' => '使用 Telegram 通知之前,您必需先取得 API Token。請到 <a
href="http://docs.phpservermonitor.org/" target="_blank">文件庫</a>
取得說明。',
'alert_type' => '需要提醒的類別',
'alert_type_description' => '<b>狀態改變:</b> 伺服器 連線 -> 離線或連線 ->
連線的狀態變化將會收到提醒通知。<br/><br /><b>離線:</b>
伺服器首次發生離線狀態將會收到提醒設定為15分鐘執行一次伺服器從1:00-6:00一直處於離線狀態那麼你將會在1:00首次收到一則提醒通知,之後便不會在收到重覆的提醒通知。<br/><br><b>全部:</b>
每次執行當伺服器離線(即使伺服器離線很久已提醒過了)均發送提醒通知。',
'alert_type_status' => '狀態改變',
'alert_type_offline' => '離線',
'alert_type_always' => '全部',
'alert_proxy_url' => '<b>格式:</b> Host:Port',
'log_status' => '狀態記錄',
'log_status_description' => '如果啟用狀態記錄,則每一筆提醒通知都會保留記錄。',
'log_email' => '保留電子郵件通知發送記錄',
'log_sms' => '保留簡訊通知發送記錄',
'log_pushover' => '保留 pushover 通知發送記錄',
'log_telegram' => '保留 telegram 通知發送記錄',
'updated' => '已更新設定。',
'tab_email' => '電子郵件發送設定',
'tab_sms' => '簡訊發送設定',
'tab_pushover' => 'Pushover 通知',
'tab_telegram' => 'Telegram 通知',
'settings_email' => '電子郵件發送設定',
'settings_sms' => '簡訊發送設定',
'settings_pushover' => 'Pushover 發送設定',
'settings_telegram' => 'Telegram 發送設定',
'settings_notification' => '提醒設定',
'settings_log' => '記錄設定',
'settings_proxy' => 'Proxy 設定',
'auto_refresh' => '自動更新',
'test' => '測試',
'test_email' => '電子郵件將發送到您在使用者設定內指定的電子郵件信箱。',
'test_sms' => '簡訊將發送到您在使用者設定內指定的行動電話號碼。',
'test_pushover' => 'Pushover 通知將發送到您在使用者設定的裝置。',
'test_telegram' => 'Telegram 通知將發送到您在使用者設定的 Chat ID。',
'send' => '傳送',
'test_subject' => '標題',
'test_message' => '訊息',
'email_sent' => '傳送',
'email_error' => '電子郵件傳送發生錯誤',
'sms_sent' => '簡訊發送',
'sms_error' => '簡訊發送發生錯誤',
'sms_error_nomobile' => '無法傳送 SMS 簡訊測試:您設定的電話號碼無效或無法找到。',
'pushover_sent' => '傳送 Pushover 通知',
'pushover_error' => '傳送 Pushover 通知發生錯誤: %s',
'pushover_error_noapp' => '無法傳送 Pushover 通知: 在系統設定找不到 Pushover App API token。',
'pushover_error_nokey' => '無法傳送 Pushover 通知: 在系統設定找不到 Pushover key found 。',
'telegram_sent' => '傳送 Telegram 通知',
'telegram_error' => '傳送 Telegram 通知發生錯誤: %s',
'telegram_error_notoken' => '無法傳送 Telegram 通知: 在系統設定找不到 Telegram API token。',
'telegram_error_noid' => '無法傳送 Telegram 通知: 在您的個人資料找不到 Chat ID。',
'log_retention_period' => '記錄保留期限',
'log_retention_period_description' => '保留伺服器運作時間和記錄歸檔的天數輸入0可以防止記錄被清除',
'log_retention_days' => '日',
),
'notifications' => array(
'off_sms' => '伺服器 \'%LABEL%\' 關機: ip=%IP%, port=%PORT%. Error=%ERROR%',
'off_email_subject' => 'IMPORTANT: 服務器 \'%LABEL%\' 關機',
'off_email_body' => '無法連線到以下伺服器:<br/><br/>伺服器: %LABEL%<br/>IP: %IP%<br/>Port:
%PORT%<br/>錯誤: %ERROR%<br/>日期: %DATE%',
'off_pushover_title' => '伺服器 \'%LABEL%\' 關機',
'off_pushover_message' => '無法連線到以下伺服器:<br/><br/>伺服器: %LABEL%<br/>IP: %IP%<br/>Port:
%PORT%<br/>錯誤: %ERROR%<br/>日期: %DATE%',
'off_telegram_message' => '無法連線到以下伺服器:<br/><br/>伺服器: %LABEL%<br/>IP: %IP%<br/>Port:
%PORT%<br/>錯誤: %ERROR%<br/>日期: %DATE%',
'on_email_subject' => 'IMPORTANT: 伺服器 \'%LABEL%\' 運行中',
'on_pushover_title' => '伺服器 \'%LABEL%\' 運作中',
),
'login' => array(
'welcome_usermenu' => '歡迎,%user_name%',
'title_sign_in' => '請登入',
'title_forgot' => '忘記密碼',
'title_reset' => '密碼重置',
'submit' => '送出',
'remember_me' => '記住我',
'login' => '登入',
'logout' => '登出',
'username' => '使用者名稱',
'password' => '密碼',
'password_repeat' => '再次輸入密碼',
'password_forgot' => '忘記密碼',
'password_reset' => '重設密碼',
'password_reset_email_subject' => '重設您的密碼',
'password_reset_email_body' => '點選以下連結來重設密碼這個連結於1小時後失效。<br/><br/>%link%',
'error_user_incorrect' => '使用者不存在。',
'error_login_incorrect' => '登入資料不正確。',
'error_login_passwords_nomatch' => '密碼不符合。',
'error_reset_invalid_link' => '重設密碼連結無效。',
'success_password_forgot' => '重設密碼電子郵件已發送。',
'success_password_reset' => '密碼重設成功,請登入。',
),
'error' => array(
'401_unauthorized' => '驗證失敗',
'401_unauthorized_description' => '您没有權限進入這個頁面。',
),
);

View File

@ -217,7 +217,7 @@ abstract class AbstractController implements ControllerInterface
if (!$this->xhr) {
// in XHR mode, we will not add the main template
$tpl_data = array(
'title' => strtoupper(psm_get_lang('system', 'title')),
'title' => psm_get_conf('site_title', strtoupper(psm_get_lang('system', 'title'))),
'label_back_to_top' => psm_get_lang('system', 'back_to_top'),
'add_footer' => $this->add_footer,
'version' => 'v' . PSM_VERSION,

View File

@ -43,13 +43,19 @@ class ConfigController extends AbstractController
'email_status',
'email_smtp',
'sms_status',
'discord_status',
'pushover_status',
'webhook_status',
'telegram_status',
'jabber_status',
'log_status',
'log_email',
'log_sms',
'log_discord',
'log_pushover',
'log_webhook',
'log_telegram',
'log_jabber',
'show_update',
'combine_notifications',
);
@ -67,14 +73,30 @@ class ConfigController extends AbstractController
'email_smtp_host',
'email_smtp_port',
'email_smtp_username',
'email_smtp_password',
'sms_gateway_username',
'sms_gateway_password',
'sms_from',
'webhook_url',
'webhook_json',
'pushover_api_token',
'telegram_api_token',
'jabber_host',
'jabber_port',
'jabber_username',
'jabber_domain',
'user_agent',
'site_title'
);
/**
* Fields for saving encrypted.
* @var array
*/
protected $encryptedFields = [
'email_smtp_password',
'jabber_password'
];
private $default_tab = 'general';
public function __construct(Database $db, \Twig_Environment $twig)
@ -178,9 +200,22 @@ class ConfigController extends AbstractController
$tpl_data[$input_key] = (isset($config[$input_key])) ? $config[$input_key] : '';
}
$tpl_data['user_agent'] = empty($tpl_data['user_agent']) ?
'Mozilla/5.0 (compatible; phpservermon/' .
PSM_VERSION . '; +https://github.com/phpservermon/phpservermon)' : $tpl_data['user_agent'];
$tpl_data['site_title'] = empty($tpl_data['site_title']) ?
strtoupper(psm_get_lang('system', 'title')) : $tpl_data['site_title'];
// encrypted fields
foreach ($this->encryptedFields as $encryptedField) {
$tpl_data[$encryptedField] = '';
}
$tpl_data[$this->default_tab . '_active'] = 'active';
$testmodals = array('email', 'sms', 'pushover', 'telegram');
$testmodals = array('email', 'sms', 'discord', 'webhook', 'pushover', 'telegram', 'jabber');
foreach ($testmodals as $modal_id) {
$modal = new \psm\Util\Module\Modal(
$this->twig,
@ -206,6 +241,7 @@ class ConfigController extends AbstractController
// save new config
$clean = array(
'language' => $_POST['language'],
'site_title' => $_POST['site_title'],
'sms_gateway' => $_POST['sms_gateway'],
'alert_type' => $_POST['alert_type'],
'email_smtp_security' =>
@ -214,7 +250,7 @@ class ConfigController extends AbstractController
: '',
'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)),
'log_retention_period' => intval(psm_POST('log_retention_period', 365)),
'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime())),
'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime()))
);
foreach ($this->checkboxes as $input_key) {
$clean[$input_key] = (isset($_POST[$input_key])) ? '1' : '0';
@ -224,6 +260,13 @@ class ConfigController extends AbstractController
$clean[$input_key] = $_POST[$input_key];
}
}
foreach ($this->encryptedFields as $encryptedField) {
$value = filter_input(INPUT_POST, $encryptedField);
if ($value !== null && $value !== '') {
$clean[$encryptedField] = psm_password_encrypt(psm_get_conf('password_encrypt_key'), $value);
}
// else { leave as is }
}
$language_refresh = ($clean['language'] != psm_get_conf('language'));
foreach ($clean as $key => $value) {
psm_update_conf($key, $value);
@ -234,10 +277,16 @@ class ConfigController extends AbstractController
$this->testEmail();
} elseif (!empty($_POST['test_sms'])) {
$this->testSMS();
} elseif (!empty($_POST['test_discord'])) {
$this->testDiscord();
} elseif (!empty($_POST['test_pushover'])) {
$this->testPushover();
}elseif (!empty($_POST['test_webhook'])) {
$this->testWebhook();
} elseif (!empty($_POST['test_telegram'])) {
$this->testTelegram();
} elseif (!empty($_POST['test_jabber'])) {
$this->testJabber();
}
if ($language_refresh) {
@ -251,10 +300,16 @@ class ConfigController extends AbstractController
$this->default_tab = 'email';
} elseif (isset($_POST['sms_submit']) || !empty($_POST['test_sms'])) {
$this->default_tab = 'sms';
} elseif (isset($_POST['discord_submit']) || !empty($_POST['test_discord'])) {
$this->default_tab = 'discord';
} elseif (isset($_POST['pushover_submit']) || !empty($_POST['test_pushover'])) {
$this->default_tab = 'pushover';
} elseif (isset($_POST['webhook_submit']) || !empty($_POST['test_webhook'])) {
$this->default_tab = 'webhook';
} elseif (isset($_POST['telegram_submit']) || !empty($_POST['test_telegram'])) {
$this->default_tab = 'telegram';
} elseif (isset($_POST['jabber_submit']) || !empty($_POST['test_jabber'])) {
$this->default_tab = 'jabber';
}
}
return $this->runAction('index');
@ -306,6 +361,88 @@ class ConfigController extends AbstractController
}
}
/**
* Execute Discord test
*
* @todo move test to separate class
*/
protected function testDiscord()
{
$user = $this->getUser()->getUser();
if (empty($user->discord)) {
$this->addMessage(psm_get_lang('config', 'discord_error_nowebhook'), 'error');
} else {
$success = 0;
$result = 'An unknown error has occurred.';
try {
$curl = curl_init($user->discord);
$json = json_decode(
'{"content":""}',
true
);
$json['content'] = psm_get_lang('config', 'test_message');
$msg = "payload_json=" . urlencode(json_encode($json));
if(isset($curl)) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POSTFIELDS, $msg);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 204) {
$success = 0;
// $result = ($result == '') ? 'Wrong input, please check if all values are correct!' : $result;
$error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
curl_strerror($err) . ". \nResult: " . $result;
$result = $error;
} else {
$success = 1;
}
curl_close($curl);
}
} catch (Exception $e) {
$success = 0;
$result = $e->getMessage();
}
if ($success === 1) {
$this->addMessage(psm_get_lang('config', 'discord_sent'), 'success');
} else {
$this->addMessage(sprintf(psm_get_lang('config', 'discord_error'), $result), 'error');
}
}
}
/** Execute webhook test
*
* @todo move test to separate class
*/
protected function testWebhook()
{
$user = $this->getUser()->getUser();
if (empty($user->webhook_url)) {
$this->addMessage(psm_get_lang('config', 'webhook_error_nourl'), 'error');
} elseif (empty($user->webhook_json)) {
$this->addMessage(psm_get_lang('config', 'webhook_error_nojson'), 'error');
} else {
$webhook = psm_build_webhook();
$webhook->setUrl($user->webhook_url);
$webhook->setJson($user->webhook_json);
$message = (psm_get_lang('config', 'test_message'));
$result = $webhook->sendWebhook($message);
if ($result==1) {
$this->addMessage(psm_get_lang('config', 'webhook_sent'), 'success');
} else {
$this->addMessage(sprintf(psm_get_lang('config', 'webhook_error'), $result), 'error');
}
}
}
/**
* Execute pushover test
*
@ -379,17 +516,43 @@ class ConfigController extends AbstractController
}
}
/**
* Test Jabber.
*/
protected function testJabber()
{
$user = $this->getUser()->getUser();
psm_jabber_send_message(
psm_get_conf('jabber_host'),
psm_get_conf('jabber_username'),
psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')),
[$user->jabber],
psm_get_lang('config', 'test_message'),
(trim(psm_get_conf('jabber_port')) !== '' ? (int)psm_get_conf('jabber_port') : null),
(trim(psm_get_conf('jabber_domain')) !== '' ? psm_get_conf('jabber_domain') : null)
);
// no message - async ... so just info
$this->addMessage(psm_get_lang('config', 'jabber_check'), 'info');
// @todo possible to set message via ajax with callback ...
}
protected function getLabels()
{
return array(
'label_tab_email' => psm_get_lang('config', 'tab_email'),
'label_tab_sms' => psm_get_lang('config', 'tab_sms'),
'label_tab_discord' => psm_get_lang('config', 'tab_discord'),
'label_tab_pushover' => psm_get_lang('config', 'tab_pushover'),
'label_tab_webhook' => psm_get_lang('config', 'tab_webhook'),
'label_tab_telegram' => psm_get_lang('config', 'tab_telegram'),
'label_tab_jabber' => psm_get_lang('config', 'tab_jabber'),
'label_settings_email' => psm_get_lang('config', 'settings_email'),
'label_settings_sms' => psm_get_lang('config', 'settings_sms'),
'label_settings_discord' => psm_get_lang('config', 'settings_discord'),
'label_settings_webhook' => psm_get_lang('config', 'settings_webhook'),
'label_settings_pushover' => psm_get_lang('config', 'settings_pushover'),
'label_settings_telegram' => psm_get_lang('config', 'settings_telegram'),
'label_settings_jabber' => psm_get_lang('config', 'settings_jabber'),
'label_settings_notification' => psm_get_lang('config', 'settings_notification'),
'label_settings_log' => psm_get_lang('config', 'settings_log'),
'label_settings_proxy' => psm_get_lang('config', 'settings_proxy'),
@ -417,6 +580,14 @@ class ConfigController extends AbstractController
'label_sms_gateway_username' => psm_get_lang('config', 'sms_gateway_username'),
'label_sms_gateway_password' => psm_get_lang('config', 'sms_gateway_password'),
'label_sms_from' => psm_get_lang('config', 'sms_from'),
'label_discord_status' => psm_get_lang('config', 'discord_status'),
'label_discord_description' => psm_get_lang('config', 'discord_description'),
'label_webhook_description' => psm_get_lang('config', 'webhook_description'),
'label_webhook_status' => psm_get_lang('config', 'webhook_status'),
'label_webhook_url' => psm_get_lang('config', 'webhook_url'),
'label_webhook_url_description' => psm_get_lang('config', 'webhook_url_description'),
'label_webhook_json' => psm_get_lang('config', 'webhook_json'),
'label_webhook_json_description' => psm_get_lang('config', 'webhook_json_description'),
'label_pushover_description' => psm_get_lang('config', 'pushover_description'),
'label_pushover_status' => psm_get_lang('config', 'pushover_status'),
'label_pushover_clone_app' => psm_get_lang('config', 'pushover_clone_app'),
@ -430,6 +601,18 @@ class ConfigController extends AbstractController
'label_telegram_status' => psm_get_lang('config', 'telegram_status'),
'label_telegram_api_token' => psm_get_lang('config', 'telegram_api_token'),
'label_telegram_api_token_description' => psm_get_lang('config', 'telegram_api_token_description'),
'label_jabber_status' => psm_get_lang('config', 'jabber_status'),
'label_jabber_description' => psm_get_lang('config', 'jabber_description'),
'label_jabber_host' => psm_get_lang('config', 'jabber_host'),
'label_jabber_host_description' => psm_get_lang('config', 'jabber_host_description'),
'label_jabber_port' => psm_get_lang('config', 'jabber_port'),
'label_jabber_port_description' => psm_get_lang('config', 'jabber_port_description'),
'label_jabber_username' => psm_get_lang('config', 'jabber_username'),
'label_jabber_username_description' => psm_get_lang('config', 'jabber_username_description'),
'label_jabber_domain' => psm_get_lang('config', 'jabber_domain'),
'label_jabber_domain_description' => psm_get_lang('config', 'jabber_domain_description'),
'label_jabber_password' => psm_get_lang('config', 'jabber_password'),
'label_jabber_password_description' => psm_get_lang('config', 'jabber_password_description'),
'label_alert_type' => psm_get_lang('config', 'alert_type'),
'label_alert_type_description' => psm_get_lang('config', 'alert_type_description'),
'label_combine_notifications' => psm_get_lang('config', 'combine_notifications'),
@ -438,20 +621,26 @@ class ConfigController extends AbstractController
'label_log_status_description' => psm_get_lang('config', 'log_status_description'),
'label_log_email' => psm_get_lang('config', 'log_email'),
'label_log_sms' => psm_get_lang('config', 'log_sms'),
'label_log_discord' => psm_get_lang('config', 'log_discord'),
'label_log_pushover' => psm_get_lang('config', 'log_pushover'),
'label_log_webhook' => psm_get_lang('config', 'log_webhook'),
'label_log_telegram' => psm_get_lang('config', 'log_telegram'),
'label_log_jabber' => psm_get_lang('config', 'log_jabber'),
'label_alert_proxy' => psm_get_lang('config', 'alert_proxy'),
'label_alert_proxy_url' => psm_get_lang('config', 'alert_proxy_url'),
'label_auto_refresh' => psm_get_lang('config', 'auto_refresh'),
'label_auto_refresh_description' => psm_get_lang('config', 'auto_refresh_description'),
'label_seconds' => psm_get_lang('config', 'seconds'),
'label_seconds' => psm_get_lang('system', 'seconds'),
'label_save' => psm_get_lang('system', 'save'),
'label_test' => psm_get_lang('config', 'test'),
'label_log_retention_period' => psm_get_lang('config', 'log_retention_period'),
'label_log_retention_period_description' => psm_get_lang('config', 'log_retention_period_description'),
'label_log_retention_days' => psm_get_lang('config', 'log_retention_days'),
'label_days' => psm_get_lang('config', 'log_retention_days'),
'label_leave_blank' => psm_get_lang('users', 'password_leave_blank'),
'label_user_agent' => psm_get_lang('config', 'user_agent'),
'label_user_agent_key_note' => psm_get_lang('config', 'user_agent_key_note'),
'label_site_title' => psm_get_lang('config', 'site_title'),
);
}
}

View File

@ -101,6 +101,53 @@ class InstallController extends AbstractController
if (!in_array('mysql', \PDO::getAvailableDrivers())) {
$errors++;
$this->addMessage('The PDO MySQL driver needs to be installed.', 'error');
} else {
$this->addMessage('PHP PDO MySQL driver found', 'success');
}
if (!extension_loaded('filter')) {
$this->addMessage('PHP is installed without the filter module. Please install filter.', 'warning');
} else {
$this->addMessage('PHP filter module found', 'success');
}
if (!extension_loaded('ctype')) {
$this->addMessage('PHP is installed without the ctype module. Please install ctype.', 'warning');
} else {
$this->addMessage('PHP ctype module found', 'success');
}
if (!extension_loaded('hash')) {
$this->addMessage('PHP is installed without the hash module. Please install hash.', 'warning');
} else {
$this->addMessage('PHP hash module found', 'success');
}
if (!extension_loaded('json')) {
$this->addMessage('PHP is installed without the json module. Please install json.', 'warning');
} else {
$this->addMessage('PHP json module found', 'success');
}
if (!extension_loaded('libxml')) {
$this->addMessage('PHP is installed without the libxml module. Please install libxml.', 'warning');
} else {
$this->addMessage('PHP libxml module found', 'success');
}
if (!extension_loaded('openssl')) {
$this->addMessage('PHP is installed without the openssl module. Please install openssl.', 'warning');
} else {
$this->addMessage('PHP openssl module found', 'success');
}
if (!extension_loaded('pcre')) {
$this->addMessage('PHP is installed without the pcre module. Please install pcre.', 'warning');
} else {
$this->addMessage('PHP pcre module found', 'success');
}
if (!extension_loaded('sockets')) {
$this->addMessage('PHP is installed without the sockets module. Please install sockets.', 'warning');
} else {
$this->addMessage('PHP sockets module found', 'success');
}
if (!extension_loaded('xml')) {
$this->addMessage('PHP is installed without the xml module. Please install xml.', 'warning');
} else {
$this->addMessage('PHP xml module found', 'success');
}
if (!ini_get('date.timezone')) {
$this->addMessage(
@ -256,7 +303,10 @@ class InstallController extends AbstractController
'level' => PSM_USER_ADMIN,
'pushover_key' => '',
'pushover_device' => '',
'webhook_url' => '',
'webhook_json' => '',
'telegram_id' => '',
'jabber' => ''
);
$validator = $this->container->get('util.user.validator');

View File

@ -81,10 +81,15 @@ abstract class AbstractServerController extends AbstractController
`s`.`active`,
`s`.`email`,
`s`.`sms`,
`s`.`discord`,
`s`.`webhook`,
`s`.`pushover`,
`s`.`telegram`,
`s`.`jabber`,
`s`.`warning_threshold`,
`s`.`warning_threshold_counter`,
`s`.`ssl_cert_expiry_days`,
`s`.`ssl_cert_expired_time`,
`s`.`timeout`,
`s`.`website_username`,
`s`.`website_password`,
@ -111,7 +116,7 @@ abstract class AbstractServerController extends AbstractController
*/
protected function formatServer($server)
{
$server['rtime'] = round((float) $server['rtime'], 4);
$server['rtime'] = $server['rtime'];
$server['last_online'] = psm_timespan($server['last_online']);
$server['last_offline'] = psm_timespan($server['last_offline']);
if ($server['last_offline'] != psm_get_lang('system', 'never')) {
@ -120,7 +125,16 @@ abstract class AbstractServerController extends AbstractController
}
$server['last_check'] = psm_timespan($server['last_check']);
if ($server['status'] == 'on' && $server['warning_threshold_counter'] > 0) {
if (
(
$server['status'] == 'on' &&
$server['warning_threshold_counter'] > 0
) || (
$server['status'] == 'on' &&
$server['ssl_cert_expired_time'] !== null &&
$server['ssl_cert_expiry_days'] > 0
)
) {
$server['status'] = 'warning';
}

View File

@ -55,8 +55,11 @@ class LogController extends AbstractServerController
'label_status' => psm_get_lang('log', 'status'),
'label_email' => psm_get_lang('log', 'email'),
'label_sms' => psm_get_lang('log', 'sms'),
'label_discord' => psm_get_lang('log', 'discord'),
'label_pushover' => psm_get_lang('log', 'pushover'),
'label_webhook' => psm_get_lang('log', 'webhook'),
'label_telegram' => psm_get_lang('log', 'telegram'),
'label_jabber' => psm_get_lang('log', 'jabber'),
'label_title' => psm_get_lang('log', 'title'),
'label_server' => psm_get_lang('servers', 'server'),
'label_type' => psm_get_lang('log', 'type'),
@ -76,7 +79,7 @@ class LogController extends AbstractServerController
$modal->setTitle(psm_get_lang('log', 'delete_title'));
$modal->setMessage(psm_get_lang('log', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
$sidebar->addButton(
'clear_logn',
psm_get_lang('log', 'clear'),
@ -88,7 +91,7 @@ class LogController extends AbstractServerController
);
}
$log_types = array('status', 'email', 'sms', 'pushover', 'telegram');
$log_types = array('status', 'email', 'sms', 'pushover', 'telegram', 'jabber', 'discord', 'webhook');
foreach ($log_types as $key) {
$records = $this->getEntries($key);
@ -160,9 +163,9 @@ class LogController extends AbstractServerController
if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`servers`.`server_id`
)";
`us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`servers`.`server_id`
)";
}
$entries = $this->db->query(
'SELECT ' .

View File

@ -100,8 +100,11 @@ class ServerController extends AbstractServerController
$icons = array(
'email' => 'icon-envelope',
'sms' => 'icon-mobile',
'discord' => 'icon-discord',
'pushover' => 'icon-pushover',
'webhook' => 'icon-webhook',
'telegram' => 'icon-telegram',
'jabber' => 'icon-jabber'
);
$servers = $this->getServers();
@ -114,6 +117,9 @@ class ServerController extends AbstractServerController
$servers[$x]['ip'] = '<a href="' . $servers[$x]['ip'] .
'" target="_blank" rel="noopener">' . $ip . '</a>';
}
if ($servers[$x]['type'] == 'ping') {
$servers[$x]['port'] = '';
}
if (($servers[$x]['active'] == 'yes')) {
$servers[$x]['active_title'] = psm_get_lang('servers', 'monitoring');
} else {
@ -123,6 +129,14 @@ class ServerController extends AbstractServerController
$servers[$x] = $this->formatServer($servers[$x]);
}
$tpl_data['servers'] = $servers;
$tpl_data['config']['email'] = psm_get_conf('email_status');
$tpl_data['config']['sms'] = psm_get_conf('sms_status');
$tpl_data['config']['discord'] = psm_get_conf('discord_status');
$tpl_data['config']['webhook'] = psm_get_conf('webhook_status');
$tpl_data['config']['pushover'] = psm_get_conf('pushover_status');
$tpl_data['config']['telegram'] = psm_get_conf('telegram_status');
return $this->twig->render('module/server/server/list.tpl.html', $tpl_data);
}
@ -133,6 +147,12 @@ class ServerController extends AbstractServerController
{
$back_to = isset($_GET['back_to']) ? $_GET['back_to'] : '';
$modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER);
$this->addModal($modal);
$modal->setTitle(psm_get_lang('servers', 'delete_title'));
$modal->setMessage(psm_get_lang('servers', 'delete_message'));
$modal->setOKButtonLabel(psm_get_lang('system', 'delete'));
$tpl_data = $this->getLabels();
$tpl_data['edit_server_id'] = $this->server_id;
$tpl_data['url_save'] = psm_build_url(array(
@ -141,6 +161,11 @@ class ServerController extends AbstractServerController
'id' => $this->server_id,
'back_to' => $back_to,
));
$tpl_data['url_delete'] = psm_build_url(array(
'mod' => 'server',
'action' => 'delete',
'id' => $this->server_id,
));
// depending on where the user came from, add the go back url:
if ($back_to == 'view' && $this->server_id > 0) {
@ -153,6 +178,13 @@ class ServerController extends AbstractServerController
$tpl_data['users'] = $this->db->select(PSM_DB_PREFIX . 'users', null, array('user_id', 'name'), '', 'name');
foreach ($tpl_data['users'] as &$user) {
$user['id'] = $user['user_id'];
unset($user['user_id']);
$user['label'] = $user['name'];
unset($user['name']);
}
switch ($this->server_id) {
case 0:
// insert mode
@ -173,10 +205,6 @@ class ServerController extends AbstractServerController
$user_idc_selected = $this->getServerUsers($this->server_id);
foreach ($tpl_data['users'] as &$user) {
$user['id'] = $user['user_id'];
unset($user['user_id']);
$user['label'] = $user['name'];
unset($user['name']);
if (in_array($user['id'], $user_idc_selected)) {
$user['edit_selected'] = 'selected="selected"';
}
@ -208,16 +236,20 @@ class ServerController extends AbstractServerController
'edit_value_website_username' => $edit_server['website_username'],
'edit_value_website_password' => empty($edit_server['website_password']) ? '' :
sha1($edit_server['website_password']),
'edit_value_ssl_cert_expiry_days' => $edit_server['ssl_cert_expiry_days'],
'edit_type_selected_' . $edit_server['type'] => 'selected="selected"',
'edit_active_selected' => $edit_server['active'],
'edit_email_selected' => $edit_server['email'],
'edit_sms_selected' => $edit_server['sms'],
'edit_discord_selected' => $edit_server['discord'],
'edit_webhook_selected' => $edit_server['webhook'],
'edit_pushover_selected' => $edit_server['pushover'],
'edit_telegram_selected' => $edit_server['telegram'],
'edit_jabber_selected' => $edit_server['jabber'],
));
}
$notifications = array('email', 'sms', 'pushover', 'telegram');
$notifications = array('email', 'sms', 'pushover', 'discord', 'webhook', 'telegram', 'jabber');
foreach ($notifications as $notification) {
if (psm_get_conf($notification . '_status') == 0) {
$tpl_data['warning_' . $notification] = true;
@ -245,7 +277,7 @@ class ServerController extends AbstractServerController
// We need the server id to encrypt the password. Encryption will be done after the server is added
$encrypted_password = '';
if (!empty($_POST['website_password'])) {
$new_password = psm_POST('website_password');
@ -281,11 +313,15 @@ class ServerController extends AbstractServerController
'header_name' => psm_POST('header_name', ''),
'header_value' => psm_POST('header_value', ''),
'warning_threshold' => intval(psm_POST('warning_threshold', 0)),
'ssl_cert_expiry_days' => intval(psm_POST('ssl_cert_expiry_days', 1)),
'active' => in_array($_POST['active'], array('yes', 'no')) ? $_POST['active'] : 'no',
'email' => in_array($_POST['email'], array('yes', 'no')) ? $_POST['email'] : 'no',
'sms' => in_array($_POST['sms'], array('yes', 'no')) ? $_POST['sms'] : 'no',
'discord' => in_array($_POST['discord'], array('yes', 'no')) ? $_POST['discord'] : 'no',
'pushover' => in_array($_POST['pushover'], array('yes', 'no')) ? $_POST['pushover'] : 'no',
'webhook' => in_array($_POST['webhook'], array('yes', 'no')) ? $_POST['webhook'] : 'no',
'telegram' => in_array($_POST['telegram'], array('yes', 'no')) ? $_POST['telegram'] : 'no',
'jabber' => in_array($_POST['jabber'], array('yes', 'no')) ? $_POST['jabber'] : 'no',
);
// make sure websites start with http://
if (
@ -325,6 +361,7 @@ class ServerController extends AbstractServerController
$server_validator->type($clean['type']);
$server_validator->ip($clean['ip'], $clean['type']);
$server_validator->warningThreshold($clean['warning_threshold']);
$server_validator->sslCertExpiryDays($clean['ssl_cert_expiry_days']);
} catch (\InvalidArgumentException $ex) {
$this->addMessage(psm_get_lang('servers', 'error_' . $ex->getMessage()), 'error');
return $this->executeEdit();
@ -492,6 +529,15 @@ class ServerController extends AbstractServerController
if (strlen($tpl_data['last_error_output']) > 255) {
$tpl_data['last_error_output_truncated'] = substr($tpl_data['last_error_output'], 0, 255) . '...';
}
// fetch server status logs
$log_entries = $this->getServerLogs($this->server_id);
for ($x = 0; $x < count($log_entries); $x++) {
$record = &$log_entries[$x];
$record['datetime_format'] = psm_date($record['datetime']);
}
$tpl_data['log_entries'] = $log_entries;
return $this->twig->render('module/server/server/view.tpl.html', $tpl_data);
}
@ -551,13 +597,22 @@ class ServerController extends AbstractServerController
'label_send_email' => psm_get_lang('servers', 'send_email'),
'label_sms' => psm_get_lang('servers', 'sms'),
'label_send_sms' => psm_get_lang('servers', 'send_sms'),
'label_discord' => psm_get_lang('servers', 'discord'),
'label_send_discord' => psm_get_lang('servers', 'send_discord'),
'label_pushover' => psm_get_lang('servers', 'pushover'),
'label_send_pushover' => psm_get_lang('servers', 'send_pushover'),
'label_send_webhook' => psm_get_lang('servers', 'send_webhook'),
'label_telegram' => psm_get_lang('servers', 'telegram'),
'label_jabber' => psm_get_lang('servers', 'jabber'),
'label_send_jabber' => psm_get_lang('servers', 'send_jabber'),
'label_webhook' => psm_get_lang('servers', 'webhook'),
'label_pushover' => psm_get_lang('servers', 'pushover'),
'label_send_telegram' => psm_get_lang('servers', 'send_telegram'),
'label_users' => psm_get_lang('servers', 'users'),
'label_warning_threshold' => psm_get_lang('servers', 'warning_threshold'),
'label_warning_threshold_description' => psm_get_lang('servers', 'warning_threshold_description'),
'label_ssl_cert_expiry_days' => psm_get_lang('servers', 'ssl_cert_expiry_days'),
'label_ssl_cert_expiry_days_description' => psm_get_lang('servers', 'ssl_cert_expiry_days_description'),
'label_action' => psm_get_lang('system', 'action'),
'label_save' => psm_get_lang('system', 'save'),
'label_go_back' => psm_get_lang('system', 'go_back'),
@ -567,7 +622,8 @@ class ServerController extends AbstractServerController
'label_yes' => psm_get_lang('system', 'yes'),
'label_no' => psm_get_lang('system', 'no'),
'label_add_new' => psm_get_lang('system', 'add_new'),
'label_seconds' => psm_get_lang('config', 'seconds'),
'label_seconds' => psm_get_lang('system', 'seconds'),
'label_milliseconds' => psm_get_lang('system', 'milliseconds'),
'label_online' => psm_get_lang('servers', 'online'),
'label_offline' => psm_get_lang('servers', 'offline'),
'label_ok' => psm_get_lang('system', 'ok'),
@ -576,6 +632,10 @@ class ServerController extends AbstractServerController
'label_settings' => psm_get_lang('system', 'settings'),
'label_output' => psm_get_lang('servers', 'output'),
'label_search' => psm_get_lang('system', 'search'),
'label_log_title' => psm_get_lang('log', 'title'),
'label_log_no_logs' => psm_get_lang('log', 'no_logs'),
'label_date' => psm_get_lang('system', 'date'),
'label_message' => psm_get_lang('system', 'message'),
);
}
@ -597,4 +657,42 @@ class ServerController extends AbstractServerController
}
return $result;
}
/**
* Get logs for a server
* @param int $server_id
* @param string $type status/email/sms
* @return \PDOStatement array
*/
protected function getServerLogs($server_id, $type = 'status')
{
$sql_join = '';
if ($this->getUser()->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->getUser()->getUserId()}
AND `us`.`server_id`=`servers`.`server_id`
)";
}
$entries = $this->db->query(
'SELECT ' .
'`servers`.`label`, ' .
'`servers`.`ip`, ' .
'`servers`.`port`, ' .
'`servers`.`type` AS server_type, ' .
'`log`.`log_id`, ' .
'`log`.`type`, ' .
'`log`.`message`, ' .
'`log`.`datetime` ' .
'FROM `' . PSM_DB_PREFIX . 'log` AS `log` ' .
'JOIN `' . PSM_DB_PREFIX . 'servers` AS `servers` ON (`servers`.`server_id`=`log`.`server_id`) ' .
$sql_join .
'WHERE `log`.`type`=\'' . $type . '\' ' .
'AND `log`.`server_id`=' . $server_id . ' ' .
'ORDER BY `datetime` DESC ' .
'LIMIT 0,20'
);
return $entries;
}
}

View File

@ -100,6 +100,8 @@ class StatusController extends AbstractServerController
$layout_data['servers_offline'][] = $server;
} elseif ($server['warning_threshold_counter'] > 0) {
$layout_data['servers_warning'][] = $server;
} elseif ($server['ssl_cert_expired_time'] !== null && $server['ssl_cert_expiry_days'] > 0) {
$layout_data['servers_warning'][] = $server;
} else {
$layout_data['servers_online'][] = $server;
}

View File

@ -39,7 +39,7 @@ class ProfileController extends AbstractController
* @var array $profile_fields
*/
protected $profile_fields =
array('name', 'user_name', 'email', 'mobile', 'pushover_key', 'pushover_device', 'telegram_id');
array('name', 'user_name', 'email', 'mobile', 'pushover_key', 'pushover_device', 'discord', 'webhook_url', 'webhook_json', 'telegram_id', 'jabber');
public function __construct(Database $db, \Twig_Environment $twig)
{
@ -78,11 +78,21 @@ class ProfileController extends AbstractController
'label_password_repeat' => psm_get_lang('users', 'password_repeat'),
'label_level' => psm_get_lang('users', 'level'),
'label_mobile' => psm_get_lang('users', 'mobile'),
'label_webhook' => psm_get_lang('users', 'webhook'),
'label_webhook_description' => psm_get_lang('users', 'webhook_description'),
'label_webhook_url' => psm_get_lang('users', 'webhook_url'),
'label_webhook_url_description' => psm_get_lang('users', 'webhook_url_description'),
'label_webhook_json' => psm_get_lang('users', 'webhook_json'),
'label_webhook_json_description' => psm_get_lang('users', 'webhook_json_description'),
'label_pushover' => psm_get_lang('users', 'pushover'),
'label_pushover_description' => psm_get_lang('users', 'pushover_description'),
'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_discord' => psm_get_lang('users', 'discord'),
'label_discord_description' => psm_get_lang('users', 'discord_description'),
'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_chat_id' => psm_get_lang('users', 'telegram_chat_id'),
@ -90,6 +100,8 @@ class ProfileController extends AbstractController
'label_activate_telegram' => psm_get_lang('users', 'activate_telegram'),
'label_telegram_get_chat_id' => psm_get_lang('users', 'telegram_get_chat_id'),
'telegram_get_chat_id_url' => PSM_TELEGRAM_GET_ID_URL,
'label_jabber' => psm_get_lang('users', 'jabber'),
'label_jabber_description' => psm_get_lang('users', 'jabber_description'),
'label_email' => psm_get_lang('users', 'email'),
'label_save' => psm_get_lang('system', 'save'),
'form_action' => psm_build_url(array(

View File

@ -158,9 +158,13 @@ class UserController extends AbstractController
'name',
'user_name',
'mobile',
'discord',
'webhook_url',
'webhook_json',
'pushover_key',
'pushover_device',
'telegram_id',
'jabber',
'email'
);
@ -254,9 +258,13 @@ class UserController extends AbstractController
'password_repeat',
'level',
'mobile',
'discord',
'webhook_url',
'webhook_json',
'pushover_key',
'pushover_device',
'telegram_id',
'jabber',
'email'
);
$clean = array();
@ -310,6 +318,15 @@ class UserController extends AbstractController
if ($user_id > 0) {
// edit user
unset($clean['password']); // password update is executed separately
$admins = $this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN));
if (
(int) count($admins) === (int) 1 &&
(int) $admins[0]['user_id'] === (int) $user_id &&
(int) $clean['level'] === (int) PSM_USER_USER
) {
$this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'warning');
$clean['level'] = PSM_USER_ADMIN;
}
$this->db->save(PSM_DB_PREFIX . 'users', $clean, array('user_id' => $user_id));
$this->addMessage(psm_get_lang('users', 'updated'), 'success');
@ -360,7 +377,11 @@ class UserController extends AbstractController
try {
$this->container->get('util.user.validator')->userId($id);
if (count($this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN))) == 1) {
$admins = $this->db->select(PSM_DB_PREFIX . 'users', array('level' => PSM_USER_ADMIN));
if (
(int) count($admins) === (int) 1 &&
(int) $admins[0]['user_id'] === (int) $id
) {
$this->addMessage(psm_get_lang('users', 'error_user_admin_cant_be_deleted'), 'error');
} else {
$this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,));
@ -392,15 +413,24 @@ class UserController extends AbstractController
'label_level' => psm_get_lang('users', 'level'),
'label_level_description' => psm_get_lang('users', 'level_description'),
'label_mobile' => psm_get_lang('users', 'mobile'),
'label_discord' => psm_get_lang('users', 'discord'),
'label_discord_description' => psm_get_lang('users', 'discord_description'),
'label_webhook' => psm_get_lang('users', 'webhook'),
'label_webhook_description' => psm_get_lang('users', 'webhook_description'),
'label_webhook_url' => psm_get_lang('users', 'webhook_url'),
'label_webhook_url_description' => psm_get_lang('users', 'webhook_url_description'),
'label_webhook_json' => psm_get_lang('users', 'webhook_json'),
'label_webhook_json_description' => psm_get_lang('users', 'webhook_json_description'),
'label_pushover' => psm_get_lang('users', 'pushover'),
'label_pushover_description' => psm_get_lang('users', 'pushover_description'),
'label_pushover_key' => psm_get_lang('users', 'pushover_key'),
'label_pushover_device' => psm_get_lang('users', 'pushover_device'),
'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'),
'label_telegram' => psm_get_lang('users', 'telegram'),
'label_telegram_description' => psm_get_lang('users', 'telegram_description'),
'label_telegram_id' => psm_get_lang('users', 'telegram_chat_id'),
'label_telegram_id_description' => psm_get_lang('users', 'telegram_chat_id_description'),
'label_jabber' => psm_get_lang('users', 'jabber'),
'label_jabber_description' => psm_get_lang('users', 'jabber_description'),
'label_email' => psm_get_lang('users', 'email'),
'label_servers' => psm_get_lang('menu', 'server'),
'label_save' => psm_get_lang('system', 'save'),

View File

@ -35,15 +35,15 @@ final class UserEvents
/**
* @var string
*/
public const USER_ADD = 'user.add';
const USER_ADD = 'user.add';
/**
* @var string
*/
public const USER_EDIT = 'user.edit';
const USER_EDIT = 'user.edit';
/**
* @var string
*/
public const USER_DELETE = 'user.delete';
const USER_DELETE = 'user.delete';
}

View File

@ -67,10 +67,10 @@ class CMBulkSMS extends Core
protected $messageBody;
/** @var string JSON Gateway API URL */
public const GATEWAY_URL_JSON = "https://gw.cmtelecom.com/v1.0/message";
const GATEWAY_URL_JSON = "https://gw.cmtelecom.com/v1.0/message";
/** @var string XML Gateway API URL */
public const GATEWAY_URL_XML = "https://sgw01.cm.nl/gateway.ashx";
const GATEWAY_URL_XML = "https://sgw01.cm.nl/gateway.ashx";
/**
* Build the message and send cURL request to the sms gateway
@ -131,7 +131,7 @@ class CMBulkSMS extends Core
),
'msg' => array(
array(
'from' => substr($this->originator, 0, 11),
'from' => substr($this->originator, 0, 15),
'to' => $recipients,
'body' => array(
'content' => $message
@ -172,7 +172,7 @@ class CMBulkSMS extends Core
$msg = $xml->addChild('MSG');
// From
$msg->addChild('FROM', substr($this->originator, 0, 11));
$msg->addChild('FROM', substr($this->originator, 0, 15));
// Recipients
foreach ($this->recipients as $recipient) {

View File

@ -64,7 +64,7 @@ class ClickSend extends Core
foreach ($this->recipients as $recipient) {
$data['messages'][] = array(
'source' => 'phpservermon',
'from' => substr($this->originator, 0, 11),
'from' => substr($this->originator, 0, 15),
'to' => $recipient,
'body' => $message,
);

2
src/psm/Txtmsg/FreeVoipDeal.php Executable file → Normal file
View File

@ -63,7 +63,7 @@ class FreeVoipDeal extends Core
array(
"username" => $this->username,
"password" => $this->password,
"from" => substr($this->originator, 0, 11),
"from" => substr($this->originator, 0, 15),
"to" => $recipient,
"text" => $message,
)

View File

@ -63,7 +63,7 @@ class Mosms extends Core
array(
"username" => $this->username,
"password" => $this->password,
"customsender" => substr($this->originator, 0, 11),
"customsender" => substr($this->originator, 0, 15),
"nr" => $recipient,
"type" => "text",
"data" => $message,

101
src/psm/Txtmsg/OVHsms.php Normal file
View File

@ -0,0 +1,101 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Alexis Urien <Alexis.urien@free.fr>
* @Author Tim Zandbergen <Tim@Xervion.nl>
* @author Ward Pieters <ward@wardpieters.nl>
* @author Alexandre ZANELLI <alexandre@les-z.org>
* @copyright Copyright (c) 2016 Alexis Urien <alexis.urien@free.fr>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.5
**/
namespace psm\Txtmsg;
class OVHsms extends Core {
/**
* Send sms using the OVH http2sms gateway
* Online documentation :https://docs.ovh.com/fr/sms/envoyer_des_sms_depuis_une_url_-_http2sms/
* Ovh need Account and Login, then use format login@account in username field.
*
* @var string $message
* @var string $this->username
* @var string $this->password
* @var array $this->recipients
* @var array $this->originator
*
* @var resource $curl
* @var SimpleXMLElement $xmlResults
* @var string $err
* @var string $recipient
* @var mixed $result
*
* @var int $success
* @var string $error
*
* @return bool|string
*/
public function sendSMS($message) {
$error = "";
$success = 1;
$account_login = explode('@',$this->username);
$recipients = join(',', $this->recipients);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://www.ovh.com/cgi-bin/sms/http2sms.cgi?".http_build_query(
array(
"account" => $account_login[1],
"login" => $account_login[0],
"password" => $this->password,
"from" => str_replace('+', '00', $this->originator),
"to" => $recipients,
"message" => $message,
"contentType" => "text/xml",
"noStop" => 1,
)
)
);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$xmlResults = simplexml_load_string($result);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 200 || $xmlResults === false ||($xmlResults->status != '100' && $xmlResults->status != '101')) {
$success = 0;
$error = "HTTP_code: ".$httpcode.".\ncURL error (".$err."): ".curl_strerror($err).". \nResult: ".$xmlResults->status." \n".$xmlResults->Message;
}
curl_close($curl);
if ($success) {
return 1;
}
return $error;
}
}

View File

@ -59,11 +59,11 @@ class Octopush extends Core
{
$error = "";
$success = 1;
$smsType = "XXX"; //FR = premium, WWW = world, XXX = Low cost
$smsType = "FR"; //FR = premium, WWW = world, XXX = Low cost
$recipients = join(',', $this->recipients);
$message = ($smsType == "FR") ? urlencode($message . " STOP au XXXX") : urlencode($message);
$message = ($smsType == "FR") ? rawurlencode($message . " STOP au XXXXX") : rawurlencode($message);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "http://www.octopush-dm.com/api/sms/?" . http_build_query(
@ -72,7 +72,7 @@ class Octopush extends Core
"api_key" => $this->password,
"sms_recipients" => $recipients,
"sms_type" => $smsType,
"sms_sender" => substr($this->originator, 0, 11),
"sms_sender" => substr($this->originator, 0, 15),
"sms_text" => $message,
)
));

149
src/psm/Txtmsg/SMSAPI.php Executable file
View File

@ -0,0 +1,149 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Mateusz Małek <tajgeer@gmail.com>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.5
**/
namespace psm\Txtmsg;
class SMSAPI extends Core
{
const VARIANT_INTERNATIONAL = 1;
const VARIANT_POLISH = 2;
/**
* SMSAPI comes with two variants - designed for polish or international customers.
*
* @var int
*/
private $variant = self::VARIANT_INTERNATIONAL;
/**
* Name of the sender. As a default the sender name is set to "Test".
* Only verified names are being accepted.
* Sender name may be set after logging into Customer Portal on Sendernames.
* @see https://www.smsapi.com/docs/#2-single-sms
*
* @var string
*/
protected $originator;
/**
* Token used to authenticate in SMSAPI system.
* @see https://www.smsapi.com/docs/#authentication
*
* @var string
*/
protected $password;
/**
* Send sms using the SMSAPI
*
* @var string $message
* @var array $this->recipients
* @var array $this->originator
* @var string $this->password
* @var array $recipients_chunk
* @var string $host
*
* @var mixed $result
* @var array $headers
*
* @var int $success
* @var string $error
*
* @return bool|string
*/
public function sendSMS($message)
{
$tld = ($this->variant === static::VARIANT_INTERNATIONAL) ? "com" : "pl";
$host = "api.smsapi.{$tld}";
$backupHost = "api2.smsapi.{$tld}";
// One user at a time.
$recipients_chunk = array_chunk($this->recipients, 1);
foreach ($recipients_chunk as $recipient) {
try {
$response = $this->processSendOperation($host, $recipient, $message);
} catch (\RuntimeException $e) {
try {
$response = $this->processSendOperation($backupHost, $recipient, $message);
} catch (\RuntimeException $e) {
return "({$recipient}) " . $e->getMessage();
}
}
if (isset($response->error)) {
return $response->message;
}
return 1;
}
}
/**
* Perform actual SMS sending operation
*
* @param $host
* @param $recipient
* @param $message
* @return object
* @throws RuntimeException
*/
private function processSendOperation($host, $recipient, $message)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://{$host}/sms.do");
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
"access_token" => $this->password,
"from" => $this->originator,
"to" => $recipient,
"message" => $message,
"encoding" => "utf-8",
"normalize" => "1",
"format" => "json"
)));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$result = curl_exec($ch);
$error = false;
if (curl_errno($ch)) {
$error = curl_error($ch);
}
curl_close($ch);
if ($error !== false) {
throw new \RuntimeException($error);
}
return json_decode($result);
}
}

View File

@ -58,7 +58,7 @@ class Smsglobal extends Core
$recipients = join(',', $this->recipients);
$from = substr($this->originator, 0, 11); // Max 11 Characters
$from = substr($this->originator, 0, 15); // Max 15 Characters
$message = substr(rawurlencode($message), 0, 153);
$curl = curl_init();

View File

@ -64,7 +64,7 @@ class Smsit extends Core
"apiKey" => $this->password,
"mobile" => $recipient,
"message" => urlencode($message),
"senderId" => substr($this->originator, 0, 11),
"senderId" => substr($this->originator, 0, 15),
)
));

View File

@ -66,7 +66,7 @@ class SolutionsInfini extends Core
"api_key" => $this->password,
"method" => "sms",
"to" => $recipients,
"sender" => substr($this->originator, 0, 11),
"sender" => substr($this->originator, 0, 15),
"message" => $message,
)
));

92
src/psm/Txtmsg/Ysmal.php Normal file
View File

@ -0,0 +1,92 @@
<?php
/**
* PHP Server Monitor
* Monitor your servers and websites.
*
* This file is part of PHP Server Monitor.
* PHP Server Monitor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PHP Server Monitor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP Server Monitor. If not, see <http://www.gnu.org/licenses/>.
*
* @package phpservermon
* @author Perri Vardy-Mason
* @author Dylan Ysmal <dylan@ysmal.fr>
* @copyright Copyright (c) 2008-2017 Pepijn Over <pep@mailbox.org>
* @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3
* @version Release: @package_version@
* @link http://www.phpservermonitor.org/
* @since phpservermon 3.5
**/
namespace psm\Txtmsg;
class Ysmal extends Core
{
/**
* Send sms using the Hermes SMS API on Ysmal.fr
* @var string $message
* @var array $this->recipients
* @var string $this->password
*
* @var mixed $result
* @var array $headers
*
* @var int $success
* @var string $error
*
* @return bool|string
*/
public function sendSMS($message)
{
$success = 1;
$error = '';
foreach ($this->recipients as $recipient) {
$opts['http'] = [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
'User-Agent: PHPServerMonitor (+https://phpservermonitor.org)',
'content' => http_build_query([
'key' => $this->password,
'number' => $recipient,
'message' => $message
]),
'ignore_errors' => true
];
$api = 'https://sms-api.ysmal.fr/';
$ctx = stream_context_create($opts);
$res = file_get_contents($api, false, $ctx);
$json = json_decode($res, true);
if ($json === NULL) {
$success = 0;
$error = "($recipient) json_decode_error";
break;
}
if ($json['status'] !== 'success') {
$success = 0;
$error = "($recipient) $json[error]";
break;
}
}
if ($success) {
return 1;
}
return $error;
}
}

View File

@ -134,51 +134,64 @@ class Installer
$queries = array();
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "servers` (
`ip`, `port`, `label`, `type`, `pattern`, `pattern_online`, `redirect_check`,
`status`, `rtime`, `active`, `email`, `sms`, `pushover`, `telegram`)
`status`, `rtime`, `active`, `email`, `sms`, `pushover`,`webhook`, `telegram`, `jabber`)
VALUES ('http://sourceforge.net/index.php', 80, 'SourceForge', 'website', '',
'yes', 'bad', 'on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes'),
'yes', 'bad', 'on', '0.0000000', 'yes', 'yes', 'yes', 'yes','yes', 'yes', 'yes'),
('smtp.gmail.com', 465, 'Gmail SMTP', 'service', '',
'yes', 'bad','on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes')";
'yes', 'bad','on', '0.0000000', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes')";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users_servers` (`user_id`,`server_id`) VALUES (1, 1), (1, 2);";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('language', 'en_US'),
('proxy', '0'),
('proxy_url', ''),
('proxy_user', ''),
('proxy_password', ''),
('email_status', '1'),
('email_from_email', 'monitor@example.org'),
('email_from_name', 'Server Monitor'),
('email_smtp', ''),
('email_smtp_host', ''),
('email_smtp_port', ''),
('email_smtp_security', ''),
('email_smtp_username', ''),
('email_smtp_password', ''),
('sms_status', '0'),
('sms_gateway', 'messagebird'),
('sms_gateway_username', 'username'),
('sms_gateway_password', 'password'),
('sms_from', '1234567890'),
('pushover_status', '0'),
('pushover_api_token', ''),
('telegram_status', '0'),
('telegram_api_token', ''),
('password_encrypt_key', '" . sha1(microtime()) . "'),
('alert_type', 'status'),
('log_status', '1'),
('log_email', '1'),
('log_sms', '1'),
('log_pushover', '1'),
('log_telegram', '1'),
('log_retention_period', '365'),
('version', '" . PSM_VERSION . "'),
('version_update_check', '" . PSM_VERSION . "'),
('auto_refresh_servers', '0'),
('show_update', '1'),
('last_update_check', '0'),
('cron_running', '0'),
('cron_running_time', '0');";
('language', 'en_US'),
('proxy', '0'),
('proxy_url', ''),
('proxy_user', ''),
('proxy_password', ''),
('email_status', '1'),
('email_from_email', 'monitor@example.org'),
('email_from_name', 'Server Monitor'),
('email_smtp', ''),
('email_smtp_host', ''),
('email_smtp_port', ''),
('email_smtp_security', ''),
('email_smtp_username', ''),
('email_smtp_password', ''),
('sms_status', '0'),
('sms_gateway', 'messagebird'),
('sms_gateway_username', 'username'),
('sms_gateway_password', 'password'),
('sms_from', '1234567890'),
('webhook_status', '0'),
('pushover_status', '0'),
('pushover_api_token', ''),
('telegram_status', '0'),
('telegram_api_token', ''),
('jabber_status', '1'),
('jabber_host', ''),
('jabber_port', ''),
('jabber_username', ''),
('jabber_domain', ''),
('jabber_password', ''),
('password_encrypt_key', '" . sha1(microtime()) . "'),
('alert_type', 'status'),
('log_status', '1'),
('log_email', '1'),
('log_sms', '1'),
('log_pushover', '1'),
('log_webhook', '1'),
('log_telegram', '1'),
('log_jabber', '1'),
('discord_status', '0'),
('log_jdiscord', '1'),
('log_retention_period', '365'),
('version', '" . PSM_VERSION . "'),
('version_update_check', '" . PSM_VERSION . "'),
('auto_refresh_servers', '0'),
('show_update', '1'),
('last_update_check', '0'),
('cron_running', '0'),
('cron_running_time', '0'),
('cron_off_running', '0'),
('cron_off_running_time', '0');";
$this->execSQL($queries);
}
@ -189,45 +202,49 @@ class Installer
{
$tables = array(
PSM_DB_PREFIX . 'config' => "CREATE TABLE `" . PSM_DB_PREFIX . "config` (
`key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
`key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'users' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users` (
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(64) NOT NULL COMMENT 'user''s name, unique',
`password` varchar(255) NOT NULL COMMENT 'user''s password in salted and hashed format',
`password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code',
`password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request',
`rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token',
`level` tinyint(2) unsigned NOT NULL DEFAULT '20',
`name` varchar(255) NOT NULL,
`mobile` varchar(15) NOT NULL,
`pushover_key` varchar(255) NOT NULL,
`pushover_device` varchar(255) NOT NULL,
`telegram_id` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_name` varchar(64) NOT NULL COMMENT 'user''s name, unique',
`password` varchar(255) NOT NULL COMMENT 'user''s password in salted and hashed format',
`password_reset_hash` char(40) DEFAULT NULL COMMENT 'user''s password reset code',
`password_reset_timestamp` bigint(20) DEFAULT NULL COMMENT 'timestamp of the password reset request',
`rememberme_token` varchar(64) DEFAULT NULL COMMENT 'user''s remember-me cookie token',
`level` tinyint(2) unsigned NOT NULL DEFAULT '20',
`name` varchar(255) NOT NULL,
`mobile` varchar(15) NOT NULL,
`discord` varchar(255) NOT NULL,
`pushover_key` varchar(255) NOT NULL,
`pushover_device` varchar(255) NOT NULL,
`webhook_url` varchar(255) NOT NULL,
`webhook_json` varchar(255) NOT NULL DEFAULT '{\"text\":\"servermon: #message\"}',
`telegram_id` varchar(255) NOT NULL ,
`jabber` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `unique_username` (`user_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX .
'users_preferences' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (
`user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
`user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`, `key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'users_servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` (
`user_id` INT( 11 ) UNSIGNED NOT NULL ,
`server_id` INT( 11 ) UNSIGNED NOT NULL ,
`user_id` INT( 11 ) UNSIGNED NOT NULL ,
`server_id` INT( 11 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( `user_id` , `server_id` )
) ENGINE = MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'log' => "CREATE TABLE `" . PSM_DB_PREFIX . "log` (
`log_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`type` enum('status','email','sms','pushover','telegram') NOT NULL,
`message` TEXT NOT NULL,
`datetime` timestamp NOT NULL default CURRENT_TIMESTAMP,
`log_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`type` enum('status','email','sms','discord','pushover','webhook','telegram', 'jabber') NOT NULL,
`message` TEXT NOT NULL,
`datetime` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`log_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'log_users' => "CREATE TABLE `" . PSM_DB_PREFIX . "log_users` (
@ -236,41 +253,46 @@ class Installer
PRIMARY KEY (`log_id`, `user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers' => "CREATE TABLE `" . PSM_DB_PREFIX . "servers` (
`server_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(500) NOT NULL,
`port` int(5) NOT NULL,
`request_method` varchar(50) NULL,
`label` varchar(255) NOT NULL,
`type` enum('ping','service','website') NOT NULL default 'service',
`pattern` varchar(255) NOT NULL default '',
`pattern_online` enum('yes','no') NOT NULL default 'yes',
`post_field` varchar(255) NULL,
`redirect_check` enum('ok','bad') NOT NULL default 'bad',
`allow_http_status` varchar(255) NOT NULL default '',
`header_name` varchar(255) NOT NULL default '',
`header_value` varchar(255) NOT NULL default '',
`status` enum('on','off') NOT NULL default 'on',
`error` varchar(255) NULL,
`rtime` FLOAT(9, 7) NULL,
`last_online` datetime NULL,
`last_offline` datetime NULL,
`last_offline_duration` varchar(255) NULL,
`last_check` datetime NULL,
`active` enum('yes','no') NOT NULL default 'yes',
`email` enum('yes','no') NOT NULL default 'yes',
`sms` enum('yes','no') NOT NULL default 'no',
`pushover` enum('yes','no') NOT NULL default 'yes',
`telegram` enum('yes','no') NOT NULL default 'yes',
`warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1',
`warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0',
`timeout` smallint(1) unsigned NULL DEFAULT NULL,
`website_username` varchar(255) DEFAULT NULL,
`website_password` varchar(255) DEFAULT NULL,
`last_error` varchar(255) DEFAULT NULL,
`last_error_output` TEXT,
`last_output` TEXT,
PRIMARY KEY (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
`server_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ip` varchar(500) NOT NULL,
`port` int(5) NOT NULL,
`request_method` varchar(50) NULL,
`label` varchar(255) NOT NULL,
`type` enum('ping','service','website') NOT NULL default 'service',
`pattern` varchar(255) NOT NULL default '',
`pattern_online` enum('yes','no') NOT NULL default 'yes',
`post_field` varchar(255) NULL,
`redirect_check` enum('ok','bad') NOT NULL default 'bad',
`allow_http_status` varchar(255) NOT NULL default '',
`header_name` varchar(255) NOT NULL default '',
`header_value` varchar(255) NOT NULL default '',
`status` enum('on','off') NOT NULL default 'on',
`error` varchar(255) NULL,
`rtime` FLOAT(9, 7) NULL,
`last_online` datetime NULL,
`last_offline` datetime NULL,
`last_offline_duration` varchar(255) NULL,
`last_check` datetime NULL,
`active` enum('yes','no') NOT NULL default 'yes',
`email` enum('yes','no') NOT NULL default 'yes',
`sms` enum('yes','no') NOT NULL default 'no',
`discord` enum('yes','no') NOT NULL default 'yes',
`pushover` enum('yes','no') NOT NULL default 'yes',
`webhook` enum('yes','no') NOT NULL default 'yes',
`telegram` enum('yes','no') NOT NULL default 'yes',
`jabber` enum('yes','no') NOT NULL default 'yes',
`warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1',
`warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0',
`ssl_cert_expiry_days` mediumint(1) unsigned NOT NULL DEFAULT '0',
`ssl_cert_expired_time` varchar(255) NULL,
`timeout` smallint(1) unsigned NULL DEFAULT NULL,
`website_username` varchar(255) DEFAULT NULL,
`website_password` varchar(255) DEFAULT NULL,
`last_error` varchar(255) DEFAULT NULL,
`last_error_output` TEXT,
`last_output` TEXT,
PRIMARY KEY (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers_uptime' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` (
`servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
@ -281,14 +303,14 @@ class Installer
KEY `server_id` (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
PSM_DB_PREFIX . 'servers_history' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` (
`servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`date` date NOT NULL,
`latency_min` float(9,7) NOT NULL,
`latency_avg` float(9,7) NOT NULL,
`latency_max` float(9,7) NOT NULL,
`checks_total` int(11) unsigned NOT NULL,
`checks_failed` int(11) unsigned NOT NULL,
`servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`date` date NOT NULL,
`latency_min` float(9,7) NOT NULL,
`latency_avg` float(9,7) NOT NULL,
`latency_max` float(9,7) NOT NULL,
`checks_total` int(11) unsigned NOT NULL,
`checks_failed` int(11) unsigned NOT NULL,
PRIMARY KEY (`servers_history_id`),
UNIQUE KEY `server_id_date` (`server_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;",
@ -341,6 +363,9 @@ class Installer
if (version_compare($version_from, '3.4.2', '<')) {
$this->upgrade342();
}
if (version_compare($version_from, '3.5.0', '<')) {
$this->upgrade350();
}
if (version_compare($version_from, '3.6.0', '<')) {
$this->upgrade360();
}
@ -418,49 +443,49 @@ class Installer
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` CHANGE `user_id` `user_id` INT( 11 )
UNSIGNED NOT NULL AUTO_INCREMENT;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `user_name` varchar(64) COLLATE utf8_general_ci NOT NULL
ADD `user_name` varchar(64) COLLATE utf8_general_ci NOT NULL
COMMENT 'user\'s name, unique' AFTER `user_id`,
ADD `password` varchar(255) COLLATE utf8_general_ci NOT NULL
ADD `password` varchar(255) COLLATE utf8_general_ci NOT NULL
COMMENT 'user\'s password in salted and hashed format' AFTER `user_name`,
ADD `password_reset_hash` char(40) COLLATE utf8_general_ci DEFAULT NULL
ADD `password_reset_hash` char(40) COLLATE utf8_general_ci DEFAULT NULL
COMMENT 'user\'s password reset code' AFTER `password`,
ADD `password_reset_timestamp` bigint(20) DEFAULT NULL
ADD `password_reset_timestamp` bigint(20) DEFAULT NULL
COMMENT 'timestamp of the password reset request' AFTER `password_reset_hash`,
ADD `rememberme_token` varchar(64) COLLATE utf8_general_ci DEFAULT NULL
ADD `rememberme_token` varchar(64) COLLATE utf8_general_ci DEFAULT NULL
COMMENT 'user\'s remember-me cookie token' AFTER `password_reset_timestamp`,
ADD `level` TINYINT( 2 ) UNSIGNED NOT NULL DEFAULT '20' AFTER `rememberme_token`;";
ADD `level` TINYINT( 2 ) UNSIGNED NOT NULL DEFAULT '20' AFTER `rememberme_token`;";
// make sure all current users are admins (previously we didnt have non-admins):
$queries[] = "UPDATE `" . PSM_DB_PREFIX . "users` SET `user_name`=`email`, `level`=10;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users` ADD UNIQUE `unique_username` ( `user_name` );";
$queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` (
`servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`date` datetime NOT NULL,
`status` tinyint(1) unsigned NOT NULL,
`latency` float(9,7) DEFAULT NULL,
PRIMARY KEY (`servers_uptime_id`),
KEY `server_id` (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
`servers_uptime_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`date` datetime NOT NULL,
`status` tinyint(1) unsigned NOT NULL,
`latency` float(9,7) DEFAULT NULL,
PRIMARY KEY (`servers_uptime_id`),
KEY `server_id` (`server_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
$queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_history` (
`servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`date` date NOT NULL,
`latency_min` float(9,7) NOT NULL,
`latency_avg` float(9,7) NOT NULL,
`latency_max` float(9,7) NOT NULL,
`checks_total` int(11) unsigned NOT NULL,
`checks_failed` int(11) unsigned NOT NULL,
PRIMARY KEY (`servers_history_id`),
UNIQUE KEY `server_id_date` (`server_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
`servers_history_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`server_id` int(11) unsigned NOT NULL,
`date` date NOT NULL,
`latency_min` float(9,7) NOT NULL,
`latency_avg` float(9,7) NOT NULL,
`latency_max` float(9,7) NOT NULL,
`checks_total` int(11) unsigned NOT NULL,
`checks_failed` int(11) unsigned NOT NULL,
PRIMARY KEY (`servers_history_id`),
UNIQUE KEY `server_id_date` (`server_id`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
$queries[] = "CREATE TABLE `" . PSM_DB_PREFIX . "users_servers` (
`user_id` INT( 11 ) UNSIGNED NOT NULL ,
`server_id` INT( 11 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( `user_id` , `server_id` )
) ENGINE = MYISAM ;";
`user_id` INT( 11 ) UNSIGNED NOT NULL ,
`server_id` INT( 11 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( `user_id` , `server_id` )
) ENGINE = MYISAM ;";
$this->execSQL($queries);
// from 3.0 all user-server relations are in a separate table
@ -512,11 +537,11 @@ class Installer
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `last_offline_duration` varchar(255) NULL;";
$queries[] = "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "users_preferences` (
`user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`, `key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
`user_id` int(11) unsigned NOT NULL,
`key` varchar(255) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`user_id`, `key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;";
$this->execSQL($queries);
}
@ -533,14 +558,14 @@ class Installer
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `website_username` varchar(255) NULL,
ADD `website_password` varchar(255) NULL AFTER `website_username`;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('proxy', '0'),
('proxy_url', ''),
('proxy_user', ''),
('proxy_password', '');";
('proxy', '0'),
('proxy_url', ''),
('proxy_user', ''),
('proxy_password', '');";
$this->execSQL($queries);
// Create log_users table
// Create log_users table
$this->execSQL("CREATE TABLE `" . PSM_DB_PREFIX . "log_users` (
`log_id` int(11) UNSIGNED NOT NULL ,
`user_id` int(11) UNSIGNED NOT NULL ,
@ -590,9 +615,9 @@ class Installer
"log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover', 'telegram' )
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('telegram_status', '0'),
('log_telegram', '1'),
('telegram_api_token', '');";
('telegram_status', '0'),
('log_telegram', '1'),
('telegram_api_token', '');";
$this->execSQL($queries);
}
@ -646,7 +671,7 @@ class Installer
$this->execSQL($queries);
$this->log('Combined notifications enabled. Check out the config page for more info.');
}
/**
* Patch for v3.4.2 release
* Version_compare was forgotten in v3.4.1 and query failed.
@ -659,13 +684,80 @@ class Installer
$this->execSQL($queries);
}
protected function upgrade360()
/**
* Upgrade for v3.5.0 release
*/
protected function upgrade350()
{
$queries = array();
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `ssl_cert_expiry_days` MEDIUMINT(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `warning_threshold_counter`";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `ssl_cert_expired_time` VARCHAR(255) NULL AFTER `ssl_cert_expiry_days`";
if (
@psm_password_decrypt(
psm_get_conf('password_encrypt_key'),
psm_get_conf('email_smtp_password')
) === false
) {
// Prevents encrypting the password multiple times.
$queries[] = "UPDATE `" . PSM_DB_PREFIX . "config`
SET `value` = '" .
psm_password_encrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('email_smtp_password')) .
"' WHERE `key` = 'email_smtp_password'";
$this->log('SMTP password is now encrypted.');
}
$queries[] = 'ALTER TABLE `' . PSM_DB_PREFIX . 'users` ADD `jabber` VARCHAR( 255 )
NOT NULL AFTER `telegram_id`;';
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `jabber` ENUM( 'yes','no' )
NOT NULL DEFAULT 'yes' AFTER `telegram`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX .
"log` CHANGE `type` `type` ENUM( 'status', 'email', 'sms', 'pushover', 'telegram', 'jabber' )
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('jabber_status', '0'),
('log_jabber', '1'),
('jabber_host', ''),
('jabber_port', ''),
('jabber_username', ''),
('jabber_domain', ''),
('jabber_password', '');";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "users` (
`user_name`, `level`, `name`, `email`)
VALUES ('__PUBLIC__', 30, 'Public page', 'publicpage@psm.psm')";
$this->execSQL($queries);
$this->log('Added user \'__PUBLIC__\'.');
}
/**
* Patch for v3.6.0 release
* Added support for Discord and webhooks
*/
protected function upgrade360()
{
$queries = array();
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `webhook_url` VARCHAR( 255 ) NOT NULL AFTER `telegram_id`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `webhook_json` VARCHAR( 255 ) NOT NULL AFTER `telegram_id`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "log`
CHANGE `type` `type` ENUM('status','email','sms','discord','webhook','pushover','telegram','jabber')
CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `webhook` ENUM( 'yes','no' ) NOT NULL DEFAULT 'yes' AFTER `telegram`;";
$queries[] = "INSERT INTO `" . PSM_DB_PREFIX . "config` (`key`, `value`) VALUE
('discord_status', '0'),
('log_discord', '1'),
('webhook_status', '0'),
('log_webhook', '1')";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "users`
ADD `discord` VARCHAR( 255 ) NOT NULL AFTER `mobile`;";
$queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers`
ADD `discord` ENUM( 'yes','no' ) NOT NULL DEFAULT 'yes' AFTER `sms`;";
$this->execSQL($queries);
}
}

View File

@ -32,9 +32,9 @@ namespace psm\Util\Module;
class Modal implements ModalInterface
{
public const MODAL_TYPE_OK = 0;
public const MODAL_TYPE_OKCANCEL = 1;
public const MODAL_TYPE_DANGER = 2;
const MODAL_TYPE_OK = 0;
const MODAL_TYPE_OKCANCEL = 1;
const MODAL_TYPE_DANGER = 2;
/**
* prefix used for modal dialog box elements
@ -145,7 +145,7 @@ class Modal implements ModalInterface
$tpl = $this->twig->loadTemplate('util/module/modal.tpl.html');
$html = $tpl->render(array(
'modal_id' => $this->modal_id,
'modal_title' => !empty($this->title) ? $this->title : psm_get_lang('system', 'title'),
'modal_title' => !empty($this->title) ? $this->title : psm_get_conf('site_title', psm_get_lang('system', 'title')),
'modal_body' => $message,
'has_cancel' => $has_cancel,
'label_cancel' => psm_get_lang('system', 'cancel'),

View File

@ -29,7 +29,10 @@
namespace psm\Util\Server;
use DateTime;
use psm\Service\Database;
use Twig\Error\Error;
use Twig_Environment;
/**
* History util, create HTML for server graphs
@ -39,17 +42,17 @@ class HistoryGraph
/**
* Database service
* @var \psm\Service\Database $db;
* @var Database $db;
*/
protected $db;
/**
* Twig environment
* @var \Twig_Environment $twig
* @var Twig_Environment $twig
*/
protected $twig;
public function __construct(Database $db, \Twig_Environment $twig)
public function __construct(Database $db, Twig_Environment $twig)
{
$this->db = $db;
$this->twig = $twig;
@ -57,7 +60,9 @@ class HistoryGraph
/**
* Prepare the HTML for the graph
* @return string
* @param string $server_id ID of server to fetch data for
* @return string Created HTML
* @throws Error On twig error
*/
public function createHTML($server_id)
{
@ -65,16 +70,16 @@ class HistoryGraph
$archive = new ArchiveManager($this->db);
$archive->archive($server_id);
$now = new \DateTime();
$last_week = new \DateTime('-1 week 0:0:0');
$last_year = new \DateTime('-1 year -1 week 0:0:0');
$now = new DateTime();
$last_week = new DateTime('-1 week 0:0:0');
$last_year = new DateTime('-1 year -1 week 0:0:0');
$graphs = array(
0 => $this->generateGraphUptime($server_id, $last_week, $now),
1 => $this->generateGraphHistory($server_id, $last_year, $last_week),
);
$info_fields = array(
'latency_avg' => '%01.4f',
'latency_avg' => '%01.5f',
'uptime' => '%01.3f%%',
);
@ -101,8 +106,8 @@ class HistoryGraph
/**
* Generate data for uptime graph
* @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph
* @param DateTime $start_time Lowest DateTime of the graph
* @param DateTime $end_time Highest DateTime of the graph
* @return array
*/
public function generateGraphUptime($server_id, $start_time, $end_time)
@ -112,9 +117,9 @@ class HistoryGraph
'latency' => array(),
);
$hour = new \DateTime('-1 hour');
$day = new \DateTime('-1 day');
$week = new \DateTime('-1 week');
$hour = new DateTime('-1 hour');
$day = new DateTime('-1 day');
$week = new DateTime('-1 week');
$records = $this->getRecords('uptime', $server_id, $start_time, $end_time);
@ -148,8 +153,8 @@ class HistoryGraph
/**
* Generate data for history graph
* @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph
* @param DateTime $start_time Lowest DateTime of the graph
* @param DateTime $end_time Highest DateTime of the graph
* @return array
*/
public function generateGraphHistory($server_id, $start_time, $end_time)
@ -160,9 +165,9 @@ class HistoryGraph
'latency_max' => array(),
);
$week = new \DateTime('-2 week 0:0:0');
$month = new \DateTime('-1 month -1 week 0:0:0');
$year = new \DateTime('-1 year -1 week 0:0:0');
$week = new DateTime('-2 week 0:0:0');
$month = new DateTime('-1 month -1 week 0:0:0');
$year = new DateTime('-1 year -1 week 0:0:0');
$records = $this->getRecords('history', $server_id, $year, $end_time);
@ -197,8 +202,8 @@ class HistoryGraph
* Get all uptime/history records for a server
* @param string $type
* @param int $server_id
* @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph
* @param DateTime $start_time Lowest DateTime of the graph
* @param DateTime $end_time Highest DateTime of the graph
* @return array
*/
protected function getRecords($type, $server_id, $start_time, $end_time)
@ -207,17 +212,19 @@ class HistoryGraph
return array();
}
$records = $this->db->execute(
"SELECT *
/** @noinspection SqlNoDataSourceInspection */
/** @noinspection SqlResolve */
/** @noinspection PhpUndefinedConstantInspection */
return $this->db->execute(
"SELECT *, UNIX_TIMESTAMP(CONVERT_TZ(`date`, '+00:00', @@session.time_zone)) AS date_ts
FROM `" . PSM_DB_PREFIX . "servers_$type`
WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date` ASC",
WHERE `server_id` = :server_id AND `date` BETWEEN :start_time AND :end_time ORDER BY `date`",
array(
'server_id' => $server_id,
'start_time' => $start_time->format('Y-m-d H:i:s'),
'end_time' => $end_time->format('Y-m-d H:i:s'),
)
);
return $records;
}
/**
@ -225,12 +232,9 @@ class HistoryGraph
* @param array $records All uptime records to parse, MUST BE SORTED BY DATE IN ASCENDING ORDER
* @param array $lines Array with keys as line ids to prepare (key must be available in uptime records)
* @param string $latency_avg_key which key from uptime records to use for calculating averages
* @param \DateTime $start_time Lowest DateTime of the graph
* @param \DateTime $end_time Highest DateTime of the graph
* @param DateTime $start_time Lowest DateTime of the graph
* @param DateTime $end_time Highest DateTime of the graph
* @param boolean $add_uptime Add uptime calculation?
* @param array $prev Previous result
* @param int $downtime Total downtime
* @param int $prev_downtime Timestamp from last offline record. 0 when last record is uptime
* @return array
*/
protected function generateGraphLines(
@ -241,64 +245,90 @@ class HistoryGraph
$end_time,
$add_uptime = false
) {
$now = new \DateTime();
$now = new DateTime();
$data = array();
// PLEASE NOTE: all times are in microseconds! because of javascript.
$latency_avg = 0;
/** @var array $prev Previous record */
$prev = reset($records);
// Timestamp from last offline record. 0 when last record is up.
$prev_downtime = 0;
// Total downtime
$downtime = 0;
// The keys of the lines iterated
$line_keys = array_keys($lines);
// Determine whether to process data for the short history graph
$is_short_graph = count($line_keys) === 1 && $line_keys[0] === 'latency';
// get highest latency record for offline height
$highest_latency = 0.0;
if ($is_short_graph) {
foreach ($records as $record) {
$latency = (float) $record['latency'];
if ($latency > $highest_latency) {
$highest_latency = $latency;
}
}
// to ms
$highest_latency = round($highest_latency * 1000);
}
// Create the list of points and server down zones
foreach ($records as $record) {
$time = strtotime($record['date']);
// use the first line to calculate average latency
$latency_avg += (float) $record[$latency_avg_key];
foreach ($lines as $key => $value) {
// add the value for each of the different lines
if (isset($record[$key])) {
if (isset($record['status'])) {
// down
if ($record['status'] == 0) {
$lines['online'][] = $prev['status']
// Previous datapoint was online
? '{ x: ' . ($time * 1000) . ', y: ' . $prev['latency'] . '}'
// Previous datapoint was offline
: '{ x: ' . ($time * 1000) . ', y: null}';
// new outage start
$lines['offline'][] = '{ x: ' . ($time * 1000) . ', y:0.1}';
if ($is_short_graph) {
$time = (int) $record['date_ts'];
// Timestamp in milliseconds
$time_ms = $time * 1000;
if (!$record['status']) {
// down
$lines['online'][] = $prev['status']
// Previous datapoint was online
? ['x' => $time_ms, 'y' => round($prev['latency'] * 1000, 3)]
// Previous datapoint was offline
: ['x' => $time_ms, 'y' => null];
// new outage start
$lines['offline'][] = ['x' => $time_ms, 'y' => $highest_latency];
$prev_downtime != 0 ?: $prev_downtime = $time;
} else {
// up
// outage ends
$lines['offline'][] = $prev['status']
// Previous datapoint was online
? '{ x: ' . ($time * 1000) . ', y:null}'
// Previous datapoint was offline
: '{ x: ' . ($time * 1000) . ', y:0.1}';
$lines['online'][] = '{ x: ' . ($time * 1000) . ', y: ' .
round((float) $record[$key], 4) . '}';
$prev_downtime == 0 ?: $downtime += ($time - $prev_downtime);
$prev_downtime = 0;
}
} else {
$lines[$key][] = '{ x: \'' . $record['date'] . '\', y: ' . $record[$key] . '}';
if ($prev_downtime === 0) {
$prev_downtime = $time;
}
$prev = $record;
} else {
// up
// outage ends
$lines['offline'][] = $prev['status']
// Previous datapoint was online
? ['x' => $time_ms, 'y' => null]
// Previous datapoint was offline
: ['x' => $time_ms, 'y' => $highest_latency];
$lines['online'][] = ['x' => $time_ms, 'y' => round($record['latency'] * 1000, 3)];
if ($prev_downtime !== 0) {
$downtime += ($time - $prev_downtime);
}
$prev_downtime = 0;
}
} else {
foreach ($line_keys as $key) {
// add the value for each of the different lines
$lines[$key][] = ['x' => $record['date'], 'y' => $record[$key] * 1000];
}
}
$prev = $record;
}
// Was down before.
// Record the first and last date as a string in the down array
$prev_downtime == 0 ?: $downtime += ($now->getTimestamp() - $prev_downtime);
if ($add_uptime) {
$prev['status'] ?: $lines['offline'][] = '{ x: ' . ($now->getTimestamp() * 1000) . ', y:0.1}';
if (!$prev['status']) {
$lines['offline'][] = ['x' => $now->getTimestamp() * 1000, 'y' => $highest_latency];
}
$data['uptime'] = 100 - ($downtime / ($end_time->getTimestamp() - $start_time->getTimestamp()));
}
@ -307,11 +337,12 @@ class HistoryGraph
if (empty($line_value)) {
continue;
}
$lines_merged[$line_key]['value'] = implode(', ', $line_value);
$lines_merged[$line_key]['value'] = json_encode($line_value);
$lines_merged[$line_key]['name'] = psm_get_lang('servers', $line_key);
}
$data['latency_avg'] = count($records) > 0 ? ($latency_avg / count($records)) : 0;
$n_records = count($records);
$data['latency_avg'] = $n_records > 0 ? ($latency_avg / $n_records) : 0;
$data['lines'] = sizeof($lines_merged) ? $lines_merged : '';
$data['end_timestamp'] = number_format($end_time->getTimestamp(), 0, '', '') * 1000;
$data['start_timestamp'] = number_format($start_time->getTimestamp(), 0, '', '') * 1000;

View File

@ -154,4 +154,18 @@ class ServerValidator
}
return true;
}
/**
* Check SSL expiry days
* @param int $value
* @return boolean
* @throws \InvalidArgumentException
*/
public function sslCertExpiryDays($value)
{
if (!is_numeric($value) || $value < 0) {
throw new \InvalidArgumentException('server_ssl_cert_expiry_days');
}
return true;
}
}

View File

@ -49,25 +49,31 @@ class UpdateManager implements ContainerAwareInterface
* Go :-)
*
* @param boolean $skip_perms if TRUE, no user permissions will be taken in account and all servers will be updated
* @param string|null $status If all servers (null), or just `on` or `off` should be checked.
*/
public function run($skip_perms = false)
public function run($skip_perms = false, $status = null)
{
if (false === in_array($status, ['on', 'off'], true)) {
$status = null;
}
// check if we need to restrict the servers to a certain user
$sql_join = '';
if (!$skip_perms && $this->container->get('user')->getUserLevel() > PSM_USER_ADMIN) {
// restrict by user_id
$sql_join = "JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`={$this->container->get('user')->getUserId()}
AND `us`.`server_id`=`s`.`server_id`
)";
`us`.`user_id`={$this->container->get('user')->getUserId()}
AND `us`.`server_id`=`s`.`server_id`
)";
}
$sql = "SELECT `s`.`server_id`,`s`.`ip`,`s`.`port`,`s`.`label`,`s`.`type`,`s`.`pattern`,`s`.`header_name`,
`s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`telegram`
FROM `" . PSM_DB_PREFIX . "servers` AS `s`
{$sql_join}
WHERE `active`='yes' ";
`s`.`header_value`,`s`.`status`,`s`.`active`,`s`.`email`,`s`.`sms`,`s`.`pushover`,`s`.`webhook`,`s`.`telegram`,
`s`.`jabber`
FROM `" . PSM_DB_PREFIX . "servers` AS `s`
{$sql_join}
WHERE `active`='yes' " . ($status !== null ? ' AND `status` = \'' . $status . '\'' : '');
$servers = $this->container->get('db')->query($sql);
@ -76,7 +82,8 @@ class UpdateManager implements ContainerAwareInterface
foreach ($servers as $server) {
$status_old = ($server['status'] == 'on') ? true : false;
$status_new = $updater->update($server['server_id']);
$status_new = $updater->
update($server['server_id']);
// notify the nerds if applicable
$notifier->notify($server['server_id'], $status_old, $status_new);
// clean-up time!! archive all records

View File

@ -33,6 +33,7 @@
* @see \psm\Util\Server\Updater\Autorun
*/
namespace psm\Util\Server\Updater;
use Norgul\Xmpp\Options;
use psm\Service\Database;
class StatusNotifier
@ -56,18 +57,36 @@ class StatusNotifier
*/
protected $send_sms = false;
/**
* Send Discord notification?
* @var boolean $send_discord
*/
protected $send_discord = false;
/**
* Send Pushover notification?
* @var boolean $send_pushover
*/
protected $send_pushover = false;
/**
* Send webhook notification?
* @var boolean $send_webhook
*/
protected $send_webhook = false;
/**
* Send telegram?
* @var boolean $send_telegram
*/
protected $send_telegram = false;
/**
* Send Jabber?
* @var bool
*/
protected $send_jabber = false;
/**
* Save log records?
* @var boolean $save_log
@ -119,12 +138,15 @@ class StatusNotifier
{
$this->db = $db;
$this->send_emails = psm_get_conf('email_status');
$this->send_sms = psm_get_conf('sms_status');
$this->send_pushover = psm_get_conf('pushover_status');
$this->send_telegram = psm_get_conf('telegram_status');
$this->save_logs = psm_get_conf('log_status');
$this->combine = psm_get_conf('combine_notifications');
$this->send_emails = (bool)psm_get_conf('email_status');
$this->send_sms = (bool)psm_get_conf('sms_status');
$this->send_discord = (bool)psm_get_conf('discord_status');
$this->send_webhook = (bool)psm_get_conf('webhook_status');
$this->send_pushover = (bool)psm_get_conf('pushover_status');
$this->send_telegram = (bool)psm_get_conf('telegram_status');
$this->send_jabber = (bool)psm_get_conf('jabber_status');
$this->save_logs = (bool)psm_get_conf('log_status');
$this->combine = (bool)psm_get_conf('combine_notifications');
}
/**
@ -141,8 +163,11 @@ class StatusNotifier
if (
!$this->send_emails &&
!$this->send_sms &&
!$this->send_discord &&
!$this->send_webhook &&
!$this->send_pushover &&
!$this->send_telegram &&
!$this->send_jabber &&
!$this->save_logs
) {
// seems like we have nothing to do. skip the rest
@ -166,8 +191,11 @@ class StatusNotifier
'error',
'email',
'sms',
'discord',
'webhook',
'pushover',
'telegram',
'jabber',
'last_online',
'last_offline',
'last_offline_duration',
@ -236,6 +264,18 @@ class StatusNotifier
$this->notifyByTxtMsg($users);
}
// check if discord is enabled for this server
if ($this->send_discord && $this->server['discord'] == 'yes') {
// yay lets wake those nerds up!
$this->combine ? $this->setCombi('discord') : $this->notifyByDiscord($users);
}
// check if webhook is enabled for this server
if ($this->send_webhook && $this->server['webhook'] == 'yes') {
// yay lets wake those nerds up!
$this->combine ? $this->setCombi('webhook') : $this->notifyByWebhook($users);
}
// check if pushover is enabled for this server
if ($this->send_pushover && $this->server['pushover'] == 'yes') {
// yay lets wake those nerds up!
@ -247,6 +287,10 @@ class StatusNotifier
$this->combine ? $this->setCombi('telegram') : $this->notifyByTelegram($users);
}
if ($this->send_jabber && $this->server['jaber'] == 'yes') {
$this->combine ? $this->setCombi('jabber') : $this->notifyByJabber($users);
}
return $notify;
}
@ -403,6 +447,86 @@ class StatusNotifier
}
}
/**
* This functions performs the discord notifications
*
* @param \PDOStatement $users
* @param array $combi contains message and subject (optional)
* @return void
*/
protected function notifyByDiscord($users, $combi = array())
{
$message_log = key_exists('message', $combi) ?
$combi['message'] :
psm_parse_msg($this->status_new, 'discord_message', $this->server);
// Remove users that have no Discord webhook
foreach ($users as $k => $user) {
if (trim($user['discord']) == '') {
unset($users[$k]);
}
}
// Validation
if (empty($users)) {
return;
}
// fix message for Discord viewing
$message = str_replace(array('<b>', '</b>'), array('**', '**'), $message_log);
$message = str_replace(array('<ul>', '</ul>'), array('', ''), $message);
$message = str_replace(array('<br>', '</li>'), array("\n", "\n"), $message);
$message = str_replace('<li>', " * ", $message);
$json = json_decode(
'{"content":""}',
true
);
$json['content'] = $message;
// Log
if (psm_get_conf('log_discord')) {
$log_id = psm_add_log($this->server_id, 'discord', $message_log);
}
foreach ($users as $user) {
// Log
if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
// set discord webhook and send
try {
$msg = "payload_json=" . urlencode(json_encode($json));
$curl = curl_init(trim($user['discord']));
if(isset($curl)) {
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_POSTFIELDS, $msg);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
$httpcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$err = curl_errno($curl);
if ($err != 0 || $httpcode != 204) {
// $result = ($result == '') ? 'Wrong input, please check if all values are correct!' : $result;
$error = "HTTP_code: " . $httpcode . ".\ncURL error (" . $err . "): " .
curl_strerror($err) . ". \nResult: " . $result;
$log_id = psm_add_log($this->server_id, 'discord', $error);
}
curl_close($curl);
}
} catch (Exception $e) {
$log_id = psm_add_log($this->server_id, 'discord', $e->getMessage());
}
}
}
/**
* This functions performs the pushover notifications
*
@ -447,7 +571,7 @@ class StatusNotifier
$pushover->setTitle($title);
$pushover->setMessage(str_replace('<br/>', "\n", $message));
$pushover->setUrl(psm_build_url());
$pushover->setUrlTitle(psm_get_lang('system', 'title'));
$pushover->setUrlTitle(psm_get_conf('site_title', psm_get_lang('system', 'title')));
// Log
if (psm_get_conf('log_pushover')) {
@ -468,7 +592,48 @@ class StatusNotifier
$pushover->send();
}
}
/**
* This functions performs the webhook notifications
*
* @param \PDOStatement $users
* @param array $combi contains message and subject (optional)
* @return void
*/
protected function notifyByWebhook($users, $combi = array())
{
foreach ($users as $k => $user) {
if (trim($user['webhook_url']) == '') {
unset($users[$k]);
}
}
$webhook = psm_build_webhook();
$message = key_exists('message', $combi) ?
$combi['message'] :
psm_parse_msg($this->status_new, 'webhook_message', $this->server);
$message = str_replace('<br/>', "\n", $message);
$message = str_replace('<br>', "\n", $message);
$title = key_exists('subject', $combi) ?
$combi['subject'] :
psm_parse_msg($this->status_new, 'webhook_title', $this->server);
// Log
if (psm_get_conf('log_webhook')) {
$log_id = psm_add_log($this->server_id, 'webhook', $message);
}
// send notifications to all users
foreach ($users as $user) {
// Log
if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
$webhook->setUrl($user['webhook_url']);
$webhook->setJson($user['webhook_json']);
$webhook->sendWebhook($message);
}
}
/**
* This functions performs the text message notifications
*
@ -548,6 +713,54 @@ class StatusNotifier
}
}
/**
* @param array $users
* @param array $combi
*/
protected function notifyByJabber($users, $combi = [])
{
// Remove users that have no jabber
foreach ($users as $k => $user) {
if (trim($user['jabber']) === '') {
unset($users[$k]);
}
}
// Validation
if (empty($users)) {
return;
}
// Message
$message = key_exists('message', $combi) ?
$combi['message'] :
psm_parse_msg($this->status_new, 'jabber_message', $this->server);
// Log
if (psm_get_conf('log_jabber')) {
$log_id = psm_add_log($this->server_id, 'jabber', $message);
}
$usersJabber = [];
foreach ($users as $user) {
// Log
if (!empty($log_id)) {
psm_add_log_user($log_id, $user['user_id']);
}
$usersJabber[] = $user['jabber'];
}
// Jabber
psm_jabber_send_message(
psm_get_conf('jabber_host'),
psm_get_conf('jabber_username'),
psm_password_decrypt(psm_get_conf('password_encrypt_key'), psm_get_conf('jabber_password')),
$usersJabber,
$message,
(trim(psm_get_conf('jabber_port')) !== '' ? (int)psm_get_conf('jabber_port') : null),
(trim(psm_get_conf('jabber_domain')) !== '' ? psm_get_conf('jabber_domain') : null)
);
}
/**
* Get all users for the provided server id
* @param int $server_id
@ -556,15 +769,16 @@ class StatusNotifier
public function getUsers($server_id)
{
// find all the users with this server listed
$users = $this->db->query("
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`,
`u`.`pushover_device`, `u`.`telegram_id`
FROM `" . PSM_DB_PREFIX . "users` AS `u`
JOIN `" . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`=`u`.`user_id`
AND `us`.`server_id` = {$server_id}
)
");
$users = $this->db->query('
SELECT `u`.`user_id`, `u`.`name`,`u`.`email`, `u`.`mobile`, `u`.`pushover_key`, `u`.`discord`, `u`.`webhook_url`,`u`.`webhook_json`,
`u`.`pushover_device`, `u`.`telegram_id`,
`u`.`jabber`
FROM `' . PSM_DB_PREFIX . 'users` AS `u`
JOIN `' . PSM_DB_PREFIX . "users_servers` AS `us` ON (
`us`.`user_id`=`u`.`user_id`
AND `us`.`server_id` = {$server_id}
)
");
return $users;
}
}

View File

@ -41,6 +41,8 @@ class StatusUpdater
public $header = '';
public $curl_info = '';
public $rtime = 0;
public $status_new = false;
@ -86,7 +88,8 @@ class StatusUpdater
$this->server_id = $server_id;
$this->error = '';
$this->header = '';
$this->rtime = '';
$this->curl_info = '';
$this->rtime = 0;
// get server info from db
$this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array(
@ -96,7 +99,7 @@ class StatusUpdater
'type', 'pattern', 'pattern_online', 'post_field',
'allow_http_status', 'redirect_check', 'header_name',
'header_value', 'status', 'active', 'warning_threshold',
'warning_threshold_counter', 'timeout', 'website_username',
'warning_threshold_counter', 'ssl_cert_expiry_days', 'ssl_cert_expired_time', 'timeout', 'website_username',
'website_password', 'last_offline'
));
if (empty($this->server)) {
@ -165,40 +168,26 @@ class StatusUpdater
}
/**
* Check the current servers ping status - Code from http://stackoverflow.com/a/20467492
* Check the current servers ping status
* @param int $max_runs
* @param int $run
* @return boolean
*/
protected function updatePing($max_runs, $run = 1)
{
// save response time
$starttime = microtime(true);
// set ping payload
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
// Settings
$max_runs = ($max_runs == null || $max_runs > 1) ? 1 : $max_runs;
$server_ip = escapeshellcmd($this->server['ip']);
$os_is_windows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
$socket = socket_create(AF_INET, SOCK_RAW, 1);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0));
socket_connect($socket, $this->server['ip'], null);
socket_send($socket, $package, strLen($package), 0);
if (socket_read($socket, 255)) {
$status = true;
} else {
$status = false;
// set error message
$errorcode = socket_last_error();
$this->error = "Couldn't create socket [" . $errorcode . "]: " . socket_strerror($errorcode);
}
$this->rtime = microtime(true) - $starttime;
socket_close($socket);
$status = $os_is_windows ?
$this->pingFromWindowsMachine($server_ip, $max_runs) :
$this->pingFromNonWindowsMachine($server_ip, $max_runs);
// check if server is available and rerun if asked.
if (!$status && $run < $max_runs) {
return $this->updatePing($max_runs, $run + 1);
}
return $status;
}
@ -216,7 +205,11 @@ class StatusUpdater
// save response time
$starttime = microtime(true);
$fp = @fsockopen($this->server['ip'], $this->server['port'], $errno, $this->error, $timeout);
$serverIp = $this->server['ip'];
if (filter_var($serverIp, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
$serverIp = "[$serverIp]";
}
$fp = @fsockopen($serverIp, $this->server['port'], $errno, $this->error, $timeout);
$status = ($fp === false) ? false : true;
$this->rtime = (microtime(true) - $starttime);
@ -257,12 +250,13 @@ class StatusUpdater
$this->server['request_method'],
$this->server['post_field']
);
$this->header = $curl_result;
$this->header = $curl_result['exec'];
$this->curl_info = $curl_result['info'];
$this->rtime = (microtime(true) - $starttime);
// the first line would be the status code..
$status_code = strtok($curl_result, "\r\n");
$status_code = strtok($curl_result['exec'], "\r\n");
// keep it general
// $code[2][0] = status code
// $code[3][0] = name of status code
@ -293,7 +287,7 @@ class StatusUpdater
($this->server['pattern_online'] == 'yes') ==
!preg_match(
"/{$this->server['pattern']}/i",
$curl_result
$curl_result['exec']
)
) {
$this->error = "TEXT ERROR : Pattern '{$this->server['pattern']}' " .
@ -308,7 +302,7 @@ class StatusUpdater
$location_matches = array();
preg_match(
'/([Ll]ocation: )(https*:\/\/)(www.)?([a-zA-Z.:0-9]*)([\/][[:alnum:][:punct:]]*)/',
$curl_result,
$curl_result['exec'],
$location_matches
);
if (!empty($location_matches)) {
@ -329,7 +323,7 @@ class StatusUpdater
if ($this->server['header_name'] != '' && $this->server['header_value'] != '') {
$header_flag = false;
// Only get the header text if the result also includes the body
$header_text = substr($curl_result, 0, strpos($curl_result, "\r\n\r\n"));
$header_text = substr($curl_result['exec'], 0, strpos($curl_result['exec'], "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0 || strpos($line, ':') == false) {
continue; // We skip the status code & other non-header lines. Needed for proxy or redirects
@ -356,6 +350,11 @@ class StatusUpdater
}
}
// Check ssl cert just when other error is not already in...
if ($result !== false) {
$this->checkSsl($this->server, $this->error, $result);
}
// check if server is available and rerun if asked.
if (!$result && $run < $max_runs) {
return $this->updateWebsite($max_runs, $run + 1);
@ -383,4 +382,129 @@ class StatusUpdater
{
return $this->rtime;
}
/**
* Check if a server speaks SSL and if the certificate is not expired.
* @param string $error
* @param bool $result
*/
private function checkSsl($server, &$error, &$result)
{
if (version_compare(PHP_VERSION, '7.1', '<')) {
$error = "The server you're running PSM on must use PHP 7.1 or higher to test the SSL expiration.";
return;
}
if (
!empty($this->curl_info['certinfo']) &&
$server['ssl_cert_expiry_days'] > 0
) {
$certinfo = reset($this->curl_info['certinfo']);
$certinfo = openssl_x509_parse($certinfo['Cert']);
$cert_expiration_date = $certinfo['validTo_time_t'];
$expiration_time =
round((int)($cert_expiration_date - time()) / 86400);
$latest_time = time() + (86400 * $server['ssl_cert_expiry_days']);
if ($expiration_time - $server['ssl_cert_expiry_days'] < 0) {
// Cert is not expired, but date is withing user set range
$this->header = psm_get_lang('servers', 'ssl_cert_expiring') . " " .
psm_date($this->curl_info['certinfo'][0]['Expire date']) .
"\n\n" . $this->header;
$save['ssl_cert_expired_time'] = $expiration_time - $server['ssl_cert_expiry_days'];
} elseif ($expiration_time >= 0) {
// Cert is not expired
$save['ssl_cert_expired_time'] = null;
} else {
// Cert is expired
$error = psm_get_lang('servers', 'ssl_cert_expired') . " " .
psm_timespan($cert_expiration_date) . ".\n\n" .
$error;
$save['ssl_cert_expired_time'] = $expiration_time;
}
$this->db->save(PSM_DB_PREFIX . 'servers', $save, array('server_id' => $this->server_id));
}
}
/**
* Ping from a Windows Machine
* @param string $server_id
* @param int $max_runs
* @return boolean
*/
private function pingFromWindowsMachine($server_ip, $max_runs)
{
// Windows / Linux variant: use socket on Windows, commandline on Linux
// socket ping - Code from http://stackoverflow.com/a/20467492
// save response time
$starttime = microtime(true);
// set ping payload
$package = "\x08\x00\x7d\x4b\x00\x00\x00\x00PingHost";
$socket = socket_create(AF_INET, SOCK_RAW, 1);
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 10, 'usec' => 0));
socket_connect($socket, $server_ip, null);
socket_send($socket, $package, strLen($package), 0);
// socket_read returns a string or false
$status = socket_read($socket, 255) !== false ? true : false;
if ($status) {
$this->header = "Success.";
} else {
$this->error = "Couldn't create socket [" . $errorcode . "]: " . socket_strerror(socket_last_error());
}
$this->rtime = microtime(true) - $starttime;
socket_close($socket);
return $status;
}
/**
* Ping from a non Windows Machine
* @param string $server_id
* @param int $max_runs
* @param string $ping_command
* @return boolean
*/
private function pingFromNonWindowsMachine($server_ip, $max_runs)
{
// Choose right ping version, ping6 for IPV6, ping for IPV4
$ping_command = filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false ? 'ping6' : 'ping';
// execute PING
exec($ping_command . " -c " . $max_runs . " " . $server_ip . " 2>&1", $output);
// Check if output is PING and if transmitted packets is equal to received packets.
preg_match(
'/^(\d{1,3}) packets transmitted, (\d{1,3}).*$/',
$output[count($output) - 2],
$output_package_loss
);
if (
substr($output[0], 0, 4) == 'PING' &&
!empty($output_package_loss) &&
$output_package_loss[1] === $output_package_loss[2]
) {
// Gets avg from 'round-trip min/avg/max/stddev = 7.109/7.109/7.109/0.000 ms'
preg_match_all("/(\d+\.\d+)/", $output[count($output) - 1], $result);
// Converted to milliseconds
$this->rtime = floatval($result[0][1]) / 1000;
$this->header = "";
foreach ($output as $key => $value) {
$this->header .= $value . "\n";
}
return true;
}
$this->header = "-";
foreach ($output as $key => $value) {
$this->header .= $value . "\n";
}
$this->error = $output[count($output) - 2];
return false;
}
}

View File

@ -31,31 +31,33 @@
<body>
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="index.php">{{ title }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="container-fluid">
<a class="navbar-brand" href="index.php">{{ title }}</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbar">
{{ html_menu|raw }}
</div>
<div class="collapse navbar-collapse" id="navbar">
{{ html_menu|raw }}
</div>
</div>
</nav>
{{ html_modal|raw }}
<main role="main" class="container">
<main role="main" class="container-fluid px-4">
<noscript>
<div class="alert alert-danger" role="alert">
<b>Javascript is disabled!</b> PHP Server Monitor works best with JavaScript enabled!
</div>
</noscript>
{% if not user_level and subtitle %}<h1>{{ subtitle }}</h1>{% endif %}
<div class="container">{{ header_accessories|raw }}</div>
<div class="container-fluid">{{ header_accessories|raw }}</div>
{% for msg in messages %}
<div class="alert alert-{{ msg.class }}" role="alert">
<i class="fas fa-{{ msg.icon }}"></i> {{ msg.message|raw }}
</div>
{% endfor %}
<div class="container">
<div class="container-fluid">
<div class="row">{{ html_sidebar|raw }}</div>
<div class="row" id="content">{{ html_content|raw }}</div>
</div>
@ -74,7 +76,7 @@
</footer>
{% endblock %}
{% endif %}
<script src="src/templates/default/static/plugin/jquery/jquery-3.3.1.min.js"></script>
<script src="src/templates/default/static/plugin/jquery/jquery-3.5.1.min.js"></script>
<script src="src/templates/default/static/plugin/popper.js/popper.min.js"></script>
<script src="src/templates/default/static/plugin/bootstrap/js/dist/index.js"></script>
<script src="src/templates/default/static/plugin/bootstrap/js/dist/util.js"></script>
@ -87,7 +89,8 @@
<script type="text/javascript" src="src/templates/default/static/plugin/bootstrap-select/dist/js/bootstrap-select.min.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/bootstrap-select/dist/js/i18n/defaults-{{ language }}.min.js"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/solid.min.js"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/fontawesome.min.js" data-auto-replace-svg="nest"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/fontawesome.min.js" data-auto-replace-svg="nest"></script>
<script defer src="src/templates/default/static/plugin/font-awesome/js/brands.min.js" data-auto-replace-svg="nest"></script>
<script type="text/javascript" src="src/templates/default/static/js/scripts.js"></script>
</body>

View File

@ -27,6 +27,21 @@
role="tab" aria-controls="config-telegram" aria-selected="{% if telegram_active %}true{% else %}false{% endif %}">{{
label_tab_telegram }}</a>
</li>
<li class="nav-item">
<a class="nav-link {{ jabber_active }}" id="config-jabber-tab" data-toggle="tab" href="#config-jabber"
role="tab" aria-controls="config-jabber" aria-selected="{% if jabber_active %}true{% else %}false{% endif %}">{{
label_tab_jabber }}</a>
</li>
<li class="nav-item">
<a class="nav-link {{ discord_active }}" id="config-discord-tab" data-toggle="tab" href="#config-discord" role="tab"
aria-controls="config-discord" aria-selected="{% if discord_active %}true{% else %}false{% endif %}">{{
label_tab_discord }}</a>
</li>
<li class="nav-item">
<a class="nav-link {{ webhook_active }}" id="config-webhook-tab" data-toggle="tab" href="#config-webhook" role="tab"
aria-controls="config-webhook" aria-selected="{% if webhook_active %}true{% else %}false{% endif %}">{{
label_tab_webhook }}</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
@ -36,6 +51,8 @@
<legend>{{ label_general }}</legend>
<!-- Update check -->
{{ macro.input_checkbox("show_update", "show_update[]", label_show_update, show_update_checked) }}
<!-- Site title -->
{{ macro.input_field("text", "site_title", null, "site_title", label_site_title, site_title, label_site_title, "255", null, null, null, null, true) }}
<!-- Language -->
{{ macro.input_select("language", "language", label_language, languages, language_current) }}
<!-- Auto refresh -->
@ -43,6 +60,8 @@
<!-- Password encryption key -->
<!-- TODO how does the encryption function works currently? -->
{{ macro.input_field("text", "password_encrypt_key", null, "password_encrypt_key", label_password_encrypt_key, password_encrypt_key, "cab03a766...", "40", "password_encrypt_key_help", label_password_encrypt_key_note) }}
<!-- Custom user agent -->
{{ macro.input_field("text", "user_agent", null, "user_agent", label_user_agent, user_agent, "Mozilla/5.0...", "255", "user_agent_key_help", label_user_agent_key_note) }}
</fieldset>
<!-- Notification settings -->
<fieldset>
@ -99,7 +118,7 @@
<!-- email user -->
{{ macro.input_field("text", "email_smtp_username", null, "email_smtp_username", label_email_smtp_username, email_smtp_username, label_email_smtp_username, "255") }}
<!-- email password -->
{{ macro.input_field("password", "email_smtp_password", null, "email_smtp_password", label_email_smtp_password, email_smtp_password, label_email_smtp_password, "255", null, null, null, true) }}
{{ macro.input_field("password", "email_smtp_password", null, "email_smtp_password", label_email_smtp_password, email_smtp_password, label_leave_blank, "255", null, null, null, true) }}
{{ macro.button_test("testEmail", label_test) }}
{{ macro.input_hidden("test_email", "0") }}
{{ macro.button_save("email_submit", label_save) }}
@ -120,15 +139,28 @@
{{ macro.input_field("text", "sms_gateway_password", null, "sms_gateway_password", label_sms_gateway_password, sms_gateway_password, label_sms_gateway_password, "255") }}
<!-- sms sender number-->
{{ macro.input_field("text", "sms_from", null, "sms_from", label_sms_from, sms_from, "+31123456789", "255") }}
{{ macro.button_test("testSms", label_test) }}
{{ macro.input_hidden("test_sms", "0") }}
{{ macro.button_save("sms_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ pushover_active }}" id="config-pushover" role="tabpanel" aria-labelledby="config-telegram-tab">
<div class="tab-pane {{ discord_active }}" id="config-discord" role="tabpanel" aria-labelledby="config-discord-tab">
<fieldset>
<legend>{{ label_settings_discord }}</legend>
<!-- enable discord -->
{{ macro.input_checkbox("discord_status", "discord_status[]", label_discord_status, discord_status_checked) }}
<!-- enable discord log -->
{{ macro.input_checkbox("log_discord", "log_discord[]", label_log_discord, log_discord_checked) }}
{{ macro.button_test("testDiscord", label_test) }}
{{ macro.input_hidden("test_discord", "0") }}
{{ macro.button_save("discord_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ pushover_active }}" id="config-pushover" role="tabpanel" aria-labelledby="config-pushover-tab">
<fieldset>
<legend>{{ label_settings_pushover }}</legend>
<p>{{ label_pushover_description|raw }}</p>
<!-- enable pushover -->
{{ macro.input_checkbox("pushover_status", "pushover_status", label_pushover_status, pushover_status_checked) }}
<!-- enable pushover log -->
@ -140,9 +172,10 @@
{{ macro.button_save("pushover_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ telegram_active }}" id="config-telegram" role="tabpanel" aria-labelledby="config-pushover-tab">
<div class="tab-pane {{ telegram_active }}" id="config-telegram" role="tabpanel" aria-labelledby="config-telegram-tab">
<fieldset>
<legend>{{ label_settings_telegram }}</legend>
<p>{{ label_telegram_description|raw }}</p>
<!-- enable telegram -->
{{ macro.input_checkbox("telegram_status", "telegram_status[]", label_telegram_status, telegram_status_checked) }}
<!-- enable telegram log -->
@ -154,6 +187,42 @@
{{ macro.button_save("telegram_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ jabber_active }}" id="config-jabber" role="tabpanel" aria-labelledby="config-jabber-tab">
<fieldset>
<legend>{{ label_settings_jabber }}</legend>
<!-- enable jabber -->
{{ macro.input_checkbox("jabber_status", "jabber_status[]", label_jabber_status, jabber_status_checked) }}
<!-- enable jabber log -->
{{ macro.input_checkbox("log_jabber", "log_jabber[]", label_log_jabber, log_jabber_checked) }}
<!-- jabber settings -->
{{ macro.input_field("text", "jabber_host", null, "jabber_host", label_jabber_host, jabber_host, label_jabber_host, "255", "jabber_host_help", label_jabber_host_description) }}
{{ macro.input_field("number", "jabber_port", null, "jabber_port", label_jabber_port, jabber_port, label_jabber_port, "255", "jabber_port_help", label_jabber_port_description) }}
{{ macro.input_field("text", "jabber_username", null, "jabber_username", label_jabber_username, jabber_username, label_jabber_username, "255", 'jabber_username_help', label_jabber_username_description) }}
{{ macro.input_field("text", "jabber_domain", null, "jabber_domain", label_jabber_domain, jabber_domain, label_jabber_domain, "255", "jabber_domain_help", label_jabber_domain_description) }}
{{ macro.input_field("password", "jabber_password", null, "jabber_password", label_jabber_password, jabber_password, label_jabber_password, "255", "jabber_password_help", label_jabber_password_description) }}
{{ macro.button_test("testJabber", label_test) }}
{{ macro.input_hidden("test_jabber", "0") }}
{{ macro.button_save("jabber_submit", label_save) }}
</fieldset>
</div>
<div class="tab-pane {{ webhook_active }}" id="config-webhook" role="tabpanel" aria-labelledby="config-webhook-tab">
<fieldset>
<legend>{{ label_settings_webhook }}</legend>
<p>{{ label_webhook_description|raw }}</p>
<!-- enable webhooks -->
{{ macro.input_checkbox("webhook_status", "webhook_status", label_webhook_status, webhook_status_checked) }}
<!-- enable webhook log -->
{{ macro.input_checkbox("log_webhook", "log_webhook", label_log_webhook, log_webhook_checked) }}
<!-- webhook url -->
<!-- {{ macro.input_field("text", "webhook_url", null, "webhook_url", label_webhook_url, webhook_url, label_webhook_url, "255", "webhook_url_help", label_webhook_url_description) }} -->
<!-- webhook json -->
<!-- {{ macro.input_field("text", "webhook_json", null, "webhook_json", label_webhook_json, webhook_json, label_webhook_json, "255", "webhook_json_help", label_webhook_json_description) }} -->
{{ macro.button_test("testWebhook", label_test) }}
{{ macro.input_hidden("test_webhook", "0") }}
{{ macro.button_save("webhook_submit", label_save) }}
</fieldset>
</div>
</div>
{{ macro.input_csrf() }}
</form>

View File

@ -12,8 +12,8 @@
If no errors have occurred, you are good to go.</p>
<div class="w-100 mb-4"></div>
<a class="btn btn-primary btn-lg" href="index.php">Go to your monitor</a>
<a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://www.phpservermonitor.org/">PHP Server Monitor</a>
<a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://docs.phpservermonitor.org/">Documentation</a>
<a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://www.phpservermonitor.org/ " target="_blank">PHP Server Monitor</a>
<a class="btn btn-secondary btn-lg" target="_blank" rel="noopener" href="http://docs.phpservermonitor.org/" target="_blank">Documentation</a>
</div>
</div>
{% endblock %}

View File

@ -1,5 +1,7 @@
<script type="text/javascript" src="src/templates/default/static/plugin/momentjs/moment.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/chartjs/chart-2.7.3.min.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/hammer/hammer.min.js"></script>
<script type="text/javascript" src="src/templates/default/static/plugin/chartjs/plugin-zoom.min.js"></script>
{% for graph in graphs %}
<div class="chart-container col-10" style="position: relative; width:60vw">
<canvas id="{{ graph.id }}">Your browser does not support the canvas element.</canvas>
@ -20,7 +22,7 @@
<span id="needle" style="transform: rotate({{ ((graph.uptime|round/100)*180)|round }}deg);"></span>
</div><br>
{% endif %}
{{ graph.info.0.label }}: {{ graph.info.0.value }}s
{{ graph.info.0.label }}: {{ graph.info.0.value * 1000 }} ms
</div>
{% if graph.id == 'history_short' %}
@ -30,7 +32,7 @@
data: {
datasets: [
{
data: [{{ graph.lines.offline.value }}],
data: {{ graph.lines.offline.value|raw }},
label: '{{ graph.lines.offline.name }}',
backgroundColor: '#dc3545',
borderColor: '#dc3545',
@ -41,7 +43,7 @@
spanGaps: false,
},
{
data: [{{ graph.lines.online.value }}],
data: {{ graph.lines.online.value|raw }},
label: '{{graph.lines.online.name }}',
fill: false,
spanGaps: false,
@ -72,6 +74,25 @@
source: 'auto',
}
}]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
},
zoom: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
speed: 0.05,
}
}
}
}
});
@ -99,7 +120,7 @@
datasets: [
{% for key,line in graph.lines %}
{
data: [{{ line.value|raw }}],
data: {{ line.value|raw }},
label: '{{ line.name }}',
backgroundColor: colors['{{key}}'],
borderColor: colors['{{key}}'],
@ -133,6 +154,25 @@
source: 'auto',
}
}]
},
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
},
zoom: {
enabled: true,
mode: 'x',
rangeMax: {
x: new Date,
},
speed: 0.05,
}
}
}
}
});

View File

@ -5,17 +5,17 @@
<thead>
<tr>
<!--class="d-none d-lg-table-cell"-->
<th scope="col">{{ label_label }}</th>
<th scope="col">{{ label_domain }}</th>
<th scope="col">{{ label_port }}</th>
<th scope="col">{{ label_type }}</th>
<th scope="col">{{ label_rtime }}</th>
<th scope="col">{{ label_last_online }}</th>
<th scope="col">{{ label_last_offline }}</th>
<th scope="col">{{ label_monitoring }}</th>
{% if user_level == 10 %}
<th scope="col">&#32</th>
{% endif %}
<th scope="col">{{ label_label }}</th>
<th scope="col">{{ label_domain }}</th>
<th scope="col" style="width: 5%;">{{ label_port }}</th>
<th scope="col" style="width: 8%;">{{ label_type }}</th>
<th scope="col" style="width: 8%;">{{ label_rtime }} (ms)</th>
<th scope="col" style="width: 10%;">{{ label_last_online }}</th>
<th scope="col" style="width: 10%;">{{ label_last_offline }}</th>
<th scope="col" style="width: 10%;">{{ label_monitoring }}</th>
{% if user_level == 10 %}
<th scope="col" style="width: 5%;">&#32</th>
{% endif %}
</tr>
<tr class="warning no-result">
<td colspan="9"><i class="fas fa-exclamation-triangle"></i> No result</td>
@ -41,7 +41,7 @@
<td><div class="content">{{ server.ip|raw }}</div></td>
<td>{{ server.port }}</td>
<td>{{ server.type }}</td>
<td>{{ server.rtime }}</td>
<td>{{ (server.rtime * 1000)|round(2) }}</td>
<td><div class="content">{{ server.last_online }}</div></td>
<td><div class="content">{{ server.last_offline }}</div></td>
<td>
@ -50,24 +50,36 @@
{% else %}
<i class="fas fa-eye-slash" title="{{ server.active_title }}"></i>
{% endif %}
{% if server.email|lower == 'yes'%}
{% if server.email|lower == 'yes' and config.email|lower%}
<i class="fas fa-envelope" title="{{ label_email }}"></i>
{% endif %}
{% if server.sms|lower == 'yes'%}
{% if server.sms|lower == 'yes' and config.sms|lower%}
<i class="fas fa-sms" title="{{ label_sms }}"></i>
{% endif %}
{% if server.pushover|lower == 'yes'%}
{% if server.pushover|lower == 'yes'and config.pushover|lower %}
<span class="fa-layers">
<i class="fas fa-circle" title="{{ label_pushover }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">P</span>
</span>
{% endif %}
{% if server.telegram|lower == 'yes'%}
<span class="fa-layers">
<i class="fas fa-circle" title="{{ label_telegram }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">T</span>
</span>
{% if server.telegram|lower == 'yes' and config.telegram|lower%}
<i class="fab fa-telegram" title="{{ label_telegram }}"></i>
{% endif %}
{% if server.jabber|lower == 'yes'%}
<span class="fa-layers">
<i class="fas fa-circle" title="{{ label_jabber }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:400; font-size:75%">J</span>
</span>
{% endif %}
{% if server.discord|lower == 'yes' and config.discord|lower %}
<i class="fab fa-discord" title="{{ label_discord }}"></i>
{% endif %}
{% if server.webhook|lower == 'yes' and config.webhook|lower %}
<span class="fa-layers">
<i class="fas fa-circle" title="{{ label_webhook }}"></i>
<span class="fa-layers-text fa-inverse" style="font-weight:600; font-size:55%">W</span>
</span>
{% endif %}
</td>
{% if user_level == 10 %}
<td>
@ -81,7 +93,7 @@
<i class="fas fa-edit"></i> {{ label_edit }}
</a>
<a class="dropdown-item show-modal" href="{{ server.url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete"
data-modal-param="{{ server.server_name }}">
data-modal-param="{{ server.label }}">
<i class="fas fa-trash"></i> {{ label_delete }}
</a>
</div>

View File

@ -46,7 +46,9 @@
</select>
</div>
<!-- Custom port -->
{{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }}
{{ macro.input_field("number", "port", "port types typeService", "port", label_custom_port, edit_value_port, null, "5") }}
<!-- SSL Cert check -->
{{ macro.input_field("number", "ssl_cert_expiry_days", "types typeWebsite", "ssl_cert_expiry_days", label_ssl_cert_expiry_days, edit_value_ssl_cert_expiry_days, 0, "5", 'ssl_cert_help', label_ssl_cert_expiry_days_description) }}
<!-- Request method -->
<div class="form-group types typeWebsite">
<label for="popular_request_methods">{{ label_request_method }}</label>
@ -140,14 +142,32 @@
{{ macro.input_select_monitoring("pushover", "pushover", label_send_pushover, edit_pushover_selected, label_yes, label_no, warning_pushover, label_warning_pushover) }}
<!-- Telegram -->
{{ macro.input_select_monitoring("telegram", "telegram", label_send_telegram, edit_telegram_selected, label_yes, label_no, warning_telegram, label_warning_telegram) }}
<!-- Jabber -->
{{ macro.input_select_monitoring("jabber", "jabber", label_send_jabber, edit_jabber_selected, label_yes, label_no, warning_jabber, label_warning_jabber) }}
<!-- Discord -->
{{ macro.input_select_monitoring("discord", "discord", label_send_discord, edit_discord_selected, label_yes, label_no, warning_discord, label_warning_discord) }}
<!-- Webhook -->
{{ macro.input_select_monitoring("webhook", "webhook", label_send_webhook, edit_webhook_selected, label_yes, label_no, warning_webhook, label_warning_webhook) }}
</div>
</fieldset>
</fieldset>
<fieldset>
<legend>{{ label_fieldset_permissions }}</legend>
<!-- Permissions -->
{{ macro.input_select_multiple("user_id", "user_id[]", label_permissions, label_search, users, label_please_select) }}
{{ macro.button_save(null, label_save) }}
<a class="btn" href="{{ url_go_back|raw }}">{{ label_go_back }}</a>
</fieldset>
</fieldset>
<fieldset>
<legend>{{ label_save }}</legend>
{{ macro.button_save(null, label_save) }}
<a class="btn" href="{{ url_go_back|raw }}">{{ label_go_back }}</a>
</fieldset>
{% if edit_server_id > 0 %}
<fieldset>
<legend class="mt-4">{{ label_delete }}</legend>
<a class="btn btn-danger show-modal" href="{{ url_delete|raw }}" title="{{ label_delete }}" data-modal-id="delete"
data-modal-param="{{ edit_value_label }}">
<i class="fas fa-trash"></i> {{ label_delete }}
</a>
</fieldset>
{% endif %}
{{ macro.input_csrf() }}
</form>

View File

@ -1,6 +1,6 @@
{% import 'main/macros.tpl.html' as macro %}
{{ macro.input_csrf() }}
<div class="container">
<div class="container-fluid">
<div class="row">
<div class="card text-white text-center col-md-2 pl-0 pr-0 mb-4 {% if status|lower == 'on' %}bg-success{% elseif status|lower == 'warning' %}bg-warning{% elseif status|lower == 'off' %}bg-danger{% endif %}">
<div class="card-body d-flex align-items-center justify-content-center">
@ -27,7 +27,11 @@
<li class="list-group-item">
<dl class="row">
<dt class="col-md-4">{{ label_domain }}:</dt>
<dd class="col-md-8">{{ ip|raw }}</dd>
<dd class="col-md-8">
<a href="{{ ip|raw }}" title="{{ ip|raw }}" target="_blank" rel="noopener">
{{ ip|raw }}
</a>
</dd>
</dl>
</li>
{% if type|lower == 'service' %}
@ -47,7 +51,7 @@
<li class="list-group-item">
<dl class="row">
<dt class="col-md-4">{{ label_rtime }}:</dt>
<dd class="col-md-8">{{ rtime }} {{ label_seconds }}</dd>
<dd class="col-md-8">{{ (rtime * 1000)|round(2) }} {{ label_milliseconds }}</dd>
</dl>
</li>
</ul>
@ -227,13 +231,13 @@
<li class="list-group-item">
<dl class="row">
<dt class="col-md-3">{{ label_last_error }}:</dt>
<dd class="col-md-9">{{ last_error }}</dd>
<dd class="col-md-9">{{ last_error|nl2br }}</dd>
</dl>
</li>
<li class="list-group-item">
<dl class="row">
<dt class="col-md-3">{{ label_last_output }}:</dt>
<dd class="col-md-9">{{ last_output_truncated }}</dd>
<dd class="col-md-9">{{ last_output_truncated|nl2br }}</dd>
{% if last_output_truncated != last_output %}
<dt class="col-md-3"></dt>
<dd class="col-md-9">
@ -247,7 +251,7 @@
<li class="list-group-item">
<dl class="row">
<dt class="col-md-3">{{ label_last_error_output }}:</dt>
<dd class="col-md-9">{{ last_error_output_truncated }}</dd>
<dd class="col-md-9">{{ last_error_output_truncated|nl2br }}</dd>
{% if last_error_output_truncated != last_error_output %}
<dt class="col-md-3"></dt>
<dd class="col-md-9">
@ -305,6 +309,19 @@
<noscript>&#8263</noscript>
{% endif %}
</li>
<li class="list-group-item">
{{ label_discord }}:
{% if discord|lower == 'yes' %}
<i class="fas fa-bell float-right"></i>
<noscript>&#10003</noscript>
{% elseif discord|lower == 'no' %}
<i class="fas fa-bell-slash float-right"></i>
<noscript>&#10005</noscript>
{% else %}
<i class="fas fa-question-circle float-right" title="Value from database should either be yes or no."></i>
<noscript>&#8263</noscript>
{% endif %}
</li>
<li class="list-group-item">
{{ label_pushover }}:
{% if pushover|lower == 'yes' %}
@ -331,12 +348,67 @@
<noscript>&#8263</noscript>
{% endif %}
</li>
<li class="list-group-item">
{{ label_jabber }}:
{% if jabber|lower == 'yes' %}
<i class="fas fa-bell float-right"></i>
<noscript>&#10003</noscript>
{% elseif jabber|lower == 'no' %}
<i class="fas fa-bell-slash float-right"></i>
<noscript>&#10005</noscript>
{% else %}
<i class="fas fa-question-circle float-right" title="Value from database should either be yes or no."></i>
<noscript>&#8263</noscript>
{% endif %}
</li>
<li class="list-group-item">
{{ label_webhook }}:
{% if webhook|lower == 'yes' %}
<i class="fas fa-bell float-right"></i>
<noscript>&#10003</noscript>
{% elseif webhook|lower == 'no' %}
<i class="fas fa-bell-slash float-right"></i>
<noscript>&#10005</noscript>
{% else %}
<i class="fas fa-question-circle float-right" title="Value from database should either be yes or no."></i>
<noscript>&#8263</noscript>
{% endif %}
</li>
</ul>
</div>
</div>
<div class="row">
{{ html_history|raw }}
</div>
{% if log_entries %}
<div class="row mt-4">
<div class="card col-md-12 pl-0 pr-0">
<div class="card-header">
{{ label_log_title }}
</div>
<div class="card-body d-flex align-items-center justify-content-center">
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead>
<tr>
<th scope="col" style="width: 15%;">{{ label_date }}</th>
<th scope="col">{{ label_message }}</th>
</tr>
</thead>
<tbody>
{% for entry in log_entries %}
<tr>
<td><time>{{ entry.datetime_format }}</time></td>
<td class="full">{{ entry.message|raw }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endif %}
<div class="modal fade" id="modal_last_output" tabindex="-1" role="dialog" aria-labelledby="modal_last_output_label" aria-hidden="true">
<div class="modal-dialog" style="width:75%;max-width: 100%" role="document">

View File

@ -1,13 +1,12 @@
{% import 'main/macros.tpl.html' as macro %}
{{ macro.input_csrf() }}
<div class="container">
<div class="container-fluid">
<div id="flow-layout" class="{{ block_layout_active }}" aria-labelledby="block-layout">
<div class="row">
{% for server in servers_offline %}
<div class="col-sm-4 col-md-3">
<noscript><a href="{{ server.url_view|raw }}"></noscript>
<div class="col-sm-4 col-md-3 col-xl-2">
<div class="card text-white bg-danger mb-3" onclick="window.location.href='{{ server.url_view|raw }}'">
<div class="card-header">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></div>
<div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></a></div>
<div class="card-body">
<p class="card-text">
{{ label_last_online }}: {{ server.last_online_nice }}<br>
@ -15,14 +14,12 @@
</p>
</div>
</div>
<noscript></a></noscript>
</div>
{% endfor %}
{% for server in servers_warning %}
<div class="col-sm-4 col-md-3">
<noscript><a href="{{ server.url_view|raw }}"></noscript>
<div class="col-sm-4 col-md-3 col-xl-2">
<div class="card text-white bg-warning mb-3" onclick="window.location.href='{{ server.url_view|raw }}'">
<div class="card-header">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></div>
<div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></a></div>
<div class="card-body">
<p class="card-text">
{{ label_last_online }}: {{ server.last_online_nice }}<br>
@ -30,23 +27,20 @@
</p>
</div>
</div>
<noscript></a></noscript>
</div>
{% endfor %}
{% for server in servers_online %}
<div class="col-sm-4 col-md-3">
<noscript><a href="{{ server.url_view|raw }}"></noscript>
<div class="col-sm-4 col-md-3 col-xl-2">
<div class="card text-white bg-success mb-3" onclick="window.location.href='{{ server.url_view|raw }}'">
<div class="card-header">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></div>
<div class="card-header"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></a></div>
<div class="card-body">
<p class="card-text">
{{ label_last_online }}: {{ server.last_online_nice }}<br>
{{ label_last_offline }}: {{ server.last_offline_nice }} {{ server.last_offline_duration_nice }}<br>
{{ label_rtime }}: {{ server.rtime }}
{{ label_rtime }}: {{ (server.rtime * 1000)|round(2) }} ms
</p>
</div>
</div>
<noscript></a></noscript>
</div>
{% endfor %}
{% if not servers_offline and not servers_warning and not servers_online %}
@ -72,7 +66,7 @@
<tbody>
{% for server in servers_offline %}
<tr class="bg-danger text-white" onclick="window.location.href='{{ server.url_view|raw }}'">
<th class="full">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></th>
<th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_offline }})</span></a></th>
<td>{{ server.last_online_nice }}</td>
<td>{{ server.last_checked_nice }}</td>
<td></td>
@ -80,7 +74,7 @@
{% endfor %}
{% for server in servers_warning %}
<tr class="bg-warning text-white" onclick="window.location.href='{{ server.url_view|raw }}'">
<th class="full">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></th>
<th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_warning }})</span></a></th>
<td>{{ server.last_online_nice }}</td>
<td>{{ server.last_checked_nice }}</td>
<td></td>
@ -100,10 +94,10 @@
<tbody>
{% for server in servers_online %}
<tr class="bg-success text-white" onclick="window.location.href='{{ server.url_view|raw }}'">
<th class="full">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></th>
<th class="full"><a href="{{ server.url_view|raw }}" class="text-white">{{ server.label }}<span class="sr-only"> ({{ label_online }})</span></a></th>
<td>{{ server.last_online_nice }}</td>
<td>{{ server.last_offline_nice }} {{ server.last_offline_duration_nice }}</td>
<td>{{ server.rtime }}s</td>
<td>{{ (server.rtime * 1000)|round(2) }} ms</td>
</tr>
{% endfor %}
</tbody>
@ -130,4 +124,4 @@ setInterval(function() {
});
}, {{ auto_refresh_seconds }} * 1000);
</script>
{% endif %}
{% endif %}

View File

@ -21,22 +21,44 @@
</fieldset>
<!-- Pushover settings -->
<fieldset>
<legend>{{ label_pushover }}</legend>
<legend>{{ label_pushover }}</legend>
<p>{{ label_pushover_description|raw }}</p>
<!-- pushover key -->
{{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, pushover_key, label_pushover_key, "255", "pushover_key_help", pushover_key_description) }}
{{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, pushover_key, label_pushover_key, "255", "pushover_key_help", label_pushover_key_description) }}
<!-- pushover device -->
{{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, pushover_device, label_pushover_device, "255", "pushover_device_help", pushover_device_description) }}
{{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, pushover_device, label_pushover_device, "255", "pushover_device_help", label_pushover_device_description) }}
</fieldset>
<!-- Telegram settings -->
<fieldset>
<legend>{{ label_telegram }}</legend>
<legend>{{ label_telegram }}</legend>
<p>{{ label_telegram_description|raw }}</p>
<!-- telegram id -->
<div class="form-group">
<a class="btn btn-primary mb-2" href="{{ telegram_get_chat_id_url }}">{{ label_telegram_get_chat_id }}</a>
<a class="btn btn-primary mb-2" href="{{ telegram_get_chat_id_url }}">{{ label_telegram_get_chat_id }}</a>
</div>
{{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_chat_id, telegram_id, label_telegram_chat_id, "255", "telegram_id_help", telegram_id_description) }}
{{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_chat_id, telegram_id, label_telegram_chat_id, "255", "telegram_id_help", label_telegram_id_description) }}
<button class="btn btn-primary show-modal" data-toggle="modal" data-modal-id="activateTelegram">{{ label_activate_telegram }}</button>
{{ macro.input_hidden("activate_telegram", "0") }}
{{ macro.button_save(null, label_save) }}
</fieldset>
</form>
<!-- Jabber settings -->
<fieldset>
<legend>{{ label_jabber }}</legend>
<!-- jabber -->
{{ macro.input_field("text", "jabber", null, "jabber", label_jabber, jabber, label_jabber, "255", "jabber_help", label_jabber_description) }}
</fieldset>
<!-- Discord settings -->
<fieldset>
<legend>{{ label_discord }}</legend>
{{ macro.input_field("text", "discord", null, "discord", label_discord, discord, "https://discordapp.com/api/webhooks/xxxxx", "255", "discord_help", label_discord_description) }}
</fieldset>
<!-- Webhook settings -->
<fieldset>
<legend>{{ label_webhook }}</legend>
<p>{{ label_webhook_description|raw }}</p>
<!-- webhook url -->
{{ macro.input_field("text", "webhook_url", null, "webhook_url", label_webhook_url, webhook_url, "https://test.com/api/abcde", "255", "webhook_url_help", label_webhook_url_description) }}
<!-- webhook json -->
{{ macro.input_field("text", "webhook_json", null, "webhook_json", label_webhook_json, webhook_json, "{\"text\":\"servermon: #message\"}", "255", "webhook_json_help", label_webhook_json_description) }}
</fieldset>
{{ macro.button_save(null, label_save) }}
</form>

View File

@ -17,12 +17,20 @@
{{ macro.input_field("email", "email", null, "email", label_email, edit_value_email, null, "255") }}
<!-- Mobile -->
{{ macro.input_field("tel", "mobile", null, "mobile", label_mobile, edit_value_mobile, null, "20") }}
<!-- Discord -->
{{ macro.input_field("text", "discord", null, "discord", label_discord, edit_value_discord, null, "255") }}
<!-- Webhook_url -->
{{ macro.input_field("text", "webhook_url", null, "webhook_url", label_webhook_url, edit_value_webhook_url, null, "255") }}
<!-- Webhook_json -->
{{ macro.input_field("text", "webhook_json", null, "webhook_json", label_webhook_json, edit_value_webhook_json, null, "255") }}
<!-- Pushover_key -->
{{ macro.input_field("text", "pushover_key", null, "pushover_key", label_pushover_key, edit_value_pushover_key, null, "255") }}
<!-- Pushover_device -->
{{ macro.input_field("text", "pushover_device", null, "pushover_device", label_pushover_device, edit_value_pushover_device, null, "255") }}
<!-- Telegram_id -->
{{ macro.input_field("text", "telegram_id", null, "telegram_id", label_telegram_id, edit_value_telegram_id, null, "255") }}
<!-- Jabber -->
{{ macro.input_field("text", "jabber", null, "jabber", label_jabber, edit_value_jabber, null, "255") }}
<!-- Servers -->
{{ macro.input_select_multiple("server_id", "server_id[]", label_servers, label_search, servers, label_please_select) }}
</div>

View File

@ -1,2 +1,2 @@
html{position:relative;min-height:100%}html[dir='rtl'] #auto_refresh_description,html[dir='rtl'] #log_retention_period_help{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}html[dir='ltr'] #auto_refresh_description,html[dir='ltr'] #log_retention_period_help{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}body{padding-top:4.5rem;margin-bottom:80px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;background-color:#f5f5f5}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.64)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,0.85)}dl,dt,dd{margin-bottom:0}footer .text-muted{color:#4C5557 !important}a,button,.nav-link{min-height:44px !important;min-width:44px !important}a.icon{text-decoration:none;cursor:pointer;padding-left:10px}form.form-signin input[type="text"],form.form-reset input[type="text"]{border-bottom-left-radius:0;border-bottom-right-radius:0}form.form-signin input[type="password"]{border-top-left-radius:0;border-top-right-radius:0}form.form-reset input#input-password{border-radius:0}form.form-reset input#input-password-repeat{border-top-left-radius:0;border-top-right-radius:0}form.form-signin,form.form-forgot,form.form-reset{margin:auto}table{table-layout:fixed}th,td{max-width:1px}.content{word-wrap:break-word;overflow-wrap:break-word}table tr[visible='false'],.no-result{display:none}table tr[visible='true']{display:table-row}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:unset}#meter{border-radius:200px 200px 0 0;height:100px;margin:50px auto 0;overflow:hidden;position:relative;width:200px}#meter:before{background:#fbfbfb;border-radius:200px 200px 0 0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;content:"";height:100px;position:absolute;width:200px}#meter:after{background:#fff;border-radius:140px 140px 0 0;bottom:0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15);box-shadow:3px 1px 8px rgba(0,0,0,0.15);content:"\a" attr(data-value) "%\a" attr(translation);font-size:1.5em;font-weight:100;height:80px;left:20px;line-height:25px;position:absolute;text-align:center;width:160px;z-index:3;white-space:pre}#needle{background:rgba(52,52,64,0.7);border-radius:4px;bottom:-4px;-webkit-box-shadow:3px -1px 4px rgba(0,0,0,0.4);box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;-webkit-transform-origin:100% 4px;transform-origin:100% 4px;-webkit-transition:all 1s;transition:all 1s;border-radius:4px;bottom:-4px;box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;transform-origin:100% 4px;transition:all 1s}
html{position:relative;min-height:100%}html[dir='rtl'] #auto_refresh_description,html[dir='rtl'] #log_retention_period_help{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}html[dir='ltr'] #auto_refresh_description,html[dir='ltr'] #log_retention_period_help{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}body{padding-top:4.5rem;margin-bottom:80px}.container-fluid{max-width:1920px}.footer{position:absolute;bottom:0;width:100%;height:60px;line-height:60px;background-color:#f5f5f5}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,0.64)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,0.85)}dl,dt,dd{margin-bottom:0}footer .text-muted{color:#4C5557 !important}a,button,.nav-link{min-height:44px !important;min-width:44px !important}a.icon{text-decoration:none;cursor:pointer;padding-left:10px}form.form-signin input[type="text"],form.form-reset input[type="text"]{border-bottom-left-radius:0;border-bottom-right-radius:0}form.form-signin input[type="password"]{border-top-left-radius:0;border-top-right-radius:0}form.form-reset input#input-password{border-radius:0}form.form-reset input#input-password-repeat{border-top-left-radius:0;border-top-right-radius:0}form.form-signin,form.form-forgot,form.form-reset{margin:auto}table{table-layout:fixed}th,td{max-width:1px}.content{word-wrap:break-word;overflow-wrap:break-word}table tr[visible='false'],.no-result{display:none}table tr[visible='true']{display:table-row}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:unset}#meter{border-radius:200px 200px 0 0;height:100px;margin:50px auto 0;overflow:hidden;position:relative;width:200px}#meter:before{background:#fbfbfb;border-radius:200px 200px 0 0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;box-shadow:3px 1px 8px rgba(0,0,0,0.15) inset;content:"";height:100px;position:absolute;width:200px}#meter:after{background:#fff;border-radius:140px 140px 0 0;bottom:0;-webkit-box-shadow:3px 1px 8px rgba(0,0,0,0.15);box-shadow:3px 1px 8px rgba(0,0,0,0.15);content:"\a" attr(data-value) "%\a" attr(translation);font-size:1.5em;font-weight:100;height:80px;left:20px;line-height:25px;position:absolute;text-align:center;width:160px;z-index:3;white-space:pre}#needle{background:rgba(52,52,64,0.7);border-radius:4px;bottom:-4px;-webkit-box-shadow:3px -1px 4px rgba(0,0,0,0.4);box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;-webkit-transform-origin:100% 4px;transform-origin:100% 4px;-webkit-transition:all 1s;transition:all 1s;border-radius:4px;bottom:-4px;box-shadow:3px -1px 4px rgba(0,0,0,0.4);display:block;height:8px;left:5px;position:absolute;width:95px;transform-origin:100% 4px;transition:all 1s}.dropdown-menu.show{left:inherit;right:0px}
/*# sourceMappingURL=style.min.css.map */

View File

@ -1,6 +1,6 @@
{
"version": 3,
"mappings": "AAAA,AAAA,IAAI,AAAC,CACD,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,IAAI,CACnB,AAED,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,sBAAsB,CAAE,MAAM,CAC9B,yBAAyB,CAAE,MAAM,CACpC,AAGL,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,uBAAuB,CAAE,MAAM,CAC/B,0BAA0B,CAAE,MAAM,CACrC,AAGL,AAAA,IAAI,AAAC,CACD,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,IAAI,CACtB,AAED,AAAA,OAAO,AAAC,CACJ,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,IAAI,CACjB,gBAAgB,CAAE,OAAO,CAC5B,AAED,AAAA,YAAY,CAAC,WAAW,CAAC,SAAS,AAAC,CAC/B,KAAK,CAAE,sBAAwB,CAMlC,AAPD,AAGI,YAHQ,CAAC,WAAW,CAAC,SAAS,AAG7B,MAAM,CAHX,YAAY,CAAC,WAAW,CAAC,SAAS,AAI7B,MAAM,AAAC,CACJ,KAAK,CAAE,sBAAwB,CAClC,AAGL,AAAA,EAAE,CACF,EAAE,CACF,EAAE,AAAC,CACC,aAAa,CAAE,CAAC,CACnB,AAED,AAAA,MAAM,CAAC,WAAW,AAAC,CACf,KAAK,CAAE,kBAAkB,CAC5B,AAED,AAAA,CAAC,CACD,MAAM,CACN,SAAS,AAAC,CACN,UAAU,CAAE,eAAe,CAC3B,SAAS,CAAE,eAAe,CAC7B,AAED,AAAA,CAAC,AAAA,KAAK,AAAC,CACH,eAAe,CAAE,IAAI,CACrB,MAAM,CAAE,OAAO,CACf,YAAY,CAAE,IAAI,CACrB,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,EACvB,IAAI,AAAA,WAAW,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,CAAa,CAC/B,yBAAyB,CAAE,CAAC,CAC5B,0BAA0B,CAAE,CAAC,CAChC,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,UAAU,AAAf,CAAiB,CACpC,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAED,AACI,IADA,AAAA,WAAW,CACX,KAAK,AAAA,eAAe,AAAC,CACjB,aAAa,CAAE,CAAC,CACnB,AAHL,AAKI,IALA,AAAA,WAAW,CAKX,KAAK,AAAA,sBAAsB,AAAC,CACxB,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAGL,AAAA,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,WAAW,AAAC,CACZ,MAAM,CAAE,IAAI,CACf,AAED,AAAA,KAAK,AAAC,CACF,YAAY,CAAE,KAAK,CACtB,AAED,AAAA,EAAE,CAAE,EAAE,AAAC,CACH,SAAS,CAAC,GAAG,CAChB,AACD,AAAA,QAAQ,AAAC,CACL,SAAS,CAAC,UAAU,CACpB,aAAa,CAAC,UAAU,CAC3B,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,OAAO,AAAf,EACT,UAAU,AAAC,CACP,OAAO,CAAE,IAAI,CAChB,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,MAAM,AAAd,CAAgB,CACrB,OAAO,CAAE,SAAS,CACrB,AAED,AAAA,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,CACjD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,OAAO,CACxD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,CACvD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,AAAC,CACpD,KAAK,CAAE,KAAK,CACf,AAED,AAAA,MAAM,AAAC,CACH,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,WAAW,CACnB,QAAQ,CAAE,MAAM,CAChB,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CA4Bf,AAlCD,AAOI,MAPE,AAOD,OAAO,AAAC,CACL,UAAU,CAAE,OAAO,CACnB,aAAa,CAAE,eAAe,CAC9B,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAAC,KAAK,CACjD,OAAO,CAAE,EAAE,CACX,MAAM,CAAE,KAAK,CACb,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CACf,AAfL,AAgBI,MAhBE,AAgBD,MAAM,AAAC,CACJ,UAAU,CAAE,IAAI,CAChB,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,CAAC,CACT,kBAAkB,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CACnD,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAC3C,OAAO,CAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAA,iBAAiB,CACrD,SAAS,CAAE,KAAK,CAChB,WAAW,CAAE,GAAG,CAChB,MAAM,CAAE,IAAI,CACZ,IAAI,CAAE,IAAI,CACV,WAAW,CAAE,IAAI,CACjB,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,MAAM,CAClB,KAAK,CAAE,KAAK,CACZ,OAAO,CAAE,CAAC,CACV,WAAW,CAAE,GAAG,CACnB,AAGL,AAAA,OAAO,AAAC,CACJ,UAAU,CAAE,kBAAqB,CACjC,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CAClB,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CACrB",
"mappings": "AAAA,AAAA,IAAI,AAAC,CACD,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,IAAI,CACnB,AAED,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,sBAAsB,CAAE,MAAM,CAC9B,yBAAyB,CAAE,MAAM,CACpC,AAGL,AACI,IADA,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EACD,yBAAyB,CAD7B,IAAI,CAAA,AAAA,GAAC,CAAI,KAAK,AAAT,EAED,0BAA0B,AAAC,CACvB,uBAAuB,CAAE,MAAM,CAC/B,0BAA0B,CAAE,MAAM,CACrC,AAGL,AAAA,IAAI,AAAC,CACD,WAAW,CAAE,MAAM,CACnB,aAAa,CAAE,IAAI,CACtB,AAED,AAAA,gBAAgB,AAAC,CACb,SAAS,CAAE,MAAM,CACpB,AAED,AAAA,OAAO,AAAC,CACJ,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,WAAW,CAAE,IAAI,CACjB,gBAAgB,CAAE,OAAO,CAC5B,AAED,AAAA,YAAY,CAAC,WAAW,CAAC,SAAS,AAAC,CAC/B,KAAK,CAAE,sBAAwB,CAMlC,AAPD,AAGI,YAHQ,CAAC,WAAW,CAAC,SAAS,AAG7B,MAAM,CAHX,YAAY,CAAC,WAAW,CAAC,SAAS,AAI7B,MAAM,AAAC,CACJ,KAAK,CAAE,sBAAwB,CAClC,AAGL,AAAA,EAAE,CACF,EAAE,CACF,EAAE,AAAC,CACC,aAAa,CAAE,CAAC,CACnB,AAED,AAAA,MAAM,CAAC,WAAW,AAAC,CACf,KAAK,CAAE,kBAAkB,CAC5B,AAED,AAAA,CAAC,CACD,MAAM,CACN,SAAS,AAAC,CACN,UAAU,CAAE,eAAe,CAC3B,SAAS,CAAE,eAAe,CAC7B,AAED,AAAA,CAAC,AAAA,KAAK,AAAC,CACH,eAAe,CAAE,IAAI,CACrB,MAAM,CAAE,OAAO,CACf,YAAY,CAAE,IAAI,CACrB,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,EACvB,IAAI,AAAA,WAAW,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,CAAa,CAC/B,yBAAyB,CAAE,CAAC,CAC5B,0BAA0B,CAAE,CAAC,CAChC,AAED,AAAA,IAAI,AAAA,YAAY,CAAC,KAAK,CAAA,AAAA,IAAC,CAAK,UAAU,AAAf,CAAiB,CACpC,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAED,AACI,IADA,AAAA,WAAW,CACX,KAAK,AAAA,eAAe,AAAC,CACjB,aAAa,CAAE,CAAC,CACnB,AAHL,AAKI,IALA,AAAA,WAAW,CAKX,KAAK,AAAA,sBAAsB,AAAC,CACxB,sBAAsB,CAAE,CAAC,CACzB,uBAAuB,CAAE,CAAC,CAC7B,AAGL,AAAA,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,YAAY,CAChB,IAAI,AAAA,WAAW,AAAC,CACZ,MAAM,CAAE,IAAI,CACf,AAED,AAAA,KAAK,AAAC,CACF,YAAY,CAAE,KAAK,CACtB,AAED,AAAA,EAAE,CAAE,EAAE,AAAC,CACH,SAAS,CAAC,GAAG,CAChB,AACD,AAAA,QAAQ,AAAC,CACL,SAAS,CAAC,UAAU,CACpB,aAAa,CAAC,UAAU,CAC3B,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,OAAO,AAAf,EACT,UAAU,AAAC,CACP,OAAO,CAAE,IAAI,CAChB,AAED,AAAA,KAAK,CAAC,EAAE,CAAA,AAAA,OAAC,CAAQ,MAAM,AAAd,CAAgB,CACrB,OAAO,CAAE,SAAS,CACrB,AAED,AAAA,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,CACjD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,OAAO,CACxD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,CACvD,iBAAiB,CAAC,gBAAgB,AAAA,eAAe,AAAA,MAAM,AAAC,CACpD,KAAK,CAAE,KAAK,CACf,AAED,AAAA,MAAM,AAAC,CACH,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,KAAK,CACb,MAAM,CAAE,WAAW,CACnB,QAAQ,CAAE,MAAM,CAChB,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CA4Bf,AAlCD,AAOI,MAPE,AAOD,OAAO,AAAC,CACL,UAAU,CAAE,OAAO,CACnB,aAAa,CAAE,eAAe,CAC9B,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAAC,KAAK,CACjD,OAAO,CAAE,EAAE,CACX,MAAM,CAAE,KAAK,CACb,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,KAAK,CACf,AAfL,AAgBI,MAhBE,AAgBD,MAAM,AAAC,CACJ,UAAU,CAAE,IAAI,CAChB,aAAa,CAAE,eAAe,CAC9B,MAAM,CAAE,CAAC,CACT,kBAAkB,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CACnD,UAAU,CAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,gBAAmB,CAC3C,OAAO,CAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAA,iBAAiB,CACrD,SAAS,CAAE,KAAK,CAChB,WAAW,CAAE,GAAG,CAChB,MAAM,CAAE,IAAI,CACZ,IAAI,CAAE,IAAI,CACV,WAAW,CAAE,IAAI,CACjB,QAAQ,CAAE,QAAQ,CAClB,UAAU,CAAE,MAAM,CAClB,KAAK,CAAE,KAAK,CACZ,OAAO,CAAE,CAAC,CACV,WAAW,CAAE,GAAG,CACnB,AAGL,AAAA,OAAO,AAAC,CACJ,UAAU,CAAE,kBAAqB,CACjC,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CAClB,aAAa,CAAE,GAAG,CAClB,MAAM,CAAE,IAAI,CACZ,UAAU,CAAE,GAAG,CAAE,IAAG,CAAC,GAAG,CAAC,eAAkB,CAC3C,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,GAAG,CACX,IAAI,CAAE,GAAG,CACT,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,QAAQ,CAC1B,UAAU,CAAE,MAAM,CACrB,AAED,AAAA,cAAc,AAAA,KAAK,AAAC,CAChB,IAAI,CAAE,OAAO,CACb,KAAK,CAAE,GAAG,CACb",
"sources": [
"../scss/style.scss"
],

0
src/templates/default/static/js/history.js Executable file → Normal file
View File

0
src/templates/default/static/js/scripts.js Executable file → Normal file
View File

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -24,6 +24,10 @@ body {
margin-bottom: 80px;
}
.container-fluid {
max-width: 1920px;
}
.footer {
position: absolute;
bottom: 0;
@ -179,4 +183,9 @@ table tr[visible='true'] {
width: 95px;
transform-origin: 100% 4px;
transition: all 1s;
}
.dropdown-menu.show {
left: inherit;
right: 0px;
}