From fd0081d4d0b8f7d57eb343b8a110707bacb82fda Mon Sep 17 00:00:00 2001 From: chiko Date: Mon, 20 Oct 2025 23:12:38 +0200 Subject: [PATCH 01/12] Fixed dockerfile, added a docker-compose.yml, added db init function to run on every startup --- Crontab | 2 ++ Dockerfile | 13 +++++++++---- docker-compose.yml | 5 +++++ package.json | 3 ++- src/app.ts | 2 +- src/sendNotification.ts | 10 ++++++---- src/sql.ts | 4 +++- 7 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 Crontab create mode 100644 docker-compose.yml diff --git a/Crontab b/Crontab new file mode 100644 index 0000000..b6ea5bc --- /dev/null +++ b/Crontab @@ -0,0 +1,2 @@ +0 8 * * * bun run ./src/app.ts --today > /dev/null 2>&1 +0 * * * * bun run ./src/app.ts > /dev/null 2>&1 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c4a8a55..775a558 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM debian:12 AS base WORKDIR /opt/app RUN apt-get update && \ - apt-get install -y curl unzip ca-certificates python3 python3-pip && \ + apt-get install -y curl unzip cron ca-certificates python3 python3-pip && \ rm -rf /var/lib/apt/lists/* # install BunJs RUN curl -fsSL https://bun.com/install | bash @@ -38,7 +38,12 @@ FROM base AS release COPY --from=install /temp/prod/node_modules node_modules COPY --from=prerelease /opt/app/src/app.ts . COPY --from=prerelease /opt/app/package.json . +COPY --from=prerelease /opt/app/entrypoint.sh . +COPY Crontab /etc/cron.d/ +RUN chmod 0644 /etc/cron.d/Crontab +# USER bun +RUN touch /var/log/cron.log +# RUN chmod +x entrypoint.sh +# ENTRYPOINT ["./entrypoint.sh"] VOLUME ["/opt/app/data/db"] -# run the app -USER bun -ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file +CMD cron && tail -f /var/log/cron.log \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..67e3b70 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,5 @@ +services: + app: + build: . + volumes: + - ./data/db:./data/db \ No newline at end of file diff --git a/package.json b/package.json index 32b5b91..434a70f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "dev:init": "bun run ./src/app.ts --init", "db:init": "bun run ./run/db_init.ts", "db:deleteall": "bun run ./run/db_deleteall.ts", - "build": "bun build ./src/app.ts --compile --outfile ./build/77th_event_calendar_notification", + "build": "bun build --compile --minify --sourcemap ./src/app.ts --outfile ./build/77th_event_calendar_notification", + "build:linux": "bun build --compile --minify --sourcemap --target=bun-linux-arm64 ./src/app.ts --outfile ./build/77th_event_calendar_notification", "docker:build": "docker build -t chiko/77th_eventcalendarntfy:0.1.0 ." }, "peerDependencies": { diff --git a/src/app.ts b/src/app.ts index 70c6df5..db8a048 100644 --- a/src/app.ts +++ b/src/app.ts @@ -112,7 +112,7 @@ async function main( ) { } return false; })( ev ); - sendNotification( + await sendNotification( `${today_prefix ? "TODAY " : ""}${notification_prefix ? notification_prefix + ": " : ""} ${ev.title} (${ TEventType[ ev.event_type ] })`, `${body}` // `${ev.link || "https://77th-jsoc.com/#/events"}` diff --git a/src/sendNotification.ts b/src/sendNotification.ts index cb0a754..3792745 100644 --- a/src/sendNotification.ts +++ b/src/sendNotification.ts @@ -1,14 +1,16 @@ import * as Bun from "bun"; -export function sendNotification(title: string, body: string, click?: string | null) { +export async function sendNotification(title: string, body: string, click?: string | null) { const command = [ "python", - "./app/notification.py", + "./src/notification.py", `--title=${title}`, `--body=${body}`, ]; - if (click) { + if ( click ) { command.push(`--click=${click}`); } - Bun.spawn(command); + const proc = Bun.spawn(command); + const text = await proc.stdout.text(); + console.log("sendNotification: " + text); } diff --git a/src/sql.ts b/src/sql.ts index 04be71c..6d55878 100644 --- a/src/sql.ts +++ b/src/sql.ts @@ -10,4 +10,6 @@ export const db = new Database(db_filepath); export function init () { Event.createTable(db); -} \ No newline at end of file +} + +init(); \ No newline at end of file -- 2.49.1 From 877d9e37b3f07c0947f9ba728a6e487c5ed38e11 Mon Sep 17 00:00:00 2001 From: chiko Date: Mon, 20 Oct 2025 23:16:35 +0200 Subject: [PATCH 02/12] Udpated Dockerfile, changed Crontab for testing purposes --- Crontab | 2 +- Dockerfile | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Crontab b/Crontab index b6ea5bc..c1dd39e 100644 --- a/Crontab +++ b/Crontab @@ -1,2 +1,2 @@ -0 8 * * * bun run ./src/app.ts --today > /dev/null 2>&1 +1 * * * * bun run ./src/app.ts --today > /dev/null 2>&1 0 * * * * bun run ./src/app.ts > /dev/null 2>&1 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 775a558..4de43a6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,22 +28,24 @@ RUN cd /temp/prod && bun install --frozen-lockfile --production # then copy all (non-ignored) project files into the image FROM base AS prerelease COPY --from=install /temp/dev/node_modules node_modules -COPY . . +COPY . ./ # [optional] tests & build ENV NODE_ENV=production # copy production dependencies and source code into final image FROM base AS release +WORKDIR /opt/app COPY --from=install /temp/prod/node_modules node_modules COPY --from=prerelease /opt/app/src/app.ts . COPY --from=prerelease /opt/app/package.json . -COPY --from=prerelease /opt/app/entrypoint.sh . +#COPY --from=prerelease .entrypoint.sh . COPY Crontab /etc/cron.d/ RUN chmod 0644 /etc/cron.d/Crontab +COPY . ./ # USER bun RUN touch /var/log/cron.log # RUN chmod +x entrypoint.sh # ENTRYPOINT ["./entrypoint.sh"] VOLUME ["/opt/app/data/db"] -CMD cron && tail -f /var/log/cron.log \ No newline at end of file +CMD bun run ./src/app.ts --today && cron && tail -f /var/log/cron.log \ No newline at end of file -- 2.49.1 From 3167bd7976b8363a56cac367cb739104c127ba73 Mon Sep 17 00:00:00 2001 From: chiko Date: Mon, 20 Oct 2025 23:24:56 +0200 Subject: [PATCH 03/12] added dotenv as python dependency --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 356ca44..eb8f961 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -apprise \ No newline at end of file +apprise +dotenv \ No newline at end of file -- 2.49.1 From 66212229f5a27636412652e01751bb1ab1193a87 Mon Sep 17 00:00:00 2001 From: chiko Date: Mon, 20 Oct 2025 23:48:31 +0200 Subject: [PATCH 04/12] fixed python dependency and Dockerfile Volume Bind --- Dockerfile | 2 +- docker-compose.yml | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4de43a6..12c0164 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,5 +47,5 @@ COPY . ./ RUN touch /var/log/cron.log # RUN chmod +x entrypoint.sh # ENTRYPOINT ["./entrypoint.sh"] -VOLUME ["/opt/app/data/db"] +VOLUME /opt/app/data/db CMD bun run ./src/app.ts --today && cron && tail -f /var/log/cron.log \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 67e3b70..2570df8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,4 +2,4 @@ services: app: build: . volumes: - - ./data/db:./data/db \ No newline at end of file + - ./data/db:/opt/app/data/db \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index eb8f961..b4d8f3e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ apprise -dotenv \ No newline at end of file +python-dotenv \ No newline at end of file -- 2.49.1 From 714738dcbaa88be4316912d543e04b968d275658 Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 01:16:59 +0200 Subject: [PATCH 05/12] Fixing python... --- Dockerfile | 7 ++--- src/notification.py | 64 ++++++++++++++++++++++------------------- src/sendNotification.ts | 2 +- 3 files changed, 38 insertions(+), 35 deletions(-) diff --git a/Dockerfile b/Dockerfile index 12c0164..06f59b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,12 @@ FROM debian:12 AS base WORKDIR /opt/app +ENV PYTHONPATH=/app RUN apt-get update && \ apt-get install -y curl unzip cron ca-certificates python3 python3-pip && \ rm -rf /var/lib/apt/lists/* # install BunJs RUN curl -fsSL https://bun.com/install | bash ENV PATH="/root/.bun/bin:$PATH" -# symlink python3 to python -RUN ln -s /usr/bin/python3 /usr/bin/python # install dependencies into temp directory # this will cache them and speed up future builds @@ -17,8 +16,8 @@ COPY package.json bun.lock /temp/dev/ RUN cd /temp/dev && bun install --frozen-lockfile # and install python dependencies COPY ./requirements.txt . -RUN pip3 install --break-system-packages -r ./requirements.txt - +RUN python3 -m pip install -r requirements.txt +# RUN python3 -m pip install -U python-dotenv # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod COPY package.json bun.lock /temp/prod/ diff --git a/src/notification.py b/src/notification.py index cda75a9..13a3dfb 100644 --- a/src/notification.py +++ b/src/notification.py @@ -1,37 +1,41 @@ from dotenv import load_dotenv import os -load_dotenv() # Load environment variables from .env file -ntfy_username = os.getenv('ntfy_username') -ntfy_password = os.getenv('ntfy_password') -ntfy_host = os.getenv('ntfy_host') -ntfy_topic = os.getenv('ntfy_topic') -dc_webhook = os.getenv('dc_webhook') -dc_botname = os.getenv('dc_botname') -dc_avatar_url = os.getenv('dc_avatar_url') +def main(): + load_dotenv() # Load environment variables from .env file + ntfy_username = os.getenv('ntfy_username') + ntfy_password = os.getenv('ntfy_password') + ntfy_host = os.getenv('ntfy_host') + ntfy_topic = os.getenv('ntfy_topic') + dc_webhook = os.getenv('dc_webhook') + dc_botname = os.getenv('dc_botname') + dc_avatar_url = os.getenv('dc_avatar_url') -from argparse import ArgumentParser -import apprise + from argparse import ArgumentParser + import apprise -parser = ArgumentParser() -parser.add_argument("--title") -parser.add_argument("--body") -parser.add_argument("--click") -args = parser.parse_args() -print(args) + parser = ArgumentParser() + parser.add_argument("--title") + parser.add_argument("--body") + parser.add_argument("--click") + args = parser.parse_args() + print(args) -apobj = apprise.Apprise() -# config = apprise.AppriseConfig() -# config.add('https://myserver:8080/path/to/config') -if ntfy_host and ntfy_topic: - ntfy_link = f"ntfys://{ntfy_username}:{ntfy_password}@{ntfy_host}/{ntfy_topic}" - if args.click: - ntfy_link = ntfy_link + "?click=" + args.click - apobj.add(ntfy_link) -if dc_webhook: - apobj.add(f"discord://{dc_webhook}?avatar_url={dc_avatar_url}&botname={dc_botname}"); + apobj = apprise.Apprise() + # config = apprise.AppriseConfig() + # config.add('https://myserver:8080/path/to/config') + if ntfy_host and ntfy_topic: + ntfy_link = f"ntfys://{ntfy_username}:{ntfy_password}@{ntfy_host}/{ntfy_topic}" + if args.click: + ntfy_link = ntfy_link + "?click=" + args.click + apobj.add(ntfy_link) + if dc_webhook: + apobj.add(f"discord://{dc_webhook}?avatar_url={dc_avatar_url}&botname={dc_botname}"); -apobj.notify( - body=args.body, - title=args.title -) \ No newline at end of file + apobj.notify( + body=args.body, + title=args.title + ) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/src/sendNotification.ts b/src/sendNotification.ts index 3792745..639ff21 100644 --- a/src/sendNotification.ts +++ b/src/sendNotification.ts @@ -2,7 +2,7 @@ import * as Bun from "bun"; export async function sendNotification(title: string, body: string, click?: string | null) { const command = [ - "python", + "python3", "./src/notification.py", `--title=${title}`, `--body=${body}`, -- 2.49.1 From 156a2db485f6e679a821ad34965c026e15e13472 Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 01:21:39 +0200 Subject: [PATCH 06/12] fixing docker file --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 06f59b1..1c38a6d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,6 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* # install BunJs RUN curl -fsSL https://bun.com/install | bash -ENV PATH="/root/.bun/bin:$PATH" # install dependencies into temp directory # this will cache them and speed up future builds @@ -16,7 +15,7 @@ COPY package.json bun.lock /temp/dev/ RUN cd /temp/dev && bun install --frozen-lockfile # and install python dependencies COPY ./requirements.txt . -RUN python3 -m pip install -r requirements.txt +RUN python3 -m pip install --break-system-packages -r requirements.txt # RUN python3 -m pip install -U python-dotenv # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod -- 2.49.1 From 1bf297752d8ea42e11e45e8cb892d6d3606e16a0 Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 01:23:41 +0200 Subject: [PATCH 07/12] more dockerfile fixing --- Dockerfile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1c38a6d..f5c1d1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,5 @@ FROM debian:12 AS base WORKDIR /opt/app -ENV PYTHONPATH=/app RUN apt-get update && \ apt-get install -y curl unzip cron ca-certificates python3 python3-pip && \ rm -rf /var/lib/apt/lists/* @@ -13,15 +12,17 @@ FROM base AS install RUN mkdir -p /temp/dev COPY package.json bun.lock /temp/dev/ RUN cd /temp/dev && bun install --frozen-lockfile -# and install python dependencies -COPY ./requirements.txt . -RUN python3 -m pip install --break-system-packages -r requirements.txt -# RUN python3 -m pip install -U python-dotenv + # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod COPY package.json bun.lock /temp/prod/ RUN cd /temp/prod && bun install --frozen-lockfile --production +# and install python dependencies +COPY ./requirements.txt . +RUN python3 -m pip install --break-system-packages -r requirements.txt +# RUN python3 -m pip install -U python-dotenv + # copy node_modules from temp directory # then copy all (non-ignored) project files into the image FROM base AS prerelease -- 2.49.1 From 92a2c6956a74ed96d3bb971518d60594645b053f Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 01:26:18 +0200 Subject: [PATCH 08/12] forgot the ENV for bun --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f5c1d1e..44e3e8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,7 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* # install BunJs RUN curl -fsSL https://bun.com/install | bash - +ENV PATH="/root/.bun/bin:$PATH" # install dependencies into temp directory # this will cache them and speed up future builds FROM base AS install -- 2.49.1 From 457a49e75474509ae78e0ed8943d323d01c1465d Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 02:22:51 +0200 Subject: [PATCH 09/12] fuck python, switching to apprise-api as a docker container --- Dockerfile | 5 +++-- docker-compose.yml | 19 ++++++++++++++++++- src/app.ts | 28 +++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 44e3e8f..19ef720 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,7 @@ FROM debian:12 AS base WORKDIR /opt/app RUN apt-get update && \ + # apt-get install -y curl unzip cron ca-certificates python3 python3-pip && \ apt-get install -y curl unzip cron ca-certificates python3 python3-pip && \ rm -rf /var/lib/apt/lists/* # install BunJs @@ -19,8 +20,8 @@ COPY package.json bun.lock /temp/prod/ RUN cd /temp/prod && bun install --frozen-lockfile --production # and install python dependencies -COPY ./requirements.txt . -RUN python3 -m pip install --break-system-packages -r requirements.txt +# COPY ./requirements.txt . +# RUN python3 -m pip install --break-system-packages -r requirements.txt # RUN python3 -m pip install -U python-dotenv # copy node_modules from temp directory diff --git a/docker-compose.yml b/docker-compose.yml index 2570df8..2b45635 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,4 +2,21 @@ services: app: build: . volumes: - - ./data/db:/opt/app/data/db \ No newline at end of file + - ./data/db:/opt/app/data/db + apprise: + image: caronc/apprise:latest + environment: + - APPRISE_WORKER_COUNT=1 + - APPRISE_STATEFUL_MODE=simple + - PUID=$(id -u) + - PGID=$(id -g) + volumes: + - ./data/apprise/config:/config + - ./data/apprise/plugin:/plugin + - ./data/apprise/attach:/attach + ports: + - 8000:8000 +networks: + default: + external: true + name: npm \ No newline at end of file diff --git a/src/app.ts b/src/app.ts index db8a048..384df25 100644 --- a/src/app.ts +++ b/src/app.ts @@ -112,11 +112,29 @@ async function main( ) { } return false; })( ev ); - await sendNotification( - `${today_prefix ? "TODAY " : ""}${notification_prefix ? notification_prefix + ": " : ""} ${ev.title} (${ TEventType[ ev.event_type ] })`, - `${body}` - // `${ev.link || "https://77th-jsoc.com/#/events"}` - ); + const title = `${today_prefix ? "TODAY " : ""}${notification_prefix ? notification_prefix + ": " : ""} ${ev.title} (${ TEventType[ ev.event_type ] })`; + + await fetch("http://localhost:8000/notify", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + urls: [ + `ntfys://${process.env.ntfy_username}:${process.env.ntfy_password}@${process.env.ntfy_host}/${process.env.ntfy_topic}${ ev.link ? `?click=${ev.link}`: "?click=https://77th-jsoc.com/#/events" }`, + `discord://${process.env.dc_webhook}?avatar_url=${process.env.dc_avatar_url}&botname=${process.env.dc_botname}` + ].join(","), + title: title, + body: body, + format: "text" + }) + }); + + // await sendNotification( + // title, + // body + // // `${ev.link || "https://77th-jsoc.com/#/events"}` + // ); ev.set_notification("done", db); } }; -- 2.49.1 From de11a6934c310f998751763fec263f377d347e66 Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 02:29:54 +0200 Subject: [PATCH 10/12] fixing docker-compose.yml --- docker-compose.yml | 9 ++++++--- src/app.ts | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 2b45635..132d01a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,18 @@ services: - app: + app: build: . volumes: - ./data/db:/opt/app/data/db + depends_on: + - apprise apprise: image: caronc/apprise:latest + hostname: apprise environment: - APPRISE_WORKER_COUNT=1 - APPRISE_STATEFUL_MODE=simple - - PUID=$(id -u) - - PGID=$(id -g) + # - PUID=$(id -u) + # - PGID=$(id -g) volumes: - ./data/apprise/config:/config - ./data/apprise/plugin:/plugin diff --git a/src/app.ts b/src/app.ts index 384df25..86f295e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -114,7 +114,7 @@ async function main( ) { })( ev ); const title = `${today_prefix ? "TODAY " : ""}${notification_prefix ? notification_prefix + ": " : ""} ${ev.title} (${ TEventType[ ev.event_type ] })`; - await fetch("http://localhost:8000/notify", { + await fetch("http://apprise:8000/notify", { method: "POST", headers: { "Content-Type": "application/json" -- 2.49.1 From 5f735dce6a06ef27871081047eaa07c9dcfa4144 Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 02:35:59 +0200 Subject: [PATCH 11/12] container healthchecks.. --- docker-compose.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 132d01a..b4111ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,6 +4,9 @@ services: volumes: - ./data/db:/opt/app/data/db depends_on: + apprise: + condition: service_healthy + links: - apprise apprise: image: caronc/apprise:latest @@ -19,7 +22,12 @@ services: - ./data/apprise/attach:/attach ports: - 8000:8000 -networks: - default: - external: true - name: npm \ No newline at end of file + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/status"] + interval: 30s + timeout: 10s + retries: 5 +# networks: +# default: +# external: true +# name: npm \ No newline at end of file -- 2.49.1 From 8c5d6de5a44e274832e3344d15a15c6549219927 Mon Sep 17 00:00:00 2001 From: chiko Date: Tue, 21 Oct 2025 02:47:36 +0200 Subject: [PATCH 12/12] fixed not loading the env file for docker --- docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index b4111ef..a0fca37 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,9 @@ services: build: . volumes: - ./data/db:/opt/app/data/db + env_file: + - path: ./.env + required: true depends_on: apprise: condition: service_healthy -- 2.49.1