mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-09-10 20:57:19 +08:00
Compare commits
107 Commits
1.19.0-bet
...
1.19.0-bet
Author | SHA1 | Date | |
---|---|---|---|
|
2532becf61 | ||
|
6154776b34 | ||
|
7e6b92203d | ||
|
1da00d19fd | ||
|
da4bdab4f6 | ||
|
86ab97ef56 | ||
|
345b0c1829 | ||
|
2ac87fcea7 | ||
|
4862bec965 | ||
|
aa784fb3b2 | ||
|
466b403a96 | ||
|
39987ba9ac | ||
|
3b87209e26 | ||
|
e6dc0a0293 | ||
|
5c5a339a36 | ||
|
3040bd41d9 | ||
|
3b58fd3b3c | ||
|
bc86f8bb5f | ||
|
ab5f6dc82c | ||
|
5176fd02c1 | ||
|
02b5cae577 | ||
|
54aa7d5dca | ||
|
4cd5b5563f | ||
|
f1c30204b6 | ||
|
e478084ff9 | ||
|
2dff7dd380 | ||
|
9bfa43100b | ||
|
ad5e1957b1 | ||
|
cc68ebca39 | ||
|
aa27d976c2 | ||
|
ecbc0f0477 | ||
|
92caec95fe | ||
|
2c3abdc146 | ||
|
b1170211b7 | ||
|
eadf2c810a | ||
|
8aa97635ec | ||
|
ee1a56caae | ||
|
e886df4788 | ||
|
5196abfd36 | ||
|
3e68cf2a1c | ||
|
0ab82e6de3 | ||
|
8cdbe37f6f | ||
|
28d13e198c | ||
|
14a062804e | ||
|
cf3e03ab40 | ||
|
191f3ad53b | ||
|
370d522920 | ||
|
e0a1ad8a1c | ||
|
9720006934 | ||
|
cd270bd8b5 | ||
|
bc3229828e | ||
|
a5f23b9839 | ||
|
2052fa175f | ||
|
15b63c82c3 | ||
|
b053bc61ce | ||
|
258ff56962 | ||
|
cb4e512dc6 | ||
|
4042c26390 | ||
|
5da2315534 | ||
|
204015f1f5 | ||
|
cc6d17d2e0 | ||
|
68862c0b3f | ||
|
fd15e7c2dc | ||
|
5c4cf68937 | ||
|
214ddc264d | ||
|
2ea71839d1 | ||
|
54efde8185 | ||
|
705124d4ac | ||
|
1cb6940590 | ||
|
0f8ad288f3 | ||
|
434174d350 | ||
|
3d1237ed53 | ||
|
b459408b10 | ||
|
f04fe4d230 | ||
|
e579610426 | ||
|
b115d3f8b9 | ||
|
134b3b8ac1 | ||
|
e7e7751e7b | ||
|
5cd58e6fa3 | ||
|
08763b700a | ||
|
781f855921 | ||
|
9e81fe120f | ||
|
c0e67b6de9 | ||
|
a17084f75d | ||
|
e4fe7b802a | ||
|
5761bc9b90 | ||
|
92ea019fd4 | ||
|
a774b37369 | ||
|
1e8a16504b | ||
|
b879428a03 | ||
|
3c5de1c889 | ||
|
f9be918246 | ||
|
314ae38f91 | ||
|
c03d911657 | ||
|
e12642cf21 | ||
|
618d904001 | ||
|
6f86236b63 | ||
|
68875c3091 | ||
|
f35d7c0a1a | ||
|
3a90d246a4 | ||
|
6bb79597e8 | ||
|
34ab6142db | ||
|
2232236a7a | ||
|
dcecd10c88 | ||
|
af07c7f050 | ||
|
95dba6dcaf | ||
|
90c2bf7c94 |
@@ -31,6 +31,9 @@ tsconfig.json
|
||||
/tmp
|
||||
/babel.config.js
|
||||
/ecosystem.config.js
|
||||
/extra/healthcheck.exe
|
||||
/extra/healthcheck
|
||||
|
||||
|
||||
### .gitignore content (commented rules are duplicated)
|
||||
|
||||
|
@@ -19,3 +19,6 @@ indent_size = 2
|
||||
|
||||
[*.vue]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.go]
|
||||
indent_style = tab
|
||||
|
6
.github/workflows/stale-bot.yml
vendored
6
.github/workflows/stale-bot.yml
vendored
@@ -12,13 +12,11 @@ jobs:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
stale-issue-message: 'We are clearing up our old issues and your ticket has been open for 3 months with no activity. Remove stale label or comment or this will be closed in 2 days.'
|
||||
stale-pr-message: 'We are clearing up our old Pull Requests and yours has been open for 3 months with no activity. Remove stale label or comment or this will be closed in 2 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 2 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 2 days with no activity.'
|
||||
days-before-stale: 90
|
||||
days-before-close: 2
|
||||
days-before-pr-stale: 999999999
|
||||
days-before-pr-close: 1
|
||||
exempt-issue-labels: 'News,Medium,High,discussion,bug,doc,feature-request'
|
||||
exempt-pr-labels: 'awaiting-approval,work-in-progress,enhancement,feature-request'
|
||||
exempt-issue-assignees: 'louislam'
|
||||
exempt-pr-assignees: 'louislam'
|
||||
operations-per-run: 200
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@@ -16,3 +16,7 @@ dist-ssr
|
||||
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
|
||||
/extra/healthcheck.exe
|
||||
/extra/healthcheck
|
||||
/extra/healthcheck-armv7
|
||||
|
25
db/patch-grpc-monitor.sql
Normal file
25
db/patch-grpc-monitor.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_url VARCHAR(255) default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_protobuf TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_body TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_metadata TEXT default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_method VARCHAR(255) default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_service_name VARCHAR(255) default null;
|
||||
|
||||
ALTER TABLE monitor
|
||||
ADD grpc_enable_tls BOOLEAN default 0 not null;
|
||||
|
||||
COMMIT;
|
@@ -4,5 +4,5 @@ WORKDIR /app
|
||||
|
||||
# Install apprise, iputils for non-root ping, setpriv
|
||||
RUN apk add --no-cache iputils setpriv dumb-init python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib && \
|
||||
pip3 --no-cache-dir install apprise==1.0.0 && \
|
||||
pip3 --no-cache-dir install apprise==1.2.0 && \
|
||||
rm -rf /root/.cache
|
||||
|
@@ -11,7 +11,7 @@ WORKDIR /app
|
||||
RUN apt update && \
|
||||
apt --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \
|
||||
sqlite3 iputils-ping util-linux dumb-init && \
|
||||
pip3 --no-cache-dir install apprise==1.0.0 && \
|
||||
pip3 --no-cache-dir install apprise==1.2.0 && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
apt --yes autoremove
|
||||
|
||||
|
@@ -1,30 +1,57 @@
|
||||
############################################
|
||||
# Build in Golang
|
||||
# Run npm run build-healthcheck-armv7 in the host first, another it will be super slow where it is building the armv7 healthcheck
|
||||
############################################
|
||||
FROM golang:1.19.4-buster AS build_healthcheck
|
||||
WORKDIR /app
|
||||
ARG TARGETPLATFORM
|
||||
COPY ./extra/ ./extra/
|
||||
|
||||
# Compile healthcheck.go
|
||||
RUN apt update
|
||||
RUN apt --yes --no-install-recommends install curl
|
||||
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash
|
||||
RUN apt --yes --no-install-recommends install nodejs
|
||||
RUN node -v
|
||||
RUN node ./extra/build-healthcheck.js $TARGETPLATFORM
|
||||
|
||||
############################################
|
||||
# Build in Node.js
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS build
|
||||
WORKDIR /app
|
||||
|
||||
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
|
||||
|
||||
COPY . .
|
||||
COPY --from=build_healthcheck /app/extra/healthcheck /app/extra/healthcheck
|
||||
RUN npm ci --production && \
|
||||
chmod +x /app/extra/entrypoint.sh
|
||||
|
||||
|
||||
############################################
|
||||
# ⭐ Main Image
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS release
|
||||
WORKDIR /app
|
||||
|
||||
# Copy app files from build layer
|
||||
COPY --from=build /app /app
|
||||
|
||||
|
||||
EXPOSE 3001
|
||||
VOLUME ["/app/data"]
|
||||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js
|
||||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD extra/healthcheck
|
||||
ENTRYPOINT ["/usr/bin/dumb-init", "--", "extra/entrypoint.sh"]
|
||||
CMD ["node", "server/server.js"]
|
||||
|
||||
|
||||
############################################
|
||||
# Mark as Nightly
|
||||
############################################
|
||||
FROM release AS nightly
|
||||
RUN npm run mark-as-nightly
|
||||
|
||||
############################################
|
||||
# Build an image for testing pr
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS pr-test
|
||||
|
||||
WORKDIR /app
|
||||
@@ -54,8 +81,9 @@ VOLUME ["/app/data"]
|
||||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js
|
||||
CMD ["npm", "run", "start-pr-test"]
|
||||
|
||||
|
||||
############################################
|
||||
# Upload the artifact to Github
|
||||
############################################
|
||||
FROM louislam/uptime-kuma:base-debian AS upload-artifact
|
||||
WORKDIR /
|
||||
RUN apt update && \
|
||||
|
27
extra/build-healthcheck.js
Normal file
27
extra/build-healthcheck.js
Normal file
@@ -0,0 +1,27 @@
|
||||
const childProcess = require("child_process");
|
||||
const fs = require("fs");
|
||||
const platform = process.argv[2];
|
||||
|
||||
if (!platform) {
|
||||
console.error("No platform??");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (platform === "linux/arm/v7") {
|
||||
console.log("Arch: armv7");
|
||||
if (fs.existsSync("./extra/healthcheck-armv7")) {
|
||||
fs.renameSync("./extra/healthcheck-armv7", "./extra/healthcheck");
|
||||
console.log("Already built in the host, skip.");
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log("prebuilt not found, it will be slow! You should execute `npm run build-healthcheck-armv7` before build.");
|
||||
}
|
||||
} else {
|
||||
if (fs.existsSync("./extra/healthcheck-armv7")) {
|
||||
fs.rmSync("./extra/healthcheck-armv7");
|
||||
}
|
||||
}
|
||||
|
||||
const output = childProcess.execSync("go build -x -o ./extra/healthcheck ./extra/healthcheck.go").toString("utf8");
|
||||
console.log(output);
|
||||
|
77
extra/healthcheck.go
Normal file
77
extra/healthcheck.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
isFreeBSD := runtime.GOOS == "freebsd"
|
||||
|
||||
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
Timeout: 28 * time.Second,
|
||||
}
|
||||
|
||||
sslKey := os.Getenv("UPTIME_KUMA_SSL_KEY")
|
||||
if len(sslKey) == 0 {
|
||||
sslKey = os.Getenv("SSL_KEY")
|
||||
}
|
||||
|
||||
sslCert := os.Getenv("UPTIME_KUMA_SSL_CERT")
|
||||
if len(sslCert) == 0 {
|
||||
sslCert = os.Getenv("SSL_CERT")
|
||||
}
|
||||
|
||||
hostname := os.Getenv("UPTIME_KUMA_HOST")
|
||||
if len(hostname) == 0 && !isFreeBSD {
|
||||
hostname = os.Getenv("HOST")
|
||||
}
|
||||
if len(hostname) == 0 {
|
||||
hostname = "127.0.0.1"
|
||||
}
|
||||
|
||||
port := os.Getenv("UPTIME_KUMA_PORT")
|
||||
if len(port) == 0 {
|
||||
port = os.Getenv("PORT")
|
||||
}
|
||||
if len(port) == 0 {
|
||||
port = "3001"
|
||||
}
|
||||
|
||||
protocol := ""
|
||||
if len(sslKey) != 0 && len(sslCert) != 0 {
|
||||
protocol = "https"
|
||||
} else {
|
||||
protocol = "http"
|
||||
}
|
||||
|
||||
url := protocol + "://" + hostname + ":" + port
|
||||
|
||||
log.Println("Checking " + url)
|
||||
resp, err := client.Get(url)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
_, err = ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Printf("Health Check OK [Res Code: %d]\n", resp.StatusCode)
|
||||
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* ⚠️ Deprecated: Changed to healthcheck.go, it will be deleted in the future.
|
||||
* This script should be run after a period of time (180s), because the server may need some time to prepare.
|
||||
*/
|
||||
const { FBSD } = require("../server/util-server");
|
||||
|
@@ -5,7 +5,7 @@ const util = require("../src/util");
|
||||
util.polyfill();
|
||||
|
||||
const oldVersion = pkg.version;
|
||||
const newVersion = oldVersion + "-nightly";
|
||||
const newVersion = oldVersion + "-nightly-" + util.genSecret(8);
|
||||
|
||||
console.log("Old Version: " + oldVersion);
|
||||
console.log("New Version: " + newVersion);
|
||||
|
5010
package-lock.json
generated
5010
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "uptime-kuma",
|
||||
"version": "1.19.0-beta.0",
|
||||
"version": "1.19.0-beta.2",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -60,13 +60,15 @@
|
||||
"start-pr-test": "node extra/checkout-pr.js && npm install && npm run dev",
|
||||
"cy:test": "node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/ --e2e",
|
||||
"cy:run": "npx cypress run --browser chrome --headless --config-file ./config/cypress.config.js",
|
||||
"cypress-open": "concurrently -k -r \"node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/\" \"cypress open --config-file ./config/cypress.config.js\""
|
||||
"cypress-open": "concurrently -k -r \"node test/prepare-test-server.js && node server/server.js --port=3002 --data-dir=./data/test/\" \"cypress open --config-file ./config/cypress.config.js\"",
|
||||
"build-healthcheck-armv7": "cross-env GOOS=linux GOARCH=arm GOARM=7 go build -x -o ./extra/healthcheck-armv7 ./extra/healthcheck.go"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "~1.7.3",
|
||||
"@louislam/sqlite3": "15.1.2",
|
||||
"args-parser": "~1.3.0",
|
||||
"axios": "~0.27.0",
|
||||
"axios-ntlm": "~1.3.0",
|
||||
"axios-ntlm": "1.3.0",
|
||||
"badge-maker": "~3.3.1",
|
||||
"bcryptjs": "~2.4.3",
|
||||
"bree": "~7.1.5",
|
||||
@@ -93,6 +95,7 @@
|
||||
"limiter": "~2.1.0",
|
||||
"mqtt": "~4.3.7",
|
||||
"mssql": "~8.1.4",
|
||||
"mysql2": "~2.3.3",
|
||||
"node-cloudflared-tunnel": "~1.0.9",
|
||||
"node-radius-client": "~1.0.0",
|
||||
"nodemailer": "~6.6.5",
|
||||
@@ -102,9 +105,10 @@
|
||||
"pg-connection-string": "~2.5.0",
|
||||
"prom-client": "~13.2.0",
|
||||
"prometheus-api-metrics": "~3.2.1",
|
||||
"protobufjs": "~7.1.1",
|
||||
"redbean-node": "0.1.4",
|
||||
"socket.io": "~4.4.1",
|
||||
"socket.io-client": "~4.4.1",
|
||||
"socket.io": "~4.5.3",
|
||||
"socket.io-client": "~4.5.3",
|
||||
"socks-proxy-agent": "6.1.1",
|
||||
"tar": "~6.1.11",
|
||||
"tcp-ping": "~0.1.1",
|
||||
@@ -130,7 +134,7 @@
|
||||
"chart.js": "~3.6.2",
|
||||
"chartjs-adapter-dayjs": "~1.0.0",
|
||||
"concurrently": "^7.1.0",
|
||||
"core-js": "~3.18.3",
|
||||
"core-js": "~3.26.1",
|
||||
"cross-env": "~7.0.3",
|
||||
"cypress": "^10.1.0",
|
||||
"delay": "^5.0.0",
|
||||
|
@@ -1,6 +1,8 @@
|
||||
const https = require("https");
|
||||
const http = require("http");
|
||||
const CacheableLookup = require("cacheable-lookup");
|
||||
const { Settings } = require("./settings");
|
||||
const { log } = require("../src/util");
|
||||
|
||||
class CacheableDnsHttpAgent {
|
||||
|
||||
@@ -9,12 +11,30 @@ class CacheableDnsHttpAgent {
|
||||
static httpAgentList = {};
|
||||
static httpsAgentList = {};
|
||||
|
||||
static enable = false;
|
||||
|
||||
/**
|
||||
* Register cacheable to global agents
|
||||
* Register/Disable cacheable to global agents
|
||||
*/
|
||||
static registerGlobalAgent() {
|
||||
this.cacheable.install(http.globalAgent);
|
||||
this.cacheable.install(https.globalAgent);
|
||||
static async update() {
|
||||
log.debug("CacheableDnsHttpAgent", "update");
|
||||
let isEnable = await Settings.get("dnsCache");
|
||||
|
||||
if (isEnable !== this.enable) {
|
||||
log.debug("CacheableDnsHttpAgent", "value changed");
|
||||
|
||||
if (isEnable) {
|
||||
log.debug("CacheableDnsHttpAgent", "enable");
|
||||
this.cacheable.install(http.globalAgent);
|
||||
this.cacheable.install(https.globalAgent);
|
||||
} else {
|
||||
log.debug("CacheableDnsHttpAgent", "disable");
|
||||
this.cacheable.uninstall(http.globalAgent);
|
||||
this.cacheable.uninstall(https.globalAgent);
|
||||
}
|
||||
}
|
||||
|
||||
this.enable = isEnable;
|
||||
}
|
||||
|
||||
static install(agent) {
|
||||
@@ -26,6 +46,10 @@ class CacheableDnsHttpAgent {
|
||||
* @return {https.Agent}
|
||||
*/
|
||||
static getHttpsAgent(agentOptions) {
|
||||
if (!this.enable) {
|
||||
return new https.Agent(agentOptions);
|
||||
}
|
||||
|
||||
let key = JSON.stringify(agentOptions);
|
||||
if (!(key in this.httpsAgentList)) {
|
||||
this.httpsAgentList[key] = new https.Agent(agentOptions);
|
||||
@@ -39,6 +63,10 @@ class CacheableDnsHttpAgent {
|
||||
* @return {https.Agents}
|
||||
*/
|
||||
static getHttpAgent(agentOptions) {
|
||||
if (!this.enable) {
|
||||
return new http.Agent(agentOptions);
|
||||
}
|
||||
|
||||
let key = JSON.stringify(agentOptions);
|
||||
if (!(key in this.httpAgentList)) {
|
||||
this.httpAgentList[key] = new http.Agent(agentOptions);
|
||||
|
@@ -25,7 +25,7 @@ exports.startInterval = () => {
|
||||
let checkBeta = await setting("checkBeta");
|
||||
|
||||
if (checkBeta && res.data.beta) {
|
||||
if (compareVersions.compare(res.data.beta, res.data.beta, ">")) {
|
||||
if (compareVersions.compare(res.data.beta, res.data.slow, ">")) {
|
||||
exports.latestVersion = res.data.beta;
|
||||
return;
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@ class Database {
|
||||
"patch-add-clickable-status-page-link.sql": true,
|
||||
"patch-add-sqlserver-monitor.sql": true,
|
||||
"patch-add-other-auth.sql": { parents: [ "patch-monitor-basic-auth.sql" ] },
|
||||
"patch-grpc-monitor.sql": true,
|
||||
"patch-add-radius-monitor.sql": true,
|
||||
"patch-monitor-add-resend-interval.sql": true,
|
||||
"patch-maintenance-table2.sql": true,
|
||||
@@ -151,9 +152,6 @@ class Database {
|
||||
await R.exec("PRAGMA cache_size = -12000");
|
||||
await R.exec("PRAGMA auto_vacuum = FULL");
|
||||
|
||||
// Avoid error "SQLITE_BUSY: database is locked" by allowing SQLITE to wait up to 5 seconds to do a write
|
||||
await R.exec("PRAGMA busy_timeout = 5000");
|
||||
|
||||
// This ensures that an operating system crash or power failure will not corrupt the database.
|
||||
// FULL synchronous is very safe, but it is also slower.
|
||||
// Read more: https://sqlite.org/pragma.html#pragma_synchronous
|
||||
|
@@ -1,4 +1,3 @@
|
||||
const dayjs = require("dayjs");
|
||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||
|
||||
/**
|
||||
|
@@ -188,13 +188,13 @@ class Maintenance extends BeanModel {
|
||||
*/
|
||||
static getActiveMaintenanceSQLCondition() {
|
||||
return `
|
||||
|
||||
(maintenance_timeslot.start_date <= DATETIME('now')
|
||||
AND maintenance_timeslot.end_date >= DATETIME('now')
|
||||
AND maintenance.active = 1)
|
||||
OR
|
||||
(maintenance.strategy = 'manual' AND active = 1)
|
||||
|
||||
(
|
||||
(maintenance_timeslot.start_date <= DATETIME('now')
|
||||
AND maintenance_timeslot.end_date >= DATETIME('now')
|
||||
AND maintenance.active = 1)
|
||||
OR
|
||||
(maintenance.strategy = 'manual' AND active = 1)
|
||||
)
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -204,10 +204,12 @@ class Maintenance extends BeanModel {
|
||||
*/
|
||||
static getActiveAndFutureMaintenanceSQLCondition() {
|
||||
return `
|
||||
((maintenance_timeslot.end_date >= DATETIME('now')
|
||||
AND maintenance.active = 1)
|
||||
OR
|
||||
(maintenance.strategy = 'manual' AND active = 1))
|
||||
(
|
||||
((maintenance_timeslot.end_date >= DATETIME('now')
|
||||
AND maintenance.active = 1)
|
||||
OR
|
||||
(maintenance.strategy = 'manual' AND active = 1))
|
||||
)
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,8 @@ const https = require("https");
|
||||
const dayjs = require("dayjs");
|
||||
const axios = require("axios");
|
||||
const { Prometheus } = require("../prometheus");
|
||||
const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, TimeLogger } = require("../../src/util");
|
||||
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mqttAsync, setSetting, httpNtlm, radius } = require("../util-server");
|
||||
const { log, UP, DOWN, PENDING, MAINTENANCE, flipStatus, TimeLogger, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND } = require("../../src/util");
|
||||
const { tcping, ping, dnsResolve, checkCertificate, checkStatusCode, getTotalClientInRoom, setting, mssqlQuery, postgresQuery, mysqlQuery, mqttAsync, setSetting, httpNtlm, radius, grpcQuery } = require("../util-server");
|
||||
const { R } = require("redbean-node");
|
||||
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||
const { Notification } = require("../notification");
|
||||
@@ -15,6 +15,8 @@ const { UptimeKumaServer } = require("../uptime-kuma-server");
|
||||
const { CacheableDnsHttpAgent } = require("../cacheable-dns-http-agent");
|
||||
const { DockerHost } = require("../docker");
|
||||
const Maintenance = require("./maintenance");
|
||||
const { UptimeCacheList } = require("../uptime-cache-list");
|
||||
const zlib = require("zlib");
|
||||
|
||||
/**
|
||||
* status:
|
||||
@@ -89,27 +91,23 @@ class Monitor extends BeanModel {
|
||||
dns_resolve_type: this.dns_resolve_type,
|
||||
dns_resolve_server: this.dns_resolve_server,
|
||||
dns_last_result: this.dns_last_result,
|
||||
pushToken: this.pushToken,
|
||||
docker_container: this.docker_container,
|
||||
docker_host: this.docker_host,
|
||||
proxyId: this.proxy_id,
|
||||
notificationIDList,
|
||||
tags: tags,
|
||||
maintenance: await Monitor.isUnderMaintenance(this.id),
|
||||
mqttUsername: this.mqttUsername,
|
||||
mqttPassword: this.mqttPassword,
|
||||
mqttTopic: this.mqttTopic,
|
||||
mqttSuccessMessage: this.mqttSuccessMessage,
|
||||
databaseConnectionString: this.databaseConnectionString,
|
||||
databaseQuery: this.databaseQuery,
|
||||
authMethod: this.authMethod,
|
||||
authWorkstation: this.authWorkstation,
|
||||
authDomain: this.authDomain,
|
||||
radiusUsername: this.radiusUsername,
|
||||
radiusPassword: this.radiusPassword,
|
||||
grpcUrl: this.grpcUrl,
|
||||
grpcProtobuf: this.grpcProtobuf,
|
||||
grpcMethod: this.grpcMethod,
|
||||
grpcServiceName: this.grpcServiceName,
|
||||
grpcEnableTls: this.getGrpcEnableTls(),
|
||||
radiusCalledStationId: this.radiusCalledStationId,
|
||||
radiusCallingStationId: this.radiusCallingStationId,
|
||||
radiusSecret: this.radiusSecret,
|
||||
};
|
||||
|
||||
if (includeSensitiveData) {
|
||||
@@ -117,12 +115,23 @@ class Monitor extends BeanModel {
|
||||
...data,
|
||||
headers: this.headers,
|
||||
body: this.body,
|
||||
grpcBody: this.grpcBody,
|
||||
grpcMetadata: this.grpcMetadata,
|
||||
basic_auth_user: this.basic_auth_user,
|
||||
basic_auth_pass: this.basic_auth_pass,
|
||||
pushToken: this.pushToken,
|
||||
databaseConnectionString: this.databaseConnectionString,
|
||||
radiusUsername: this.radiusUsername,
|
||||
radiusPassword: this.radiusPassword,
|
||||
radiusSecret: this.radiusSecret,
|
||||
mqttUsername: this.mqttUsername,
|
||||
mqttPassword: this.mqttPassword,
|
||||
authWorkstation: this.authWorkstation,
|
||||
authDomain: this.authDomain,
|
||||
};
|
||||
}
|
||||
|
||||
data.includeSensitiveData = includeSensitiveData;
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -167,6 +176,14 @@ class Monitor extends BeanModel {
|
||||
return Boolean(this.upsideDown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse to boolean
|
||||
* @returns {boolean}
|
||||
*/
|
||||
getGrpcEnableTls() {
|
||||
return Boolean(this.grpcEnableTls);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get accepted status codes
|
||||
* @returns {Object}
|
||||
@@ -252,12 +269,16 @@ class Monitor extends BeanModel {
|
||||
|
||||
log.debug("monitor", `[${this.name}] Prepare Options for axios`);
|
||||
|
||||
// Axios Options
|
||||
const options = {
|
||||
url: this.url,
|
||||
method: (this.method || "get").toLowerCase(),
|
||||
...(this.body ? { data: JSON.parse(this.body) } : {}),
|
||||
timeout: this.interval * 1000 * 0.8,
|
||||
headers: {
|
||||
// Fix #2253
|
||||
// Read more: https://stackoverflow.com/questions/1759956/curl-error-18-transfer-closed-with-outstanding-read-data-remaining
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
|
||||
"User-Agent": "Uptime-Kuma/" + version,
|
||||
...(this.headers ? JSON.parse(this.headers) : {}),
|
||||
@@ -527,11 +548,50 @@ class Monitor extends BeanModel {
|
||||
bean.msg = "";
|
||||
bean.status = UP;
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
} else if (this.type === "grpc-keyword") {
|
||||
let startTime = dayjs().valueOf();
|
||||
const options = {
|
||||
grpcUrl: this.grpcUrl,
|
||||
grpcProtobufData: this.grpcProtobuf,
|
||||
grpcServiceName: this.grpcServiceName,
|
||||
grpcEnableTls: this.grpcEnableTls,
|
||||
grpcMethod: this.grpcMethod,
|
||||
grpcBody: this.grpcBody,
|
||||
keyword: this.keyword
|
||||
};
|
||||
const response = await grpcQuery(options);
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
log.debug("monitor:", `gRPC response: ${JSON.stringify(response)}`);
|
||||
let responseData = response.data;
|
||||
if (responseData.length > 50) {
|
||||
responseData = response.substring(0, 47) + "...";
|
||||
}
|
||||
if (response.code !== 1) {
|
||||
bean.status = DOWN;
|
||||
bean.msg = `Error in send gRPC ${response.code} ${response.errorMessage}`;
|
||||
} else {
|
||||
if (response.data.toString().includes(this.keyword)) {
|
||||
bean.status = UP;
|
||||
bean.msg = `${responseData}, keyword [${this.keyword}] is found`;
|
||||
} else {
|
||||
log.debug("monitor:", `GRPC response [${response.data}] + ", but keyword [${this.keyword}] is not in [" + ${response.data} + "]"`);
|
||||
bean.status = DOWN;
|
||||
bean.msg = `, but keyword [${this.keyword}] is not in [" + ${responseData} + "]`;
|
||||
}
|
||||
}
|
||||
} else if (this.type === "postgres") {
|
||||
let startTime = dayjs().valueOf();
|
||||
|
||||
await postgresQuery(this.databaseConnectionString, this.databaseQuery);
|
||||
|
||||
bean.msg = "";
|
||||
bean.status = UP;
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
} else if (this.type === "mysql") {
|
||||
let startTime = dayjs().valueOf();
|
||||
|
||||
await mysqlQuery(this.databaseConnectionString, this.databaseQuery);
|
||||
|
||||
bean.msg = "";
|
||||
bean.status = UP;
|
||||
bean.ping = dayjs().valueOf() - startTime;
|
||||
@@ -655,6 +715,7 @@ class Monitor extends BeanModel {
|
||||
}
|
||||
|
||||
log.debug("monitor", `[${this.name}] Send to socket`);
|
||||
UptimeCacheList.clearCache(this.id);
|
||||
io.to(this.user_id).emit("heartbeat", bean.toJSON());
|
||||
Monitor.sendStats(io, this.id, this.user_id);
|
||||
|
||||
@@ -839,7 +900,15 @@ class Monitor extends BeanModel {
|
||||
* @param {number} duration Hours
|
||||
* @param {number} monitorID ID of monitor to calculate
|
||||
*/
|
||||
static async calcUptime(duration, monitorID) {
|
||||
static async calcUptime(duration, monitorID, forceNoCache = false) {
|
||||
|
||||
if (!forceNoCache) {
|
||||
let cachedUptime = UptimeCacheList.getUptime(monitorID, duration);
|
||||
if (cachedUptime != null) {
|
||||
return cachedUptime;
|
||||
}
|
||||
}
|
||||
|
||||
const timeLogger = new TimeLogger();
|
||||
|
||||
const startTime = R.isoDateTime(dayjs.utc().subtract(duration, "hour"));
|
||||
@@ -898,6 +967,9 @@ class Monitor extends BeanModel {
|
||||
}
|
||||
}
|
||||
|
||||
// Cache
|
||||
UptimeCacheList.addUptime(monitorID, duration, uptime);
|
||||
|
||||
return uptime;
|
||||
}
|
||||
|
||||
@@ -1130,6 +1202,15 @@ class Monitor extends BeanModel {
|
||||
LIMIT 1`, [ monitorID ]);
|
||||
return maintenance.count !== 0;
|
||||
}
|
||||
|
||||
validate() {
|
||||
if (this.interval > MAX_INTERVAL_SECOND) {
|
||||
throw new Error(`Interval cannot be more than ${MAX_INTERVAL_SECOND} seconds`);
|
||||
}
|
||||
if (this.interval < MIN_INTERVAL_SECOND) {
|
||||
throw new Error(`Interval cannot be less than ${MIN_INTERVAL_SECOND} seconds`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Monitor;
|
||||
|
@@ -38,7 +38,7 @@ class StatusPage extends BeanModel {
|
||||
*/
|
||||
static async renderHTML(indexHTML, statusPage) {
|
||||
const $ = cheerio.load(indexHTML);
|
||||
const description155 = statusPage.description?.substring(0, 155);
|
||||
const description155 = statusPage.description?.substring(0, 155) ?? "";
|
||||
|
||||
$("title").text(statusPage.title);
|
||||
$("meta[name=description]").attr("content", description155);
|
||||
@@ -282,11 +282,13 @@ class StatusPage extends BeanModel {
|
||||
let activeCondition = Maintenance.getActiveMaintenanceSQLCondition();
|
||||
let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(`
|
||||
SELECT maintenance.*
|
||||
FROM maintenance, maintenance_status_page msp, maintenance_timeslot
|
||||
WHERE msp.maintenance_id = maintenance.id
|
||||
AND maintenance_timeslot.maintenance_id = maintenance.id
|
||||
AND msp.status_page_id = ?
|
||||
AND ${activeCondition}
|
||||
FROM maintenance
|
||||
JOIN maintenance_status_page
|
||||
ON maintenance_status_page.maintenance_id = maintenance.id
|
||||
AND maintenance_status_page.status_page_id = ?
|
||||
LEFT JOIN maintenance_timeslot
|
||||
ON maintenance_timeslot.maintenance_id = maintenance.id
|
||||
WHERE ${activeCondition}
|
||||
ORDER BY maintenance.end_date
|
||||
`, [ statusPageId ]));
|
||||
|
||||
|
@@ -20,6 +20,11 @@ class Ntfy extends NotificationProvider {
|
||||
"priority": notification.ntfyPriority || 4,
|
||||
"title": "Uptime-Kuma",
|
||||
};
|
||||
|
||||
if (notification.ntfyIcon) {
|
||||
data.icon = notification.ntfyIcon;
|
||||
}
|
||||
|
||||
await axios.post(`${notification.ntfyserverurl}`, data, { headers: headers });
|
||||
|
||||
return okMsg;
|
||||
|
@@ -19,26 +19,26 @@ class Pushbullet extends NotificationProvider {
|
||||
}
|
||||
};
|
||||
if (heartbeatJSON == null) {
|
||||
let testdata = {
|
||||
let data = {
|
||||
"type": "note",
|
||||
"title": "Uptime Kuma Alert",
|
||||
"body": "Testing Successful.",
|
||||
"body": msg,
|
||||
};
|
||||
await axios.post(pushbulletUrl, testdata, config);
|
||||
await axios.post(pushbulletUrl, data, config);
|
||||
} else if (heartbeatJSON["status"] === DOWN) {
|
||||
let downdata = {
|
||||
let downData = {
|
||||
"type": "note",
|
||||
"title": "UptimeKuma Alert: " + monitorJSON["name"],
|
||||
"body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"],
|
||||
};
|
||||
await axios.post(pushbulletUrl, downdata, config);
|
||||
await axios.post(pushbulletUrl, downData, config);
|
||||
} else if (heartbeatJSON["status"] === UP) {
|
||||
let updata = {
|
||||
let upData = {
|
||||
"type": "note",
|
||||
"title": "UptimeKuma Alert: " + monitorJSON["name"],
|
||||
"body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"],
|
||||
};
|
||||
await axios.post(pushbulletUrl, updata, config);
|
||||
await axios.post(pushbulletUrl, upData, config);
|
||||
}
|
||||
return okMsg;
|
||||
} catch (error) {
|
||||
|
71
server/notification-providers/smseagle.js
Normal file
71
server/notification-providers/smseagle.js
Normal file
@@ -0,0 +1,71 @@
|
||||
const NotificationProvider = require("./notification-provider");
|
||||
const axios = require("axios");
|
||||
|
||||
class SMSEagle extends NotificationProvider {
|
||||
|
||||
name = "SMSEagle";
|
||||
|
||||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
|
||||
let okMsg = "Sent Successfully.";
|
||||
|
||||
try {
|
||||
let config = {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
|
||||
let postData;
|
||||
let sendMethod;
|
||||
let recipientType;
|
||||
|
||||
let encoding = (notification.smseagleEncoding) ? "1" : "0";
|
||||
let priority = (notification.smseaglePriority) ? notification.smseaglePriority : "0";
|
||||
|
||||
if (notification.smseagleRecipientType === "smseagle-contact") {
|
||||
recipientType = "contactname";
|
||||
sendMethod = "sms.send_tocontact";
|
||||
}
|
||||
if (notification.smseagleRecipientType === "smseagle-group") {
|
||||
recipientType = "groupname";
|
||||
sendMethod = "sms.send_togroup";
|
||||
}
|
||||
if (notification.smseagleRecipientType === "smseagle-to") {
|
||||
recipientType = "to";
|
||||
sendMethod = "sms.send_sms";
|
||||
}
|
||||
|
||||
let params = {
|
||||
access_token: notification.smseagleToken,
|
||||
[recipientType]: notification.smseagleRecipient,
|
||||
message: msg,
|
||||
responsetype: "extended",
|
||||
unicode: encoding,
|
||||
highpriority: priority
|
||||
};
|
||||
|
||||
postData = {
|
||||
method: sendMethod,
|
||||
params: params
|
||||
};
|
||||
|
||||
let resp = await axios.post(notification.smseagleUrl + "/jsonrpc/sms", postData, config);
|
||||
|
||||
if ((JSON.stringify(resp.data)).indexOf("message_id") === -1) {
|
||||
let error = "";
|
||||
if (resp.data.result && resp.data.result.error_text) {
|
||||
error = `SMSEagle API returned error: ${JSON.stringify(resp.data.result.error_text)}`;
|
||||
} else {
|
||||
error = "SMSEagle API returned an unexpected response";
|
||||
}
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
return okMsg;
|
||||
} catch (error) {
|
||||
this.throwGeneralAxiosError(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SMSEagle;
|
@@ -16,20 +16,29 @@ class Webhook extends NotificationProvider {
|
||||
msg,
|
||||
};
|
||||
let finalData;
|
||||
let config = {};
|
||||
let config = {
|
||||
headers: {}
|
||||
};
|
||||
|
||||
if (notification.webhookContentType === "form-data") {
|
||||
finalData = new FormData();
|
||||
finalData.append("data", JSON.stringify(data));
|
||||
|
||||
config = {
|
||||
headers: finalData.getHeaders(),
|
||||
};
|
||||
|
||||
config.headers = finalData.getHeaders();
|
||||
} else {
|
||||
finalData = data;
|
||||
}
|
||||
|
||||
if (notification.webhookAdditionalHeaders) {
|
||||
try {
|
||||
config.headers = {
|
||||
...config.headers,
|
||||
...JSON.parse(notification.webhookAdditionalHeaders)
|
||||
};
|
||||
} catch (err) {
|
||||
throw "Additional Headers is not a valid JSON";
|
||||
}
|
||||
}
|
||||
|
||||
await axios.post(notification.webhookURL, finalData, config);
|
||||
return okMsg;
|
||||
|
||||
|
@@ -32,6 +32,7 @@ const RocketChat = require("./notification-providers/rocket-chat");
|
||||
const SerwerSMS = require("./notification-providers/serwersms");
|
||||
const Signal = require("./notification-providers/signal");
|
||||
const Slack = require("./notification-providers/slack");
|
||||
const SMSEagle = require("./notification-providers/smseagle");
|
||||
const SMTP = require("./notification-providers/smtp");
|
||||
const Squadcast = require("./notification-providers/squadcast");
|
||||
const Stackfield = require("./notification-providers/stackfield");
|
||||
@@ -89,6 +90,7 @@ class Notification {
|
||||
new Signal(),
|
||||
new SMSManager(),
|
||||
new Slack(),
|
||||
new SMSEagle(),
|
||||
new SMTP(),
|
||||
new Squadcast(),
|
||||
new Stackfield(),
|
||||
|
@@ -7,7 +7,7 @@ const { UptimeKumaServer } = require("./uptime-kuma-server");
|
||||
|
||||
class Proxy {
|
||||
|
||||
static SUPPORTED_PROXY_PROTOCOLS = [ "http", "https", "socks", "socks5", "socks4" ];
|
||||
static SUPPORTED_PROXY_PROTOCOLS = [ "http", "https", "socks", "socks5", "socks5h", "socks4" ];
|
||||
|
||||
/**
|
||||
* Saves and updates given proxy entity
|
||||
@@ -126,6 +126,7 @@ class Proxy {
|
||||
break;
|
||||
case "socks":
|
||||
case "socks5":
|
||||
case "socks5h":
|
||||
case "socks4":
|
||||
agent = new SocksProxyAgent({
|
||||
...httpAgentOptions,
|
||||
|
@@ -135,7 +135,9 @@ const { cloudflaredSocketHandler, autoStart: cloudflaredAutoStart, stop: cloudfl
|
||||
const { proxySocketHandler } = require("./socket-handlers/proxy-socket-handler");
|
||||
const { dockerSocketHandler } = require("./socket-handlers/docker-socket-handler");
|
||||
const { maintenanceSocketHandler } = require("./socket-handlers/maintenance-socket-handler");
|
||||
const { generalSocketHandler } = require("./socket-handlers/general-socket-handler");
|
||||
const { Settings } = require("./settings");
|
||||
const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent");
|
||||
|
||||
app.use(express.json());
|
||||
|
||||
@@ -203,6 +205,7 @@ let needSetup = false;
|
||||
|
||||
if (isDev) {
|
||||
app.post("/test-webhook", async (request, response) => {
|
||||
log.debug("test", request.headers);
|
||||
log.debug("test", request.body);
|
||||
response.send("OK");
|
||||
});
|
||||
@@ -631,6 +634,9 @@ let needSetup = false;
|
||||
|
||||
bean.import(monitor);
|
||||
bean.user_id = socket.userID;
|
||||
|
||||
bean.validate();
|
||||
|
||||
await R.store(bean);
|
||||
|
||||
await updateMonitorNotification(bean.id, notificationIDList);
|
||||
@@ -706,12 +712,20 @@ let needSetup = false;
|
||||
bean.authMethod = monitor.authMethod;
|
||||
bean.authWorkstation = monitor.authWorkstation;
|
||||
bean.authDomain = monitor.authDomain;
|
||||
bean.grpcUrl = monitor.grpcUrl;
|
||||
bean.grpcProtobuf = monitor.grpcProtobuf;
|
||||
bean.grpcMethod = monitor.grpcMethod;
|
||||
bean.grpcBody = monitor.grpcBody;
|
||||
bean.grpcMetadata = monitor.grpcMetadata;
|
||||
bean.grpcEnableTls = monitor.grpcEnableTls;
|
||||
bean.radiusUsername = monitor.radiusUsername;
|
||||
bean.radiusPassword = monitor.radiusPassword;
|
||||
bean.radiusCalledStationId = monitor.radiusCalledStationId;
|
||||
bean.radiusCallingStationId = monitor.radiusCallingStationId;
|
||||
bean.radiusSecret = monitor.radiusSecret;
|
||||
|
||||
bean.validate();
|
||||
|
||||
await R.store(bean);
|
||||
|
||||
await updateMonitorNotification(bean.id, monitor.notificationIDList);
|
||||
@@ -1102,6 +1116,8 @@ let needSetup = false;
|
||||
await setSettings("general", data);
|
||||
server.entryPage = data.entryPage;
|
||||
|
||||
await CacheableDnsHttpAgent.update();
|
||||
|
||||
// Also need to apply timezone globally
|
||||
if (data.serverTimezone) {
|
||||
await server.setTimezone(data.serverTimezone);
|
||||
@@ -1473,6 +1489,7 @@ let needSetup = false;
|
||||
proxySocketHandler(socket);
|
||||
dockerSocketHandler(socket);
|
||||
maintenanceSocketHandler(socket);
|
||||
generalSocketHandler(socket, server);
|
||||
|
||||
log.debug("server", "added all socket handlers");
|
||||
|
||||
@@ -1595,6 +1612,13 @@ async function afterLogin(socket, user) {
|
||||
for (let monitorID in monitorList) {
|
||||
await Monitor.sendStats(io, monitorID, user.id);
|
||||
}
|
||||
|
||||
// Set server timezone from client browser if not set
|
||||
// It should be run once only
|
||||
if (! await Settings.get("initServerTimezone")) {
|
||||
log.debug("server", "emit initServerTimezone");
|
||||
socket.emit("initServerTimezone");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1733,6 +1757,7 @@ async function shutdownFunction(signal) {
|
||||
|
||||
stopBackgroundJobs();
|
||||
await cloudflaredStop();
|
||||
Settings.stopCacheCleaner();
|
||||
}
|
||||
|
||||
/** Final function called before application exits */
|
||||
|
@@ -158,6 +158,13 @@ class Settings {
|
||||
delete Settings.cacheList[key];
|
||||
}
|
||||
}
|
||||
|
||||
static stopCacheCleaner() {
|
||||
if (Settings.cacheCleaner) {
|
||||
clearInterval(Settings.cacheCleaner);
|
||||
Settings.cacheCleaner = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
const { checkLogin, setSetting, setting, doubleCheckPassword } = require("../util-server");
|
||||
const { CloudflaredTunnel } = require("node-cloudflared-tunnel");
|
||||
const { UptimeKumaServer } = require("../uptime-kuma-server");
|
||||
const { log } = require("../../src/util");
|
||||
const io = UptimeKumaServer.getInstance().io;
|
||||
|
||||
const prefix = "cloudflared_";
|
||||
@@ -107,7 +108,7 @@ module.exports.autoStart = async (token) => {
|
||||
|
||||
/** Stop cloudflared */
|
||||
module.exports.stop = async () => {
|
||||
console.log("Stop cloudflared");
|
||||
log.info("cloudflared", "Stop cloudflared");
|
||||
if (cloudflared) {
|
||||
cloudflared.stop();
|
||||
}
|
||||
|
18
server/socket-handlers/general-socket-handler.js
Normal file
18
server/socket-handlers/general-socket-handler.js
Normal file
@@ -0,0 +1,18 @@
|
||||
const { log } = require("../../src/util");
|
||||
const { Settings } = require("../settings");
|
||||
const { sendInfo } = require("../client");
|
||||
|
||||
module.exports.generalSocketHandler = (socket, server) => {
|
||||
|
||||
socket.on("initServerTimezone", async (timezone) => {
|
||||
try {
|
||||
log.debug("generalSocketHandler", "Timezone: " + timezone);
|
||||
await Settings.set("initServerTimezone", true);
|
||||
await server.setTimezone(timezone);
|
||||
await sendInfo(socket);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
};
|
39
server/uptime-cache-list.js
Normal file
39
server/uptime-cache-list.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const { log } = require("../src/util");
|
||||
class UptimeCacheList {
|
||||
/**
|
||||
* list[monitorID][duration]
|
||||
*/
|
||||
static list = {};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param monitorID
|
||||
* @param duration
|
||||
* @return number
|
||||
*/
|
||||
static getUptime(monitorID, duration) {
|
||||
if (UptimeCacheList.list[monitorID] && UptimeCacheList.list[monitorID][duration]) {
|
||||
log.debug("UptimeCacheList", "getUptime: " + monitorID + " " + duration);
|
||||
return UptimeCacheList.list[monitorID][duration];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static addUptime(monitorID, duration, uptime) {
|
||||
log.debug("UptimeCacheList", "addUptime: " + monitorID + " " + duration);
|
||||
if (!UptimeCacheList.list[monitorID]) {
|
||||
UptimeCacheList.list[monitorID] = {};
|
||||
}
|
||||
UptimeCacheList.list[monitorID][duration] = uptime;
|
||||
}
|
||||
|
||||
static clearCache(monitorID) {
|
||||
log.debug("UptimeCacheList", "clearCache: " + monitorID);
|
||||
delete UptimeCacheList.list[monitorID];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
UptimeCacheList,
|
||||
};
|
@@ -83,12 +83,12 @@ class UptimeKumaServer {
|
||||
}
|
||||
}
|
||||
|
||||
CacheableDnsHttpAgent.registerGlobalAgent();
|
||||
|
||||
this.io = new Server(this.httpServer);
|
||||
}
|
||||
|
||||
async initAfterDatabaseReady() {
|
||||
await CacheableDnsHttpAgent.update();
|
||||
|
||||
process.env.TZ = await this.getTimezone();
|
||||
dayjs.tz.setDefault(process.env.TZ);
|
||||
log.debug("DEBUG", "Timezone: " + process.env.TZ);
|
||||
|
@@ -13,8 +13,11 @@ const { badgeConstants } = require("./config");
|
||||
const mssql = require("mssql");
|
||||
const { Client } = require("pg");
|
||||
const postgresConParse = require("pg-connection-string").parse;
|
||||
const mysql = require("mysql2");
|
||||
const { NtlmClient } = require("axios-ntlm");
|
||||
const { Settings } = require("./settings");
|
||||
const grpc = require("@grpc/grpc-js");
|
||||
const protojs = require("protobufjs");
|
||||
const radiusClient = require("node-radius-client");
|
||||
const {
|
||||
dictionaries: {
|
||||
@@ -292,6 +295,28 @@ exports.postgresQuery = function (connectionString, query) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Run a query on MySQL/MariaDB
|
||||
* @param {string} connectionString The database connection string
|
||||
* @param {string} query The query to validate the database with
|
||||
* @returns {Promise<(string[]|Object[]|Object)>}
|
||||
*/
|
||||
exports.mysqlQuery = function (connectionString, query) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const connection = mysql.createConnection(connectionString);
|
||||
connection.promise().query(query)
|
||||
.then(res => {
|
||||
resolve(res);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
})
|
||||
.finally(() => {
|
||||
connection.end();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Query radius server
|
||||
* @param {string} hostname Hostname of radius server
|
||||
@@ -445,6 +470,10 @@ const parseCertificateInfo = function (info) {
|
||||
* @returns {Object} Object containing certificate information
|
||||
*/
|
||||
exports.checkCertificate = function (res) {
|
||||
if (!res.request.res.socket) {
|
||||
throw new Error("No socket found");
|
||||
}
|
||||
|
||||
const info = res.request.res.socket.getPeerCertificate(true);
|
||||
const valid = res.request.res.socket.authorized || false;
|
||||
|
||||
@@ -720,3 +749,51 @@ module.exports.timeObjectToUTC = (obj, timezone = undefined) => {
|
||||
module.exports.timeObjectToLocal = (obj, timezone = undefined) => {
|
||||
return timeObjectConvertTimezone(obj, timezone, false);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create gRPC client stib
|
||||
* @param {Object} options from gRPC client
|
||||
*/
|
||||
module.exports.grpcQuery = async (options) => {
|
||||
const { grpcUrl, grpcProtobufData, grpcServiceName, grpcEnableTls, grpcMethod, grpcBody } = options;
|
||||
const protocObject = protojs.parse(grpcProtobufData);
|
||||
const protoServiceObject = protocObject.root.lookupService(grpcServiceName);
|
||||
const Client = grpc.makeGenericClientConstructor({});
|
||||
const credentials = grpcEnableTls ? grpc.credentials.createSsl() : grpc.credentials.createInsecure();
|
||||
const client = new Client(
|
||||
grpcUrl,
|
||||
credentials
|
||||
);
|
||||
const grpcService = protoServiceObject.create(function (method, requestData, cb) {
|
||||
const fullServiceName = method.fullName;
|
||||
const serviceFQDN = fullServiceName.split(".");
|
||||
const serviceMethod = serviceFQDN.pop();
|
||||
const serviceMethodClientImpl = `/${serviceFQDN.slice(1).join(".")}/${serviceMethod}`;
|
||||
log.debug("monitor", `gRPC method ${serviceMethodClientImpl}`);
|
||||
client.makeUnaryRequest(
|
||||
serviceMethodClientImpl,
|
||||
arg => arg,
|
||||
arg => arg,
|
||||
requestData,
|
||||
cb);
|
||||
}, false, false);
|
||||
return new Promise((resolve, _) => {
|
||||
return grpcService[`${grpcMethod}`](JSON.parse(grpcBody), function (err, response) {
|
||||
const responseData = JSON.stringify(response);
|
||||
if (err) {
|
||||
return resolve({
|
||||
code: err.code,
|
||||
errorMessage: err.details,
|
||||
data: ""
|
||||
});
|
||||
} else {
|
||||
log.debug("monitor:", `gRPC response: ${response}`);
|
||||
return resolve({
|
||||
code: 1,
|
||||
errorMessage: "",
|
||||
data: responseData
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@@ -3,8 +3,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from "dayjs";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
/** Value of date time */
|
||||
|
@@ -206,6 +206,16 @@ export default {
|
||||
.search-icon {
|
||||
padding: 10px;
|
||||
color: #c0c0c0;
|
||||
|
||||
// Clear filter button (X)
|
||||
svg[data-icon="times"] {
|
||||
cursor: pointer;
|
||||
transition: all ease-in-out 0.1s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-input {
|
||||
|
@@ -17,6 +17,7 @@
|
||||
<option value="http">HTTP</option>
|
||||
<option value="socks">SOCKS</option>
|
||||
<option value="socks5">SOCKS v5</option>
|
||||
<option value="socks5h">SOCKS v5 (+DNS)</option>
|
||||
<option value="socks4">SOCKS v4</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@@ -27,6 +27,10 @@
|
||||
<HiddenInput id="ntfy-password" v-model="$parent.notification.ntfypassword" autocomplete="new-password"></HiddenInput>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="ntfy-icon" class="form-label">{{ $t("IconUrl") }}</label>
|
||||
<input id="ntfy-icon" v-model="$parent.notification.ntfyIcon" type="text" class="form-control">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
40
src/components/notifications/SMSEagle.vue
Normal file
40
src/components/notifications/SMSEagle.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="mb-3">
|
||||
<label for="smseagle-url" class="form-label">{{ $t("smseagleUrl") }}</label>
|
||||
<input id="smseagle-url" v-model="$parent.notification.smseagleUrl" type="text" minlength="7" class="form-control" placeholder="http://127.0.0.1" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="smseagle-token" class="form-label">{{ $t("smseagleToken") }}</label>
|
||||
<HiddenInput id="smseagle-token" v-model="$parent.notification.smseagleToken" :required="true"></HiddenInput>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="smseagle-recipient-type" class="form-label">{{ $t("smseagleRecipientType") }}</label>
|
||||
<select id="smseagle-recipient-type" v-model="$parent.notification.smseagleRecipientType" class="form-select">
|
||||
<option value="smseagle-to" selected>{{ $t("smseagleTo") }}</option>
|
||||
<option value="smseagle-group">{{ $t("smseagleGroup") }}</option>
|
||||
<option value="smseagle-contact">{{ $t("smseagleContact") }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="smseagle-recipient" class="form-label">{{ $t("smseagleRecipient") }}</label>
|
||||
<input id="smseagle-recipient" v-model="$parent.notification.smseagleRecipient" type="text" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="smseagle-priority" class="form-label">{{ $t("smseaglePriority") }}</label>
|
||||
<input id="smseagle-priority" v-model="$parent.notification.smseaglePriority" type="number" class="form-control" min="0" max="9" step="1" placeholder="0">
|
||||
</div>
|
||||
<div class="mb-3 form-check form-switch">
|
||||
<label for="smseagle-encoding" class="form-label">{{ $t("smseagleEncoding") }}</label>
|
||||
<input id="smseagle-encoding" v-model="$parent.notification.smseagleEncoding" type="checkbox" class="form-check-input">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import HiddenInput from "../HiddenInput.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
HiddenInput,
|
||||
},
|
||||
};
|
||||
</script>
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="mb-3">
|
||||
<label for="smsmanager-key" class="form-label">API Key</label>
|
||||
<label for="smsmanager-key" class="form-label">{{ $t("API Key") }}</label>
|
||||
<div class="form-text">
|
||||
{{ $t("SMSManager API Docs") }}
|
||||
<a href="https://smsmanager.cz/api/http#send" target="_blank">{{ $t("here") }}</a>
|
||||
@@ -17,9 +17,9 @@
|
||||
<div class="mb-3">
|
||||
<label for="smsmanager-messageType" class="form-label">{{ $t("Gateway Type") }}</label>
|
||||
<select id="smsmanager-messageType" v-model="$parent.notification.messageType" class="form-select">
|
||||
<option value="economy">Economy</option>
|
||||
<option value="lowcost">Lowcost</option>
|
||||
<option value="high" selected>High</option>
|
||||
<option value="economy">{{ $t("Economy") }}</option>
|
||||
<option value="lowcost">{{ $t("Lowcost") }}</option>
|
||||
<option value="high" selected>{{ $t("High") }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
|
@@ -1,22 +1,32 @@
|
||||
<template>
|
||||
<div class="mb-3">
|
||||
<label for="webhook-url" class="form-label">{{ $t("Post URL") }}</label>
|
||||
<input id="webhook-url" v-model="$parent.notification.webhookURL" type="url" pattern="https?://.+" class="form-control" required>
|
||||
<input
|
||||
id="webhook-url"
|
||||
v-model="$parent.notification.webhookURL"
|
||||
type="url"
|
||||
pattern="https?://.+"
|
||||
class="form-control"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="webhook-content-type" class="form-label">{{ $t("Content Type") }}</label>
|
||||
<select id="webhook-content-type" v-model="$parent.notification.webhookContentType" class="form-select" required>
|
||||
<option value="json">
|
||||
application/json
|
||||
</option>
|
||||
<option value="form-data">
|
||||
multipart/form-data
|
||||
</option>
|
||||
<label for="webhook-content-type" class="form-label">{{
|
||||
$t("Content Type")
|
||||
}}</label>
|
||||
<select
|
||||
id="webhook-content-type"
|
||||
v-model="$parent.notification.webhookContentType"
|
||||
class="form-select"
|
||||
required
|
||||
>
|
||||
<option value="json">application/json</option>
|
||||
<option value="form-data">multipart/form-data</option>
|
||||
</select>
|
||||
|
||||
<div class="form-text">
|
||||
<p>{{ $t("webhookJsonDesc", ["\"application/json\""]) }}</p>
|
||||
<p>{{ $t("webhookJsonDesc", ['"application/json"']) }}</p>
|
||||
<i18n-t tag="p" keypath="webhookFormDataDesc">
|
||||
<template #multipart>"multipart/form-data"</template>
|
||||
<template #decodeFunction>
|
||||
@@ -25,4 +35,44 @@
|
||||
</i18n-t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<i18n-t
|
||||
tag="label"
|
||||
class="form-label"
|
||||
for="additionalHeaders"
|
||||
keypath="webhookAdditionalHeadersTitle"
|
||||
>
|
||||
</i18n-t>
|
||||
<textarea
|
||||
id="additionalHeaders"
|
||||
v-model="$parent.notification.webhookAdditionalHeaders"
|
||||
class="form-control"
|
||||
:placeholder="headersPlaceholder"
|
||||
></textarea>
|
||||
<div class="form-text">
|
||||
<i18n-t tag="p" keypath="webhookAdditionalHeadersDesc"> </i18n-t>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
headersPlaceholder() {
|
||||
return this.$t("Example:", [
|
||||
`
|
||||
{
|
||||
"HeaderName": "HeaderValue"
|
||||
}`,
|
||||
]);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
textarea {
|
||||
min-height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -33,6 +33,7 @@ import Signal from "./Signal.vue";
|
||||
import SMSManager from "./SMSManager.vue";
|
||||
import Slack from "./Slack.vue";
|
||||
import Squadcast from "./Squadcast.vue";
|
||||
import SMSEagle from "./SMSEagle.vue";
|
||||
import Stackfield from "./Stackfield.vue";
|
||||
import STMP from "./SMTP.vue";
|
||||
import Teams from "./Teams.vue";
|
||||
@@ -83,6 +84,7 @@ const NotificationFormList = {
|
||||
"SMSManager": SMSManager,
|
||||
"slack": Slack,
|
||||
"squadcast": Squadcast,
|
||||
"SMSEagle": SMSEagle,
|
||||
"smtp": STMP,
|
||||
"stackfield": Stackfield,
|
||||
"teams": Teams,
|
||||
|
@@ -49,7 +49,7 @@
|
||||
v-model="settings.searchEngineIndex"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
name="flexRadioDefault"
|
||||
name="searchEngineIndex"
|
||||
:value="true"
|
||||
required
|
||||
/>
|
||||
@@ -63,7 +63,7 @@
|
||||
v-model="settings.searchEngineIndex"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
name="flexRadioDefault"
|
||||
name="searchEngineIndex"
|
||||
:value="false"
|
||||
required
|
||||
/>
|
||||
@@ -150,6 +150,46 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- DNS Cache -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label">
|
||||
{{ $t("Enable DNS Cache") }}
|
||||
<div class="form-text">
|
||||
⚠️ {{ $t("dnsCacheDescription") }}
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<div class="form-check">
|
||||
<input
|
||||
id="dnsCacheEnable"
|
||||
v-model="settings.dnsCache"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
name="dnsCache"
|
||||
:value="true"
|
||||
required
|
||||
/>
|
||||
<label class="form-check-label" for="dnsCacheEnable">
|
||||
{{ $t("Enable") }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input
|
||||
id="dnsCacheDisable"
|
||||
v-model="settings.dnsCache"
|
||||
class="form-check-input"
|
||||
type="radio"
|
||||
name="dnsCache"
|
||||
:value="false"
|
||||
required
|
||||
/>
|
||||
<label class="form-check-label" for="dnsCacheDisable">
|
||||
{{ $t("Disable") }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Save Button -->
|
||||
<div>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
|
@@ -6,6 +6,7 @@ const languageList = {
|
||||
"zh-HK": "繁體中文 (香港)",
|
||||
"bg-BG": "Български",
|
||||
"de-DE": "Deutsch (Deutschland)",
|
||||
"de-CH": "Deutsch (Schweiz)",
|
||||
"nl-NL": "Nederlands",
|
||||
"nb-NO": "Norsk",
|
||||
"es-ES": "Español",
|
||||
|
@@ -1,13 +1,14 @@
|
||||
# How to translate
|
||||
|
||||
1. Fork this repo.
|
||||
2. Run `npm run update-language-files --language=<code>` where `<code>`
|
||||
2. Run `npm install`
|
||||
3. Run `npm run update-language-files --language=<code>` where `<code>`
|
||||
is a valid ISO language code:
|
||||
http://www.lingoes.net/en/translator/langcode.htm. You can also use
|
||||
this command to check if there are new strings to
|
||||
translate for your language.
|
||||
3. Your language file should be filled in. You can translate now.
|
||||
4. Add it into `languageList` constant.
|
||||
5. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
|
||||
4. Your language file should be filled in. You can translate now.
|
||||
5. Add it into `languageList` constant.
|
||||
6. Make a [pull request](https://github.com/louislam/uptime-kuma/pulls) when you have done.
|
||||
|
||||
If you do not have programming skills, let me know in [the issues section](https://github.com/louislam/uptime-kuma/issues). I will assist you. 😏
|
||||
|
@@ -2,8 +2,8 @@ export default {
|
||||
languageName: "Български",
|
||||
checkEverySecond: "Ще се извършва на всеки {0} секунди",
|
||||
retryCheckEverySecond: "Ще се извършва на всеки {0} секунди",
|
||||
retriesDescription: "Максимакен брой опити преди маркиране на услугата като недостъпна и изпращане на известие",
|
||||
ignoreTLSError: "Игнорирай TLS/SSL грешки за HTTPS уебсайтове",
|
||||
retriesDescription: "Максимален брой опити преди маркиране на услугата като недостъпна и изпращане на известие",
|
||||
ignoreTLSError: "Игнорирай TLS/SSL грешки за HTTPS уеб сайтове",
|
||||
upsideDownModeDescription: "Обръща статуса от достъпен на недостъпен. Ако услугата е достъпна, ще се вижда като НЕДОСТЪПНА.",
|
||||
maxRedirectDescription: "Максимален брой пренасочвания, които да бъдат следвани. Въведете 0 за да изключите пренасочване.",
|
||||
acceptedStatusCodesDescription: "Изберете статус кодове, които да се считат за успешен отговор.",
|
||||
@@ -95,7 +95,7 @@ export default {
|
||||
"Repeat New Password": "Повторете новата парола",
|
||||
"Update Password": "Актуализирай паролата",
|
||||
"Disable Auth": "Изключи удостоверяване",
|
||||
"Enable Auth": "Включи удостоверяване",
|
||||
"Enable Auth": "Активирай удостоверяване",
|
||||
"disableauth.message1": "Сигурни ли сте, че желаете да <strong>изключите удостоверяването</strong>?",
|
||||
"disableauth.message2": "Използва се в случаите, когато <strong>има настроен алтернативен метод за удостоверяване</strong> преди Uptime Kuma, например Cloudflare Access, Authelia или друг механизъм за удостоверяване.",
|
||||
"Please use this option carefully!": "Моля, използвайте с повишено внимание.",
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
Import: "Импорт",
|
||||
respTime: "Време за отговор (ms)",
|
||||
notAvailableShort: "Няма",
|
||||
"Default enabled": "Включен по подразбиране",
|
||||
"Default enabled": "Активирано по подразбиране",
|
||||
"Apply on all existing monitors": "Приложи върху всички съществуващи монитори",
|
||||
Create: "Създай",
|
||||
"Clear Data": "Изтрий данни",
|
||||
@@ -145,8 +145,8 @@ export default {
|
||||
"Keep both": "Запази двете",
|
||||
"Verify Token": "Провери токен код",
|
||||
"Setup 2FA": "Настройка 2FA",
|
||||
"Enable 2FA": "Включи 2FA",
|
||||
"Disable 2FA": "Изключи 2FA",
|
||||
"Enable 2FA": "Активирай 2FA",
|
||||
"Disable 2FA": "Деактивирай 2FA",
|
||||
"2FA Settings": "Настройка за 2FA",
|
||||
"Two Factor Authentication": "Двуфакторно удостоверяване",
|
||||
Active: "Активно",
|
||||
@@ -194,7 +194,7 @@ export default {
|
||||
octopush: "Octopush",
|
||||
promosms: "PromoSMS",
|
||||
lunasea: "LunaSea",
|
||||
apprise: "Apprise (Поддържа 50+ услуги за инвестяване)",
|
||||
apprise: "Apprise (Поддържа 50+ услуги за известяване)",
|
||||
pushbullet: "Pushbullet",
|
||||
line: "Line Messenger",
|
||||
mattermost: "Mattermost",
|
||||
@@ -281,19 +281,19 @@ export default {
|
||||
wayToGetLineChannelToken: "Необходимо е първо да посетите {0}, за да създадете (Messaging API) за доставчик и канал, след което може да вземете токен кода за канал и потребителско ID от споменатите по-горе елементи на менюто.",
|
||||
"Icon URL": "URL адрес за иконка",
|
||||
aboutIconURL: "Може да предоставите линк към картинка в поле \"URL Адрес за иконка\" за да отмените картинката на профила по подразбиране. Няма да се използва, ако вече сте настроили емотикон.",
|
||||
aboutMattermostChannelName: "Може да замените канала по подразбиране, към който публикува уеб куката, като въведете името на канала в полето \"Канал име\". Tрябва да бъде активирано в настройките за уеб кука на Mattermost. Например: #other-channel",
|
||||
aboutMattermostChannelName: "Може да замените канала по подразбиране, към който публикува уеб куката, като въведете името на канала в полето \"Канал име\". Трябва да бъде активирано в настройките за уеб кука на Mattermost. Например: #other-channel",
|
||||
matrix: "Matrix",
|
||||
promosmsTypeEco: "SMS ECO - евтин, но бавен. Често е претоварен. Само за получатели от Полша.",
|
||||
promosmsTypeFlash: "SMS FLASH - Съобщението автоматично се показва на устройството на получателя. Само за получатели от Полша.",
|
||||
promosmsTypeFull: "SMS FULL - Високо ниво на SMS услуга. Може да използвате Вашето име като подател (Необходимо е първо да регистрирате името). Надежден метод за съобщения тип тревога.",
|
||||
promosmsTypeSpeed: "SMS SPEED - Най-висок приоритет в системата. Много бърза и надеждна, но същвременно скъпа услуга. (Около два пъти по-висока цена в сравнение с SMS FULL).",
|
||||
promosmsTypeSpeed: "SMS SPEED - Най-висок приоритет в системата. Много бърза и надеждна, но същевременно скъпа услуга. (Около два пъти по-висока цена в сравнение с SMS FULL).",
|
||||
promosmsPhoneNumber: "Телефонен номер (за получатели от Полша, може да пропуснете въвеждането на код за населено място)",
|
||||
promosmsSMSSender: "SMS Подател име: Предварително регистрирано име или някое от имената по подразбиране: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
|
||||
"Feishu WebHookUrl": "Feishu URL адрес за уеб кука",
|
||||
matrixHomeserverURL: "Сървър URL адрес (започва с http(s):// и порт по желание)",
|
||||
"Internal Room Id": "ID на вътрешна стая",
|
||||
matrixDesc1: "Може да намерите \"ID на вътрешна стая\" в разширените настройки на стаята във вашия Matrix клиент. Примерен изглед: !QMdRCpUIfLwsfjxye6:home.server.",
|
||||
matrixDesc2: "Силно препоръчваме да създадете НОВ потребител и да НЕ използвате токен кодът на вашия личен Matrix потребирел, т.к. той позволява пълен достъп до вашия акаунт и всички стаи към които сте се присъединили. Вместо това създайте нов потребител и го поканете само в стаята, където желаете да получавате известията. Токен код за достъп ще получите изпълнявайки {0}",
|
||||
matrixDesc2: "Силно препоръчваме да създадете НОВ потребител и да НЕ използвате токен кодът на вашия личен Matrix потребител, т.к. той позволява пълен достъп до вашия акаунт и всички стаи към които сте се присъединили. Вместо това създайте нов потребител и го поканете само в стаята, където желаете да получавате известията. Токен код за достъп ще получите изпълнявайки {0}",
|
||||
Method: "Метод",
|
||||
Body: "Съобщение",
|
||||
Headers: "Хедъри",
|
||||
@@ -316,7 +316,7 @@ export default {
|
||||
Security: "Сигурност",
|
||||
"Steam API Key": "Steam API ключ",
|
||||
"Shrink Database": "Редуцирай базата данни",
|
||||
"Pick a RR-Type...": "Изберете вида на ресурсния запис за мониторитане...",
|
||||
"Pick a RR-Type...": "Изберете вида на ресурсния запис за мониториране...",
|
||||
"Pick Accepted Status Codes...": "Изберете статус кодове, които да се считат за успешен отговор...",
|
||||
Default: "По подразбиране",
|
||||
"HTTP Options": "HTTP Опции",
|
||||
@@ -375,12 +375,12 @@ export default {
|
||||
deleteStatusPageMsg: "Сигурни ли сте, че желаете да изтриете тази статус страница?",
|
||||
Proxies: "Прокси",
|
||||
default: "По подразбиране",
|
||||
enabled: "Включено",
|
||||
enabled: "Активирано",
|
||||
setAsDefault: "Зададен по подразбиране",
|
||||
deleteProxyMsg: "Сигурни ли сте, че желаете да изтриете това прокси за всички монитори?",
|
||||
proxyDescription: "За да функционират трябва да бъдат зададени към монитор.",
|
||||
enableProxyDescription: "Това прокси няма да има ефект върху заявките за мониторинг, докато не бъде активирано. Може да контролирате временното деактивиране на проксито от всички монитори чрез статуса на активиране.",
|
||||
setAsDefaultProxyDescription: "Това прокси ще бъде включено по подразбиране за новите монитори. Може да го изключите по отделно за всеки един монитор.",
|
||||
setAsDefaultProxyDescription: "Това прокси ще бъде активно по подразбиране за новите монитори. Може да го изключите по отделно за всеки един монитор.",
|
||||
"Certificate Chain": "Верига на сертификата",
|
||||
Valid: "Валиден",
|
||||
Invalid: "Невалиден",
|
||||
@@ -432,7 +432,7 @@ export default {
|
||||
Backup: "Архивиране",
|
||||
About: "Относно",
|
||||
wayToGetCloudflaredURL: "(Свалете \"cloudflared\" от {0})",
|
||||
cloudflareWebsite: "Cloudflare уебсайт",
|
||||
cloudflareWebsite: "Cloudflare уеб сайт",
|
||||
"Message:": "Съобщение:",
|
||||
"Don't know how to get the token? Please read the guide:": "Не знаете как да вземете токен? Моля, прочетете ръководството:",
|
||||
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "Текущата връзка може да прекъсне ако в момента сте свързани чрез \"Cloudflare Tunnel\". Сигурни ли сте, че желаете да го спрете? Въведете Вашата текуща парола за да потвърдите.",
|
||||
@@ -582,4 +582,72 @@ export default {
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "Отпаднало: Тъй като са добавени много функции, тази опция за архивиране не е достатъчно поддържана и не може да генерира или възстанови пълен архив.",
|
||||
backupRecommend: "Моля, архивирайте дяла или папката (./data/) директно вместо това.",
|
||||
Maintenance: "Поддръжка",
|
||||
statusMaintenance: "Поддръжка",
|
||||
"Schedule maintenance": "Планиране на поддръжка",
|
||||
"Affected Monitors": "Засегнати монитори",
|
||||
"Pick Affected Monitors...": "Изберете засегнати монитори...",
|
||||
"Start of maintenance": "Стартирай поддръжка",
|
||||
"All Status Pages": "Всички статус страници",
|
||||
"Select status pages...": "Изберете статус страници...",
|
||||
recurringIntervalMessage: "Изпълнявай ежедневно | Изпълнявай всеки {0} дни",
|
||||
affectedMonitorsDescription: "Изберете монитори, засегнати от текущата поддръжка",
|
||||
affectedStatusPages: "Покажи това съобщение за поддръжка на избрани статус страници",
|
||||
atLeastOneMonitor: "Изберете поне един засегнат монитор",
|
||||
deleteMaintenanceMsg: "Сигурни ли сте, че желаете да изтриете тази поддръжка?",
|
||||
Optional: "По желание",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "SMSManager API Документация ",
|
||||
"Gateway Type": "Тип на шлюза",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "Може да разделяте числата с",
|
||||
or: "или",
|
||||
recurringInterval: "Интервал",
|
||||
Recurring: "Повтаряне",
|
||||
strategyManual: "Активен/Неактивен ръчно",
|
||||
warningTimezone: "Използва се часовата зона на сървъра",
|
||||
weekdayShortMon: "Пон",
|
||||
weekdayShortTue: "Вт",
|
||||
weekdayShortWed: "Ср",
|
||||
weekdayShortThu: "Чет",
|
||||
weekdayShortFri: "Пет",
|
||||
weekdayShortSat: "Съб",
|
||||
weekdayShortSun: "Нед",
|
||||
dayOfWeek: "Ден",
|
||||
dayOfMonth: "Дата",
|
||||
lastDay: "Последен ден",
|
||||
lastDay1: "Последен ден от месеца",
|
||||
lastDay2: "2-ри последен ден на месеца",
|
||||
lastDay3: "3-ти последен ден на месеца",
|
||||
lastDay4: "4-ти последен ден на месеца",
|
||||
"No Maintenance": "Няма поддръжка",
|
||||
pauseMaintenanceMsg: "Сигурни ли сте, че желаете да направите пауза?",
|
||||
"maintenanceStatus-under-maintenance": "В режим поддръжка",
|
||||
"maintenanceStatus-inactive": "Неактивна",
|
||||
"maintenanceStatus-scheduled": "Планирана",
|
||||
"maintenanceStatus-ended": "Приключена",
|
||||
"maintenanceStatus-unknown": "Неизвестна",
|
||||
"Display Timezone": "Покажи часова зона",
|
||||
"Server Timezone": "Часова зона на сървъра",
|
||||
statusPageMaintenanceEndDate: "Край",
|
||||
enableGRPCTls: "Разреши изпращане на gRPC заявка с TLS връзка",
|
||||
grpcMethodDescription: "Името на метода се форматира в \"cammelCase\", например sayHello, check, и т.н.",
|
||||
smseagle: "SMSEagle",
|
||||
smseagleTo: "Тел. номер(а)",
|
||||
smseagleGroup: "Име на група/и от тел. указател",
|
||||
smseagleContact: "Име(на) от тел. указател",
|
||||
smseagleRecipientType: "Получател тип",
|
||||
smseagleRecipient: "Получател(и) (при повече от един разделете със запетая)",
|
||||
smseagleToken: "API токен за достъп",
|
||||
smseagleUrl: "Вашият SMSEagle URL на устройството",
|
||||
smseagleEncoding: "Изпрати като Unicode",
|
||||
smseaglePriority: "Приоритет на съобщението (0-9, по подразбиране = 0)",
|
||||
IconUrl: "Икона URL адрес",
|
||||
webhookAdditionalHeadersTitle: "Допълнителни хедъри",
|
||||
webhookAdditionalHeadersDesc: "Задава допълнителни хедъри, изпратени с уеб куката.",
|
||||
"Enable DNS Cache": "Активирай DNS кеширане",
|
||||
Enable: "Активирай",
|
||||
Disable: "Деактивирай",
|
||||
dnsCacheDescription: "Възможно е да не работи в IPv6 среда - деактивирайте, ако срещнете проблеми.",
|
||||
};
|
||||
|
634
src/languages/de-CH.js
Normal file
634
src/languages/de-CH.js
Normal file
@@ -0,0 +1,634 @@
|
||||
export default {
|
||||
languageName: "Deutsch (Schweiz)",
|
||||
Settings: "Einstellungen",
|
||||
Dashboard: "Dashboard",
|
||||
"New Update": "Update verfügbar",
|
||||
Language: "Sprache",
|
||||
Appearance: "Erscheinungsbild",
|
||||
Theme: "Erscheinungsbild",
|
||||
General: "Allgemein",
|
||||
Version: "Version",
|
||||
"Check Update On GitHub": "Auf GitHub nach Updates suchen",
|
||||
List: "Liste",
|
||||
Add: "Hinzufügen",
|
||||
"Add New Monitor": "Neuen Monitor hinzufügen",
|
||||
"Quick Stats": "Übersicht",
|
||||
Up: "Aktiv",
|
||||
Down: "Inaktiv",
|
||||
Pending: "Ausstehend",
|
||||
Unknown: "Unbekannt",
|
||||
Pause: "Pausieren",
|
||||
pauseDashboardHome: "Pausiert",
|
||||
Name: "Name",
|
||||
Status: "Status",
|
||||
DateTime: "Datum / Uhrzeit",
|
||||
Message: "Nachricht",
|
||||
"No important events": "Keine wichtigen Ereignisse",
|
||||
Resume: "Fortsetzen",
|
||||
Edit: "Bearbeiten",
|
||||
Delete: "Löschen",
|
||||
Current: "Aktuell",
|
||||
Uptime: "Verfügbarkeit",
|
||||
"Cert Exp.": "Zertifikatsablauf",
|
||||
day: "Tag | Tage",
|
||||
"-day": "-Tage",
|
||||
hour: "Stunde",
|
||||
"-hour": "-Stunden",
|
||||
checkEverySecond: "Überprüfe alle {0} Sekunden",
|
||||
Response: "Antwortzeit",
|
||||
Ping: "Ping",
|
||||
"Monitor Type": "Monitor-Typ",
|
||||
Keyword: "Suchwort",
|
||||
"Friendly Name": "Anzeigename",
|
||||
URL: "URL",
|
||||
Hostname: "Hostname",
|
||||
Port: "Port",
|
||||
"Heartbeat Interval": "Prüfintervall",
|
||||
Retries: "Wiederholungen",
|
||||
retriesDescription: "Maximale Anzahl von Wiederholungen, bevor der Dienst als inaktiv markiert und eine Benachrichtigung gesendet wird.",
|
||||
Advanced: "Erweitert",
|
||||
ignoreTLSError: "Ignoriere TLS-/SSL-Fehler von Webseiten",
|
||||
"Upside Down Mode": "Umgekehrter Modus",
|
||||
upsideDownModeDescription: "Im umgekehrten Modus wird der Dienst als inaktiv angezeigt, wenn er erreichbar ist.",
|
||||
"Max. Redirects": "Max. Weiterleitungen",
|
||||
maxRedirectDescription: "Maximale Anzahl von Weiterleitungen, denen gefolgt werden soll. Auf 0 setzen, um Weiterleitungen zu deaktivieren.",
|
||||
"Accepted Status Codes": "Erlaubte HTTP-Statuscodes",
|
||||
acceptedStatusCodesDescription: "Statuscodes auswählen, die als erfolgreiche Verbindung gelten sollen.",
|
||||
Save: "Speichern",
|
||||
Notifications: "Benachrichtigungen",
|
||||
"Not available, please setup.": "Nicht verfügbar, bitte einrichten.",
|
||||
"Setup Notification": "Benachrichtigung einrichten",
|
||||
Light: "Hell",
|
||||
Dark: "Dunkel",
|
||||
Auto: "Auto",
|
||||
"Theme - Heartbeat Bar": "Erscheinungsbild - Zeitleiste",
|
||||
Normal: "Normal",
|
||||
Bottom: "Unten",
|
||||
None: "Keine",
|
||||
Timezone: "Zeitzone",
|
||||
"Search Engine Visibility": "Sichtbarkeit für Suchmaschinen",
|
||||
"Allow indexing": "Indizierung zulassen",
|
||||
"Discourage search engines from indexing site": "Suchmaschinen darum bitten, die Seite nicht zu indizieren",
|
||||
"Change Password": "Passwort ändern",
|
||||
"Current Password": "Aktuelles Passwort",
|
||||
"New Password": "Neues Passwort",
|
||||
"Repeat New Password": "Neues Passwort wiederholen",
|
||||
passwordNotMatchMsg: "Passwörter stimmen nicht überein.",
|
||||
"Update Password": "Passwort aktualisieren",
|
||||
"Disable Auth": "Authentifizierung deaktivieren",
|
||||
"Enable Auth": "Authentifizierung aktivieren",
|
||||
"disableauth.message1": "Bist du sicher das du die <strong>Authentifizierung deaktivieren</strong> möchtest?",
|
||||
"disableauth.message2": "Dies ist für Szenarien gedacht, <strong>in denen man eine externe Authentifizierung</strong> vor Uptime Kuma geschaltet hat, wie z.B. Cloudflare Access, Authelia oder andere Authentifizierungsmechanismen.",
|
||||
"Please use this option carefully!": "Bitte mit Vorsicht nutzen.",
|
||||
Logout: "Ausloggen",
|
||||
notificationDescription: "Benachrichtigungen müssen einem Monitor zugewiesen werden, damit diese funktionieren.",
|
||||
Leave: "Verlassen",
|
||||
"I understand, please disable": "Ich verstehe, bitte deaktivieren",
|
||||
Confirm: "Bestätigen",
|
||||
Yes: "Ja",
|
||||
No: "Nein",
|
||||
Username: "Benutzername",
|
||||
Password: "Passwort",
|
||||
"Remember me": "Angemeldet bleiben",
|
||||
Login: "Einloggen",
|
||||
"No Monitors, please": "Keine Monitore, bitte",
|
||||
"add one": "hinzufügen",
|
||||
"Notification Type": "Benachrichtigungsdienst",
|
||||
Email: "E-Mail",
|
||||
Test: "Test",
|
||||
"Certificate Info": "Zertifikatsinformation",
|
||||
keywordDescription: "Ein Suchwort in der HTML- oder JSON-Ausgabe finden. Bitte beachte: es wird zwischen Gross-/Kleinschreibung unterschieden.",
|
||||
deleteMonitorMsg: "Bist du sicher, dass du den Monitor löschen möchtest?",
|
||||
deleteNotificationMsg: "Möchtest du diese Benachrichtigung wirklich für alle Monitore löschen?",
|
||||
resolverserverDescription: "Cloudflare ist als der Standardserver festgelegt. Dieser kann jederzeit geändert werden.",
|
||||
"Resolver Server": "Auflösungsserver",
|
||||
rrtypeDescription: "Wähle den RR-Typ aus, welchen du überwachen möchtest.",
|
||||
"Last Result": "Letztes Ergebnis",
|
||||
pauseMonitorMsg: "Bist du sicher, dass du den Monitor pausieren möchtest?",
|
||||
clearEventsMsg: "Bist du sicher, dass du alle Ereignisse für diesen Monitor löschen möchtest?",
|
||||
clearHeartbeatsMsg: "Bist du sicher, dass du alle Statistiken für diesen Monitor löschen möchtest?",
|
||||
"Clear Data": "Lösche Daten",
|
||||
Events: "Ereignisse",
|
||||
Heartbeats: "Statistiken",
|
||||
confirmClearStatisticsMsg: "Bist du dir sicher, dass du ALLE Statistiken löschen möchtest?",
|
||||
"Create your admin account": "Erstelle dein Admin-Konto",
|
||||
"Repeat Password": "Passwort erneut eingeben",
|
||||
"Resource Record Type": "Ressourcen Record Typ",
|
||||
Export: "Export",
|
||||
Import: "Import",
|
||||
respTime: "Antw.-Zeit (ms)",
|
||||
notAvailableShort: "N/A",
|
||||
"Default enabled": "Standardmässig aktiviert",
|
||||
"Apply on all existing monitors": "Auf alle existierenden Monitore anwenden",
|
||||
enableDefaultNotificationDescription: "Für jeden neuen Monitor wird diese Benachrichtigung standardmässig aktiviert. Die Benachrichtigung kann weiterhin für jeden Monitor separat deaktiviert werden.",
|
||||
Create: "Erstellen",
|
||||
"Auto Get": "Auto Get",
|
||||
backupDescription: "Es können alle Monitore und Benachrichtigungen in einer JSON-Datei gesichert werden.",
|
||||
backupDescription2: "PS: Verlaufs- und Ereignisdaten sind nicht enthalten.",
|
||||
backupDescription3: "Sensible Daten wie Benachrichtigungs-Token sind in der Exportdatei enthalten, bitte bewahre sie sorgfältig auf.",
|
||||
alertNoFile: "Bitte wähle eine Datei zum Importieren aus.",
|
||||
alertWrongFileType: "Bitte wähle eine JSON-Datei aus.",
|
||||
"Clear all statistics": "Lösche alle Statistiken",
|
||||
importHandleDescription: "Wähle 'Vorhandene überspringen' aus, wenn jeder Monitor oder jede Benachrichtigung mit demselben Namen übersprungen werden soll. 'Überschreiben' löscht jeden vorhandenen Monitor sowie Benachrichtigungen.",
|
||||
"Skip existing": "Vorhandene überspringen",
|
||||
Overwrite: "Überschreiben",
|
||||
Options: "Optionen",
|
||||
confirmImportMsg: "Möchtest du das Backup wirklich importieren? Bitte stelle sicher, dass die richtige Import-Option ausgewählt ist.",
|
||||
"Keep both": "Beide behalten",
|
||||
twoFAVerifyLabel: "Bitte trage deinen Token ein, um zu verifizieren, dass 2FA funktioniert",
|
||||
"Verify Token": "Token verifizieren",
|
||||
"Setup 2FA": "2FA einrichten",
|
||||
"Enable 2FA": "2FA aktivieren",
|
||||
"Disable 2FA": "2FA deaktivieren",
|
||||
"2FA Settings": "2FA-Einstellungen",
|
||||
confirmEnableTwoFAMsg: "Bist du sicher, dass du 2FA aktivieren möchtest?",
|
||||
confirmDisableTwoFAMsg: "Bist du sicher, dass du 2FA deaktivieren möchtest?",
|
||||
tokenValidSettingsMsg: "Token gültig! Du kannst jetzt die 2FA-Einstellungen speichern.",
|
||||
"Two Factor Authentication": "Zwei-Faktor-Authentifizierung",
|
||||
Active: "Aktiv",
|
||||
Inactive: "Inaktiv",
|
||||
Token: "Token",
|
||||
"Show URI": "URI anzeigen",
|
||||
Tags: "Tags",
|
||||
"Add New below or Select...": "Einen bestehenden Tag auswählen oder neuen hinzufügen...",
|
||||
"Tag with this name already exist.": "Ein Tag mit diesem Namen existiert bereits.",
|
||||
"Tag with this value already exist.": "Ein Tag mit diesem Wert existiert bereits.",
|
||||
color: "Farbe",
|
||||
"value (optional)": "Wert (optional)",
|
||||
Gray: "Grau",
|
||||
Red: "Rot",
|
||||
Orange: "Orange",
|
||||
Green: "Grün",
|
||||
Blue: "Blau",
|
||||
Indigo: "Indigo",
|
||||
Purple: "Lila",
|
||||
Pink: "Pink",
|
||||
"Search...": "Suchen...",
|
||||
"Heartbeat Retry Interval": "Überprüfungsintervall",
|
||||
"Resend Notification if Down X times consequently": "Benachrichtigung erneut senden, wenn Inaktiv X mal hintereinander",
|
||||
retryCheckEverySecond: "Alle {0} Sekunden neu versuchen",
|
||||
resendEveryXTimes: "Erneut versenden alle {0} mal",
|
||||
resendDisabled: "Erneut versenden deaktiviert",
|
||||
"Import Backup": "Backup importieren",
|
||||
"Export Backup": "Backup exportieren",
|
||||
"Avg. Ping": "Ping ø",
|
||||
"Avg. Response": "Antwortzeit ø",
|
||||
"Entry Page": "Einstiegsseite",
|
||||
statusPageNothing: "Noch ist hier nichts. Bitte füge eine Gruppe oder einen Monitor hinzu.",
|
||||
"No Services": "Keine Dienste",
|
||||
"All Systems Operational": "Alle Systeme betriebsbereit",
|
||||
"Partially Degraded Service": "Teilweise beeinträchtigter Dienst",
|
||||
"Degraded Service": "Eingeschränkter Dienst",
|
||||
"Add Group": "Gruppe hinzufügen",
|
||||
"Add a monitor": "Monitor hinzufügen",
|
||||
"Edit Status Page": "Bearbeite Status-Seite",
|
||||
"Go to Dashboard": "Gehe zum Dashboard",
|
||||
"Status Page": "Status-Seite",
|
||||
"Status Pages": "Status-Seiten",
|
||||
telegram: "Telegram",
|
||||
webhook: "Webhook",
|
||||
smtp: "E-Mail (SMTP)",
|
||||
discord: "Discord",
|
||||
teams: "Microsoft Teams",
|
||||
signal: "Signal",
|
||||
gotify: "Gotify",
|
||||
slack: "Slack",
|
||||
"rocket.chat": "Rocket.chat",
|
||||
pushover: "Pushover",
|
||||
pushy: "Pushy",
|
||||
octopush: "Octopush",
|
||||
promosms: "PromoSMS",
|
||||
lunasea: "LunaSea",
|
||||
apprise: "Apprise (Unterstützung für 50+ Benachrichtigungsdienste)",
|
||||
GoogleChat: "Google Chat (nur Google Workspace)",
|
||||
pushbullet: "Pushbullet",
|
||||
line: "Line Messenger",
|
||||
mattermost: "Mattermost",
|
||||
"Primary Base URL": "Primär URL",
|
||||
"Push URL": "Push URL",
|
||||
needPushEvery: "Du solltest diese URL alle {0} Sekunden aufrufen",
|
||||
pushOptionalParams: "Optionale Parameter: {0}",
|
||||
defaultNotificationName: "Mein {notification} Alarm ({number})",
|
||||
here: "hier",
|
||||
Required: "Erforderlich",
|
||||
"Bot Token": "Bot Token",
|
||||
wayToGetTelegramToken: "Hier kannst du einen Token erhalten {0}.",
|
||||
"Chat ID": "Chat ID",
|
||||
supportTelegramChatID: "Unterstützt Direkt Chat / Gruppe / Kanal Chat-ID's",
|
||||
wayToGetTelegramChatID: "Du kannst die Chat-ID erhalten, indem du eine Nachricht an den Bot sendest und zu dieser URL gehst, um die chat_id: zu sehen.",
|
||||
"YOUR BOT TOKEN HERE": "HIER DEIN BOT TOKEN",
|
||||
chatIDNotFound: "Chat-ID wurde nicht gefunden: bitte sende zuerst eine Nachricht an diesen Bot",
|
||||
"Post URL": "Post URL",
|
||||
"Content Type": "Content Type",
|
||||
webhookJsonDesc: "{0} ist gut für alle modernen HTTP-Server, wie z.B. Express.js, geeignet",
|
||||
webhookFormDataDesc: "{multipart} ist gut für PHP. Das JSON muss mit {decodeFunction} verarbeitet werden",
|
||||
secureOptionNone: "Keine / STARTTLS (25, 587)",
|
||||
secureOptionTLS: "TLS (465)",
|
||||
"Ignore TLS Error": "TLS-Fehler ignorieren",
|
||||
"From Email": "Absender E-Mail",
|
||||
emailCustomSubject: "Benutzerdefinierter Betreff",
|
||||
"To Email": "Empfänger E-Mail",
|
||||
smtpCC: "CC",
|
||||
smtpBCC: "BCC",
|
||||
"Discord Webhook URL": "Discord Webhook URL",
|
||||
wayToGetDiscordURL: "Du kannst diese erhalten, indem du zu den Servereinstellungen gehst -> Integrationen -> Neuer Webhook",
|
||||
"Bot Display Name": "Bot-Anzeigename",
|
||||
"Prefix Custom Message": "Benutzerdefinierter Nachrichten Präfix",
|
||||
"Hello @everyone is...": "Hallo {'@'}everyone ist...",
|
||||
"Webhook URL": "Webhook URL",
|
||||
wayToGetTeamsURL: "Wie eine Webhook-URL erstellt werden kann, erfährst du {0}.",
|
||||
Number: "Nummer",
|
||||
Recipients: "Empfänger",
|
||||
needSignalAPI: "Es wird ein Signal Client mit REST-API benötigt.",
|
||||
wayToCheckSignalURL: "Du kannst diese URL aufrufen, um zu sehen, wie du eine einrichtest:",
|
||||
signalImportant: "WICHTIG: Gruppen und Nummern können in Empfängern nicht gemischt werden!",
|
||||
"Application Token": "Anwendungstoken",
|
||||
"Server URL": "Server URL",
|
||||
Priority: "Priorität",
|
||||
"Icon Emoji": "Icon Emoji",
|
||||
"Channel Name": "Kanalname",
|
||||
"Uptime Kuma URL": "Uptime Kuma URL",
|
||||
aboutWebhooks: "Weitere Informationen zu Webhooks auf: {0}",
|
||||
aboutChannelName: "Gebe den Kanalnamen ein in {0} Feld Kanalname, falls du den Webhook-Kanal umgehen möchtest. Ex: #other-channel",
|
||||
aboutKumaURL: "Wenn das Feld für die Uptime Kuma URL leer gelassen wird, wird standardmässig die GitHub Projekt Seite verwendet.",
|
||||
emojiCheatSheet: "Emoji Cheat Sheet: {0}",
|
||||
"User Key": "Benutzerschlüssel",
|
||||
Device: "Gerät",
|
||||
"Message Title": "Nachrichtentitel",
|
||||
"Notification Sound": "Benachrichtigungston",
|
||||
"More info on:": "Mehr Infos auf: {0}",
|
||||
pushoverDesc1: "Notfallpriorität (2) hat standardmässig 30 Sekunden Auszeit zwischen den Versuchen und läuft nach 1 Stunde ab.",
|
||||
pushoverDesc2: "Fülle das Geräte Feld aus, wenn du Benachrichtigungen an verschiedene Geräte senden möchtest.",
|
||||
"SMS Type": "SMS Typ",
|
||||
octopushTypePremium: "Premium (Schnell - zur Benachrichtigung empfohlen)",
|
||||
octopushTypeLowCost: "Kostengünstig (Langsam - manchmal vom Betreiber gesperrt)",
|
||||
checkPrice: "Prüfe {0} Preise:",
|
||||
octopushLegacyHint: "Verwendest du die Legacy-Version von Octopush (2011-2020) oder die neue Version?",
|
||||
"Check octopush prices": "Vergleiche die Oktopush Preise {0}.",
|
||||
octopushPhoneNumber: "Telefonnummer (Internationales Format, z.B : +49612345678) ",
|
||||
octopushSMSSender: "Name des SMS-Absenders : 3-11 alphanumerische Zeichen und Leerzeichen (a-zA-Z0-9)",
|
||||
"LunaSea Device ID": "LunaSea Geräte ID",
|
||||
"Apprise URL": "Apprise URL",
|
||||
"Example:": "Beispiel: {0}",
|
||||
"Read more:": "Weiterlesen: {0}",
|
||||
"Status:": "Status: {0}",
|
||||
"Read more": "Weiterlesen",
|
||||
appriseInstalled: "Apprise ist installiert.",
|
||||
appriseNotInstalled: "Apprise ist nicht installiert. {0}",
|
||||
"Access Token": "Access Token",
|
||||
"Channel access token": "Channel access token",
|
||||
"Line Developers Console": "Line Developers Console",
|
||||
lineDevConsoleTo: "Line Developers Console - {0}",
|
||||
"Basic Settings": "Basic Settings",
|
||||
"User ID": "User ID",
|
||||
"Messaging API": "Messaging API",
|
||||
wayToGetLineChannelToken: "Rufe zuerst {0} auf, erstelle dann einen Provider und Channel (Messaging API). Als nächstes kannst du den Channel access token und die User ID aus den oben genannten Menüpunkten abrufen.",
|
||||
"Icon URL": "Icon URL",
|
||||
aboutIconURL: "Du kannst einen Link zu einem Bild in 'Icon URL' übergeben um das Standardprofilbild zu überschreiben. Wird nicht verwendet, wenn ein Icon Emoji gesetzt ist.",
|
||||
aboutMattermostChannelName: "Du kannst den Standardkanal, auf dem der Webhook gesendet wird überschreiben, indem der Kanalnamen in das Feld 'Channel Name' eingeben wird. Dies muss in den Mattermost Webhook-Einstellungen aktiviert werden. Ex: #other-channel",
|
||||
matrix: "Matrix",
|
||||
promosmsTypeEco: "SMS ECO - billig, aber langsam und oft überladen. Auf polnische Empfänger beschränkt.",
|
||||
promosmsTypeFlash: "SMS FLASH - Die Nachricht wird automatisch auf dem Empfängergerät angezeigt. Auf polnische Empfänger beschränkt.",
|
||||
promosmsTypeFull: "SMS FULL - Premium Stufe von SMS, es kann der Absendernamen verwendet werden (Der Name musst zuerst registriert werden). Zuverlässig für Warnungen.",
|
||||
promosmsTypeSpeed: "SMS SPEED - Höchste Priorität im System. Sehr schnell und zuverlässig, aber teuer (Ungefähr das doppelte von SMS FULL).",
|
||||
promosmsPhoneNumber: "Telefonnummer (für polnische Empfänger können die Vorwahlen übersprungen werden)",
|
||||
promosmsSMSSender: "Name des SMS-Absenders : vorregistrierter Name oder einer der Standardwerte: InfoSMS, SMS Info, MaxSMS, INFO, SMS",
|
||||
"Feishu WebHookUrl": "Feishu Webhook URL",
|
||||
matrixHomeserverURL: "Heimserver URL (mit http(s):// und optionalen Ports)",
|
||||
"Internal Room Id": "Interne Raum-ID",
|
||||
matrixDesc1: "Die interne Raum-ID findest du im erweiterten Bereich der Raumeinstellungen im Matrix-Client. Es sollte aussehen wie z.B. !QMdRCpUIfLwsfjxye6:home.server.",
|
||||
matrixDesc2: "Es wird dringend empfohlen einen neuen Benutzer anzulegen und nicht den Zugriffstoken deines eigenen Matrix-Benutzers zu verwenden. Anderenfalls ermöglicht es vollen Zugriff auf dein Konto und alle Räume, denen du beigetreten bist. Erstelle stattdessen einen neuen Benutzer und lade ihn nur in den Raum ein, in dem du die Benachrichtigung erhalten möchtest. Du kannst den Zugriffstoken erhalten, indem du Folgendes ausführst {0}",
|
||||
Method: "Method",
|
||||
Body: "Body",
|
||||
Headers: "Headers",
|
||||
PushUrl: "Push URL",
|
||||
HeadersInvalidFormat: "Der Header ist kein gültiges JSON: ",
|
||||
BodyInvalidFormat: "Der Body ist kein gültiges JSON: ",
|
||||
"Monitor History": "Monitor Verlauf",
|
||||
clearDataOlderThan: "Bewahre die Aufzeichnungsdaten für {0} Tage auf.",
|
||||
PasswordsDoNotMatch: "Passwörter stimmen nicht überein.",
|
||||
records: "Einträge",
|
||||
"One record": "Ein Eintrag",
|
||||
steamApiKeyDescription: "Um einen Steam Game Server zu überwachen, wird ein Steam Web-API-Schlüssel benötigt. Dieser kann hier registriert werden: ",
|
||||
"Current User": "Aktueller Benutzer",
|
||||
recent: "Letzte",
|
||||
Done: "Fertig",
|
||||
Info: "Info",
|
||||
Security: "Sicherheit",
|
||||
"Steam API Key": "Steam API Key",
|
||||
"Shrink Database": "Datenbank verkleinern",
|
||||
"Pick a RR-Type...": "Wähle ein RR-Typ aus...",
|
||||
"Pick Accepted Status Codes...": "Wähle akzeptierte Statuscodes aus...",
|
||||
Default: "Standard",
|
||||
"HTTP Options": "HTTP Optionen",
|
||||
"Create Incident": "Vorfall erstellen",
|
||||
Title: "Titel",
|
||||
Content: "Inhalt",
|
||||
Style: "Stil",
|
||||
info: "info",
|
||||
warning: "warnung",
|
||||
danger: "gefahr",
|
||||
primary: "primär",
|
||||
light: "hell",
|
||||
dark: "dunkel",
|
||||
Post: "Eintrag",
|
||||
"Please input title and content": "Bitte Titel und Inhalt eingeben",
|
||||
Created: "Erstellt",
|
||||
"Last Updated": "Zuletzt aktualisiert",
|
||||
Unpin: "Loslösen",
|
||||
"Switch to Light Theme": "Zu hellem Thema wechseln",
|
||||
"Switch to Dark Theme": "Zum dunklen Thema wechseln",
|
||||
"Show Tags": "Tags anzeigen",
|
||||
"Hide Tags": "Tags ausblenden",
|
||||
Description: "Beschreibung",
|
||||
"No monitors available.": "Keine Monitore verfügbar.",
|
||||
"Add one": "Hinzufügen",
|
||||
"No Monitors": "Keine Monitore",
|
||||
"Untitled Group": "Gruppe ohne Titel",
|
||||
Services: "Dienste",
|
||||
Discard: "Verwerfen",
|
||||
Cancel: "Abbrechen",
|
||||
"Powered by": "Powered by",
|
||||
shrinkDatabaseDescription: "Löse VACUUM für die SQLite Datenbank aus. Wenn die Datenbank nach 1.10.0 erstellt wurde, ist AUTO_VACUUM bereits aktiviert und diese Aktion ist nicht erforderlich.",
|
||||
serwersms: "SerwerSMS.pl",
|
||||
serwersmsAPIUser: "API Benutzername (inkl. webapi_ prefix)",
|
||||
serwersmsAPIPassword: "API Passwort",
|
||||
serwersmsPhoneNumber: "Telefonnummer",
|
||||
serwersmsSenderName: "Name des SMS-Absenders (über Kundenportal registriert)",
|
||||
stackfield: "Stackfield",
|
||||
clicksendsms: "ClickSend SMS",
|
||||
apiCredentials: "API Zugangsdaten",
|
||||
smtpDkimSettings: "DKIM Einstellungen",
|
||||
smtpDkimDesc: "Details zur Konfiguration sind in der Nodemailer DKIM {0} zu finden.",
|
||||
documentation: "Dokumentation",
|
||||
smtpDkimDomain: "Domain Name",
|
||||
smtpDkimKeySelector: "Schlüssel Auswahl",
|
||||
smtpDkimPrivateKey: "Privater Schlüssel",
|
||||
smtpDkimHashAlgo: "Hash-Algorithmus (Optional)",
|
||||
smtpDkimheaderFieldNames: "Zu validierende Header-Schlüssel (optional)",
|
||||
smtpDkimskipFields: "Zu ignorierende Header Schlüssel (optional)",
|
||||
PushByTechulus: "Push by Techulus",
|
||||
gorush: "Gorush",
|
||||
alerta: "Alerta",
|
||||
alertaApiEndpoint: "API Endpunkt",
|
||||
alertaEnvironment: "Umgebung",
|
||||
alertaApiKey: "API Schlüssel",
|
||||
alertaAlertState: "Alarmstatus",
|
||||
alertaRecoverState: "Wiederherstellungsstatus",
|
||||
deleteStatusPageMsg: "Bist du sicher, dass du diese Status-Seite löschen willst?",
|
||||
Proxies: "Proxies",
|
||||
default: "Standard",
|
||||
enabled: "Aktiviert",
|
||||
setAsDefault: "Als Standard setzen",
|
||||
deleteProxyMsg: "Bist du sicher, dass du diesen Proxy für alle Monitore löschen willst?",
|
||||
proxyDescription: "Proxies müssen einem Monitor zugewiesen werden, um zu funktionieren.",
|
||||
enableProxyDescription: "Dieser Proxy wird keinen Effekt auf Monitor-Anfragen haben, bis er aktiviert ist. Du kannst ihn temporär von allen Monitoren nach Aktivierungsstatus deaktivieren.",
|
||||
setAsDefaultProxyDescription: "Dieser Proxy wird standardmässig für alle neuen Monitore aktiviert sein. Du kannst den Proxy immer noch für jeden Monitor einzeln deaktivieren.",
|
||||
"Certificate Chain": "Zertifikatskette",
|
||||
Valid: "Gültig",
|
||||
Invalid: "Ungültig",
|
||||
AccessKeyId: "AccessKey ID",
|
||||
SecretAccessKey: "AccessKey Secret",
|
||||
PhoneNumbers: "Telefonnummern",
|
||||
TemplateCode: "Vorlagencode",
|
||||
SignName: "Signaturname",
|
||||
"Sms template must contain parameters: ": "SMS Vorlage muss folgende Parameter enthalten: ",
|
||||
"Bark Endpoint": "Bark Endpunkt",
|
||||
WebHookUrl: "Webhook URL",
|
||||
SecretKey: "Geheimer Schlüssel",
|
||||
"For safety, must use secret key": "Zur Sicherheit muss ein geheimer Schlüssel verwendet werden",
|
||||
"Device Token": "Gerätetoken",
|
||||
Platform: "Platform",
|
||||
iOS: "iOS",
|
||||
Android: "Android",
|
||||
Huawei: "Huawei",
|
||||
High: "Hoch",
|
||||
Retry: "Wiederholungen",
|
||||
Topic: "Thema",
|
||||
"WeCom Bot Key": "WeCom Bot Schlüssel",
|
||||
"Setup Proxy": "Proxy einrichten",
|
||||
"Proxy Protocol": "Proxy Protokoll",
|
||||
"Proxy Server": "Proxy-Server",
|
||||
"Proxy server has authentication": "Proxy-Server hat Authentifizierung",
|
||||
User: "Benutzer",
|
||||
Installed: "Installiert",
|
||||
"Not installed": "Nicht installiert",
|
||||
Running: "Läuft",
|
||||
"Not running": "Gestoppt",
|
||||
"Remove Token": "Token entfernen",
|
||||
Start: "Start",
|
||||
Stop: "Stop",
|
||||
"Uptime Kuma": "Uptime Kuma",
|
||||
"Add New Status Page": "Neue Status-Seite hinzufügen",
|
||||
Slug: "Slug",
|
||||
"Accept characters:": "Akzeptierte Zeichen:",
|
||||
startOrEndWithOnly: "Nur mit {0} anfangen und enden",
|
||||
"No consecutive dashes": "Keine aufeinanderfolgenden Bindestriche",
|
||||
Next: "Weiter",
|
||||
"The slug is already taken. Please choose another slug.": "Der Slug ist bereits in Verwendung. Bitte wähle einen anderen.",
|
||||
"No Proxy": "Kein Proxy",
|
||||
Authentication: "Authentifizierung",
|
||||
"HTTP Basic Auth": "HTTP Basisauthentifizierung",
|
||||
"New Status Page": "Neue Status-Seite",
|
||||
"Page Not Found": "Seite nicht gefunden",
|
||||
"Reverse Proxy": "Reverse Proxy",
|
||||
Backup: "Sicherung",
|
||||
About: "Über",
|
||||
wayToGetCloudflaredURL: "(Lade Cloudflare von {0} herunter)",
|
||||
cloudflareWebsite: "Cloudflare Website",
|
||||
"Message:": "Nachricht:",
|
||||
"Don't know how to get the token? Please read the guide:": "Du weisst nicht, wie man den Token bekommt? Lies die Anleitung dazu:",
|
||||
"The current connection may be lost if you are currently connecting via Cloudflare Tunnel. Are you sure want to stop it? Type your current password to confirm it.": "Die aktuelle Verbindung kann unterbrochen werden, wenn du aktuell über Cloudflare Tunnel verbunden bist. Bist du sicher, dass du es stoppen willst? Gib zur Bestätigung dein aktuelles Passwort ein.",
|
||||
"Other Software": "Andere Software",
|
||||
"For example: nginx, Apache and Traefik.": "Zum Beispiel: nginx, Apache und Traefik.",
|
||||
"Please read": "Bitte lesen",
|
||||
"Subject:": "Betreff:",
|
||||
"Valid To:": "Gültig bis:",
|
||||
"Days Remaining:": "Tage verbleibend:",
|
||||
"Issuer:": "Aussteller:",
|
||||
"Fingerprint:": "Fingerabdruck:",
|
||||
"No status pages": "Keine Status-Seiten",
|
||||
"Domain Name Expiry Notification": "Benachrichtigung bei Ablauf des Domainnamens",
|
||||
Customize: "Anpassen",
|
||||
"Custom Footer": "Eigener Footer",
|
||||
"Custom CSS": "Eigenes CSS",
|
||||
"Footer Text": "Fusszeile",
|
||||
"Show Powered By": "Zeige 'Powered By'",
|
||||
"Date Created": "Erstellt am",
|
||||
"Domain Names": "Domainnamen",
|
||||
signedInDisp: "Angemeldet als {0}",
|
||||
signedInDispDisabled: "Authentifizierung deaktiviert.",
|
||||
dnsPortDescription: "DNS server port. Standard ist 53. Der Port kann jederzeit geändert werden.",
|
||||
topic: "Thema",
|
||||
topicExplanation: "MQTT Thema für den monitor",
|
||||
successMessage: "Erfolgsnachricht",
|
||||
successMessageExplanation: "MQTT Nachricht, die als Erfolg angesehen wird",
|
||||
error: "Fehler",
|
||||
critical: "kritisch",
|
||||
wayToGetPagerDutyKey: "Dieser kann unter Service -> Service Directory -> (Select a service) -> Integrations -> Add integration gefunden werden. Hier muss nach \"Events API V2\" gesucht werden. Mehr informationen {0}",
|
||||
"Integration Key": "Schlüssel der Integration",
|
||||
"Integration URL": "URL der Integration",
|
||||
"Auto resolve or acknowledged": "Automatisch lösen oder bestätigen",
|
||||
"do nothing": "nichts tun",
|
||||
"auto acknowledged": "automatisch bestätigen",
|
||||
"auto resolve": "automatisch lösen",
|
||||
"Bark Group": "Bark Gruppe",
|
||||
"Bark Sound": "Bark Klang",
|
||||
"HTTP Headers": "HTTP Kopfzeilen",
|
||||
"Trust Proxy": "Vertrauenswürdiger Proxy",
|
||||
Proxy: "Proxy",
|
||||
HomeAssistant: "Home Assistant",
|
||||
onebotHttpAddress: "OneBot HTTP Adresse",
|
||||
onebotMessageType: "OneBot Nachrichtentyp",
|
||||
onebotGroupMessage: "Gruppe",
|
||||
onebotPrivateMessage: "Privat",
|
||||
onebotUserOrGroupId: "Gruppe/Nutzer ID",
|
||||
onebotSafetyTips: "Zur Sicherheit ein access token setzen",
|
||||
"PushDeer Key": "PushDeer Schlüssel",
|
||||
RadiusSecret: "Radius Geheimnis",
|
||||
RadiusSecretDescription: "Geteiltes Geheimnis zwischen Client und Server",
|
||||
RadiusCalledStationId: "ID der angesprochenen Station",
|
||||
RadiusCalledStationIdDescription: "Identifikation des angesprochenen Geräts",
|
||||
RadiusCallingStationId: "ID der ansprechenden Station",
|
||||
RadiusCallingStationIdDescription: "Identifikation des ansprechenden Geräts",
|
||||
"Certificate Expiry Notification": "Benachrichtigung ablaufendes Zertifikat",
|
||||
"API Username": "API Nutzername",
|
||||
"API Key": "API Schlüssel",
|
||||
"Recipient Number": "Empfängernummer",
|
||||
"From Name/Number": "Von Name/Nummer",
|
||||
"Leave blank to use a shared sender number.": "Leer lassen um eine geteilte Absendernummer zu nutzen.",
|
||||
"Octopush API Version": "Octopush API Version",
|
||||
"Legacy Octopush-DM": "Legacy Octopush-DM",
|
||||
endpoint: "Endpunkt",
|
||||
octopushAPIKey: "\"API Schlüssel\" der HTTP API Zugangsdaten im control panel",
|
||||
octopushLogin: "\"Login\" der HTTP API Zugangsdaten im control panel",
|
||||
promosmsLogin: "API Login Name",
|
||||
promosmsPassword: "API Password",
|
||||
"pushoversounds pushover": "Pushover (Standard)",
|
||||
"pushoversounds bike": "Fahrrad",
|
||||
"pushoversounds bugle": "Signalhorn",
|
||||
"pushoversounds cashregister": "Kasse",
|
||||
"pushoversounds classical": "Klassisch",
|
||||
"pushoversounds cosmic": "Kosmisch",
|
||||
"pushoversounds falling": "Abfallend",
|
||||
"pushoversounds gamelan": "Gamelan",
|
||||
"pushoversounds incoming": "Eingang",
|
||||
"pushoversounds intermission": "Pause",
|
||||
"pushoversounds magic": "Magisch",
|
||||
"pushoversounds mechanical": "Mechanisch",
|
||||
"pushoversounds pianobar": "Piano Bar",
|
||||
"pushoversounds siren": "Sirene",
|
||||
"pushoversounds spacealarm": "Space Alarm",
|
||||
"pushoversounds tugboat": "Schlepper Horn",
|
||||
"pushoversounds alien": "Ausserirdisch (lang)",
|
||||
"pushoversounds climb": "Ansteigende (lang)",
|
||||
"pushoversounds persistent": "Hartnäckig (lang)",
|
||||
"pushoversounds echo": "Pushover Echo (lang)",
|
||||
"pushoversounds updown": "Auf und Ab (lang)",
|
||||
"pushoversounds vibrate": "Nur vibrieren",
|
||||
"pushoversounds none": "Nichts (Stille)",
|
||||
pushyAPIKey: "Geheimer API Schlüssel",
|
||||
pushyToken: "Gerätetoken",
|
||||
"Show update if available": "Verfügbare Updates anzeigen",
|
||||
"Also check beta release": "Auch nach beta Versionen schauen",
|
||||
"Using a Reverse Proxy?": "Wird ein Reverse Proxy genutzt?",
|
||||
"Check how to config it for WebSocket": "Prüfen, wie er für die Nutzung mit WebSocket konfiguriert wird",
|
||||
"Steam Game Server": "Steam Game Server",
|
||||
"Most likely causes:": "Wahrscheinliche Ursachen:",
|
||||
"The resource is no longer available.": "Die Quelle ist nicht mehr verfügbar.",
|
||||
"There might be a typing error in the address.": "Es gibt einen Tippfehler in der Adresse.",
|
||||
"What you can try:": "Was du versuchen kannst:",
|
||||
"Retype the address.": "Schreibe die Adresse erneut.",
|
||||
"Go back to the previous page.": "Gehe zur vorigen Seite.",
|
||||
"Coming Soon": "Kommt bald",
|
||||
wayToGetClickSendSMSToken: "Du kannst einen API Nutzernamen und Schlüssel unter {0} erhalten.",
|
||||
"Connection String": "Verbindungstext",
|
||||
Query: "Abfrage",
|
||||
settingsCertificateExpiry: "TLS Zertifikatsablauf",
|
||||
certificationExpiryDescription: "HTTPS Monitore senden eine Benachrichtigung, wenn das Zertifikat abläuft in:",
|
||||
"Setup Docker Host": "Docker Host einrichten",
|
||||
"Connection Type": "Verbindungstyp",
|
||||
"Docker Daemon": "Docker Daemon",
|
||||
deleteDockerHostMsg: "Bist du sicher diesen docker host für alle Monitore zu löschen?",
|
||||
socket: "Socket",
|
||||
tcp: "TCP / HTTP",
|
||||
"Docker Container": "Docker Container",
|
||||
"Container Name / ID": "Container Name / ID",
|
||||
"Docker Host": "Docker Host",
|
||||
"Docker Hosts": "Docker Hosts",
|
||||
"ntfy Topic": "ntfy Thema",
|
||||
Domain: "Domain",
|
||||
Workstation: "Workstation",
|
||||
disableCloudflaredNoAuthMsg: "Du bist im nicht-authentifizieren Modus, ein Passwort wird nicht benötigt.",
|
||||
trustProxyDescription: "Vertraue 'X-Forwarded-*' headern. Wenn man die richtige client IP haben möchte und Uptime Kuma hinter einem Proxy wie Nginx or Apache läuft, wollte dies aktiviert werden.",
|
||||
wayToGetLineNotifyToken: "Du kannst hier ein Token erhalten: {0}",
|
||||
Examples: "Beispiele",
|
||||
"Home Assistant URL": "Home Assistant URL",
|
||||
"Long-Lived Access Token": "Lange gültiges Access Token",
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Lange gültige Access Token können durch klicken auf den Profilnamen (unten links) und dann einen Klick auf Create Token am Ende erstellt werden. ",
|
||||
"Notification Service": "Benachrichtigungsdienst",
|
||||
"default: notify all devices": "standard: Alle Geräte benachrichtigen",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Eine Liste der Benachrichtigungsdienste kann im Home Assistant unter \"Developer Tools > Services\" gefunden werden, wnen man nach \"notification\" sucht um den Geräte-/Telefonnamen zu finden.",
|
||||
"Automations can optionally be triggered in Home Assistant:": "Automatisierungen können optional im Home Assistant ausgelöst werden:",
|
||||
"Trigger type:": "Auslöser:",
|
||||
"Event type:": "Ereignistyp:",
|
||||
"Event data:": "Ereignis daten:",
|
||||
"Then choose an action, for example switch the scene to where an RGB light is red.": "Dann eine Aktion wählen, zum Beispiel eine Scene wählen in der ein RGB Licht rot ist.",
|
||||
"Frontend Version": "Frontend Version",
|
||||
"Frontend Version do not match backend version!": "Die Frontend Version stimmt nicht mit der backend version überein!",
|
||||
Maintenance: "Wartung",
|
||||
statusMaintenance: "Wartung",
|
||||
"Schedule maintenance": "Geplante Wartung",
|
||||
"Affected Monitors": "Betroffene Monitore",
|
||||
"Pick Affected Monitors...": "Wähle betroffene Monitore...",
|
||||
"Start of maintenance": "Beginn der Wartung",
|
||||
"All Status Pages": "Alle Status Seiten",
|
||||
"Select status pages...": "Wähle Status Seiten...",
|
||||
recurringIntervalMessage: "einmal pro Tag ausgeführt | Wird alle {0} Tage ausgführt",
|
||||
affectedMonitorsDescription: "Wähle alle Monitore die von der Wartung betroffen sind",
|
||||
affectedStatusPages: "Zeige diese Nachricht auf ausgewählten Status Seiten",
|
||||
atLeastOneMonitor: "Wähle mindestens einen Monitor",
|
||||
deleteMaintenanceMsg: "Möchtest du diese Wartung löschen?",
|
||||
"Base URL": "Basis URL",
|
||||
goAlertInfo: "GoAlert ist eine Open-Source Applikation für Rufbereitschaftsplanung, automatische Eskalation und Benachrichtigung (z.B. SMS oder Telefonanrufe). Beauftragen Sie automatisch die richtige Person, auf die richtige Art und Weise und zum richtigen Zeitpunkt. {0}",
|
||||
goAlertIntegrationKeyInfo: "Bekommt einen generischen API Schlüssel in folgenden Format \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\". Normalerweise entspricht dies dem Wert des Token aus der URL.",
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "Veraltet: Eine menge Neuerungen sind eingeflossen und diese Funktion wurde etwas vernachlässigt worden. Es kann kein vollständiges Backup erstellt oder eingespielt werden.",
|
||||
backupRecommend: "Bitte Backup das Volume oder den Ordner (./ data /) selbst.",
|
||||
Optional: "Optional",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "SMSManager API Dokumente",
|
||||
"Gateway Type": "Gateway Type",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "Du kannst Zahlen teilen mit",
|
||||
or: "oder",
|
||||
recurringInterval: "Intervall",
|
||||
Recurring: "Wiederkehrend",
|
||||
strategyManual: "Active/Inactive Manually",
|
||||
warningTimezone: "Es wird die Zeitzone des Servers genutzt",
|
||||
weekdayShortMon: "Mo",
|
||||
weekdayShortTue: "Di",
|
||||
weekdayShortWed: "Mi",
|
||||
weekdayShortThu: "Do",
|
||||
weekdayShortFri: "Fr",
|
||||
weekdayShortSat: "Sa",
|
||||
weekdayShortSun: "So",
|
||||
dayOfWeek: "Tag der Woche",
|
||||
dayOfMonth: "Tag im Monat",
|
||||
lastDay: "Letzter Tag",
|
||||
lastDay1: "Letzter Tag im Monat",
|
||||
lastDay2: "Vorletzer Tag im Monat",
|
||||
lastDay3: "3. letzter Tag im Monat",
|
||||
lastDay4: "4. letzter Tag im Monat",
|
||||
"No Maintenance": "Keine Wartung",
|
||||
pauseMaintenanceMsg: "Möchtest du wirklich pausieren?",
|
||||
"maintenanceStatus-under-maintenance": "Unter Wartung",
|
||||
"maintenanceStatus-inactive": "Inaktiv",
|
||||
"maintenanceStatus-scheduled": "Geplant",
|
||||
"maintenanceStatus-ended": "Ende",
|
||||
"maintenanceStatus-unknown": "Unbekannt",
|
||||
"Display Timezone": "Zeitzone anzeigen",
|
||||
"Server Timezone": "Server Zeitzone",
|
||||
statusPageMaintenanceEndDate: "Ende",
|
||||
};
|
@@ -96,7 +96,7 @@ export default {
|
||||
"Notification Type": "Benachrichtigungsdienst",
|
||||
Email: "E-Mail",
|
||||
Test: "Test",
|
||||
"Certificate Info": "Zertifikatsinfo",
|
||||
"Certificate Info": "Zertifikatsinformation",
|
||||
keywordDescription: "Ein Suchwort in der HTML- oder JSON-Ausgabe finden. Bitte beachte: es wird zwischen Groß-/Kleinschreibung unterschieden.",
|
||||
deleteMonitorMsg: "Bist du sicher, dass du den Monitor löschen möchtest?",
|
||||
deleteNotificationMsg: "Möchtest du diese Benachrichtigung wirklich für alle Monitore löschen?",
|
||||
@@ -204,7 +204,7 @@ export default {
|
||||
pushbullet: "Pushbullet",
|
||||
line: "Line Messenger",
|
||||
mattermost: "Mattermost",
|
||||
"Primary Base URL": "Primär URL",
|
||||
"Primary Base URL": "Primäre Basis-URL",
|
||||
"Push URL": "Push URL",
|
||||
needPushEvery: "Du solltest diese URL alle {0} Sekunden aufrufen",
|
||||
pushOptionalParams: "Optionale Parameter: {0}",
|
||||
@@ -383,7 +383,7 @@ export default {
|
||||
deleteProxyMsg: "Bist du sicher, dass du diesen Proxy für alle Monitore löschen willst?",
|
||||
proxyDescription: "Proxies müssen einem Monitor zugewiesen werden, um zu funktionieren.",
|
||||
enableProxyDescription: "Dieser Proxy wird keinen Effekt auf Monitor-Anfragen haben, bis er aktiviert ist. Du kannst ihn temporär von allen Monitoren nach Aktivierungsstatus deaktivieren.",
|
||||
setAsDefaultProxyDescription: "Dieser Proxy wird standardmäßig für alle neuen Monitore aktiviert sein. Du kannst den Proxy immernoch für jeden Monitor einzeln deaktivieren.",
|
||||
setAsDefaultProxyDescription: "Dieser Proxy wird standardmäßig für alle neuen Monitore aktiviert sein. Du kannst den Proxy immer noch für jeden Monitor einzeln deaktivieren.",
|
||||
"Certificate Chain": "Zertifikatskette",
|
||||
Valid: "Gültig",
|
||||
Invalid: "Ungültig",
|
||||
@@ -496,7 +496,7 @@ export default {
|
||||
"API Key": "API Schlüssel",
|
||||
"Recipient Number": "Empfängernummer",
|
||||
"From Name/Number": "Von Name/Nummer",
|
||||
"Leave blank to use a shared sender number.": "Leer lassen um eine geteilte Sendernummer zu nutzen.",
|
||||
"Leave blank to use a shared sender number.": "Leer lassen um eine geteilte Absendernummer zu nutzen.",
|
||||
"Octopush API Version": "Octopush API Version",
|
||||
"Legacy Octopush-DM": "Legacy Octopush-DM",
|
||||
endpoint: "Endpunkt",
|
||||
@@ -530,7 +530,7 @@ export default {
|
||||
pushyAPIKey: "Geheimer API Schlüssel",
|
||||
pushyToken: "Gerätetoken",
|
||||
"Show update if available": "Verfügbare Updates anzeigen",
|
||||
"Also check beta release": "Auch nach beta Versionen schauen",
|
||||
"Also check beta release": "Auch nach Beta Versionen schauen",
|
||||
"Using a Reverse Proxy?": "Wird ein Reverse Proxy genutzt?",
|
||||
"Check how to config it for WebSocket": "Prüfen, wie er für die Nutzung mit WebSocket konfiguriert wird",
|
||||
"Steam Game Server": "Steam Game Server",
|
||||
@@ -568,12 +568,67 @@ export default {
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Lange gültige Access Token können durch klicken auf den Profilnamen (unten links) und dann einen Klick auf Create Token am Ende erstellt werden. ",
|
||||
"Notification Service": "Benachrichtigungsdienst",
|
||||
"default: notify all devices": "standard: Alle Geräte benachrichtigen",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Eine Liste der Benachrichtigungsdiesnte kann im Home Assistant unter \"Developer Tools > Services\" gefunden werden, wnen man nach \"notification\" sucht um den Geräte-/Telefonnamen zu finden.",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Eine Liste der Benachrichtigungsdienste kann im Home Assistant unter \"Developer Tools > Services\" gefunden werden, wnen man nach \"notification\" sucht um den Geräte-/Telefonnamen zu finden.",
|
||||
"Automations can optionally be triggered in Home Assistant:": "Automatisierungen können optional im Home Assistant ausgelöst werden:",
|
||||
"Trigger type:": "Auslösertyp:",
|
||||
"Trigger type:": "Auslöser:",
|
||||
"Event type:": "Ereignistyp:",
|
||||
"Event data:": "Ereignis daten:",
|
||||
"Then choose an action, for example switch the scene to where an RGB light is red.": "Dann eine Aktion wählen, zum Beispiel eine Scene wählen in der ein RGB Licht rot ist.",
|
||||
"Frontend Version": "Frontend Version",
|
||||
"Frontend Version do not match backend version!": "Die Frontend Version stimmt nicht mit der backend version überein!",
|
||||
Maintenance: "Wartung",
|
||||
statusMaintenance: "Wartung",
|
||||
"Schedule maintenance": "Geplante Wartung",
|
||||
"Affected Monitors": "Betroffene Monitore",
|
||||
"Pick Affected Monitors...": "Wähle betroffene Monitore...",
|
||||
"Start of maintenance": "Beginn der Wartung",
|
||||
"All Status Pages": "Alle Status Seiten",
|
||||
"Select status pages...": "Wähle Status Seiten...",
|
||||
recurringIntervalMessage: "einmal pro Tag ausgeführt | Wird alle {0} Tage ausgführt",
|
||||
affectedMonitorsDescription: "Wähle alle Monitore die von der Wartung betroffen sind",
|
||||
affectedStatusPages: "Zeige diese Nachricht auf ausgewählten Status Seiten",
|
||||
atLeastOneMonitor: "Wähle mindestens einen Monitor",
|
||||
deleteMaintenanceMsg: "Möchtest du diese Wartung löschen?",
|
||||
"Base URL": "Basis URL",
|
||||
goAlertInfo: "GoAlert ist eine Open-Source Applikation für Rufbereitschaftsplanung, automatische Eskalation und Benachrichtigung (z.B. SMS oder Telefonanrufe). Beauftragen Sie automatisch die richtige Person, auf die richtige Art und Weise und zum richtigen Zeitpunkt. {0}",
|
||||
goAlertIntegrationKeyInfo: "Bekommt einen generischen API Schlüssel in folgenden Format \"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee\". Normalerweise entspricht dies dem Wert des Token aus der URL.",
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "Veraltet: Da viele Funktionen hinzugefügt wurden und diese Sicherungsfunktion nicht mehr gepflegt wird, kann sie keine vollständige Sicherung erstellen oder wiederherstellen.",
|
||||
backupRecommend: "Bitte sichere stattdessen das Volume oder den Datenordner (./data/) direkt.",
|
||||
Optional: "Optional",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "SMSManager API Dokumente",
|
||||
"Gateway Type": "Gateway Type",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "Du kannst Zahlen teilen mit",
|
||||
or: "oder",
|
||||
recurringInterval: "Intervall",
|
||||
Recurring: "Wiederkehrend",
|
||||
strategyManual: "Active/Inactive Manually",
|
||||
warningTimezone: "Es wird die Zeitzone des Servers genutzt",
|
||||
weekdayShortMon: "Mo",
|
||||
weekdayShortTue: "Di",
|
||||
weekdayShortWed: "Mi",
|
||||
weekdayShortThu: "Do",
|
||||
weekdayShortFri: "Fr",
|
||||
weekdayShortSat: "Sa",
|
||||
weekdayShortSun: "So",
|
||||
dayOfWeek: "Tag der Woche",
|
||||
dayOfMonth: "Tag im Monat",
|
||||
lastDay: "Letzter Tag",
|
||||
lastDay1: "Letzter Tag im Monat",
|
||||
lastDay2: "Vorletzer Tag im Monat",
|
||||
lastDay3: "3. letzter Tag im Monat",
|
||||
lastDay4: "4. letzter Tag im Monat",
|
||||
"No Maintenance": "Keine Wartung",
|
||||
pauseMaintenanceMsg: "Möchtest du wirklich pausieren?",
|
||||
"maintenanceStatus-under-maintenance": "Unter Wartung",
|
||||
"maintenanceStatus-inactive": "Inaktiv",
|
||||
"maintenanceStatus-scheduled": "Geplant",
|
||||
"maintenanceStatus-ended": "Ende",
|
||||
"maintenanceStatus-unknown": "Unbekannt",
|
||||
"Display Timezone": "Zeitzone anzeigen",
|
||||
"Server Timezone": "Server Zeitzone",
|
||||
statusPageMaintenanceEndDate: "Ende",
|
||||
};
|
||||
|
@@ -8,6 +8,8 @@ export default {
|
||||
ignoreTLSError: "Ignore TLS/SSL error for HTTPS websites",
|
||||
upsideDownModeDescription: "Flip the status upside down. If the service is reachable, it is DOWN.",
|
||||
maxRedirectDescription: "Maximum number of redirects to follow. Set to 0 to disable redirects.",
|
||||
enableGRPCTls: "Allow to send gRPC request with TLS connection",
|
||||
grpcMethodDescription: "Method name is convert to cammelCase format such as sayHello, check, etc.",
|
||||
acceptedStatusCodesDescription: "Select status codes which are considered as a successful response.",
|
||||
Maintenance: "Maintenance",
|
||||
statusMaintenance: "Maintenance",
|
||||
@@ -219,6 +221,8 @@ export default {
|
||||
"Content Type": "Content Type",
|
||||
webhookJsonDesc: "{0} is good for any modern HTTP servers such as Express.js",
|
||||
webhookFormDataDesc: "{multipart} is good for PHP. The JSON will need to be parsed with {decodeFunction}",
|
||||
webhookAdditionalHeadersTitle: "Additional Headers",
|
||||
webhookAdditionalHeadersDesc: "Sets additional headers sent with the webhook.",
|
||||
smtp: "Email (SMTP)",
|
||||
secureOptionNone: "None / STARTTLS (25, 587)",
|
||||
secureOptionTLS: "TLS (465)",
|
||||
@@ -378,6 +382,16 @@ export default {
|
||||
serwersmsAPIPassword: "API Password",
|
||||
serwersmsPhoneNumber: "Phone number",
|
||||
serwersmsSenderName: "SMS Sender Name (registered via customer portal)",
|
||||
smseagle: "SMSEagle",
|
||||
smseagleTo: "Phone number(s)",
|
||||
smseagleGroup: "Phonebook group name(s)",
|
||||
smseagleContact: "Phonebook contact name(s)",
|
||||
smseagleRecipientType: "Recipient type",
|
||||
smseagleRecipient: "Recipient(s) (multiple must be separated with comma)",
|
||||
smseagleToken: "API Access token",
|
||||
smseagleUrl: "Your SMSEagle device URL",
|
||||
smseagleEncoding: "Send as Unicode",
|
||||
smseaglePriority: "Message priority (0-9, default = 0)",
|
||||
stackfield: "Stackfield",
|
||||
Customize: "Customize",
|
||||
"Custom Footer": "Custom Footer",
|
||||
@@ -631,4 +645,9 @@ export default {
|
||||
"Display Timezone": "Display Timezone",
|
||||
"Server Timezone": "Server Timezone",
|
||||
statusPageMaintenanceEndDate: "End",
|
||||
IconUrl: "Icon URL",
|
||||
"Enable DNS Cache": "Enable DNS Cache",
|
||||
"Enable": "Enable",
|
||||
"Disable": "Disable",
|
||||
dnsCacheDescription: "It may be not working in some IPv6 environments, disable it if you encounter any issues.",
|
||||
};
|
||||
|
@@ -334,10 +334,10 @@ export default {
|
||||
Security: "Sécurité",
|
||||
"Steam API Key": "Clé API Steam",
|
||||
"Shrink Database": "Réduire la base de données",
|
||||
"Pick a RR-Type...": "Pick a RR-Type...",
|
||||
"Pick Accepted Status Codes...": "Pick Accepted Status Codes...",
|
||||
"Pick a RR-Type...": "Choisissez un type d'enregistrement...",
|
||||
"Pick Accepted Status Codes...": "Choisissez les codes de statut acceptés...",
|
||||
Default: "Défaut",
|
||||
"HTTP Options": "HTTP Options",
|
||||
"HTTP Options": "Options HTTP ",
|
||||
"Create Incident": "Créer un incident",
|
||||
Title: "Titre",
|
||||
Content: "Contenu",
|
||||
@@ -503,7 +503,7 @@ export default {
|
||||
RadiusCallingStationIdDescription: "Identifiant de l'appareil appelant",
|
||||
"Certificate Expiry Notification": "Notification d'expiration du certificat",
|
||||
"API Username": "Nom d'utilisateur de l'API",
|
||||
"API Key": "clé API",
|
||||
"API Key": "Clé API",
|
||||
"Recipient Number": "Numéro du destinataire",
|
||||
"From Name/Number": "De Nom/Numéro",
|
||||
"Leave blank to use a shared sender number.": "Laisser vide pour utiliser un numéro d'expéditeur partagé.",
|
||||
@@ -531,4 +531,90 @@ export default {
|
||||
backupRecommend: "Veuillez sauvegarder le volume ou le dossier de données (./data/) directement à la place.",
|
||||
Optional: "Optionnel",
|
||||
squadcast: "Squadcast",
|
||||
Maintenance: "Maintenance",
|
||||
statusMaintenance: "Maintenance",
|
||||
"Schedule maintenance": "Planifier la maintenance",
|
||||
"Affected Monitors": "Moniteurs concernés",
|
||||
"Pick Affected Monitors...": "Sélectionnez les moniteurs concernés...",
|
||||
"Start of maintenance": "Début de la maintenance",
|
||||
"All Status Pages": "Toutes les pages d'état",
|
||||
"Select status pages...": "Sélectionnez les pages d'état...",
|
||||
recurringIntervalMessage: "Exécuter une fois par jour | Exécuter une fois tous les {0} jours",
|
||||
affectedMonitorsDescription: "Sélectionnez les moniteurs concernés par la maintenance en cours",
|
||||
affectedStatusPages: "Afficher ce message de maintenance sur les pages d'état sélectionnées",
|
||||
atLeastOneMonitor: "Sélectionnez au moins un moniteur concerné",
|
||||
deleteMaintenanceMsg: "Voulez-vous vraiment supprimer cette maintenance ?",
|
||||
pushyAPIKey: "Clé API secrète",
|
||||
pushyToken: "Jeton d'appareil",
|
||||
"You can divide numbers with": "Vous pouvez diviser des nombres avec",
|
||||
or: "ou",
|
||||
recurringInterval: "Intervalle",
|
||||
Recurring: "Récurrent",
|
||||
"Single Maintenance Window": "Fenêtre de maintenance unique",
|
||||
"Maintenance Time Window of a Day": "Fenêtre de temps de maintenance",
|
||||
"Effective Date Range": "Plage de dates d'effet",
|
||||
strategyManual: "activer/desactiver manuellement",
|
||||
warningTimezone: "Il utilise le fuseau horaire du serveur",
|
||||
weekdayShortMon: "Lun",
|
||||
weekdayShortTue: "Mar",
|
||||
weekdayShortWed: "Mer",
|
||||
weekdayShortThu: "Jeu",
|
||||
weekdayShortFri: "Ven",
|
||||
weekdayShortSat: "Sam",
|
||||
weekdayShortSun: "Dim",
|
||||
dayOfWeek: "Jour de la semaine",
|
||||
dayOfMonth: "Jour du mois",
|
||||
lastDay: "Dernier jour",
|
||||
lastDay1: "Dernier jour du mois",
|
||||
lastDay2: "2ème dernier jour du mois",
|
||||
lastDay3: "3ème dernier jour du mois",
|
||||
lastDay4: "4ème dernier jour du mois",
|
||||
"No Maintenance": "Aucune Maintenance",
|
||||
"Schedule Maintenance": "Crée une Maintenance",
|
||||
pauseMaintenanceMsg: "Voulez-vous vraiment mettre en pause ?",
|
||||
"maintenanceStatus-under-maintenance": "En maintenance",
|
||||
"maintenanceStatus-inactive": "Inactif",
|
||||
"maintenanceStatus-scheduled": "Programmé",
|
||||
"maintenanceStatus-ended": "Terminé",
|
||||
"maintenanceStatus-unknown": "Inconnue",
|
||||
"Display Timezone": "Afficher le fuseau horaire",
|
||||
"Server Timezone": "Fuseau horaire du serveur",
|
||||
"Date and Time": "Date et heure",
|
||||
"DateTime Range": "Plage de dates et d'heures",
|
||||
Strategy: "Stratégie",
|
||||
statusPageMaintenanceEndDate: "Fin",
|
||||
"Free Mobile User Identifier": "Identifiant d'utilisateur Free Mobile",
|
||||
"Free Mobile API Key": "Clé API Free Mobile",
|
||||
enableGRPCTls: "Autoriser l'envoi d'une requête gRPC avec une connexion TLS",
|
||||
grpcMethodDescription: "Le nom de la méthode est converti au format cammelCase tel que sayHello, check, etc.",
|
||||
smseagleTo: "Numéro(s) de téléphone",
|
||||
smseagleGroup: "Nom(s) de groupe(s) de répertoire",
|
||||
smseagleContact: "Nom(s) de contact du répertoire",
|
||||
smseagleRecipientType: "Type de destinataire",
|
||||
smseagleRecipient: "Destinataire(s) (les multiples doivent être séparés par une virgule)",
|
||||
smseagleToken: "Jeton d'accès à l'API",
|
||||
smseagleUrl: "L'URL de votre appareil SMSEagle",
|
||||
smseagleEncoding: "Envoyer en Unicode",
|
||||
smseaglePriority: "Priorité des messages (0-9, par défaut = 0)",
|
||||
"Proxy Server": "Serveur proxy",
|
||||
promosmsLogin: "Nom de connexion API",
|
||||
promosmsPassword: "Mot de passe API",
|
||||
"SMSManager API Docs": "Documentations d'API SMSManager ",
|
||||
"Gateway Type": "Type de passerelle",
|
||||
webhookAdditionalHeadersTitle: "En-têtes supplémentaires",
|
||||
webhookAdditionalHeadersDesc: "Définit des en-têtes supplémentaires envoyés avec le webhook.",
|
||||
"Enable TLS": "Activer le TLS",
|
||||
"Proto Service Name": "Nom du service proto",
|
||||
"Proto Method": "Méthode Proto",
|
||||
"Proto Content": "Contenu proto",
|
||||
"Enable DNS Cache": "Activer le cache DNS",
|
||||
dnsCacheDescription: "Il peut ne pas fonctionner dans certains environnements IPv6, désactivez-le si vous rencontrez des problèmes.",
|
||||
Enable: "Activer",
|
||||
Disable: "Désactiver",
|
||||
"Economy": "économique",
|
||||
"Lowcost": "Faible coût",
|
||||
"high": "Haute",
|
||||
"General Monitor Type": "Type de moniteur général",
|
||||
"Passive Monitor Type": "Type de moniteur passif",
|
||||
"Specific Monitor Type": "Type de moniteur spécifique",
|
||||
};
|
||||
|
@@ -27,8 +27,8 @@ export default {
|
||||
confirmImportMsg: "Apakah Anda yakin untuk mengimpor cadangan? Pastikan Anda telah memilih opsi impor yang tepat.",
|
||||
twoFAVerifyLabel: "Silakan ketik token Anda untuk memverifikasi bahwa 2FA berfungsi",
|
||||
tokenValidSettingsMsg: "Token benar! Anda sekarang dapat menyimpan pengaturan 2FA.",
|
||||
confirmEnableTwoFAMsg: "Apakah anda yakin ingin mengaktifkan 2FA?",
|
||||
confirmDisableTwoFAMsg: "Apakah anda yakin ingin menonaktifkan 2FA?",
|
||||
confirmEnableTwoFAMsg: "Apakah Anda yakin ingin mengaktifkan 2FA?",
|
||||
confirmDisableTwoFAMsg: "Apakah Anda yakin ingin menonaktifkan 2FA?",
|
||||
Settings: "Pengaturan",
|
||||
Dashboard: "Dasbor",
|
||||
"New Update": "Pembaruan Baru",
|
||||
@@ -126,7 +126,7 @@ export default {
|
||||
"Resolver Server": "Resolver Server",
|
||||
"Resource Record Type": "Resource Record Type",
|
||||
"Last Result": "Hasil Terakhir",
|
||||
"Create your admin account": "Buat akun admin anda",
|
||||
"Create your admin account": "Buat akun admin Anda",
|
||||
"Repeat Password": "Ulangi Sandi",
|
||||
"Import Backup": "Impor Cadangan",
|
||||
"Export Backup": "Ekspor Cadangan",
|
||||
@@ -568,7 +568,7 @@ export default {
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Token Akses Berumur Panjang dapat dibuat dengan mengklik nama profil Anda (kiri bawah) dan menggulir ke bawah lalu klik Buat Token. ",
|
||||
"Notification Service": "Layanan Pemberitahuan",
|
||||
"default: notify all devices": "bawaan: notifikasi seluruh perangkat",
|
||||
"A listof Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Daftar Layanan Pemberitahuan dapat ditemukan di Home Assistant pada \"Developer Tools > Services\" cari \"notification\" lalu cari nama perangkat Anda.",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Daftar Layanan Pemberitahuan dapat ditemukan di Home Assistant pada \"Developer Tools > Services\" cari \"notification\" lalu cari nama perangkat Anda.",
|
||||
"Automations can optionally be triggered in Home Assistant:": "Otomatisasi dapat dipicu secara opsional di Home Assistant:",
|
||||
"Trigger type:": "Tipe Trigger/Pemicu:",
|
||||
"Event type:": "Tipe event:",
|
||||
|
@@ -125,7 +125,7 @@ export default {
|
||||
Export: "Eksportuj",
|
||||
Import: "Importuj",
|
||||
respTime: "Czas odp. (ms)",
|
||||
notAvailableShort: "N/A",
|
||||
notAvailableShort: "N/D",
|
||||
"Default enabled": "Włącz domyślnie",
|
||||
"Apply on all existing monitors": "Zastosuj do istniejących monitorów",
|
||||
Create: "Stwórz",
|
||||
@@ -181,7 +181,7 @@ export default {
|
||||
"Edit Status Page": "Edytuj stronę statusu",
|
||||
"Go to Dashboard": "Idź do panelu",
|
||||
"Status Page": "Strona statusu",
|
||||
"Status Pages": "Strona statusu",
|
||||
"Status Pages": "Strony statusów",
|
||||
defaultNotificationName: "Moje powiadomienie {notification} ({number})",
|
||||
here: "tutaj",
|
||||
Required: "Wymagane",
|
||||
@@ -359,6 +359,16 @@ export default {
|
||||
serwersmsAPIPassword: "Hasło API",
|
||||
serwersmsPhoneNumber: "Numer telefonu",
|
||||
serwersmsSenderName: "Nazwa nadawcy (zatwierdzona w panelu klienta)",
|
||||
smseagle: "SMSEagle",
|
||||
smseagleTo: "Numer/y telefonu",
|
||||
smseagleGroup: "Grupa/y z Książki adresowej",
|
||||
smseagleContact: "Kontakt/y z Książki adresowej",
|
||||
smseagleRecipientType: "Typ odbiorcy",
|
||||
smseagleRecipient: "Odbiorca/y (wiele musi być oddzielone przecinkami)",
|
||||
smseagleToken: "Klucz dostępu API",
|
||||
smseagleUrl: "URL Twojego urządzenia SMSEagle",
|
||||
smseagleEncoding: "Wyślij jako Unicode",
|
||||
smseaglePriority: "Priorytet wiadomości (0-9, domyślnie = 0)",
|
||||
stackfield: "Stackfield",
|
||||
Customize: "Dostosuj",
|
||||
"Custom Footer": "Niestandardowa stopka",
|
||||
@@ -435,7 +445,7 @@ export default {
|
||||
"HTTP Basic Auth": "Podstawowa autoryzacja HTTP",
|
||||
"New Status Page": "Nowa strona statusu",
|
||||
"Page Not Found": "Strona nie została znaleziona",
|
||||
"Reverse Proxy": "Odwrotne Proxy",
|
||||
"Reverse Proxy": "Zwrotny serwer proxy",
|
||||
Backup: "Backup",
|
||||
About: "O skrypcie",
|
||||
wayToGetCloudflaredURL: "(Pobierz cloudflared z {0})",
|
||||
@@ -447,7 +457,7 @@ export default {
|
||||
"For example: nginx, Apache and Traefik.": "Na przykład: nginx, Apache i Traefik.",
|
||||
"Please read": "Przeczytaj proszę",
|
||||
"Subject:": "Temat:",
|
||||
"Valid To:": "Ważdny do:",
|
||||
"Valid To:": "Ważny do:",
|
||||
"Days Remaining:": "Pozostało dni:",
|
||||
"Issuer:": "Wydawca:",
|
||||
"Fingerprint:": "Odcisk palca:",
|
||||
@@ -467,4 +477,168 @@ export default {
|
||||
"Domain Names": "Domeny",
|
||||
signedInDisp: "Zalogowany jako {0}",
|
||||
signedInDispDisabled: "Autoryzacja wyłączona.",
|
||||
resendEveryXTimes: "Wysyłaj ponownie co {0} razy",
|
||||
resendDisabled: "Ponowne wysyłanie jest wyłączone",
|
||||
Maintenance: "Konserwacja",
|
||||
statusMaintenance: "Konserwacja",
|
||||
"Schedule maintenance": "Planowanie konserwacji",
|
||||
"Affected Monitors": "Monitory dotknięte problemem",
|
||||
"Pick Affected Monitors...": "Wybierz monitory, których to dotyczy...",
|
||||
"Start of maintenance": "Rozpoczęcie konserwacji",
|
||||
"All Status Pages": "Wszystkie strony statusu",
|
||||
"Select status pages...": "Wybierz strony statusu...",
|
||||
recurringIntervalMessage: "Uruchom raz dziennie | Uruchom raz na {0} dni",
|
||||
affectedMonitorsDescription: "Wybierz monitory, których dotyczy bieżąca konserwacja",
|
||||
affectedStatusPages: "Pokaż ten komunikat o konserwacji na wybranych stronach statusu",
|
||||
atLeastOneMonitor: "Wybierz co najmniej jeden monitor, którego dotyczy problem",
|
||||
deleteMaintenanceMsg: "Czy na pewno chcesz usunąć tę konserwację?",
|
||||
dnsPortDescription: "Port serwera DNS. Domyślnie 53. Możesz zmienić port w dowolnym momencie.",
|
||||
"Resend Notification if Down X times consequently": "Wyślij ponownie powiadomienie, jeśli nie działa X razy pod rząd",
|
||||
error: "błąd",
|
||||
critical: "krytyczny",
|
||||
wayToGetPagerDutyKey: "Możesz to uzyskać, przechodząc do Service -> Service Directory -> (wybierz usługę) -> Integrations -> Add integration. Tutaj możesz wyszukać \"Events API V2\". Więcej informacji {0}",
|
||||
"Integration Key": "Klucz integracji",
|
||||
"Integration URL": "Adres URL integracji",
|
||||
"Auto resolve or acknowledged": "Automatycznie rozwiązany lub potwierdzony",
|
||||
"do nothing": "nie rób nic",
|
||||
"auto acknowledged": "auto potwierdzony",
|
||||
"auto resolve": "automatycznie rozwiązany",
|
||||
"Bark Group": "Grupa Bark",
|
||||
"Bark Sound": "Dźwięk Bark",
|
||||
"HTTP Headers": "Nagłówki HTTP",
|
||||
"Trust Proxy": "Ufaj proxy",
|
||||
HomeAssistant: "Home Assistant",
|
||||
RadiusSecret: "Sekretny klucz Radius",
|
||||
RadiusSecretDescription: "Współdzielony sekretny klucz pomiędzy klientem a serwerem",
|
||||
RadiusCalledStationId: "Id stacji wywoływanej",
|
||||
RadiusCalledStationIdDescription: "Identyfikator wywoływanego urządzenia",
|
||||
RadiusCallingStationId: "Id stacji wywoławczej",
|
||||
RadiusCallingStationIdDescription: "Identyfikator urządzenia wywołującego",
|
||||
"Certificate Expiry Notification": "Powiadomienie o wygaśnięciu certyfikatu",
|
||||
"API Username": "Nazwa użytkownika API",
|
||||
"API Key": "Klucz API",
|
||||
"Recipient Number": "Numer odbiorcy",
|
||||
"From Name/Number": "Od nazwa/numer",
|
||||
"Leave blank to use a shared sender number.": "Pozostaw puste, aby użyć wspólnego numeru nadawcy.",
|
||||
"Octopush API Version": "Wersja API Octopush",
|
||||
"Legacy Octopush-DM": "Starsze Octopush-DM",
|
||||
endpoint: "punkt końcowy",
|
||||
octopushAPIKey: "\"API key\" z poświadczeń HTTP API w panelu sterowania",
|
||||
octopushLogin: "\"Login\" z poświadczeń HTTP API w panelu sterowania",
|
||||
promosmsLogin: "Nazwa logowania API",
|
||||
promosmsPassword: "Hasło API",
|
||||
"pushoversounds pushover": "Pushover (domyślny)",
|
||||
"pushoversounds bike": "Bike",
|
||||
"pushoversounds bugle": "Bugle",
|
||||
"pushoversounds cashregister": "Cash Register",
|
||||
"pushoversounds classical": "Classical",
|
||||
"pushoversounds cosmic": "Cosmic",
|
||||
"pushoversounds falling": "Falling",
|
||||
"pushoversounds gamelan": "Gamelan",
|
||||
"pushoversounds incoming": "Incoming",
|
||||
"pushoversounds intermission": "Intermission",
|
||||
"pushoversounds magic": "Magic",
|
||||
"pushoversounds mechanical": "Mechanical",
|
||||
"pushoversounds pianobar": "Piano Bar",
|
||||
"pushoversounds siren": "Siren",
|
||||
"pushoversounds spacealarm": "Space Alarm",
|
||||
"pushoversounds tugboat": "Tug Boat",
|
||||
"pushoversounds alien": "Alien Alarm (długie)",
|
||||
"pushoversounds climb": "Climb (długie)",
|
||||
"pushoversounds persistent": "Persistent (długie)",
|
||||
"pushoversounds echo": "Pushover Echo (długie)",
|
||||
"pushoversounds updown": "Up Down (długie)",
|
||||
"pushoversounds vibrate": "Tylko wibracje",
|
||||
"pushoversounds none": "Brak (cisza)",
|
||||
pushyAPIKey: "Tajny klucz API",
|
||||
pushyToken: "Token urządzenia",
|
||||
"Show update if available": "Pokaż aktualizację, jeśli jest dostępna",
|
||||
"Also check beta release": "Sprawdź również wydanie beta",
|
||||
"Using a Reverse Proxy?": "Używasz odwróconego proxy?",
|
||||
"Check how to config it for WebSocket": "Sprawdź jak go skonfigurować dla WebSocket",
|
||||
"Steam Game Server": "Serwer gry Steam",
|
||||
"Most likely causes:": "Najbardziej prawdopodobne przyczyny:",
|
||||
"The resource is no longer available.": "Zasób nie jest już dostępny.",
|
||||
"There might be a typing error in the address.": "W adresie może być błąd w pisowni.",
|
||||
"What you can try:": "Co możesz spróbować:",
|
||||
"Retype the address.": "Ponownie wpisz adres.",
|
||||
"Go back to the previous page.": "Wróć do poprzedniej strony.",
|
||||
"Coming Soon": "Wkrótce",
|
||||
wayToGetClickSendSMSToken: "Możesz uzyskać nazwę użytkownika API i klucz API z {0}.",
|
||||
"Connection String": "Ciąg połączenia",
|
||||
Query: "Zapytanie",
|
||||
settingsCertificateExpiry: "Wygaśnięcie certyfikatu TLS",
|
||||
certificationExpiryDescription: "Monitory HTTPS uruchamiają powiadomienia o wygaśnięciu certyfikatu TLS w:",
|
||||
"Setup Docker Host": "Konfiguracja hosta Docker",
|
||||
"Connection Type": "Typ połączenia",
|
||||
"Docker Daemon": "Demon Dockera",
|
||||
deleteDockerHostMsg: "Czy na pewno chcesz usunąć ten host Dockera dla wszystkich monitorów?",
|
||||
socket: "Gniazdo",
|
||||
tcp: "TCP / HTTP",
|
||||
"Docker Container": "Kontener Dockera",
|
||||
"Container Name / ID": "Nazwa kontenera / ID",
|
||||
"Docker Host": "Host Dockera",
|
||||
"Docker Hosts": "Hosty Dockera",
|
||||
"ntfy Topic": "Temat ntfy",
|
||||
Domain: "Domena",
|
||||
Workstation: "Stacja robocza",
|
||||
disableCloudflaredNoAuthMsg: "Jesteś w trybie No Auth, hasło nie jest wymagane.",
|
||||
trustProxyDescription: "Zaufaj nagłówkom 'X-Forwarded-*'. Jeśli chcesz uzyskać poprawne IP klienta, a twój Uptime Kuma jest za Nginx lub Apache, powinieneś to włączyć.",
|
||||
wayToGetLineNotifyToken: "Możesz uzyskać token dostępu z {0}",
|
||||
Examples: "Przykłady",
|
||||
"Home Assistant URL": "URL Home Assistant",
|
||||
"Long-Lived Access Token": "Długotrwały token dostępu",
|
||||
"Long-Lived Access Token can be created by clicking on your profile name (bottom left) and scrolling to the bottom then click Create Token. ": "Długotrwały token dostępu można utworzyć klikając na nazwę swojego profilu (na dole po lewej stronie) i przewijając do dołu, a następnie klikając Create Token. ",
|
||||
"Notification Service": "Usługa powiadamiania",
|
||||
"default: notify all devices": "domyślnie: powiadamiaj wszystkie urządzenia",
|
||||
"A list of Notification Services can be found in Home Assistant under \"Developer Tools > Services\" search for \"notification\" to find your device/phone name.": "Listę usług powiadamiania można znaleźć w Home Assistant pod \"Developer Tools > Services\" wyszukaj \"notification\", aby znaleźć nazwę swojego urządzenia/telefonu.",
|
||||
"Automations can optionally be triggered in Home Assistant:": "Automaty mogą być opcjonalnie uruchamiane w Home Assistant:",
|
||||
"Trigger type:": "Typ wyzwalacza:",
|
||||
"Event type:": "Typ zdarzenia:",
|
||||
"Event data:": "Dane o zdarzeniu:",
|
||||
"Then choose an action, for example switch the scene to where an RGB light is red.": "Następnie wybierz akcję, na przykład przełącz scenę na taką, w której światło RGB jest czerwone.",
|
||||
"Frontend Version": "Wersja frontu",
|
||||
"Frontend Version do not match backend version!": "Wersja frontu nie pasuje do wersji backendu!",
|
||||
"Base URL": "Bazowy adres URL",
|
||||
goAlertInfo: "GoAlert to aplikacja open source do planowania, automatycznych eskalacji i powiadomień (jak SMS lub połączenia głosowe). Automatycznie angażuj właściwą osobę, we właściwy sposób i we właściwym czasie! {0}",
|
||||
goAlertIntegrationKeyInfo: "Pobierz generyczny klucz integracyjny API dla usługi, którego wartość skopiowanego tokena URL jest zwykle w formacie \"aaaaaaaa-bbb-cccc-dddd-eeeeee\".",
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "Przestarzałe: ponieważ dodano wiele funkcji i funkcja tworzenia kopii zapasowych nie jest wystarczająco utrzymywana, nie może generować ani przywracać pełnej kopii zapasowej.",
|
||||
backupRecommend: "Zamiast tego należy wykonać bezpośrednią kopię zapasową woluminu lub folderu danych (./data/).",
|
||||
Optional: "Opcjonalne",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "Dokumentacja API SMSManager ",
|
||||
"Gateway Type": "Typ bramy",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "Możesz dzielić liczby przez",
|
||||
or: "lub",
|
||||
recurringInterval: "odstęp czasu",
|
||||
Recurring: "powtarzający się",
|
||||
strategyManual: "Aktywowany/dezaktywowany ręcznie",
|
||||
warningTimezone: "Używa strefy czasowej serwera",
|
||||
weekdayShortMon: "pon",
|
||||
weekdayShortTue: "wt",
|
||||
weekdayShortWed: "śr",
|
||||
weekdayShortThu: "czw",
|
||||
weekdayShortFri: "pt",
|
||||
weekdayShortSat: "sob",
|
||||
weekdayShortSun: "niedz",
|
||||
dayOfWeek: "Dzień tygodnia",
|
||||
dayOfMonth: "Dzień miesiąca",
|
||||
lastDay: "Ostatni dzień",
|
||||
lastDay1: "Ostatni dzień miesiąca",
|
||||
lastDay2: "2. ostatni dzień miesiąca",
|
||||
lastDay3: "3. ostatni dzień miesiąca",
|
||||
lastDay4: "4. ostatni dzień miesiąca",
|
||||
"No Maintenance": "Brak konserwacji",
|
||||
pauseMaintenanceMsg: "Jesteś pewien, że chcesz zatrzymać?",
|
||||
"maintenanceStatus-under-maintenance": "Podczas konserwacji",
|
||||
"maintenanceStatus-inactive": "Nieaktywny",
|
||||
"maintenanceStatus-scheduled": "Zaplanowany",
|
||||
"maintenanceStatus-ended": "Zakończony",
|
||||
"maintenanceStatus-unknown": "Nieznany",
|
||||
"Display Timezone": "Wyświetlana strefa czasowa",
|
||||
"Server Timezone": "Strefa czasowa serwera",
|
||||
statusPageMaintenanceEndDate: "Koniec",
|
||||
};
|
||||
|
@@ -2,7 +2,7 @@ export default {
|
||||
languageName: "简体中文",
|
||||
checkEverySecond: "检测频率 {0} 秒",
|
||||
retryCheckEverySecond: "重试间隔 {0} 秒",
|
||||
retriesDescription: "服务被标记为故障并发送通知之前得最大重试次数",
|
||||
retriesDescription: "服务被标记为故障并发送通知之前的最大重试次数",
|
||||
ignoreTLSError: "忽略 HTTPS 站点的 TLS/SSL 错误",
|
||||
upsideDownModeDescription: "反转状态监控,如果服务可访问,则认为是故障。",
|
||||
maxRedirectDescription: "允许的最大重定向次数。设置为 0 禁用重定向。",
|
||||
|
@@ -382,4 +382,7 @@ export default {
|
||||
setAsDefaultProxyDescription: "預設情況下,新監測器將啟用此代理伺服器。您仍可分別停用各監測器的代理伺服器。",
|
||||
Maintenance: "維護",
|
||||
statusMaintenance: "維護中",
|
||||
"Enable DNS Cache": "啟用 DNS 快取",
|
||||
"Enable": "啟用",
|
||||
"Disable": "停用",
|
||||
};
|
||||
|
@@ -9,11 +9,24 @@ export default {
|
||||
upsideDownModeDescription: "反轉顯示狀態。若服務可以連線,將顯示離線。",
|
||||
maxRedirectDescription: "最大重新導向跟隨次數。設為 0 將停用重新導向。",
|
||||
acceptedStatusCodesDescription: "選擇視為成功回應的狀態碼。",
|
||||
Maintenance: "維護",
|
||||
statusMaintenance: "維護",
|
||||
"Schedule maintenance": "排程維護",
|
||||
"Affected Monitors": "受影響的監測器",
|
||||
"Pick Affected Monitors...": "挑選受影響的監測器...",
|
||||
"Start of maintenance": "維護起始",
|
||||
"All Status Pages": "所有狀態頁",
|
||||
"Select status pages...": "選擇狀態頁...",
|
||||
recurringIntervalMessage: "每日執行 | 每 {0} 天執行",
|
||||
affectedMonitorsDescription: "選擇受目前維護影響的監測器",
|
||||
affectedStatusPages: "在已選取的狀態頁中顯示此維護訊息",
|
||||
atLeastOneMonitor: "至少選擇一個受影響的監測器",
|
||||
passwordNotMatchMsg: "密碼不相符。",
|
||||
notificationDescription: "必須將通知指派給監測器才能運作。",
|
||||
keywordDescription: "HTML 或 JSON 回應的搜尋關鍵字。區分大小寫。",
|
||||
pauseDashboardHome: "暫停",
|
||||
deleteMonitorMsg: "您確定要刪除此監測器嗎?",
|
||||
deleteMaintenanceMsg: "您確定要刪除此維護嗎?",
|
||||
deleteNotificationMsg: "您確定要為所有監測器刪除此通知嗎?",
|
||||
dnsPortDescription: "DNS 伺服器連接埠。預設為 53。您可以隨時變更連接埠。",
|
||||
resolverserverDescription: "Cloudflare 為預設伺服器。您可以隨時更換解析伺服器。",
|
||||
@@ -305,7 +318,7 @@ export default {
|
||||
Method: "方法",
|
||||
Body: "主體",
|
||||
Headers: "標頭",
|
||||
PushUrl: "Push URL",
|
||||
PushUrl: "Push 網址",
|
||||
HeadersInvalidFormat: "要求標頭不是有效的 JSON:",
|
||||
BodyInvalidFormat: "請求主體不是有效的 JSON:",
|
||||
"Monitor History": "監測器歷史紀錄",
|
||||
@@ -582,4 +595,40 @@ export default {
|
||||
goAlert: "GoAlert",
|
||||
backupOutdatedWarning: "過時:由於新功能的增加,且未妥善維護,故此備份功能無法產生或復原完整備份。",
|
||||
backupRecommend: "請直接備份磁碟區或 ./data/ 資料夾。",
|
||||
"Optional": "選填",
|
||||
squadcast: "Squadcast",
|
||||
SendKey: "SendKey",
|
||||
"SMSManager API Docs": "SMSManager API 文件 ",
|
||||
"Gateway Type": "閘道類型",
|
||||
SMSManager: "SMSManager",
|
||||
"You can divide numbers with": "若要除數,您可以使用",
|
||||
"or": "或是",
|
||||
recurringInterval: "間隔",
|
||||
"Recurring": "週期性",
|
||||
strategyManual: "手動切換使用中/非使用中",
|
||||
warningTimezone: "正在使用伺服器的時區",
|
||||
weekdayShortMon: "一",
|
||||
weekdayShortTue: "二",
|
||||
weekdayShortWed: "三",
|
||||
weekdayShortThu: "四",
|
||||
weekdayShortFri: "五",
|
||||
weekdayShortSat: "六",
|
||||
weekdayShortSun: "日",
|
||||
dayOfWeek: "每周特定一天",
|
||||
dayOfMonth: "每月特定一天",
|
||||
lastDay: "最後一天",
|
||||
lastDay1: "每月的最後一天",
|
||||
lastDay2: "每月的倒數第二天",
|
||||
lastDay3: "每月的倒數第三天",
|
||||
lastDay4: "每月的倒數第四天",
|
||||
"No Maintenance": "無維護",
|
||||
pauseMaintenanceMsg: "您確定要暫停嗎?",
|
||||
"maintenanceStatus-under-maintenance": "維護中",
|
||||
"maintenanceStatus-inactive": "非使用中",
|
||||
"maintenanceStatus-scheduled": "已排程",
|
||||
"maintenanceStatus-ended": "已結束",
|
||||
"maintenanceStatus-unknown": "未知",
|
||||
"Display Timezone": "顯示時區",
|
||||
"Server Timezone": "伺服器時區",
|
||||
statusPageMaintenanceEndDate: "結束",
|
||||
};
|
||||
|
@@ -93,7 +93,7 @@
|
||||
<nav v-if="$root.isMobile && $root.loggedIn" class="bottom-nav">
|
||||
<router-link to="/dashboard" class="nav-link">
|
||||
<div><font-awesome-icon icon="tachometer-alt" /></div>
|
||||
{{ $t("Dashboard") }}
|
||||
{{ $t("Home") }}
|
||||
</router-link>
|
||||
|
||||
<router-link to="/list" class="nav-link">
|
||||
|
@@ -2,6 +2,7 @@ import { io } from "socket.io-client";
|
||||
import { useToast } from "vue-toastification";
|
||||
import jwtDecode from "jwt-decode";
|
||||
import Favico from "favico.js";
|
||||
import dayjs from "dayjs";
|
||||
const toast = useToast();
|
||||
|
||||
let socket;
|
||||
@@ -58,7 +59,6 @@ export default {
|
||||
},
|
||||
|
||||
created() {
|
||||
window.addEventListener("resize", this.onResize);
|
||||
this.initSocketIO();
|
||||
},
|
||||
|
||||
@@ -272,6 +272,10 @@ export default {
|
||||
socket.on("cloudflared_message", (res) => this.cloudflared.message = res);
|
||||
socket.on("cloudflared_errorMessage", (res) => this.cloudflared.errorMessage = res);
|
||||
socket.on("cloudflared_token", (res) => this.cloudflared.cloudflareTunnelToken = res);
|
||||
|
||||
socket.on("initServerTimezone", () => {
|
||||
socket.emit("initServerTimezone", dayjs.tz.guess());
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
@@ -89,7 +89,7 @@
|
||||
<label for="strategy" class="form-label">{{ $t("Strategy") }}</label>
|
||||
<select id="strategy" v-model="maintenance.strategy" class="form-select">
|
||||
<option value="manual">{{ $t("strategyManual") }}</option>
|
||||
<option value="single">Single Maintenance Window</option>
|
||||
<option value="single">{{ $t("Single Maintenance Window") }}</option>
|
||||
<option value="recurring-interval">{{ $t("Recurring") }} - {{ $t("recurringInterval") }}</option>
|
||||
<option value="recurring-weekday">{{ $t("Recurring") }} - {{ $t("dayOfWeek") }}</option>
|
||||
<option value="recurring-day-of-month">{{ $t("Recurring") }} - {{ $t("dayOfMonth") }}</option>
|
||||
@@ -284,7 +284,7 @@ export default {
|
||||
},
|
||||
{
|
||||
id: "weekday4",
|
||||
langKey: "weekdayShortTue",
|
||||
langKey: "weekdayShortThu",
|
||||
value: 4,
|
||||
},
|
||||
{
|
||||
|
@@ -11,7 +11,7 @@
|
||||
<div class="my-3">
|
||||
<label for="type" class="form-label">{{ $t("Monitor Type") }}</label>
|
||||
<select id="type" v-model="monitor.type" class="form-select">
|
||||
<optgroup label="General Monitor Type">
|
||||
<optgroup :label="$t('General Monitor Type')">
|
||||
<option value="http">
|
||||
HTTP(s)
|
||||
</option>
|
||||
@@ -24,6 +24,9 @@
|
||||
<option value="keyword">
|
||||
HTTP(s) - {{ $t("Keyword") }}
|
||||
</option>
|
||||
<option value="grpc-keyword">
|
||||
gRPC(s) - {{ $t("Keyword") }}
|
||||
</option>
|
||||
<option value="dns">
|
||||
DNS
|
||||
</option>
|
||||
@@ -32,13 +35,13 @@
|
||||
</option>
|
||||
</optgroup>
|
||||
|
||||
<optgroup label="Passive Monitor Type">
|
||||
<optgroup :label="$t('Passive Monitor Type')">
|
||||
<option value="push">
|
||||
Push
|
||||
</option>
|
||||
</optgroup>
|
||||
|
||||
<optgroup label="Specific Monitor Type">
|
||||
<optgroup :label="$t('Specific Monitor Type')">
|
||||
<option value="steam">
|
||||
{{ $t("Steam Game Server") }}
|
||||
</option>
|
||||
@@ -46,11 +49,14 @@
|
||||
MQTT
|
||||
</option>
|
||||
<option value="sqlserver">
|
||||
SQL Server
|
||||
Microsoft SQL Server
|
||||
</option>
|
||||
<option value="postgres">
|
||||
PostgreSQL
|
||||
</option>
|
||||
<option value="mysql">
|
||||
MySQL/MariaDB
|
||||
</option>
|
||||
<option value="radius">
|
||||
Radius
|
||||
</option>
|
||||
@@ -70,6 +76,12 @@
|
||||
<input id="url" v-model="monitor.url" type="url" class="form-control" pattern="https?://.+" required>
|
||||
</div>
|
||||
|
||||
<!-- gRPC URL -->
|
||||
<div v-if="monitor.type === 'grpc-keyword' " class="my-3">
|
||||
<label for="grpc-url" class="form-label">{{ $t("URL") }}</label>
|
||||
<input id="grpc-url" v-model="monitor.grpcUrl" type="url" class="form-control" pattern="[^\:]+:[0-9]{5}" required>
|
||||
</div>
|
||||
|
||||
<!-- Push URL -->
|
||||
<div v-if="monitor.type === 'push' " class="my-3">
|
||||
<label for="push-url" class="form-label">{{ $t("PushUrl") }}</label>
|
||||
@@ -81,7 +93,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Keyword -->
|
||||
<div v-if="monitor.type === 'keyword' " class="my-3">
|
||||
<div v-if="monitor.type === 'keyword' || monitor.type === 'grpc-keyword' " class="my-3">
|
||||
<label for="keyword" class="form-label">{{ $t("Keyword") }}</label>
|
||||
<input id="keyword" v-model="monitor.keyword" type="text" class="form-control" required>
|
||||
<div class="form-text">
|
||||
@@ -235,8 +247,8 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- SQL Server and PostgreSQL -->
|
||||
<template v-if="monitor.type === 'sqlserver' || monitor.type === 'postgres'">
|
||||
<!-- SQL Server / PostgreSQL / MySQL -->
|
||||
<template v-if="monitor.type === 'sqlserver' || monitor.type === 'postgres' || monitor.type === 'mysql'">
|
||||
<div class="my-3">
|
||||
<label for="sqlConnectionString" class="form-label">{{ $t("Connection String") }}</label>
|
||||
|
||||
@@ -246,6 +258,9 @@
|
||||
<template v-if="monitor.type === 'postgres'">
|
||||
<input id="sqlConnectionString" v-model="monitor.databaseConnectionString" type="text" class="form-control" placeholder="postgres://username:password@host:port/database">
|
||||
</template>
|
||||
<template v-if="monitor.type === 'mysql'">
|
||||
<input id="sqlConnectionString" v-model="monitor.databaseConnectionString" type="text" class="form-control" placeholder="mysql://username:password@host:port/database">
|
||||
</template>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<label for="sqlQuery" class="form-label">{{ $t("Query") }}</label>
|
||||
@@ -256,7 +271,7 @@
|
||||
<!-- Interval -->
|
||||
<div class="my-3">
|
||||
<label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label>
|
||||
<input id="interval" v-model="monitor.interval" type="number" class="form-control" required min="20" step="1">
|
||||
<input id="interval" v-model="monitor.interval" type="number" class="form-control" required :min="minInterval" step="1" :max="maxInterval">
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
@@ -272,7 +287,7 @@
|
||||
{{ $t("Heartbeat Retry Interval") }}
|
||||
<span>({{ $t("retryCheckEverySecond", [ monitor.retryInterval ]) }})</span>
|
||||
</label>
|
||||
<input id="retry-interval" v-model="monitor.retryInterval" type="number" class="form-control" required min="20" step="1">
|
||||
<input id="retry-interval" v-model="monitor.retryInterval" type="number" class="form-control" required :min="minInterval" step="1">
|
||||
</div>
|
||||
|
||||
<div class="my-3">
|
||||
@@ -313,7 +328,7 @@
|
||||
</div>
|
||||
|
||||
<!-- HTTP / Keyword only -->
|
||||
<template v-if="monitor.type === 'http' || monitor.type === 'keyword' ">
|
||||
<template v-if="monitor.type === 'http' || monitor.type === 'keyword' || monitor.type === 'grpc-keyword' ">
|
||||
<div class="my-3">
|
||||
<label for="maxRedirects" class="form-label">{{ $t("Max. Redirects") }}</label>
|
||||
<input id="maxRedirects" v-model="monitor.maxredirects" type="number" class="form-control" required min="0" step="1">
|
||||
@@ -491,6 +506,55 @@
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- gRPC Options -->
|
||||
<template v-if="monitor.type === 'grpc-keyword' ">
|
||||
<!-- Proto service enable TLS -->
|
||||
<h2 class="mt-5 mb-2">{{ $t("GRPC Options") }}</h2>
|
||||
<div class="my-3 form-check">
|
||||
<input id="grpc-enable-tls" v-model="monitor.grpcEnableTls" class="form-check-input" type="checkbox" value="">
|
||||
<label class="form-check-label" for="grpc-enable-tls">
|
||||
{{ $t("Enable TLS") }}
|
||||
</label>
|
||||
<div class="form-text">
|
||||
{{ $t("enableGRPCTls") }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- Proto service name data -->
|
||||
<div class="my-3">
|
||||
<label for="protobuf" class="form-label">{{ $t("Proto Service Name") }}</label>
|
||||
<input id="name" v-model="monitor.grpcServiceName" type="text" class="form-control" :placeholder="protoServicePlaceholder" required>
|
||||
</div>
|
||||
|
||||
<!-- Proto method data -->
|
||||
<div class="my-3">
|
||||
<label for="protobuf" class="form-label">{{ $t("Proto Method") }}</label>
|
||||
<input id="name" v-model="monitor.grpcMethod" type="text" class="form-control" :placeholder="protoMethodPlaceholder" required>
|
||||
<div class="form-text">
|
||||
{{ $t("grpcMethodDescription") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Proto data -->
|
||||
<div class="my-3">
|
||||
<label for="protobuf" class="form-label">{{ $t("Proto Content") }}</label>
|
||||
<textarea id="protobuf" v-model="monitor.grpcProtobuf" class="form-control" :placeholder="protoBufDataPlaceholder"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Body -->
|
||||
<div class="my-3">
|
||||
<label for="body" class="form-label">{{ $t("Body") }}</label>
|
||||
<textarea id="body" v-model="monitor.grpcBody" class="form-control" :placeholder="bodyPlaceholder"></textarea>
|
||||
</div>
|
||||
|
||||
<!-- Metadata: temporary disable waiting for next PR allow to send gRPC with metadata -->
|
||||
<template v-if="false">
|
||||
<div class="my-3">
|
||||
<label for="metadata" class="form-label">{{ $t("Metadata") }}</label>
|
||||
<textarea id="metadata" v-model="monitor.grpcMetadata" class="form-control" :placeholder="headersPlaceholder"></textarea>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -511,7 +575,7 @@ import NotificationDialog from "../components/NotificationDialog.vue";
|
||||
import DockerHostDialog from "../components/DockerHostDialog.vue";
|
||||
import ProxyDialog from "../components/ProxyDialog.vue";
|
||||
import TagsManager from "../components/TagsManager.vue";
|
||||
import { genSecret, isDev } from "../util.ts";
|
||||
import { genSecret, isDev, MAX_INTERVAL_SECOND, MIN_INTERVAL_SECOND } from "../util.ts";
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
@@ -527,6 +591,8 @@ export default {
|
||||
|
||||
data() {
|
||||
return {
|
||||
minInterval: MIN_INTERVAL_SECOND,
|
||||
maxInterval: MAX_INTERVAL_SECOND,
|
||||
processing: false,
|
||||
monitor: {
|
||||
notificationIDList: {},
|
||||
@@ -569,6 +635,40 @@ export default {
|
||||
return this.$root.baseURL + "/api/push/" + this.monitor.pushToken + "?status=up&msg=OK&ping=";
|
||||
},
|
||||
|
||||
protoServicePlaceholder() {
|
||||
return this.$t("Example:", [ "Health" ]);
|
||||
},
|
||||
|
||||
protoMethodPlaceholder() {
|
||||
return this.$t("Example:", [ "check" ]);
|
||||
},
|
||||
|
||||
protoBufDataPlaceholder() {
|
||||
return this.$t("Example:", [ `
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.health.v1;
|
||||
|
||||
service Health {
|
||||
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
|
||||
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
|
||||
}
|
||||
|
||||
message HealthCheckRequest {
|
||||
string service = 1;
|
||||
}
|
||||
|
||||
message HealthCheckResponse {
|
||||
enum ServingStatus {
|
||||
UNKNOWN = 0;
|
||||
SERVING = 1;
|
||||
NOT_SERVING = 2;
|
||||
SERVICE_UNKNOWN = 3; // Used only by the Watch method.
|
||||
}
|
||||
ServingStatus status = 1;
|
||||
}
|
||||
` ]);
|
||||
},
|
||||
bodyPlaceholder() {
|
||||
return this.$t("Example:", [ `
|
||||
{
|
||||
|
@@ -185,6 +185,14 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
@import "../assets/vars.scss";
|
||||
|
||||
.mobile {
|
||||
.item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -267,6 +275,11 @@ export default {
|
||||
.buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.btn-group {
|
||||
width: 310px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,19 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="$root.isMobile" class="shadow-box mb-3">
|
||||
<router-link to="/manage-status-page" class="nav-link">
|
||||
<font-awesome-icon icon="stream" /> {{ $t("Status Pages") }}
|
||||
</router-link>
|
||||
<router-link to="/maintenance" class="nav-link">
|
||||
<font-awesome-icon icon="wrench" /> {{ $t("Maintenance") }}
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<h1 v-show="show" class="mb-3">
|
||||
{{ $t("Settings") }}
|
||||
</h1>
|
||||
|
||||
<div class="shadow-box">
|
||||
<div class="shadow-box shadow-box-settings">
|
||||
<div class="row">
|
||||
<div v-if="showSubMenu" class="settings-menu col-lg-3 col-md-5">
|
||||
<router-link
|
||||
@@ -148,6 +157,10 @@ export default {
|
||||
this.settings.entryPage = "dashboard";
|
||||
}
|
||||
|
||||
if (this.settings.dnsCache === undefined) {
|
||||
this.settings.dnsCache = false;
|
||||
}
|
||||
|
||||
if (this.settings.keepDataPeriodDays === undefined) {
|
||||
this.settings.keepDataPeriodDays = 180;
|
||||
}
|
||||
@@ -192,7 +205,7 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
@import "../assets/vars.scss";
|
||||
|
||||
.shadow-box {
|
||||
.shadow-box-settings {
|
||||
padding: 20px;
|
||||
min-height: calc(100vh - 155px);
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
// Backend uses the compiled file util.js
|
||||
// Frontend uses util.ts
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMaintenanceRelativeURL = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0;
|
||||
exports.localToUTC = exports.utcToLocal = exports.utcToISODateTime = exports.isoToUTCDateTime = exports.parseTimeFromTimeObject = exports.parseTimeObject = exports.getMaintenanceRelativeURL = exports.getMonitorRelativeURL = exports.genSecret = exports.getCryptoRandomInt = exports.getRandomInt = exports.getRandomArbitrary = exports.TimeLogger = exports.polyfill = exports.log = exports.debug = exports.ucfirst = exports.sleep = exports.flipStatus = exports.MIN_INTERVAL_SECOND = exports.MAX_INTERVAL_SECOND = exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = exports.SQL_DATETIME_FORMAT = exports.SQL_DATE_FORMAT = exports.STATUS_PAGE_MAINTENANCE = exports.STATUS_PAGE_PARTIAL_DOWN = exports.STATUS_PAGE_ALL_UP = exports.STATUS_PAGE_ALL_DOWN = exports.MAINTENANCE = exports.PENDING = exports.UP = exports.DOWN = exports.appName = exports.isDev = void 0;
|
||||
const dayjs = require("dayjs");
|
||||
exports.isDev = process.env.NODE_ENV === "development";
|
||||
exports.appName = "Uptime Kuma";
|
||||
@@ -22,6 +22,8 @@ exports.STATUS_PAGE_MAINTENANCE = 3;
|
||||
exports.SQL_DATE_FORMAT = "YYYY-MM-DD";
|
||||
exports.SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
|
||||
exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm";
|
||||
exports.MAX_INTERVAL_SECOND = 2073600; // 24 days
|
||||
exports.MIN_INTERVAL_SECOND = 20; // 20 seconds
|
||||
/** Flip the status of s */
|
||||
function flipStatus(s) {
|
||||
if (s === exports.UP) {
|
||||
@@ -99,7 +101,7 @@ class Logger {
|
||||
* @param level Log level. One of INFO, WARN, ERROR, DEBUG or can be customized.
|
||||
*/
|
||||
log(module, msg, level) {
|
||||
if (this.hideLog[level] && this.hideLog[level].includes(module)) {
|
||||
if (this.hideLog[level] && this.hideLog[level].includes(module.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
module = module.toUpperCase();
|
||||
|
@@ -26,6 +26,9 @@ export const SQL_DATE_FORMAT = "YYYY-MM-DD";
|
||||
export const SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
|
||||
export const SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm";
|
||||
|
||||
export const MAX_INTERVAL_SECOND = 2073600; // 24 days
|
||||
export const MIN_INTERVAL_SECOND = 20; // 20 seconds
|
||||
|
||||
/** Flip the status of s */
|
||||
export function flipStatus(s: number) {
|
||||
if (s === UP) {
|
||||
@@ -112,7 +115,7 @@ class Logger {
|
||||
* @param level Log level. One of INFO, WARN, ERROR, DEBUG or can be customized.
|
||||
*/
|
||||
log(module: string, msg: any, level: string) {
|
||||
if (this.hideLog[level] && this.hideLog[level].includes(module)) {
|
||||
if (this.hideLog[level] && this.hideLog[level].includes(module.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user