diff --git a/extra/push-examples/bash-curl/index.sh b/extra/push-examples/bash-curl/index.sh index 54b7626cc..3031255f4 100644 --- a/extra/push-examples/bash-curl/index.sh +++ b/extra/push-examples/bash-curl/index.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Filename: index.sh PUSH_URL="https://example.com/api/push/key?status=up&msg=OK&ping=" INTERVAL=60 diff --git a/extra/push-examples/docker/index.sh b/extra/push-examples/docker/index.sh new file mode 100644 index 000000000..1eb43d650 --- /dev/null +++ b/extra/push-examples/docker/index.sh @@ -0,0 +1 @@ +docker run -d --restart=always --name uptime-kuma-push louislam/uptime-kuma:push "https://example.com/api/push/key?status=up&msg=OK&ping=" 60 diff --git a/extra/push-examples/javascript-fetch/index.js b/extra/push-examples/javascript-fetch/index.js index cb664513c..9d21d0db8 100644 --- a/extra/push-examples/javascript-fetch/index.js +++ b/extra/push-examples/javascript-fetch/index.js @@ -1,3 +1,4 @@ +// Supports: Node.js >= 18, Deno, Bun const pushURL = "https://example.com/api/push/key?status=up&msg=OK&ping="; const interval = 60; diff --git a/extra/push-examples/php/index.php b/extra/push-examples/php/index.php index 6c981ba11..d08b451ab 100644 --- a/extra/push-examples/php/index.php +++ b/extra/push-examples/php/index.php @@ -11,4 +11,3 @@ while (true) { echo "Pushed!\n"; sleep(interval); } - diff --git a/extra/push-examples/powershell/index.ps1 b/extra/push-examples/powershell/index.ps1 index b3f0159e5..2894e8dd6 100644 --- a/extra/push-examples/powershell/index.ps1 +++ b/extra/push-examples/powershell/index.ps1 @@ -1,3 +1,4 @@ +# Filename: index.ps1 $pushURL = "https://example.com/api/push/key?status=up&msg=OK&ping=" $interval = 60 diff --git a/extra/push-examples/python/index.py b/extra/push-examples/python/index.py index d541d7f43..c735b298c 100644 --- a/extra/push-examples/python/index.py +++ b/extra/push-examples/python/index.py @@ -8,4 +8,3 @@ while True: urllib.request.urlopen(push_url) print("Pushed!\n") time.sleep(interval) - diff --git a/extra/push-examples/typescript-fetch/index.ts b/extra/push-examples/typescript-fetch/index.ts index 6a4b0a552..bb140880c 100644 --- a/extra/push-examples/typescript-fetch/index.ts +++ b/extra/push-examples/typescript-fetch/index.ts @@ -1,3 +1,4 @@ +// Supports: Deno, Bun, Node.js >= 18 (ts-node) const pushURL : string = "https://example.com/api/push/key?status=up&msg=OK&ping="; const interval : number = 60; diff --git a/extra/uptime-kuma-push/.gitignore b/extra/uptime-kuma-push/.gitignore new file mode 100644 index 000000000..a007feab0 --- /dev/null +++ b/extra/uptime-kuma-push/.gitignore @@ -0,0 +1 @@ +build/* diff --git a/extra/uptime-kuma-push/Dockerfile b/extra/uptime-kuma-push/Dockerfile new file mode 100644 index 000000000..9d619d60d --- /dev/null +++ b/extra/uptime-kuma-push/Dockerfile @@ -0,0 +1,18 @@ +FROM node AS build +RUN useradd --create-home kuma +USER kuma +WORKDIR /home/kuma +ARG TARGETPLATFORM +COPY --chown=kuma:kuma ./build/ ./build/ +COPY --chown=kuma:kuma build.js build.js +RUN node build.js $TARGETPLATFORM + +FROM debian:bookworm-slim AS release +RUN useradd --create-home kuma +USER kuma +WORKDIR /home/kuma +COPY --from=build /home/kuma/uptime-kuma-push ./uptime-kuma-push + +ENTRYPOINT ["/home/kuma/uptime-kuma-push"] + + diff --git a/extra/uptime-kuma-push/build.js b/extra/uptime-kuma-push/build.js new file mode 100644 index 000000000..3dc8bf43b --- /dev/null +++ b/extra/uptime-kuma-push/build.js @@ -0,0 +1,48 @@ +const fs = require("fs"); +const platform = process.argv[2]; + +if (!platform) { + console.error("No platform??"); + process.exit(1); +} + +const supportedPlatforms = [ + { + name: "linux/amd64", + bin: "./build/uptime-kuma-push-amd64" + }, + { + name: "linux/arm64", + bin: "./build/uptime-kuma-push-arm64" + }, + { + name: "linux/arm/v7", + bin: "./build/uptime-kuma-push-armv7" + } +]; + +let platformObj = null; + +// Check if the platform is supported +for (let i = 0; i < supportedPlatforms.length; i++) { + if (supportedPlatforms[i].name === platform) { + platformObj = supportedPlatforms[i]; + break; + } +} + +if (platformObj) { + let filename = platformObj.bin; + + if (!fs.existsSync(filename)) { + console.error(`prebuilt: ${filename} is not found, please build it first`); + process.exit(1); + } + + fs.renameSync(filename, "./uptime-kuma-push"); + process.exit(0); +} else { + console.error("Unsupported platform: " + platform); + process.exit(1); +} + diff --git a/extra/uptime-kuma-push/package.json b/extra/uptime-kuma-push/package.json new file mode 100644 index 000000000..f215436c8 --- /dev/null +++ b/extra/uptime-kuma-push/package.json @@ -0,0 +1,13 @@ +{ + "scripts": { + "build-docker": "npm run build-all && docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t louislam/uptime-kuma:push . --push --target release", + "build-all": "npm run build-win && npm run build-linux-amd64 && npm run build-linux-arm64 && npm run build-linux-armv7 && npm run build-linux-armv6 && npm run build-linux-armv5 && npm run build-linux-riscv64", + "build-win": "cross-env GOOS=windows GOARCH=amd64 go build -x -o ./build/uptime-kuma-push.exe uptime-kuma-push.go", + "build-linux-amd64": "cross-env GOOS=linux GOARCH=amd64 go build -x -o ./build/uptime-kuma-push-amd64 uptime-kuma-push.go", + "build-linux-arm64": "cross-env GOOS=linux GOARCH=arm64 go build -x -o ./build/uptime-kuma-push-arm64 uptime-kuma-push.go", + "build-linux-armv7": "cross-env GOOS=linux GOARCH=arm GOARM=7 go build -x -o ./build/uptime-kuma-push-armv7 uptime-kuma-push.go", + "build-linux-armv6": "cross-env GOOS=linux GOARCH=arm GOARM=6 go build -x -o ./build/uptime-kuma-push-armv6 uptime-kuma-push.go", + "build-linux-armv5": "cross-env GOOS=linux GOARCH=arm GOARM=5 go build -x -o ./build/uptime-kuma-push-armv5 uptime-kuma-push.go", + "build-linux-riscv64": "cross-env GOOS=linux GOARCH=riscv64 go build -x -o ./build/uptime-kuma-push-riscv64 uptime-kuma-push.go" + } +} diff --git a/extra/uptime-kuma-push/uptime-kuma-push.go b/extra/uptime-kuma-push/uptime-kuma-push.go new file mode 100644 index 000000000..69cd1f8c2 --- /dev/null +++ b/extra/uptime-kuma-push/uptime-kuma-push.go @@ -0,0 +1,44 @@ +package main + +import ( + "fmt" + "net/http" + os "os" + "time" +) + +func main() { + if len(os.Args) < 2 { + fmt.Fprintln(os.Stderr, "Usage: uptime-kuma-push []") + os.Exit(1) + } + + pushURL := os.Args[1] + + var interval time.Duration + + if len(os.Args) >= 3 { + intervalString, err := time.ParseDuration(os.Args[2] + "s") + interval = intervalString + + if err != nil { + fmt.Fprintln(os.Stderr, "Error: Invalid interval", err) + os.Exit(1) + } + + } else { + interval = 60 * time.Second + } + + for { + _, err := http.Get(pushURL) + if err == nil { + fmt.Print("Pushed!") + } else { + fmt.Print("Error: ", err) + } + + fmt.Println(" Sleeping for", interval) + time.Sleep(interval) + } +} diff --git a/server/server.js b/server/server.js index f38b31207..0772fd72b 100644 --- a/server/server.js +++ b/server/server.js @@ -51,11 +51,6 @@ if (! process.env.NODE_ENV) { log.info("server", "Node Env: " + process.env.NODE_ENV); log.info("server", "Inside Container: " + (process.env.UPTIME_KUMA_IS_CONTAINER === "1")); -log.info("server", "Importing Node libraries"); -const fs = require("fs"); - -log.info("server", "Importing 3rd-party libraries"); - log.debug("server", "Importing express"); const express = require("express"); const expressStaticGzip = require("express-static-gzip"); diff --git a/server/socket-handlers/general-socket-handler.js b/server/socket-handlers/general-socket-handler.js index 64ace4021..82129061e 100644 --- a/server/socket-handlers/general-socket-handler.js +++ b/server/socket-handlers/general-socket-handler.js @@ -4,6 +4,8 @@ const { sendInfo } = require("../client"); const { checkLogin } = require("../util-server"); const GameResolver = require("gamedig/lib/GameResolver"); const { testChrome } = require("../monitor-types/real-browser-monitor-type"); +const fs = require("fs"); +const path = require("path"); let gameResolver = new GameResolver(); let gameList = null; @@ -62,4 +64,29 @@ module.exports.generalSocketHandler = (socket, server) => { }); }); }); + + socket.on("getPushExample", (language, callback) => { + + try { + let dir = path.join("./extra/push-examples", language); + let files = fs.readdirSync(dir); + + for (let file of files) { + if (file.startsWith("index.")) { + callback({ + ok: true, + code: fs.readFileSync(path.join(dir, file), "utf8"), + }); + return; + } + } + } catch (e) { + + } + + callback({ + ok: false, + msg: "Not found", + }); + }); }; diff --git a/src/assets/app.scss b/src/assets/app.scss index f8d5e1c8d..eb3c9f8e4 100644 --- a/src/assets/app.scss +++ b/src/assets/app.scss @@ -584,6 +584,20 @@ h5.settings-subheading::after { border-bottom: 1px solid $dark-border-color; } +/* required class */ +.code-editor, .css-editor { + /* we dont use `language-` classes anymore so thats why we need to add background and text color manually */ + + border-radius: 1rem; + padding: 10px 5px; + border: 1px solid #ced4da; + + .dark & { + background: $dark-bg2; + border: 1px solid $dark-border-color; + } +} + $shadow-box-padding: 20px; diff --git a/src/lang/en.json b/src/lang/en.json index 89af01684..11dae4969 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -84,6 +84,9 @@ "Push URL": "Push URL", "needPushEvery": "You should call this URL every {0} seconds.", "pushOptionalParams": "Optional parameters: {0}", + "pushViewCode": "View Code", + "pushOthers": "Others", + "programmingLanguages": "Programming Languages", "Save": "Save", "Notifications": "Notifications", "Not available, please setup.": "Not available, please setup.", diff --git a/src/pages/Details.vue b/src/pages/Details.vue index 73985c157..3b9357a9b 100644 --- a/src/pages/Details.vue +++ b/src/pages/Details.vue @@ -76,6 +76,34 @@ + +
+ {{ $t("pushViewCode") }} + + +
+ + + +
+
+
+
@@ -249,6 +277,12 @@ import CertificateInfo from "../components/CertificateInfo.vue"; import { getMonitorRelativeURL } from "../util.ts"; import { URL } from "whatwg-url"; import { getResBaseURL } from "../util-frontend"; +import { highlight, languages } from "prismjs/components/prism-core"; +import "prismjs/components/prism-clike"; +import "prismjs/components/prism-javascript"; +import "prismjs/components/prism-css"; +import { PrismEditor } from "vue-prism-editor"; +import "vue-prism-editor/dist/prismeditor.min.css"; export default { components: { @@ -262,6 +296,7 @@ export default { PingChart, Tag, CertificateInfo, + PrismEditor, }, data() { return { @@ -277,6 +312,11 @@ export default { cacheTime: Date.now(), importantHeartBeatListLength: 0, displayedRecords: [], + pushMonitor: { + showPushExamples: false, + currentExample: "javascript-fetch", + code: "", + }, }; }, computed: { @@ -361,13 +401,28 @@ export default { monitor(to) { this.getImportantHeartbeatListLength(); - } + }, + "monitor.type"() { + if (this.monitor && this.monitor.type === "push") { + this.loadPushExample(); + } + }, + "pushMonitor.currentExample"() { + this.loadPushExample(); + }, }, mounted() { this.getImportantHeartbeatListLength(); this.$root.emitter.on("newImportantHeartbeat", this.onNewImportantHeartbeat); + + if (this.monitor && this.monitor.type === "push") { + if (this.lastHeartBeat.status === -1) { + this.pushMonitor.showPushExamples = true; + } + this.loadPushExample(); + } }, beforeUnmount() { @@ -569,6 +624,25 @@ export default { } } }, + + /** + * Highlight the example code + * @param {string} code Code + * @returns {string} Highlighted code + */ + pushExampleHighlighter(code) { + return highlight(code, languages.js); + }, + + loadPushExample() { + this.pushMonitor.code = ""; + this.$root.getSocket().emit("getPushExample", this.pushMonitor.currentExample, (res) => { + let code = res.code + .replace("60", this.monitor.interval) + .replace("https://example.com/api/push/key?status=up&msg=OK&ping=", this.pushURL); + this.pushMonitor.code = code; + }); + } }, }; diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue index 54944d79d..a0c11be48 100644 --- a/src/pages/StatusPage.vue +++ b/src/pages/StatusPage.vue @@ -743,7 +743,7 @@ export default { /** * Provide syntax highlighting for CSS * @param {string} code Text to highlight - * @returns {string} Highlighted HTML + * @returns {string} Highlighted CSS */ highlighter(code) { return highlight(code, languages.css); @@ -1243,20 +1243,6 @@ footer { } } -/* required class */ -.css-editor { - /* we dont use `language-` classes anymore so thats why we need to add background and text color manually */ - - border-radius: 1rem; - padding: 10px 5px; - border: 1px solid #ced4da; - - .dark & { - background: $dark-bg; - border: 1px solid $dark-border-color; - } -} - .bg-maintenance { .alert-heading { font-weight: bold;