diff --git a/.upsun/config.yaml b/.upsun/config.yaml index 1fd7322..8182de4 100644 --- a/.upsun/config.yaml +++ b/.upsun/config.yaml @@ -1,74 +1,35 @@ applications: - main_app: - source: - root: apps/main - stack: - - nodejs@22 - - nodePackages.npm - hooks: - build: | - set -e - npm install - npm run setup-env - npm run build - web: - locations: - /: - root: "dist" - passthru: true - index: - - index.html - - bun_app: - source: - root: apps/bun - stack: - - bun@1 - hooks: - build: | - set -e - bun install - web: - commands: - start: bun start - nodejs_app: source: root: apps/nodejs stack: - nodejs@22 - nodePackages.npm + - python@3.12 + - python312Packages.pip + - inotify-tools hooks: build: | set -e + pip install -r requirements.txt npm install npm run build - - relationships: - database: - web: commands: start: npm run start - - deno_app: - source: - root: apps/deno - stack: - - deno - variables: - env: - DENO_DIR: "cache" - hooks: - build: | - set -e - deno cache package.json - deno compile --allow-env --allow-net --allow-read main.ts - web: - commands: - start: deno task start - + # access: + # ssh: admin + mounts: + 'sensitive-data': + source: storage + workers: + watchdog: + commands: + start: | + python watch.py $PLATFORM_APP_DIR/sensitive-data + relationships: + database: services: database: type: mariadb:10.4 @@ -78,28 +39,7 @@ routes: "https://{default}/": type: upstream primary: true - upstream: "main_app:http" + upstream: "nodejs_app:http" "https://www.{default}": type: redirect to: "https://{default}/" - - "https://{default}/bun": - type: upstream - upstream: "bun_app:http" - "https://www.{default}/bun": - type: redirect - to: "https://{default}/bun" - - "https://{default}/nodejs": - type: upstream - upstream: "nodejs_app:http" - "https://www.{default}/nodejs": - type: redirect - to: "https://{default}/nodejs" - - "https://{default}/deno": - type: upstream - upstream: "deno_app:http" - "https://www.{default}/deno": - type: redirect - to: "https://{default}/deno" diff --git a/README.md b/README.md index 1ad85ab..564ca7e 100644 --- a/README.md +++ b/README.md @@ -313,3 +313,7 @@ There are far more concepts than could be explored in a single demo project, tal But we have some of the best minds in web development and computing ready and excited to help with your side project, experiment, or next big idea. [Join us on Discord and less us help you get going](https://discord.gg/PkMc2pVCDV)! + +### 6. Testing notifications + +TBD \ No newline at end of file diff --git a/apps/nodejs/.gitignore b/apps/nodejs/.gitignore index 53c37a1..42c93c1 100644 --- a/apps/nodejs/.gitignore +++ b/apps/nodejs/.gitignore @@ -1 +1,4 @@ -dist \ No newline at end of file +dist +env +test_mount +__pycache__ diff --git a/apps/nodejs/requirements.txt b/apps/nodejs/requirements.txt new file mode 100644 index 0000000..2338585 --- /dev/null +++ b/apps/nodejs/requirements.txt @@ -0,0 +1,8 @@ +certifi==2024.6.2 +charset-normalizer==3.3.2 +idna==3.7 +nose==1.3.7 +PyYAML==6.0.1 +requests==2.32.3 +urllib3==2.2.2 +watchdog==4.0.1 diff --git a/apps/nodejs/watch.py b/apps/nodejs/watch.py new file mode 100644 index 0000000..15723bb --- /dev/null +++ b/apps/nodejs/watch.py @@ -0,0 +1,74 @@ +# https://github.com/gorakhargosh/watchdog +# https://pypi.org/project/requests/ +# https://philipkiely.com/code/python_watchdog.html +# Combined the above script with the one on the repo +# _But_ we're dealing with Network mounted drives https://www.pythonanywhere.com/forums/topic/7521/ +# ... so we need to use the PollingObserver class https://python-watchdog.readthedocs.io/en/stable/_modules/watchdog/observers/polling.html +# inotify only available on Linux, which doesn't match my local env + +import os +import sys +import time +import datetime +import requests +import logging +# from watchdog.observers import Observer +from watchdog.observers.polling import PollingObserver +from watchdog.events import FileSystemEventHandler + +class Watcher: + + def __init__(self, directory=".", handler=FileSystemEventHandler()): + # self.observer = Observer() + self.observer = PollingObserver() + self.handler = handler + self.directory = directory + + def run(self): + self.observer.schedule( + self.handler, self.directory, recursive=True) + self.observer.start() + print("\nWatcher Running in {}/\n".format(self.directory)) + try: + while True: + time.sleep(1) + except: + self.observer.stop() + self.observer.join() + print("\nWatcher Terminated\n") + +class MyHandler(FileSystemEventHandler): + + webhook_url = "https://webhook.site/cc04606b-25eb-45d5-8e55-31fa4438db0a" + + if os.environ.get("WATCH_WEBHOOK_URL") is not None: + webhook_url = os.environ["WATCH_WEBHOOK_URL"] + + logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + + def on_any_event(self, event): + uninteresting_events = ["closed", "opened"] + if ( not event.is_directory ) and ( event.event_type not in uninteresting_events ): + print(dir(event)) + event_data = { + "src_path": event.src_path, + "dest_path": event.dest_path, + "event_type": event.event_type, + "is_directory": event.is_directory, + "is_synthetic": event.is_synthetic, + "timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S%z") + } + logging.info(f'{event.event_type.upper()!r}: {event_data!r}') + resp = requests.post(self.webhook_url, json = event_data) + alert_data = { + "status_code": resp.status_code, + "url": resp.url + } + logging.info(f'{"FORWARDED".upper()!r}: {alert_data!r}') + +if __name__=="__main__": + watchpath = sys.argv[1] if len(sys.argv) > 1 else '.' + w = Watcher(watchpath, MyHandler()) + w.run()