新逸Cary
3 years ago
committed by
GitHub
68 changed files with 3673 additions and 1452 deletions
Binary file not shown.
@ -0,0 +1,10 @@ |
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. |
|||
BEGIN TRANSACTION; |
|||
|
|||
-- For sendHeartbeatList |
|||
CREATE INDEX monitor_time_index ON heartbeat (monitor_id, time); |
|||
|
|||
-- For sendImportantHeartbeatList |
|||
CREATE INDEX monitor_important_time_index ON heartbeat (monitor_id, important,time); |
|||
|
|||
COMMIT; |
@ -0,0 +1,7 @@ |
|||
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db. |
|||
BEGIN TRANSACTION; |
|||
|
|||
ALTER TABLE notification |
|||
ADD is_default BOOLEAN default 0 NOT NULL; |
|||
|
|||
COMMIT; |
@ -0,0 +1,26 @@ |
|||
# DON'T UPDATE TO alpine3.13, 1.14, see #41. |
|||
FROM node:14-alpine3.12 AS release |
|||
WORKDIR /app |
|||
|
|||
# split the sqlite install here, so that it can caches the arm prebuilt |
|||
RUN apk add --no-cache --virtual .build-deps make g++ python3 python3-dev git && \ |
|||
ln -s /usr/bin/python3 /usr/bin/python && \ |
|||
npm install mapbox/node-sqlite3#593c9d && \ |
|||
apk del .build-deps && \ |
|||
rm -f /usr/bin/python |
|||
|
|||
# Install apprise |
|||
RUN apk add --no-cache python3 py3-cryptography py3-pip py3-six py3-yaml py3-click py3-markdown py3-requests py3-requests-oauthlib |
|||
RUN pip3 --no-cache-dir install apprise && \ |
|||
rm -rf /root/.cache |
|||
|
|||
COPY . . |
|||
RUN npm install --legacy-peer-deps && npm run build && npm prune |
|||
|
|||
EXPOSE 3001 |
|||
VOLUME ["/app/data"] |
|||
HEALTHCHECK --interval=60s --timeout=30s --start-period=180s --retries=5 CMD node extra/healthcheck.js |
|||
CMD ["node", "server/server.js"] |
|||
|
|||
FROM release AS nightly |
|||
RUN npm run mark-as-nightly |
@ -1,19 +1,31 @@ |
|||
let http = require("http"); |
|||
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; |
|||
|
|||
let client; |
|||
|
|||
if (process.env.SSL_KEY && process.env.SSL_CERT) { |
|||
client = require("https"); |
|||
} else { |
|||
client = require("http"); |
|||
} |
|||
|
|||
let options = { |
|||
host: "localhost", |
|||
port: "3001", |
|||
timeout: 2000, |
|||
host: process.env.HOST || "127.0.0.1", |
|||
port: parseInt(process.env.PORT) || 3001, |
|||
timeout: 28 * 1000, |
|||
}; |
|||
let request = http.request(options, (res) => { |
|||
console.log(`STATUS: ${res.statusCode}`); |
|||
if (res.statusCode == 200) { |
|||
|
|||
let request = client.request(options, (res) => { |
|||
console.log(`Health Check OK [Res Code: ${res.statusCode}]`); |
|||
if (res.statusCode === 200) { |
|||
process.exit(0); |
|||
} else { |
|||
process.exit(1); |
|||
} |
|||
}); |
|||
|
|||
request.on("error", function (err) { |
|||
console.log("ERROR"); |
|||
console.error("Health Check ERROR"); |
|||
process.exit(1); |
|||
}); |
|||
|
|||
request.end(); |
|||
|
File diff suppressed because it is too large
@ -0,0 +1,88 @@ |
|||
/* |
|||
* For Client Socket |
|||
*/ |
|||
const { TimeLogger } = require("../src/util"); |
|||
const { R } = require("redbean-node"); |
|||
const { io } = require("./server"); |
|||
|
|||
async function sendNotificationList(socket) { |
|||
const timeLogger = new TimeLogger(); |
|||
|
|||
let result = []; |
|||
let list = await R.find("notification", " user_id = ? ", [ |
|||
socket.userID, |
|||
]); |
|||
|
|||
for (let bean of list) { |
|||
result.push(bean.export()) |
|||
} |
|||
|
|||
io.to(socket.userID).emit("notificationList", result) |
|||
|
|||
timeLogger.print("Send Notification List"); |
|||
|
|||
return list; |
|||
} |
|||
|
|||
/** |
|||
* Send Heartbeat History list to socket |
|||
* @param toUser True = send to all browsers with the same user id, False = send to the current browser only |
|||
* @param overwrite Overwrite client-side's heartbeat list |
|||
*/ |
|||
async function sendHeartbeatList(socket, monitorID, toUser = false, overwrite = false) { |
|||
const timeLogger = new TimeLogger(); |
|||
|
|||
let list = await R.getAll(` |
|||
SELECT * FROM heartbeat |
|||
WHERE monitor_id = ? |
|||
ORDER BY time DESC |
|||
LIMIT 100 |
|||
`, [
|
|||
monitorID, |
|||
]) |
|||
|
|||
let result = list.reverse(); |
|||
|
|||
if (toUser) { |
|||
io.to(socket.userID).emit("heartbeatList", monitorID, result, overwrite); |
|||
} else { |
|||
socket.emit("heartbeatList", monitorID, result, overwrite); |
|||
} |
|||
|
|||
timeLogger.print(`[Monitor: ${monitorID}] sendHeartbeatList`); |
|||
} |
|||
|
|||
/** |
|||
* Important Heart beat list (aka event list) |
|||
* @param socket |
|||
* @param monitorID |
|||
* @param toUser True = send to all browsers with the same user id, False = send to the current browser only |
|||
* @param overwrite Overwrite client-side's heartbeat list |
|||
*/ |
|||
async function sendImportantHeartbeatList(socket, monitorID, toUser = false, overwrite = false) { |
|||
const timeLogger = new TimeLogger(); |
|||
|
|||
let list = await R.find("heartbeat", ` |
|||
monitor_id = ? |
|||
AND important = 1 |
|||
ORDER BY time DESC |
|||
LIMIT 500 |
|||
`, [
|
|||
monitorID, |
|||
]) |
|||
|
|||
timeLogger.print(`[Monitor: ${monitorID}] sendImportantHeartbeatList`); |
|||
|
|||
if (toUser) { |
|||
io.to(socket.userID).emit("importantHeartbeatList", monitorID, list, overwrite); |
|||
} else { |
|||
socket.emit("importantHeartbeatList", monitorID, list, overwrite); |
|||
} |
|||
|
|||
} |
|||
|
|||
module.exports = { |
|||
sendNotificationList, |
|||
sendImportantHeartbeatList, |
|||
sendHeartbeatList, |
|||
} |
@ -0,0 +1,26 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const child_process = require("child_process"); |
|||
|
|||
class Apprise extends NotificationProvider { |
|||
|
|||
name = "apprise"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL]) |
|||
|
|||
let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found"; |
|||
|
|||
if (output) { |
|||
|
|||
if (! output.includes("ERROR")) { |
|||
return "Sent Successfully"; |
|||
} |
|||
|
|||
throw new Error(output) |
|||
} else { |
|||
return "No output from apprise"; |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Apprise; |
@ -0,0 +1,105 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
|
|||
class Discord extends NotificationProvider { |
|||
|
|||
name = "discord"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
const discordDisplayName = notification.discordUsername || "Uptime Kuma"; |
|||
|
|||
// If heartbeatJSON is null, assume we're testing.
|
|||
if (heartbeatJSON == null) { |
|||
let discordtestdata = { |
|||
username: discordDisplayName, |
|||
content: msg, |
|||
} |
|||
await axios.post(notification.discordWebhookUrl, discordtestdata) |
|||
return okMsg; |
|||
} |
|||
|
|||
let url; |
|||
|
|||
if (monitorJSON["type"] === "port") { |
|||
url = monitorJSON["hostname"]; |
|||
if (monitorJSON["port"]) { |
|||
url += ":" + monitorJSON["port"]; |
|||
} |
|||
|
|||
} else { |
|||
url = monitorJSON["url"]; |
|||
} |
|||
|
|||
// If heartbeatJSON is not null, we go into the normal alerting loop.
|
|||
if (heartbeatJSON["status"] == DOWN) { |
|||
let discorddowndata = { |
|||
username: discordDisplayName, |
|||
embeds: [{ |
|||
title: "❌ Your service " + monitorJSON["name"] + " went down. ❌", |
|||
color: 16711680, |
|||
timestamp: heartbeatJSON["time"], |
|||
fields: [ |
|||
{ |
|||
name: "Service Name", |
|||
value: monitorJSON["name"], |
|||
}, |
|||
{ |
|||
name: "Service URL", |
|||
value: url, |
|||
}, |
|||
{ |
|||
name: "Time (UTC)", |
|||
value: heartbeatJSON["time"], |
|||
}, |
|||
{ |
|||
name: "Error", |
|||
value: heartbeatJSON["msg"], |
|||
}, |
|||
], |
|||
}], |
|||
} |
|||
await axios.post(notification.discordWebhookUrl, discorddowndata) |
|||
return okMsg; |
|||
|
|||
} else if (heartbeatJSON["status"] == UP) { |
|||
let discordupdata = { |
|||
username: discordDisplayName, |
|||
embeds: [{ |
|||
title: "✅ Your service " + monitorJSON["name"] + " is up! ✅", |
|||
color: 65280, |
|||
timestamp: heartbeatJSON["time"], |
|||
fields: [ |
|||
{ |
|||
name: "Service Name", |
|||
value: monitorJSON["name"], |
|||
}, |
|||
{ |
|||
name: "Service URL", |
|||
value: url.startsWith("http") ? "[Visit Service](" + url + ")" : url, |
|||
}, |
|||
{ |
|||
name: "Time (UTC)", |
|||
value: heartbeatJSON["time"], |
|||
}, |
|||
{ |
|||
name: "Ping", |
|||
value: heartbeatJSON["ping"] + "ms", |
|||
}, |
|||
], |
|||
}], |
|||
} |
|||
await axios.post(notification.discordWebhookUrl, discordupdata) |
|||
return okMsg; |
|||
} |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
module.exports = Discord; |
@ -0,0 +1,28 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Gotify extends NotificationProvider { |
|||
|
|||
name = "gotify"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
try { |
|||
if (notification.gotifyserverurl && notification.gotifyserverurl.endsWith("/")) { |
|||
notification.gotifyserverurl = notification.gotifyserverurl.slice(0, -1); |
|||
} |
|||
await axios.post(`${notification.gotifyserverurl}/message?token=${notification.gotifyapplicationToken}`, { |
|||
"message": msg, |
|||
"priority": notification.gotifyPriority || 8, |
|||
"title": "Uptime-Kuma", |
|||
}) |
|||
|
|||
return okMsg; |
|||
|
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Gotify; |
@ -0,0 +1,60 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
|
|||
class Line extends NotificationProvider { |
|||
|
|||
name = "line"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
try { |
|||
let lineAPIUrl = "https://api.line.me/v2/bot/message/push"; |
|||
let config = { |
|||
headers: { |
|||
"Content-Type": "application/json", |
|||
"Authorization": "Bearer " + notification.lineChannelAccessToken |
|||
} |
|||
}; |
|||
if (heartbeatJSON == null) { |
|||
let testMessage = { |
|||
"to": notification.lineUserID, |
|||
"messages": [ |
|||
{ |
|||
"type": "text", |
|||
"text": "Test Successful!" |
|||
} |
|||
] |
|||
} |
|||
await axios.post(lineAPIUrl, testMessage, config) |
|||
} else if (heartbeatJSON["status"] == DOWN) { |
|||
let downMessage = { |
|||
"to": notification.lineUserID, |
|||
"messages": [ |
|||
{ |
|||
"type": "text", |
|||
"text": "UptimeKuma Alert: [🔴 Down]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"] |
|||
} |
|||
] |
|||
} |
|||
await axios.post(lineAPIUrl, downMessage, config) |
|||
} else if (heartbeatJSON["status"] == UP) { |
|||
let upMessage = { |
|||
"to": notification.lineUserID, |
|||
"messages": [ |
|||
{ |
|||
"type": "text", |
|||
"text": "UptimeKuma Alert: [✅ Up]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"] |
|||
} |
|||
] |
|||
} |
|||
await axios.post(lineAPIUrl, upMessage, config) |
|||
} |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Line; |
@ -0,0 +1,48 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
|
|||
class LunaSea extends NotificationProvider { |
|||
|
|||
name = "lunasea"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice |
|||
|
|||
try { |
|||
if (heartbeatJSON == null) { |
|||
let testdata = { |
|||
"title": "Uptime Kuma Alert", |
|||
"body": "Testing Successful.", |
|||
} |
|||
await axios.post(lunaseadevice, testdata) |
|||
return okMsg; |
|||
} |
|||
|
|||
if (heartbeatJSON["status"] == DOWN) { |
|||
let downdata = { |
|||
"title": "UptimeKuma Alert: " + monitorJSON["name"], |
|||
"body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], |
|||
} |
|||
await axios.post(lunaseadevice, downdata) |
|||
return okMsg; |
|||
} |
|||
|
|||
if (heartbeatJSON["status"] == UP) { |
|||
let updata = { |
|||
"title": "UptimeKuma Alert: " + monitorJSON["name"], |
|||
"body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], |
|||
} |
|||
await axios.post(lunaseadevice, updata) |
|||
return okMsg; |
|||
} |
|||
|
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
module.exports = LunaSea; |
@ -0,0 +1,123 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const { DOWN, UP } = require("../../src/util"); |
|||
|
|||
class Mattermost extends NotificationProvider { |
|||
|
|||
name = "mattermost"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
try { |
|||
const mattermostUserName = notification.mattermostusername || "Uptime Kuma"; |
|||
// If heartbeatJSON is null, assume we're testing.
|
|||
if (heartbeatJSON == null) { |
|||
let mattermostTestData = { |
|||
username: mattermostUserName, |
|||
text: msg, |
|||
} |
|||
await axios.post(notification.mattermostWebhookUrl, mattermostTestData) |
|||
return okMsg; |
|||
} |
|||
|
|||
const mattermostChannel = notification.mattermostchannel; |
|||
const mattermostIconEmoji = notification.mattermosticonemo; |
|||
const mattermostIconUrl = notification.mattermosticonurl; |
|||
|
|||
if (heartbeatJSON["status"] == DOWN) { |
|||
let mattermostdowndata = { |
|||
username: mattermostUserName, |
|||
text: "Uptime Kuma Alert", |
|||
channel: mattermostChannel, |
|||
icon_emoji: mattermostIconEmoji, |
|||
icon_url: mattermostIconUrl, |
|||
attachments: [ |
|||
{ |
|||
fallback: |
|||
"Your " + |
|||
monitorJSON["name"] + |
|||
" service went down.", |
|||
color: "#FF0000", |
|||
title: |
|||
"❌ " + |
|||
monitorJSON["name"] + |
|||
" service went down. ❌", |
|||
title_link: monitorJSON["url"], |
|||
fields: [ |
|||
{ |
|||
short: true, |
|||
title: "Service Name", |
|||
value: monitorJSON["name"], |
|||
}, |
|||
{ |
|||
short: true, |
|||
title: "Time (UTC)", |
|||
value: heartbeatJSON["time"], |
|||
}, |
|||
{ |
|||
short: false, |
|||
title: "Error", |
|||
value: heartbeatJSON["msg"], |
|||
}, |
|||
], |
|||
}, |
|||
], |
|||
}; |
|||
await axios.post( |
|||
notification.mattermostWebhookUrl, |
|||
mattermostdowndata |
|||
); |
|||
return okMsg; |
|||
} else if (heartbeatJSON["status"] == UP) { |
|||
let mattermostupdata = { |
|||
username: mattermostUserName, |
|||
text: "Uptime Kuma Alert", |
|||
channel: mattermostChannel, |
|||
icon_emoji: mattermostIconEmoji, |
|||
icon_url: mattermostIconUrl, |
|||
attachments: [ |
|||
{ |
|||
fallback: |
|||
"Your " + |
|||
monitorJSON["name"] + |
|||
" service went up!", |
|||
color: "#32CD32", |
|||
title: |
|||
"✅ " + |
|||
monitorJSON["name"] + |
|||
" service went up! ✅", |
|||
title_link: monitorJSON["url"], |
|||
fields: [ |
|||
{ |
|||
short: true, |
|||
title: "Service Name", |
|||
value: monitorJSON["name"], |
|||
}, |
|||
{ |
|||
short: true, |
|||
title: "Time (UTC)", |
|||
value: heartbeatJSON["time"], |
|||
}, |
|||
{ |
|||
short: false, |
|||
title: "Ping", |
|||
value: heartbeatJSON["ping"] + "ms", |
|||
}, |
|||
], |
|||
}, |
|||
], |
|||
}; |
|||
await axios.post( |
|||
notification.mattermostWebhookUrl, |
|||
mattermostupdata |
|||
); |
|||
return okMsg; |
|||
} |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
module.exports = Mattermost; |
@ -0,0 +1,36 @@ |
|||
class NotificationProvider { |
|||
|
|||
/** |
|||
* Notification Provider Name |
|||
* @type string |
|||
*/ |
|||
name = undefined; |
|||
|
|||
/** |
|||
* @param notification : BeanModel |
|||
* @param msg : string General Message |
|||
* @param monitorJSON : object Monitor details (For Up/Down only) |
|||
* @param heartbeatJSON : object Heartbeat details (For Up/Down only) |
|||
* @returns {Promise<string>} Return Successful Message |
|||
* Throw Error with fail msg |
|||
*/ |
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
throw new Error("Have to override Notification.send(...)"); |
|||
} |
|||
|
|||
throwGeneralAxiosError(error) { |
|||
let msg = "Error: " + error + " "; |
|||
|
|||
if (error.response && error.response.data) { |
|||
if (typeof error.response.data === "string") { |
|||
msg += error.response.data; |
|||
} else { |
|||
msg += JSON.stringify(error.response.data) |
|||
} |
|||
} |
|||
|
|||
throw new Error(msg) |
|||
} |
|||
} |
|||
|
|||
module.exports = NotificationProvider; |
@ -0,0 +1,40 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Octopush extends NotificationProvider { |
|||
|
|||
name = "octopush"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
let config = { |
|||
headers: { |
|||
"api-key": notification.octopushAPIKey, |
|||
"api-login": notification.octopushLogin, |
|||
"cache-control": "no-cache" |
|||
} |
|||
}; |
|||
let data = { |
|||
"recipients": [ |
|||
{ |
|||
"phone_number": notification.octopushPhoneNumber |
|||
} |
|||
], |
|||
//octopush not supporting non ascii char
|
|||
"text": msg.replace(/[^\x00-\x7F]/g, ""), |
|||
"type": notification.octopushSMSType, |
|||
"purpose": "alert", |
|||
"sender": notification.octopushSenderName |
|||
}; |
|||
|
|||
await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config) |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Octopush; |
@ -0,0 +1,50 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
const { DOWN, UP } = require("../../src/util"); |
|||
|
|||
class Pushbullet extends NotificationProvider { |
|||
|
|||
name = "pushbullet"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
let pushbulletUrl = "https://api.pushbullet.com/v2/pushes"; |
|||
let config = { |
|||
headers: { |
|||
"Access-Token": notification.pushbulletAccessToken, |
|||
"Content-Type": "application/json" |
|||
} |
|||
}; |
|||
if (heartbeatJSON == null) { |
|||
let testdata = { |
|||
"type": "note", |
|||
"title": "Uptime Kuma Alert", |
|||
"body": "Testing Successful.", |
|||
} |
|||
await axios.post(pushbulletUrl, testdata, config) |
|||
} else if (heartbeatJSON["status"] == DOWN) { |
|||
let downdata = { |
|||
"type": "note", |
|||
"title": "UptimeKuma Alert: " + monitorJSON["name"], |
|||
"body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], |
|||
} |
|||
await axios.post(pushbulletUrl, downdata, config) |
|||
} else if (heartbeatJSON["status"] == UP) { |
|||
let updata = { |
|||
"type": "note", |
|||
"title": "UptimeKuma Alert: " + monitorJSON["name"], |
|||
"body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"], |
|||
} |
|||
await axios.post(pushbulletUrl, updata, config) |
|||
} |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Pushbullet; |
@ -0,0 +1,49 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Pushover extends NotificationProvider { |
|||
|
|||
name = "pushover"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
let pushoverlink = "https://api.pushover.net/1/messages.json" |
|||
|
|||
try { |
|||
if (heartbeatJSON == null) { |
|||
let data = { |
|||
"message": "<b>Uptime Kuma Pushover testing successful.</b>", |
|||
"user": notification.pushoveruserkey, |
|||
"token": notification.pushoverapptoken, |
|||
"sound": notification.pushoversounds, |
|||
"priority": notification.pushoverpriority, |
|||
"title": notification.pushovertitle, |
|||
"retry": "30", |
|||
"expire": "3600", |
|||
"html": 1, |
|||
} |
|||
await axios.post(pushoverlink, data) |
|||
return okMsg; |
|||
} |
|||
|
|||
let data = { |
|||
"message": "<b>Uptime Kuma Alert</b>\n\n<b>Message</b>:" + msg + "\n<b>Time (UTC)</b>:" + heartbeatJSON["time"], |
|||
"user": notification.pushoveruserkey, |
|||
"token": notification.pushoverapptoken, |
|||
"sound": notification.pushoversounds, |
|||
"priority": notification.pushoverpriority, |
|||
"title": notification.pushovertitle, |
|||
"retry": "30", |
|||
"expire": "3600", |
|||
"html": 1, |
|||
} |
|||
await axios.post(pushoverlink, data) |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
module.exports = Pushover; |
@ -0,0 +1,30 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Pushy extends NotificationProvider { |
|||
|
|||
name = "pushy"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
await axios.post(`https://api.pushy.me/push?api_key=${notification.pushyAPIKey}`, { |
|||
"to": notification.pushyToken, |
|||
"data": { |
|||
"message": "Uptime-Kuma" |
|||
}, |
|||
"notification": { |
|||
"body": msg, |
|||
"badge": 1, |
|||
"sound": "ping.aiff" |
|||
} |
|||
}) |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Pushy; |
@ -0,0 +1,46 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class RocketChat extends NotificationProvider { |
|||
|
|||
name = "rocket.chat"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
try { |
|||
if (heartbeatJSON == null) { |
|||
let data = { |
|||
"text": "Uptime Kuma Rocket.chat testing successful.", |
|||
"channel": notification.rocketchannel, |
|||
"username": notification.rocketusername, |
|||
"icon_emoji": notification.rocketiconemo, |
|||
} |
|||
await axios.post(notification.rocketwebhookURL, data) |
|||
return okMsg; |
|||
} |
|||
|
|||
const time = heartbeatJSON["time"]; |
|||
let data = { |
|||
"text": "Uptime Kuma Alert", |
|||
"channel": notification.rocketchannel, |
|||
"username": notification.rocketusername, |
|||
"icon_emoji": notification.rocketiconemo, |
|||
"attachments": [ |
|||
{ |
|||
"title": "Uptime Kuma Alert *Time (UTC)*\n" + time, |
|||
"title_link": notification.rocketbutton, |
|||
"text": "*Message*\n" + msg, |
|||
"color": "#32cd32" |
|||
} |
|||
] |
|||
} |
|||
await axios.post(notification.rocketwebhookURL, data) |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
module.exports = RocketChat; |
@ -0,0 +1,27 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Signal extends NotificationProvider { |
|||
|
|||
name = "signal"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
let data = { |
|||
"message": msg, |
|||
"number": notification.signalNumber, |
|||
"recipients": notification.signalRecipients.replace(/\s/g, "").split(","), |
|||
}; |
|||
let config = {}; |
|||
|
|||
await axios.post(notification.signalURL, data, config) |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Signal; |
@ -0,0 +1,70 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Slack extends NotificationProvider { |
|||
|
|||
name = "slack"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
try { |
|||
if (heartbeatJSON == null) { |
|||
let data = { |
|||
"text": "Uptime Kuma Slack testing successful.", |
|||
"channel": notification.slackchannel, |
|||
"username": notification.slackusername, |
|||
"icon_emoji": notification.slackiconemo, |
|||
} |
|||
await axios.post(notification.slackwebhookURL, data) |
|||
return okMsg; |
|||
} |
|||
|
|||
const time = heartbeatJSON["time"]; |
|||
let data = { |
|||
"text": "Uptime Kuma Alert", |
|||
"channel": notification.slackchannel, |
|||
"username": notification.slackusername, |
|||
"icon_emoji": notification.slackiconemo, |
|||
"blocks": [{ |
|||
"type": "header", |
|||
"text": { |
|||
"type": "plain_text", |
|||
"text": "Uptime Kuma Alert", |
|||
}, |
|||
}, |
|||
{ |
|||
"type": "section", |
|||
"fields": [{ |
|||
"type": "mrkdwn", |
|||
"text": "*Message*\n" + msg, |
|||
}, |
|||
{ |
|||
"type": "mrkdwn", |
|||
"text": "*Time (UTC)*\n" + time, |
|||
}], |
|||
}, |
|||
{ |
|||
"type": "actions", |
|||
"elements": [ |
|||
{ |
|||
"type": "button", |
|||
"text": { |
|||
"type": "plain_text", |
|||
"text": "Visit Uptime Kuma", |
|||
}, |
|||
"value": "Uptime-Kuma", |
|||
"url": notification.slackbutton || "https://github.com/louislam/uptime-kuma", |
|||
}, |
|||
], |
|||
}], |
|||
} |
|||
await axios.post(notification.slackwebhookURL, data) |
|||
return okMsg; |
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
|
|||
} |
|||
} |
|||
|
|||
module.exports = Slack; |
@ -0,0 +1,48 @@ |
|||
const nodemailer = require("nodemailer"); |
|||
const NotificationProvider = require("./notification-provider"); |
|||
|
|||
class SMTP extends NotificationProvider { |
|||
|
|||
name = "smtp"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
|
|||
const config = { |
|||
host: notification.smtpHost, |
|||
port: notification.smtpPort, |
|||
secure: notification.smtpSecure, |
|||
}; |
|||
|
|||
// Should fix the issue in https://github.com/louislam/uptime-kuma/issues/26#issuecomment-896373904
|
|||
if (notification.smtpUsername || notification.smtpPassword) { |
|||
config.auth = { |
|||
user: notification.smtpUsername, |
|||
pass: notification.smtpPassword, |
|||
}; |
|||
} |
|||
|
|||
let transporter = nodemailer.createTransport(config); |
|||
|
|||
let bodyTextContent = msg; |
|||
if (heartbeatJSON) { |
|||
bodyTextContent = `${msg}\nTime (UTC): ${heartbeatJSON["time"]}`; |
|||
} |
|||
|
|||
// send mail with defined transport object
|
|||
await transporter.sendMail({ |
|||
from: notification.smtpFrom, |
|||
cc: notification.smtpCC, |
|||
bcc: notification.smtpBCC, |
|||
to: notification.smtpTo, |
|||
subject: msg, |
|||
text: bodyTextContent, |
|||
tls: { |
|||
rejectUnauthorized: notification.smtpIgnoreTLSError || false, |
|||
}, |
|||
}); |
|||
|
|||
return "Sent Successfully."; |
|||
} |
|||
} |
|||
|
|||
module.exports = SMTP; |
@ -0,0 +1,27 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
|
|||
class Telegram extends NotificationProvider { |
|||
|
|||
name = "telegram"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
await axios.get(`https://api.telegram.org/bot${notification.telegramBotToken}/sendMessage`, { |
|||
params: { |
|||
chat_id: notification.telegramChatID, |
|||
text: msg, |
|||
}, |
|||
}) |
|||
return okMsg; |
|||
|
|||
} catch (error) { |
|||
let msg = (error.response.data.description) ? error.response.data.description : "Error without description" |
|||
throw new Error(msg) |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = Telegram; |
@ -0,0 +1,44 @@ |
|||
const NotificationProvider = require("./notification-provider"); |
|||
const axios = require("axios"); |
|||
const FormData = require("form-data"); |
|||
|
|||
class Webhook extends NotificationProvider { |
|||
|
|||
name = "webhook"; |
|||
|
|||
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) { |
|||
let okMsg = "Sent Successfully. "; |
|||
|
|||
try { |
|||
let data = { |
|||
heartbeat: heartbeatJSON, |
|||
monitor: monitorJSON, |
|||
msg, |
|||
}; |
|||
let finalData; |
|||
let config = {}; |
|||
|
|||
if (notification.webhookContentType === "form-data") { |
|||
finalData = new FormData(); |
|||
finalData.append("data", JSON.stringify(data)); |
|||
|
|||
config = { |
|||
headers: finalData.getHeaders(), |
|||
} |
|||
|
|||
} else { |
|||
finalData = data; |
|||
} |
|||
|
|||
await axios.post(notification.webhookURL, finalData, config) |
|||
return okMsg; |
|||
|
|||
} catch (error) { |
|||
this.throwGeneralAxiosError(error) |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
|
|||
module.exports = Webhook; |
@ -0,0 +1,78 @@ |
|||
<template> |
|||
<div class="input-group mb-3"> |
|||
<input |
|||
ref="input" |
|||
v-model="model" |
|||
:type="visibility" |
|||
class="form-control" |
|||
:placeholder="placeholder" |
|||
:maxlength="maxlength" |
|||
:autocomplete="autocomplete" |
|||
:required="required" |
|||
:readonly="readonly" |
|||
> |
|||
|
|||
<a v-if="visibility == 'password'" class="btn btn-outline-primary" @click="showInput()"> |
|||
<font-awesome-icon icon="eye" /> |
|||
</a> |
|||
<a v-if="visibility == 'text'" class="btn btn-outline-primary" @click="hideInput()"> |
|||
<font-awesome-icon icon="eye-slash" /> |
|||
</a> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
modelValue: { |
|||
type: String, |
|||
default: "" |
|||
}, |
|||
placeholder: { |
|||
type: String, |
|||
default: "" |
|||
}, |
|||
maxlength: { |
|||
type: Number, |
|||
default: 255 |
|||
}, |
|||
autocomplete: { |
|||
type: String, |
|||
default: undefined, |
|||
}, |
|||
required: { |
|||
type: Boolean |
|||
}, |
|||
readonly: { |
|||
type: String, |
|||
default: undefined, |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
visibility: "password", |
|||
} |
|||
}, |
|||
computed: { |
|||
model: { |
|||
get() { |
|||
return this.modelValue |
|||
}, |
|||
set(value) { |
|||
this.$emit("update:modelValue", value) |
|||
} |
|||
} |
|||
}, |
|||
created() { |
|||
|
|||
}, |
|||
methods: { |
|||
showInput() { |
|||
this.visibility = "text"; |
|||
}, |
|||
hideInput() { |
|||
this.visibility = "password"; |
|||
}, |
|||
} |
|||
} |
|||
</script> |
@ -0,0 +1,75 @@ |
|||
<template> |
|||
<div class="mb-3"> |
|||
<label for="hostname" class="form-label">{{ $t("Hostname") }}</label> |
|||
<input id="hostname" v-model="$parent.notification.smtpHost" type="text" class="form-control" required> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="port" class="form-label">{{ $t("Port") }}</label> |
|||
<input id="port" v-model="$parent.notification.smtpPort" type="number" class="form-control" required min="0" max="65535" step="1"> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="secure" class="form-label">Secure</label> |
|||
<select id="secure" v-model="$parent.notification.smtpSecure" class="form-select"> |
|||
<option :value="false">None / STARTTLS (25, 587)</option> |
|||
<option :value="true">TLS (465)</option> |
|||
</select> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<div class="form-check"> |
|||
<input id="ignore-tls-error" v-model="$parent.notification.smtpIgnoreTLSError" class="form-check-input" type="checkbox" value=""> |
|||
<label class="form-check-label" for="ignore-tls-error"> |
|||
Ignore TLS Error |
|||
</label> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="username" class="form-label">{{ $t("Username") }}</label> |
|||
<input id="username" v-model="$parent.notification.smtpUsername" type="text" class="form-control" autocomplete="false"> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="password" class="form-label">{{ $t("Password") }}</label> |
|||
<HiddenInput id="password" v-model="$parent.notification.smtpPassword" :required="true" autocomplete="one-time-code"></HiddenInput> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="from-email" class="form-label">From Email</label> |
|||
<input id="from-email" v-model="$parent.notification.smtpFrom" type="text" class="form-control" required autocomplete="false" placeholder=""Uptime Kuma" <example@kuma.pet>"> |
|||
<div class="form-text"> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="to-email" class="form-label">To Email</label> |
|||
<input id="to-email" v-model="$parent.notification.smtpTo" type="text" class="form-control" required autocomplete="false" placeholder="example2@kuma.pet, example3@kuma.pet"> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="to-cc" class="form-label">CC</label> |
|||
<input id="to-cc" v-model="$parent.notification.smtpCC" type="text" class="form-control" autocomplete="false"> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="to-bcc" class="form-label">BCC</label> |
|||
<input id="to-bcc" v-model="$parent.notification.smtpBCC" type="text" class="form-control" autocomplete="false"> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import HiddenInput from "../HiddenInput.vue"; |
|||
|
|||
export default { |
|||
components: { |
|||
HiddenInput, |
|||
}, |
|||
data() { |
|||
return { |
|||
name: "smtp", |
|||
} |
|||
}, |
|||
} |
|||
</script> |
@ -0,0 +1,96 @@ |
|||
<template> |
|||
<div class="mb-3"> |
|||
<label for="telegram-bot-token" class="form-label">Bot Token</label> |
|||
<HiddenInput id="telegram-bot-token" v-model="$parent.notification.telegramBotToken" :required="true" autocomplete="one-time-code"></HiddenInput> |
|||
<div class="form-text"> |
|||
You can get a token from <a href="https://t.me/BotFather" target="_blank">https://t.me/BotFather</a>. |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="mb-3"> |
|||
<label for="telegram-chat-id" class="form-label">Chat ID</label> |
|||
|
|||
<div class="input-group mb-3"> |
|||
<input id="telegram-chat-id" v-model="$parent.notification.telegramChatID" type="text" class="form-control" required> |
|||
<button v-if="$parent.notification.telegramBotToken" class="btn btn-outline-secondary" type="button" @click="autoGetTelegramChatID"> |
|||
{{ $t("Auto Get") }} |
|||
</button> |
|||
</div> |
|||
|
|||
<div class="form-text"> |
|||
Support Direct Chat / Group / Channel's Chat ID |
|||
|
|||
<p style="margin-top: 8px;"> |
|||
You can get your chat id by sending message to the bot and go to this url to view the chat_id: |
|||
</p> |
|||
|
|||
<p style="margin-top: 8px;"> |
|||
<template v-if="$parent.notification.telegramBotToken"> |
|||
<a :href="telegramGetUpdatesURL" target="_blank" style="word-break: break-word;">{{ telegramGetUpdatesURL }}</a> |
|||
</template> |
|||
|
|||
<template v-else> |
|||
{{ telegramGetUpdatesURL }} |
|||
</template> |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import HiddenInput from "../HiddenInput.vue"; |
|||
import axios from "axios"; |
|||
import { useToast } from "vue-toastification" |
|||
const toast = useToast(); |
|||
|
|||
export default { |
|||
components: { |
|||
HiddenInput, |
|||
}, |
|||
data() { |
|||
return { |
|||
name: "telegram", |
|||
} |
|||
}, |
|||
computed: { |
|||
telegramGetUpdatesURL() { |
|||
let token = "<YOUR BOT TOKEN HERE>" |
|||
|
|||
if (this.$parent.notification.telegramBotToken) { |
|||
token = this.$parent.notification.telegramBotToken; |
|||
} |
|||
|
|||
return `https://api.telegram.org/bot${token}/getUpdates`; |
|||
}, |
|||
}, |
|||
mounted() { |
|||
|
|||
}, |
|||
methods: { |
|||
async autoGetTelegramChatID() { |
|||
try { |
|||
let res = await axios.get(this.telegramGetUpdatesURL) |
|||
|
|||
if (res.data.result.length >= 1) { |
|||
let update = res.data.result[res.data.result.length - 1] |
|||
|
|||
if (update.channel_post) { |
|||
this.notification.telegramChatID = update.channel_post.chat.id; |
|||
} else if (update.message) { |
|||
this.notification.telegramChatID = update.message.chat.id; |
|||
} else { |
|||
throw new Error("Chat ID is not found, please send a message to this bot first") |
|||
} |
|||
|
|||
} else { |
|||
throw new Error("Chat ID is not found, please send a message to this bot first") |
|||
} |
|||
|
|||
} catch (error) { |
|||
toast.error(error.message) |
|||
} |
|||
|
|||
}, |
|||
} |
|||
} |
|||
</script> |
@ -1,10 +1,10 @@ |
|||
import { library } from "@fortawesome/fontawesome-svg-core" |
|||
import { faCog, faEdit, faPlus, faPause, faPlay, faTachometerAlt, faTrash, faList, faArrowAltCircleUp } from "@fortawesome/free-solid-svg-icons" |
|||
import { faCog, faEdit, faPlus, faPause, faPlay, faTachometerAlt, faTrash, faList, faArrowAltCircleUp, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons" |
|||
//import { fa } from '@fortawesome/free-regular-svg-icons'
|
|||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome" |
|||
|
|||
// Add Free Font Awesome Icons here
|
|||
// https://fontawesome.com/v5.15/icons?d=gallery&p=2&s=solid&m=free
|
|||
library.add(faCog, faEdit, faPlus, faPause, faPlay, faTachometerAlt, faTrash, faList, faArrowAltCircleUp); |
|||
library.add(faCog, faEdit, faPlus, faPause, faPlay, faTachometerAlt, faTrash, faList, faArrowAltCircleUp, faEye, faEyeSlash); |
|||
|
|||
export { FontAwesomeIcon } |
|||
|
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "Español", |
|||
checkEverySecond: "Comprobar cada {0} segundos.", |
|||
"Avg.": "Media. ", |
|||
retriesDescription: "Número máximo de intentos antes de que el servicio se marque como CAÍDO y una notificación sea enviada.", |
|||
ignoreTLSError: "Ignorar error TLS/SSL para sitios web HTTPS", |
|||
upsideDownModeDescription: "Invertir el estado. Si el servicio es alcanzable, está CAÍDO.", |
|||
maxRedirectDescription: "Número máximo de direcciones a seguir. Establecer a 0 para deshabilitar.", |
|||
acceptedStatusCodesDescription: "Seleccionar los códigos de estado que se consideran como respuesta exitosa.", |
|||
passwordNotMatchMsg: "La contraseña repetida no coincide.", |
|||
notificationDescription: "Por favor asigne una notificación a el/los monitor(es) para hacerlos funcional(es).", |
|||
keywordDescription: "Palabra clave en HTML plano o respuesta JSON y es sensible a mayúsculas", |
|||
pauseDashboardHome: "Pausar", |
|||
deleteMonitorMsg: "¿Seguro que quieres eliminar este monitor?", |
|||
deleteNotificationMsg: "¿Seguro que quieres eliminar esta notificación para todos los monitores?", |
|||
resoverserverDescription: "Cloudflare es el servidor por defecto, puedes cambiar el servidor de resolución en cualquier momento.", |
|||
rrtypeDescription: "Selecciona el tipo de registro que quieres monitorizar", |
|||
pauseMonitorMsg: "¿Seguro que quieres pausar?", |
|||
Settings: "Ajustes", |
|||
Dashboard: "Panel", |
|||
"New Update": "Vueva actualización", |
|||
Language: "Idioma", |
|||
Appearance: "Apariencia", |
|||
Theme: "Tema", |
|||
General: "General", |
|||
Version: "Versión", |
|||
"Check Update On GitHub": "Comprobar actualizaciones en GitHub", |
|||
List: "Lista", |
|||
Add: "Añadir", |
|||
"Add New Monitor": "Añadir nuevo monitor", |
|||
"Quick Stats": "Estadísticas rápidas", |
|||
Up: "Funcional", |
|||
Down: "Caído", |
|||
Pending: "Pendiente", |
|||
Unknown: "Desconociso", |
|||
Pause: "Pausa", |
|||
Name: "Nombre", |
|||
Status: "Estado", |
|||
DateTime: "Fecha y Hora", |
|||
Message: "Mensaje", |
|||
"No important events": "No hay eventos importantes", |
|||
Resume: "Reanudar", |
|||
Edit: "Editar", |
|||
Delete: "Eliminar", |
|||
Current: "Actual", |
|||
Uptime: "Tiempo activo", |
|||
"Cert Exp.": "Caducidad cert.", |
|||
days: "días", |
|||
day: "día", |
|||
"-day": "-día", |
|||
hour: "hora", |
|||
"-hour": "-hora", |
|||
Response: "Respuesta", |
|||
Ping: "Ping", |
|||
"Monitor Type": "Tipo de Monitor", |
|||
Keyword: "Palabra clave", |
|||
"Friendly Name": "Nombre sencillo", |
|||
URL: "URL", |
|||
Hostname: "Nombre del host", |
|||
Port: "Puerto", |
|||
"Heartbeat Interval": "Intervalo de latido", |
|||
Retries: "Reintentos", |
|||
Advanced: "Avanzado", |
|||
"Upside Down Mode": "Modo invertido", |
|||
"Max. Redirects": "Máx. redirecciones", |
|||
"Accepted Status Codes": "Códigos de estado aceptados", |
|||
Save: "Guardar", |
|||
Notifications: "Notificaciones", |
|||
"Not available, please setup.": "No disponible, por favor configurar.", |
|||
"Setup Notification": "Configurar notificación", |
|||
Light: "Claro", |
|||
Dark: "Oscuro", |
|||
Auto: "Auto", |
|||
"Theme - Heartbeat Bar": "Tema - Barra de intervalo de latido", |
|||
Normal: "Normal", |
|||
Bottom: "Abajo", |
|||
None: "Ninguno", |
|||
Timezone: "Zona horaria", |
|||
"Search Engine Visibility": "Visibilidad motor de búsqueda", |
|||
"Allow indexing": "Permitir indexación", |
|||
"Discourage search engines from indexing site": "Disuadir a los motores de búsqueda de indexar el sitio", |
|||
"Change Password": "Cambiar contraseña", |
|||
"Current Password": "Contraseña actual", |
|||
"New Password": "Nueva contraseña", |
|||
"Repeat New Password": "Repetir nueva contraseña", |
|||
"Update Password": "Actualizar contraseña", |
|||
"Disable Auth": "Deshabilitar Autenticación ", |
|||
"Enable Auth": "Habilitar Autenticación ", |
|||
Logout: "Cerrar sesión", |
|||
Leave: "Salir", |
|||
"I understand, please disable": "Lo comprendo, por favor deshabilitar", |
|||
Confirm: "Confirmar", |
|||
Yes: "Sí", |
|||
No: "No", |
|||
Username: "Usuario", |
|||
Password: "Contraseña", |
|||
"Remember me": "Recordarme", |
|||
Login: "Acceso", |
|||
"No Monitors, please": "Sin monitores, por favor", |
|||
"add one": "añade uno", |
|||
"Notification Type": "Tipo de notificación", |
|||
Email: "Email", |
|||
Test: "Test", |
|||
"Certificate Info": "Información del certificado ", |
|||
"Resolver Server": "Servidor de resolución", |
|||
"Resource Record Type": "Tipo de Registro", |
|||
"Last Result": "Último resultado", |
|||
"Create your admin account": "Crea tu cuenta de administrador", |
|||
"Repeat Password": "Repetir contraseña", |
|||
respTime: "Tiempo de resp. (ms)", |
|||
notAvailableShort: "N/A", |
|||
Create: "Create", |
|||
clearEventsMsg: "Are you sure want to delete all events for this monitor?", |
|||
clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |
|||
confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |
|||
"Clear Data": "Clear Data", |
|||
Events: "Events", |
|||
Heartbeats: "Heartbeats", |
|||
"Auto Get": "Auto Get", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "eesti", |
|||
checkEverySecond: "Kontrolli {0} sekundilise vahega.", |
|||
"Avg.": "≈ ", |
|||
retriesDescription: "Mitu korda tuleb kontrollida, mille järel märkida 'maas' ja saata välja teavitus.", |
|||
ignoreTLSError: "Eira TLS/SSL viga HTTPS veebisaitidel.", |
|||
upsideDownModeDescription: "Käitle teenuse saadavust rikkena, teenuse kättesaamatust töötavaks.", |
|||
maxRedirectDescription: "Suurim arv ümbersuunamisi, millele järgida. 0 ei luba ühtegi ", |
|||
acceptedStatusCodesDescription: "Vali välja HTTP koodid, mida arvestada kõlblikuks.", |
|||
passwordNotMatchMsg: "Salasõnad ei kattu.", |
|||
notificationDescription: "Teavitusmeetodi kasutamiseks seo see seirega.", |
|||
keywordDescription: "Jälgi võtmesõna HTML või JSON vastustes. (tõstutundlik)", |
|||
pauseDashboardHome: "Seiskamine", |
|||
deleteMonitorMsg: "Kas soovid eemaldada seire?", |
|||
deleteNotificationMsg: "Kas soovid eemaldada selle teavitusmeetodi kõikidelt seiretelt?", |
|||
resoverserverDescription: "Cloudflare on vaikimisi pöördserver.", |
|||
rrtypeDescription: "Vali kirje tüüp, mida soovid jälgida.", |
|||
pauseMonitorMsg: "Kas soovid peatada seire?", |
|||
Settings: "Seaded", |
|||
Dashboard: "Töölaud", |
|||
"New Update": "Uuem tarkvara versioon on saadaval.", |
|||
Language: "Keel", |
|||
Appearance: "Välimus", |
|||
Theme: "Teema", |
|||
General: "Üldine", |
|||
Version: "Versioon", |
|||
"Check Update On GitHub": "Otsi uuendusi GitHub'ist", |
|||
List: "Nimekiri", |
|||
Add: "Lisa", |
|||
"Add New Monitor": "Seire lisamine", |
|||
"Quick Stats": "Ülevaade", |
|||
Up: "Töökorras", |
|||
Down: "Rikkis", |
|||
Pending: "Määramisel", |
|||
Unknown: "Teadmata", |
|||
Pause: "Seiskamine", |
|||
Name: "Nimi", |
|||
Status: "Olek", |
|||
DateTime: "Kuupäev", |
|||
Message: "Tulemus", |
|||
"No important events": "Märkimisväärsed juhtumid puuduvad.", |
|||
Resume: "Taasta", |
|||
Edit: "Muutmine", |
|||
Delete: "Eemalda", |
|||
Current: "Hetkeseisund", |
|||
Uptime: "Eluiga", |
|||
"Cert Exp.": "Sert. aegumine", |
|||
days: "päeva", |
|||
day: "päev", |
|||
"-day": "-päev", |
|||
hour: "tund", |
|||
"-hour": "-tund", |
|||
Response: "Vastus", |
|||
Ping: "Ping", |
|||
"Monitor Type": "Seire tüüp", |
|||
Keyword: "Võtmesõna", |
|||
"Friendly Name": "Sõbralik nimi", |
|||
URL: "URL", |
|||
Hostname: "Hostname", |
|||
Port: "Port", |
|||
"Heartbeat Interval": "Tukse sagedus", |
|||
Retries: "Korduskatsed", |
|||
Advanced: "Rohkem", |
|||
"Upside Down Mode": "Tagurpidi seire", |
|||
"Max. Redirects": "Max. ümbersuunamine", |
|||
"Accepted Status Codes": "Kõlblikud HTTP koodid", |
|||
Save: "Salvesta", |
|||
Notifications: "Teavitused", |
|||
"Not available, please setup.": "Ühtegi teavitusteenust pole saadaval.", |
|||
"Setup Notification": "Lisa teavitusteenus", |
|||
Light: "hele", |
|||
Dark: "tume", |
|||
Auto: "automaatne", |
|||
"Theme - Heartbeat Bar": "Teemasäte — tuksete riba", |
|||
Normal: "tavaline", |
|||
Bottom: "all", |
|||
None: "puudub", |
|||
Timezone: "Ajatsoon", |
|||
"Search Engine Visibility": "Otsimootorite ligipääs", |
|||
"Allow indexing": "Luba indekseerimine", |
|||
"Discourage search engines from indexing site": "Keela selle saidi indekseerimine otsimootorite poolt", |
|||
"Change Password": "Muuda parooli", |
|||
"Current Password": "praegune parool", |
|||
"New Password": "uus parool", |
|||
"Repeat New Password": "korda salasõna", |
|||
"Update Password": "Uuenda salasõna", |
|||
"Disable Auth": "Lülita autentimine välja", |
|||
"Enable Auth": "Lülita autentimine sisse", |
|||
Logout: "Logi välja", |
|||
Leave: "Lahku", |
|||
"I understand, please disable": "Olen tutvunud riskidega, lülita välja", |
|||
Confirm: "Kinnita", |
|||
Yes: "Jah", |
|||
No: "Ei", |
|||
Username: "kasutajanimi", |
|||
Password: "parool", |
|||
"Remember me": "Mäleta mind", |
|||
Login: "Logi sisse", |
|||
"No Monitors, please": "Seired puuduvad.", |
|||
"add one": "Lisa esimene", |
|||
"Notification Type": "Teavituse tüüp", |
|||
Email: "e-posti aadress", |
|||
Test: "Saada prooviteavitus", |
|||
"Certificate Info": "Sertifikaadi teave", |
|||
"Resolver Server": "Server, mis vastab DNS päringutele.", |
|||
"Resource Record Type": "DNS kirje tüüp", |
|||
"Last Result": "Viimane", |
|||
"Create your admin account": "Admininstraatori konto loomine", |
|||
"Repeat Password": "korda salasõna", |
|||
respTime: "Reageerimisaeg (ms)", |
|||
notAvailableShort: "N/A", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
clearEventsMsg: "Are you sure want to delete all events for this monitor?", |
|||
clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |
|||
confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
Create: "Create", |
|||
"Clear Data": "Clear Data", |
|||
Events: "Events", |
|||
Heartbeats: "Heartbeats", |
|||
"Auto Get": "Auto Get", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "Italiano (Italian)", |
|||
checkEverySecond: "controlla ogni {0} secondi", |
|||
"Avg.": "Media", |
|||
retriesDescription: "Tentativi da fare prima che il servizio venga marcato come \"giù\" e che una notifica venga inviata.", |
|||
ignoreTLSError: "Ignora gli errori TLS/SSL per i siti in HTTPS.", |
|||
upsideDownModeDescription: "Capovolgi lo stato. Se il servizio è raggiungibile viene marcato come \"GIÙ\".", |
|||
maxRedirectDescription: "Numero massimo di redirezionamenti consentito. Per disabilitare impostare \"0\".", |
|||
acceptedStatusCodesDescription: "Inserire i codici di stato considerati come risposte corrette.", |
|||
passwordNotMatchMsg: "La password non coincide.", |
|||
notificationDescription: "Assegnare la notifica a uno o più elementi monitorati per metterla in funzione.", |
|||
keywordDescription: "Cerca la parola chiave nella risposta in html o JSON e fai distinzione tra maiuscole e minuscole", |
|||
pauseDashboardHome: "In Pausa", |
|||
deleteMonitorMsg: "Si è certi di voler eliminare questo monitoraggio?", |
|||
deleteNotificationMsg: "Si è certi di voler eliminare questa notifica per tutti gli oggetti monitorati?", |
|||
resoverserverDescription: "Cloudflare è il server predefinito, è possibile cambiare il server DNS.", |
|||
rrtypeDescription: "Scegliere il tipo di RR che si vuole monitorare", |
|||
pauseMonitorMsg: "Si è certi di voler mettere in pausa?", |
|||
clearEventsMsg: "Si è certi di voler eliminare tutti gli eventi per questo servizio?", |
|||
clearHeartbeatsMsg: "Si è certi di voler eliminare tutti gli intervalli di controllo per questo servizio?", |
|||
confirmClearStatisticsMsg: "Si è certi di voler eliminare TUTTE le statistiche?", |
|||
Settings: "Impostazioni", |
|||
Dashboard: "Cruscotto", |
|||
"New Update": "Nuovo Aggiornamento Disponibile", |
|||
Language: "Lingua", |
|||
Appearance: "Aspetto", |
|||
Theme: "Tema", |
|||
General: "Generali", |
|||
Version: "Versione", |
|||
"Check Update On GitHub": "Controlla aggiornamenti su GitHub", |
|||
List: "Lista", |
|||
Add: "Aggiungi", |
|||
"Add New Monitor": "Aggiungi un nuovo monitoraggio", |
|||
"Quick Stats": "Statistiche rapide", |
|||
Up: "Su", |
|||
Down: "Giù", |
|||
Pending: "Pendente", |
|||
Unknown: "Sconosciuti", |
|||
Pause: "Metti in Pausa", |
|||
Name: "Nome", |
|||
Status: "Stato", |
|||
DateTime: "Data e Ora", |
|||
Message: "Messaggio", |
|||
"No important events": "Nessun evento importante", |
|||
Resume: "Riprendi", |
|||
Edit: "Modifica", |
|||
Delete: "Elimina", |
|||
Current: "Corrente", |
|||
Uptime: "Tempo di attività", |
|||
"Cert Exp.": "Scadenza certificato", |
|||
days: "giorni", |
|||
day: "giorno", |
|||
"-day": "-giorni", |
|||
hour: "ora", |
|||
"-hour": "-ore", |
|||
Response: "Risposta", |
|||
Ping: "Ping", |
|||
"Monitor Type": "Tipo di Monitoraggio", |
|||
Keyword: "Parola chiave", |
|||
"Friendly Name": "Nome Amichevole", |
|||
URL: "URL", |
|||
Hostname: "Nome Host", |
|||
Port: "Porta", |
|||
"Heartbeat Interval": "Intervallo di controllo", |
|||
Retries: "Tentativi", |
|||
Advanced: "Avanzate", |
|||
"Upside Down Mode": "Modalità capovolta", |
|||
"Max. Redirects": "Redirezionamenti massimi", |
|||
"Accepted Status Codes": "Codici di stato accettati", |
|||
Save: "Salva", |
|||
Notifications: "Notifiche", |
|||
"Not available, please setup.": "Non disponibili, da impostare.", |
|||
"Setup Notification": "Imposta le notifiche", |
|||
Light: "Chiaro", |
|||
Dark: "Scuro", |
|||
Auto: "Automatico", |
|||
"Theme - Heartbeat Bar": "Tema - Barra di Stato", |
|||
Normal: "Normale", |
|||
Bottom: "Sotto", |
|||
None: "Nessuna", |
|||
Timezone: "Fuso Orario", |
|||
"Search Engine Visibility": "Visibilità ai motori di ricerca", |
|||
"Allow indexing": "Permetti l'indicizzazione", |
|||
"Discourage search engines from indexing site": "Scoraggia l'indicizzazione da parte dei motori di ricerca", |
|||
"Change Password": "Cambio Password", |
|||
"Current Password": "Password Corrente", |
|||
"New Password": "Nuova Password", |
|||
"Repeat New Password": "Ripetere la nuova Password", |
|||
"Update Password": "Modifica Password", |
|||
"Disable Auth": "Disabilita l'autenticazione", |
|||
"Enable Auth": "Abilita Autenticazione", |
|||
Logout: "Esci", |
|||
Leave: "Annulla", |
|||
"I understand, please disable": "Lo capisco, disabilitare l'autenticazione.", |
|||
Confirm: "Conferma", |
|||
Yes: "Sì", |
|||
No: "No", |
|||
Username: "Nome Utente", |
|||
Password: "Password", |
|||
"Remember me": "Ricordami", |
|||
Login: "Accesso", |
|||
"No Monitors, please": "Nessun monitoraggio, cortesemente", |
|||
"add one": "aggiungerne uno", |
|||
"Notification Type": "Tipo di notifica", |
|||
Email: "E-mail", |
|||
Test: "Prova", |
|||
"Certificate Info": "Informazioni sul certificato", |
|||
"Resolver Server": "Server DNS", |
|||
"Resource Record Type": "Tipo di Resource Record", |
|||
"Last Result": "Ultimo risultato", |
|||
"Create your admin account": "Crea l'account amministratore", |
|||
"Repeat Password": "Ripeti Password", |
|||
respTime: "Tempo di Risposta (ms)", |
|||
notAvailableShort: "N/D", |
|||
Create: "Crea", |
|||
"Clear Data": "Cancella dati", |
|||
Events: "Eventi", |
|||
Heartbeats: "Controlli", |
|||
"Auto Get": "Auto Get", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "Nederlands", |
|||
checkEverySecond: "Controleer elke {0} seconden.", |
|||
"Avg.": "Gem. ", |
|||
retriesDescription: "Maximum aantal nieuwe pogingen voordat de service wordt gemarkeerd als niet beschikbaar en er een melding wordt verzonden", |
|||
ignoreTLSError: "Negeer TLS/SSL-fout voor HTTPS-websites", |
|||
upsideDownModeDescription: "Draai de status om. Als de service bereikbaar is, is deze OFFLINE.", |
|||
maxRedirectDescription: "Maximaal aantal te volgen omleidingen. Stel in op 0 om omleidingen uit te schakelen.", |
|||
acceptedStatusCodesDescription: "Selecteer statuscodes die als een succesvol antwoord worden beschouwd.", |
|||
passwordNotMatchMsg: "Het herhaalwachtwoord komt niet overeen.", |
|||
notificationDescription: "Wijs a.u.b. een melding toe aan de monitor(s) om het te laten werken.", |
|||
keywordDescription: "Zoek trefwoord in gewone html of JSON-response en het is hoofdlettergevoelig", |
|||
pauseDashboardHome: "Gepauzeerd", |
|||
deleteMonitorMsg: "Weet u zeker dat u deze monitor wilt verwijderen?", |
|||
deleteNotificationMsg: "Weet u zeker dat u deze melding voor alle monitoren wilt verwijderen?", |
|||
resoverserverDescription: "Cloudflare is de standaardserver, u kunt de resolver server op elk moment wijzigen.", |
|||
rrtypeDescription: "Selecteer het RR-type dat u wilt monitoren", |
|||
pauseMonitorMsg: "Weet je zeker dat je wilt pauzeren?", |
|||
Settings: "Instellingen", |
|||
Dashboard: "Dashboard", |
|||
"New Update": "Nieuwe update", |
|||
Language: "Taal", |
|||
Appearance: "Weergave", |
|||
Theme: "Thema", |
|||
General: "Algemeen", |
|||
Version: "Versie", |
|||
"Check Update On GitHub": "Controleer voor updates op GitHub", |
|||
List: "Lijst", |
|||
Add: "Toevoegen", |
|||
"Add New Monitor": "Nieuwe monitor toevoegen", |
|||
"Quick Stats": "Snelle statistieken", |
|||
Up: "Online", |
|||
Down: "Offline", |
|||
Pending: "In afwachting", |
|||
Unknown: "Onbekend", |
|||
Pause: "Pauze", |
|||
Name: "Naam", |
|||
Status: "Status", |
|||
DateTime: "Datum Tijd", |
|||
Message: "Bericht", |
|||
"No important events": "Geen belangrijke gebeurtenissen", |
|||
Resume: "Hervat", |
|||
Edit: "Wijzigen", |
|||
Delete: "Verwijderen", |
|||
Current: "Huidig", |
|||
Uptime: "Uptime", |
|||
"Cert Exp.": "Cert. verl.", |
|||
days: "dagen", |
|||
day: "dag", |
|||
"-day": "-dag", |
|||
hour: "uur", |
|||
"-hour": "-uur", |
|||
Response: "Antwoord", |
|||
Ping: "Ping", |
|||
"Monitor Type": "Monitortype:", |
|||
Keyword: "Trefwoord", |
|||
"Friendly Name": "Vriendelijke naam", |
|||
URL: "URL", |
|||
Hostname: "Hostnaam", |
|||
Port: "Poort", |
|||
"Heartbeat Interval": "Hartslaginterval", |
|||
Retries: "Pogingen", |
|||
Advanced: "Geavanceerd", |
|||
"Upside Down Mode": "Ondersteboven modus", |
|||
"Max. Redirects": "Max. Omleidingen", |
|||
"Accepted Status Codes": "Geaccepteerde statuscodes", |
|||
Save: "Opslaan", |
|||
Notifications: "Meldingen", |
|||
"Not available, please setup.": "Niet beschikbaar, stel a.u.b. in.", |
|||
"Setup Notification": "Melding instellen", |
|||
Light: "Licht", |
|||
Dark: "Donker", |
|||
Auto: "Auto", |
|||
"Theme - Heartbeat Bar": "Thema - Hartslagbalk", |
|||
Normal: "Normaal", |
|||
Bottom: "Onderkant", |
|||
None: "Geen", |
|||
Timezone: "Tijdzone", |
|||
"Search Engine Visibility": "Zichtbaarheid voor zoekmachines", |
|||
"Allow indexing": "Indexering toestaan", |
|||
"Discourage search engines from indexing site": "Ontmoedig zoekmachines om de site te indexeren", |
|||
"Change Password": "Verander wachtwoord", |
|||
"Current Password": "Huidig wachtwoord", |
|||
"New Password": "Nieuw wachtwoord", |
|||
"Repeat New Password": "Herhaal nieuw wachtwoord", |
|||
"Update Password": "Vernieuw wachtwoord", |
|||
"Disable Auth": "Autorisatie uitschakelen", |
|||
"Enable Auth": "Autorisatie inschakelen", |
|||
Logout: "Uitloggen", |
|||
Leave: "Vertrekken", |
|||
"I understand, please disable": "Ik begrijp het, schakel a.u.b. uit", |
|||
Confirm: "Bevestigen", |
|||
Yes: "Ja", |
|||
No: "Nee", |
|||
Username: "Gebruikersnaam", |
|||
Password: "Wachtwoord", |
|||
"Remember me": "Wachtwoord onthouden", |
|||
Login: "Inloggen", |
|||
"No Monitors, please": "Geen monitoren, ", |
|||
"add one": "voeg een toe", |
|||
"Notification Type": "Melding type", |
|||
Email: "E-mail", |
|||
Test: "Testen", |
|||
"Certificate Info": "Certificaat informatie", |
|||
"Resolver Server": "Resolver Server", |
|||
"Resource Record Type": "Type bronrecord", |
|||
"Last Result": "Laatste resultaat", |
|||
"Create your admin account": "Maak uw beheerdersaccount aan", |
|||
"Repeat Password": "Herhaal wachtwoord", |
|||
respTime: "resp. tijd (ms)", |
|||
notAvailableShort: "N.v.t.", |
|||
Create: "Create", |
|||
clearEventsMsg: "Are you sure want to delete all events for this monitor?", |
|||
clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |
|||
confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |
|||
"Clear Data": "Clear Data", |
|||
Events: "Events", |
|||
Heartbeats: "Heartbeats", |
|||
"Auto Get": "Auto Get", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "Polski", |
|||
checkEverySecond: "Sprawdzaj co {0} sekund.", |
|||
"Avg.": "Średnia ", |
|||
retriesDescription: "Maksymalna liczba powtórzeń, zanim usługa zostanie oznaczona jako wyłączona i zostanie wysłane powiadomienie", |
|||
ignoreTLSError: "Ignoruj błąd TLS/SSL dla stron HTTPS", |
|||
upsideDownModeDescription: "Odwróć status do góry nogami. Jeśli usługa jest osiągalna, to jest oznaczona jako niedostępna.", |
|||
maxRedirectDescription: "Maksymalna liczba przekierowań do wykonania. Ustaw na 0, aby wyłączyć przekierowania.", |
|||
acceptedStatusCodesDescription: "Wybierz kody stanu, które są uważane za udaną odpowiedź.", |
|||
passwordNotMatchMsg: "Powtórzone hasło nie pasuje.", |
|||
notificationDescription: "Proszę przypisać powiadomienie do monitora(ów), aby zadziałało.", |
|||
keywordDescription: "Wyszukiwanie słów kluczowych w zwykłym html lub odpowiedzi JSON. Wielkość liter ma znaczenie.", |
|||
pauseDashboardHome: "Pauza", |
|||
deleteMonitorMsg: "Czy na pewno chcesz usunąć ten monitor?", |
|||
deleteNotificationMsg: "Czy na pewno chcesz usunąć to powiadomienie dla wszystkich monitorów?", |
|||
resoverserverDescription: "Cloudflare jest domyślnym serwerem, możesz zmienić serwer resolver w każdej chwili.", |
|||
rrtypeDescription: "Wybierz RR-Type który chcesz monitorować", |
|||
pauseMonitorMsg: "Czy na pewno chcesz wstrzymać?", |
|||
Settings: "Ustawienia", |
|||
Dashboard: "Panel", |
|||
"New Update": "Nowa aktualizacja", |
|||
Language: "Język", |
|||
Appearance: "Wygląd", |
|||
Theme: "Motyw", |
|||
General: "Ogólne", |
|||
Version: "Wersja", |
|||
"Check Update On GitHub": "Sprawdź aktualizację na GitHub.", |
|||
List: "Lista", |
|||
Add: "Dodaj", |
|||
"Add New Monitor": "Dodaj nowy monitor", |
|||
"Quick Stats": "Szybkie statystyki", |
|||
Up: "Online", |
|||
Down: "Offline", |
|||
Pending: "Oczekujący", |
|||
Unknown: "Nieznane", |
|||
Pause: "Pauza", |
|||
Name: "Nazwa", |
|||
Status: "Status", |
|||
DateTime: "Data i godzina", |
|||
Message: "Wiadomość", |
|||
"No important events": "Brak ważnych wydarzeń", |
|||
Resume: "Wznów", |
|||
Edit: "Edytuj", |
|||
Delete: "Usuń", |
|||
Current: "aktualny", |
|||
Uptime: "Czas pracy", |
|||
"Cert Exp.": "Wygaśnięcie certyfikatu", |
|||
days: "dni", |
|||
day: "dzień", |
|||
"-day": " dni", |
|||
hour: "godzina", |
|||
"-hour": " godziny", |
|||
Response: "Odpowiedź", |
|||
Ping: "Ping", |
|||
"Monitor Type": "Typ monitora", |
|||
Keyword: "Słowo kluczowe", |
|||
"Friendly Name": "Przyjazna nazwa", |
|||
URL: "URL", |
|||
Hostname: "Nazwa hosta", |
|||
Port: "Port", |
|||
"Heartbeat Interval": "Interwał bicia serca", |
|||
Retries: "Prób", |
|||
Advanced: "Zaawansowane", |
|||
"Upside Down Mode": "Tryb do góry nogami", |
|||
"Max. Redirects": "Maks. przekierowania", |
|||
"Accepted Status Codes": "Akceptowane kody statusu", |
|||
Save: "Zapisz", |
|||
Notifications: "Powiadomienia", |
|||
"Not available, please setup.": "Niedostępne, proszę skonfigurować.", |
|||
"Setup Notification": "Konfiguracja powiadomień", |
|||
Light: "Jasny", |
|||
Dark: "Ciemny", |
|||
Auto: "Automatyczny", |
|||
"Theme - Heartbeat Bar": "Motyw - pasek bicia serca", |
|||
Normal: "Normalne", |
|||
Bottom: "Na dole", |
|||
None: "Brak", |
|||
Timezone: "Strefa czasowa", |
|||
"Search Engine Visibility": "Widoczność w wyszukiwarce", |
|||
"Allow indexing": "Pozwól na indeksowanie", |
|||
"Discourage search engines from indexing site": "Zniechęcaj wyszukiwarki do indeksowania strony", |
|||
"Change Password": "Zmień hasło", |
|||
"Current Password": "Aktualne hasło", |
|||
"New Password": "Nowe hasło", |
|||
"Repeat New Password": "Powtórz nowe hasło", |
|||
"Update Password": "Zaktualizuj hasło", |
|||
"Disable Auth": "Wyłącz autoryzację", |
|||
"Enable Auth": "Włącz autoryzację ", |
|||
Logout: "Wyloguj się", |
|||
Leave: "Zostaw", |
|||
"I understand, please disable": "Rozumiem, proszę wyłączyć", |
|||
Confirm: "Potwierdź", |
|||
Yes: "Tak", |
|||
No: "Nie", |
|||
Username: "Nazwa użytkownika", |
|||
Password: "Hasło", |
|||
"Remember me": "Zapamiętaj mnie", |
|||
Login: "Zaloguj się", |
|||
"No Monitors, please": "Brak monitorów, proszę", |
|||
"add one": "dodaj jeden", |
|||
"Notification Type": "Typ powiadomienia", |
|||
Email: "Email", |
|||
Test: "Test", |
|||
"Certificate Info": "Informacje o certyfikacie", |
|||
"Resolver Server": "Server resolver", |
|||
"Resource Record Type": "Typ rekordu zasobów", |
|||
"Last Result": "Ostatni wynik", |
|||
"Create your admin account": "Utwórz swoje konto administratora", |
|||
"Repeat Password": "Powtórz hasło", |
|||
respTime: "Czas odp. (ms)", |
|||
notAvailableShort: "N/A", |
|||
Create: "Stwórz", |
|||
clearEventsMsg: "Are you sure want to delete all events for this monitor?", |
|||
clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |
|||
confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |
|||
"Clear Data": "Clear Data", |
|||
Events: "Events", |
|||
Heartbeats: "Heartbeats", |
|||
"Auto Get": "Auto Get", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "Srpski", |
|||
checkEverySecond: "Proveri svakih {0} sekundi.", |
|||
"Avg.": "Prosečni ", |
|||
retriesDescription: "Maksimum pokušaja pre nego što se servis obeleži kao neaktivan i pošalje se obaveštenje.", |
|||
ignoreTLSError: "Ignoriši TLS/SSL greške za HTTPS veb stranice.", |
|||
upsideDownModeDescription: "Obrnite status. Ako je servis dostupan, onda je obeležen kao neaktivan.", |
|||
maxRedirectDescription: "Maksimani broj preusmerenja da se prate. Postavite na 0 da bi se isključila preusmerenja.", |
|||
acceptedStatusCodesDescription: "Odaberite statusne kodove koji se smatraju uspešnim odgovorom.", |
|||
passwordNotMatchMsg: "Ponovljena lozinka se ne poklapa.", |
|||
notificationDescription: "Molim Vas postavite obaveštenje za masmatrače da bise aktivirali.", |
|||
keywordDescription: "Pretraži ključnu reč u čistom html ili JSON odgovoru sa osetljivim velikim i malim slovima", |
|||
pauseDashboardHome: "Pauziraj", |
|||
deleteMonitorMsg: "Da li ste sigurni da želite da obrišete ovog posmatrača?", |
|||
deleteNotificationMsg: "Da li ste sigurni d aželite da uklonite ovo obaveštenje za sve posmatrače?", |
|||
resoverserverDescription: "Cloudflare je podrazumevani server. Možete promeniti server za raszrešavanje u bilo kom trenutku.", |
|||
rrtypeDescription: "Odaberite RR-Type koji želite da posmatrate", |
|||
pauseMonitorMsg: "Da li ste sigurni da želite da pauzirate?", |
|||
Settings: "Podešavanja", |
|||
Dashboard: "Komandna tabla", |
|||
"New Update": "Nova verzija", |
|||
Language: "Jezik", |
|||
Appearance: "Izgled", |
|||
Theme: "Tema", |
|||
General: "Opšte", |
|||
Version: "Verzija", |
|||
"Check Update On GitHub": "Proverite novu verziju na GitHub-u", |
|||
List: "Lista", |
|||
Add: "Dodaj", |
|||
"Add New Monitor": "Dodaj novog posmatrača", |
|||
"Quick Stats": "Brze statistike", |
|||
Up: "Aktivno", |
|||
Down: "Neaktivno", |
|||
Pending: "Nerešeno", |
|||
Unknown: "Nepoznato", |
|||
Pause: "Pauziraj", |
|||
Name: "Ime", |
|||
Status: "Status", |
|||
DateTime: "Datum i vreme", |
|||
Message: "Poruka", |
|||
"No important events": "Nema bitnih događaja", |
|||
Resume: "Nastavi", |
|||
Edit: "Izmeni", |
|||
Delete: "Ukloni", |
|||
Current: "Trenutno", |
|||
Uptime: "Vreme rada", |
|||
"Cert Exp.": "Istek sert.", |
|||
days: "dana", |
|||
day: "dan", |
|||
"-day": "-dana", |
|||
hour: "sat", |
|||
"-hour": "-sata", |
|||
Response: "Odgovor", |
|||
Ping: "Ping", |
|||
"Monitor Type": "Tip posmatrača", |
|||
Keyword: "Ključna reč", |
|||
"Friendly Name": "Prijateljsko ime", |
|||
URL: "URL", |
|||
Hostname: "Hostname", |
|||
Port: "Port", |
|||
"Heartbeat Interval": "Interval otkucaja srca", |
|||
Retries: "Pokušaji", |
|||
Advanced: "Napredno", |
|||
"Upside Down Mode": "Naopak mod", |
|||
"Max. Redirects": "Maks. preusmerenja", |
|||
"Accepted Status Codes": "Prihvaćeni statusni kodovi", |
|||
Save: "Sačuvaj", |
|||
Notifications: "Obaveštenja", |
|||
"Not available, please setup.": "Nije dostupno, molim Vas podesite.", |
|||
"Setup Notification": "Postavi obaveštenje", |
|||
Light: "Svetlo", |
|||
Dark: "Tamno", |
|||
Auto: "Automatsko", |
|||
"Theme - Heartbeat Bar": "Tema - Traka otkucaja srca", |
|||
Normal: "Normalno", |
|||
Bottom: "Dole", |
|||
None: "Isključeno", |
|||
Timezone: "Vremenska zona", |
|||
"Search Engine Visibility": "Vidljivost pretraživačima", |
|||
"Allow indexing": "Dozvoli indeksiranje", |
|||
"Discourage search engines from indexing site": "Odvraćajte pretraživače od indeksiranja sajta", |
|||
"Change Password": "Promeni lozinku", |
|||
"Current Password": "Trenutna lozinka", |
|||
"New Password": "Nova lozinka", |
|||
"Repeat New Password": "Ponovi novu lozinku", |
|||
"Update Password": "Izmeni lozinku", |
|||
"Disable Auth": "Isključi autentifikaciju", |
|||
"Enable Auth": "Uključi autentifikaciju", |
|||
Logout: "Odloguj se", |
|||
Leave: "Izađi", |
|||
"I understand, please disable": "Razumem, molim te isključi", |
|||
Confirm: "Potvrdi", |
|||
Yes: "Da", |
|||
No: "Ne", |
|||
Username: "Korisničko ime", |
|||
Password: "Lozinka", |
|||
"Remember me": "Zapamti me", |
|||
Login: "Uloguj se", |
|||
"No Monitors, please": "Bez posmatrača molim", |
|||
"add one": "dodaj jednog", |
|||
"Notification Type": "Tip obaveštenja", |
|||
Email: "E-pošta", |
|||
Test: "Test", |
|||
"Certificate Info": "Informacije sertifikata", |
|||
"Resolver Server": "Razrešivački server", |
|||
"Resource Record Type": "Tip zapisa resursa", |
|||
"Last Result": "Poslednji rezultat", |
|||
"Create your admin account": "Naprivi administratorski nalog", |
|||
"Repeat Password": "Ponovite lozinku", |
|||
respTime: "Vreme odg. (ms)", |
|||
notAvailableShort: "N/A", |
|||
Create: "Create", |
|||
clearEventsMsg: "Are you sure want to delete all events for this monitor?", |
|||
clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |
|||
confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |
|||
"Clear Data": "Clear Data", |
|||
Events: "Events", |
|||
Heartbeats: "Heartbeats", |
|||
"Auto Get": "Auto Get", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
@ -0,0 +1,131 @@ |
|||
export default { |
|||
languageName: "Српски", |
|||
checkEverySecond: "Провери сваких {0} секунди.", |
|||
"Avg.": "Просечни ", |
|||
retriesDescription: "Максимум покушаја пре него што се сервис обележи као неактиван и пошаље се обавештење.", |
|||
ignoreTLSError: "Игнориши TLS/SSL грешке за HTTPS веб странице.", |
|||
upsideDownModeDescription: "Обрните статус. Ако је сервис доступан, онда је обележен као неактиван.", |
|||
maxRedirectDescription: "Максимани број преусмерења да се прате. Поставите на 0 да би се искључила преусмерења.", |
|||
acceptedStatusCodesDescription: "Одаберите статусне кодове који се сматрају успешним одговором.", |
|||
passwordNotMatchMsg: "Поновљена лозинка се не поклапа.", |
|||
notificationDescription: "Молим Вас поставите обавештење за масматраче да бисе активирали.", |
|||
keywordDescription: "Претражи кључну реч у чистом html или JSON одговору са осетљивим великим и малим словима", |
|||
pauseDashboardHome: "Паузирај", |
|||
deleteMonitorMsg: "Да ли сте сигурни да желите да обришете овог посматрача?", |
|||
deleteNotificationMsg: "Да ли сте сигурни д ажелите да уклоните ово обавештење за све посматраче?", |
|||
resoverserverDescription: "Cloudflare је подразумевани сервер. Можете променити сервер за расзрешавање у било ком тренутку.", |
|||
rrtypeDescription: "Одаберите RR-Type који желите да посматрате", |
|||
pauseMonitorMsg: "Да ли сте сигурни да желите да паузирате?", |
|||
Settings: "Подешавања", |
|||
Dashboard: "Командна табла", |
|||
"New Update": "Нова верзија", |
|||
Language: "Језик", |
|||
Appearance: "Изглед", |
|||
Theme: "Тема", |
|||
General: "Опште", |
|||
Version: "Верзија", |
|||
"Check Update On GitHub": "Проверите нову верзију на GitHub-у", |
|||
List: "Листа", |
|||
Add: "Додај", |
|||
"Add New Monitor": "Додај новог посматрача", |
|||
"Quick Stats": "Брзе статистике", |
|||
Up: "Активно", |
|||
Down: "Неактивно", |
|||
Pending: "Нерешено", |
|||
Unknown: "Непознато", |
|||
Pause: "Паузирај", |
|||
Name: "Име", |
|||
Status: "Статус", |
|||
DateTime: "Датум и време", |
|||
Message: "Порука", |
|||
"No important events": "Нема битних догађаја", |
|||
Resume: "Настави", |
|||
Edit: "Измени", |
|||
Delete: "Уклони", |
|||
Current: "Тренутно", |
|||
Uptime: "Време рада", |
|||
"Cert Exp.": "Истек серт.", |
|||
days: "дана", |
|||
day: "дан", |
|||
"-day": "-дана", |
|||
hour: "сат", |
|||
"-hour": "-сата", |
|||
Response: "Одговор", |
|||
Ping: "Пинг", |
|||
"Monitor Type": "Тип посматрача", |
|||
Keyword: "Кључна реч", |
|||
"Friendly Name": "Пријатељско име", |
|||
URL: "URL", |
|||
Hostname: "Hostname", |
|||
Port: "Порт", |
|||
"Heartbeat Interval": "Интервал откуцаја срца", |
|||
Retries: "Покушаји", |
|||
Advanced: "Напредно", |
|||
"Upside Down Mode": "Наопак мод", |
|||
"Max. Redirects": "Макс. преусмерења", |
|||
"Accepted Status Codes": "Прихваћени статусни кодови", |
|||
Save: "Сачувај", |
|||
Notifications: "Обавештења", |
|||
"Not available, please setup.": "Није доступно, молим Вас подесите.", |
|||
"Setup Notification": "Постави обавештење", |
|||
Light: "Светло", |
|||
Dark: "Тамно", |
|||
Auto: "Аутоматско", |
|||
"Theme - Heartbeat Bar": "Тема - Трака откуцаја срца", |
|||
Normal: "Нормално", |
|||
Bottom: "Доле", |
|||
None: "Искључено", |
|||
Timezone: "Временска зона", |
|||
"Search Engine Visibility": "Видљивост претраживачима", |
|||
"Allow indexing": "Дозволи индексирање", |
|||
"Discourage search engines from indexing site": "Одвраћајте претраживаче од индексирања сајта", |
|||
"Change Password": "Промени лозинку", |
|||
"Current Password": "Тренутна лозинка", |
|||
"New Password": "Нова лозинка", |
|||
"Repeat New Password": "Понови нову лозинку", |
|||
"Update Password": "Измени лозинку", |
|||
"Disable Auth": "Искључи аутентификацију", |
|||
"Enable Auth": "Укључи аутентификацију", |
|||
Logout: "Одлогуј се", |
|||
Leave: "Изађи", |
|||
"I understand, please disable": "Разумем, молим те искључи", |
|||
Confirm: "Потврди", |
|||
Yes: "Да", |
|||
No: "Не", |
|||
Username: "Корисничко име", |
|||
Password: "Лозинка", |
|||
"Remember me": "Запамти ме", |
|||
Login: "Улогуј се", |
|||
"No Monitors, please": "Без посматрача молим", |
|||
"add one": "додај једног", |
|||
"Notification Type": "Тип обавештења", |
|||
Email: "Е-пошта", |
|||
Test: "Тест", |
|||
"Certificate Info": "Информације сертификата", |
|||
"Resolver Server": "Разрешивачки сервер", |
|||
"Resource Record Type": "Тип записа ресурса", |
|||
"Last Result": "Последњи резултат", |
|||
"Create your admin account": "Наприви администраторски налог", |
|||
"Repeat Password": "Поновите лозинку", |
|||
respTime: "Време одг. (мс)", |
|||
notAvailableShort: "N/A", |
|||
Create: "Create", |
|||
clearEventsMsg: "Are you sure want to delete all events for this monitor?", |
|||
clearHeartbeatsMsg: "Are you sure want to delete all heartbeats for this monitor?", |
|||
confirmClearStatisticsMsg: "Are you sure want to delete ALL statistics?", |
|||
"Clear Data": "Clear Data", |
|||
Events: "Events", |
|||
Heartbeats: "Heartbeats", |
|||
"Auto Get": "Auto Get", |
|||
enableDefaultNotificationDescription: "For every new monitor this notification will be enabled by default. You can still disable the notification separately for each monitor.", |
|||
"Default enabled": "Default enabled", |
|||
"Also apply to existing monitors": "Also apply to existing monitors", |
|||
"Import/Export Backup": "Import/Export Backup", |
|||
Export: "Export", |
|||
Import: "Import", |
|||
backupDescription: "You can backup all monitors and all notifications into a JSON file.", |
|||
backupDescription2: "PS: History and event data is not included.", |
|||
backupDescription3: "Sensitive data such as notification tokens is included in the export file, please keep it carefully.", |
|||
alertNoFile: "Please select a file to import.", |
|||
alertWrongFileType: "Please select a JSON file." |
|||
} |
Loading…
Reference in new issue