From 5ad56fac3f0b238d3db8552aa50583837369a971 Mon Sep 17 00:00:00 2001 From: Micha Albert Date: Fri, 26 Jul 2024 08:54:39 -0700 Subject: [PATCH] Initial commit --- .gitignore | 190 ++++++++++++++++++ README.md | 3 + review/README.md | 3 + stream/README.md | 3 + stream/backend/main.py | 188 +++++++++++++++++ .../20240719191810_init/migration.sql | 20 ++ stream/backend/migrations/migration_lock.toml | 3 + stream/backend/schema.prisma | 28 +++ stream/keygen/main.py | 30 +++ stream/tiling-frontend/README.md | 47 +++++ stream/tiling-frontend/bun.lockb | Bin 0 -> 104718 bytes stream/tiling-frontend/index.html | 13 ++ stream/tiling-frontend/package.json | 26 +++ .../public/flag-orpheus-left.svg | 1 + stream/tiling-frontend/src/App.svelte | 187 +++++++++++++++++ stream/tiling-frontend/src/main.ts | 7 + stream/tiling-frontend/src/vite-env.d.ts | 2 + stream/tiling-frontend/svelte.config.js | 7 + stream/tiling-frontend/tsconfig.json | 20 ++ stream/tiling-frontend/tsconfig.node.json | 12 ++ stream/tiling-frontend/vite.config.ts | 18 ++ 21 files changed, 808 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 review/README.md create mode 100644 stream/README.md create mode 100644 stream/backend/main.py create mode 100644 stream/backend/migrations/20240719191810_init/migration.sql create mode 100644 stream/backend/migrations/migration_lock.toml create mode 100644 stream/backend/schema.prisma create mode 100644 stream/keygen/main.py create mode 100644 stream/tiling-frontend/README.md create mode 100755 stream/tiling-frontend/bun.lockb create mode 100644 stream/tiling-frontend/index.html create mode 100644 stream/tiling-frontend/package.json create mode 100644 stream/tiling-frontend/public/flag-orpheus-left.svg create mode 100644 stream/tiling-frontend/src/App.svelte create mode 100644 stream/tiling-frontend/src/main.ts create mode 100644 stream/tiling-frontend/src/vite-env.d.ts create mode 100644 stream/tiling-frontend/svelte.config.js create mode 100644 stream/tiling-frontend/tsconfig.json create mode 100644 stream/tiling-frontend/tsconfig.node.json create mode 100644 stream/tiling-frontend/vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4820029 --- /dev/null +++ b/.gitignore @@ -0,0 +1,190 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +*.dat +dev.db* \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d2f7ff5 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# OnBoard Live + +OnBoard Live is a new Hack Club You Ship, We Ship program. More details coming soon™️! diff --git a/review/README.md b/review/README.md new file mode 100644 index 0000000..50968a3 --- /dev/null +++ b/review/README.md @@ -0,0 +1,3 @@ +# Review Helpers + +This directory is a placeholder for future review automation tools! diff --git a/stream/README.md b/stream/README.md new file mode 100644 index 0000000..b3da6d1 --- /dev/null +++ b/stream/README.md @@ -0,0 +1,3 @@ +# Stream utilities + +In this folder, you'll find all the scripts, tools, and programs that are needed to operate the OnBoard Live stream. diff --git a/stream/backend/main.py b/stream/backend/main.py new file mode 100644 index 0000000..d5066bd --- /dev/null +++ b/stream/backend/main.py @@ -0,0 +1,188 @@ +from fastapi import FastAPI, Request, Response +from prisma import Prisma +from secrets import token_hex +import asyncio +from slack_bolt import Ack, App, Say +from slack_bolt.adapter.fastapi import SlackRequestHandler +from dotenv import load_dotenv +import os +import requests + +load_dotenv() + +api = FastAPI() + +db = Prisma() + +bolt = App( + token=os.environ["SLACK_TOKEN"], signing_secret=os.environ["SLACK_SIGNING_SECRET"] +) + +bolt_handler = SlackRequestHandler(bolt) + + +@bolt.event("") +@api.get("/api/v1/stream_key/{stream_key}") +async def get_stream_by_key(stream_key: str): + await db.connect() + stream = await db.stream.find_first(where={"key": stream_key}) + await db.disconnect() + return ( + stream if stream else Response(status_code=404, content="404: Stream not found") + ) + + +@api.get("/api/v1/user/{user_id}") +async def get_user_by_id(user_id: str): + await db.connect() + user = await db.user.find_first(where={"slack_id": user_id}) + await db.disconnect() + return user if user else Response(status_code=404, content="404: User not found") + + +@api.post("/api/v1/user") +async def create_user(user: dict): + await db.connect() + try: + new_user = await db.user.create( + {"slack_id": user["slack_id"], "name": user["name"]} + ) + print(new_user.id) + new_stream = await db.stream.create( + {"user": {"connect": {"id": new_user.id}}, "key": token_hex(16)} + ) + print(new_user, new_stream) + return new_user, new_stream + except Exception as e: + await db.disconnect() + return Response(status_code=500, content=f"500: {str(e)}") + finally: + await db.disconnect() + + +@bolt.event("app_home_opened") +def handle_app_home_opened_events(body, logger, event, client): + client.views_publish( + user_id=event["user"], + # the view object that appears in the app home + view={ + "type": "home", + "callback_id": "home_view", + # body of the view + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "Welcome to OnBoard Live! Try sending `/onboard-live-apply` in the #onboard-live channel to get started!", + }, + }, + ], + }, + ) + + +@bolt.view("apply") +def handle_application_submission(ack, body): + ack() + print(body) + convo = bolt.client.conversations_open(users=body["user"]["id"], return_im=True) + bolt.client.chat_postMessage( + channel=convo["channel"]["id"], text=f"Your application has been submitted! We will review it shortly. Please do not send another application - If you haven't heard back in over 48 hours, message @mra! Here's a copy of your responses for your reference:\n{body['view']['state']['values']['project-info']['project-desc-value']['value']}" + ) + + +@bolt.command("/onboard-live-apply") +def apply(ack: Ack, command): + ack() + print(command) + r = requests.post( + "https://slack.com/api/views.open", + headers={"Authorization": f"Bearer {os.environ['SLACK_TOKEN']}"}, + json={ + "trigger_id": command["trigger_id"], + "view": { + "type": "modal", + "callback_id": "apply", + "title": {"type": "plain_text", "text": "Apply to OnBoard Live"}, + "submit": {"type": "plain_text", "text": "Submit!"}, + "blocks": [ + { + "type": "input", + "block_id": "project-info", + "label": { + "type": "plain_text", + "text": "Some info on your project(s)", + }, + "element": { + "type": "plain_text_input", + "multiline": True, + "action_id": "project-desc-value", + "placeholder": { + "type": "plain_text", + "text": "I'm going to make...", + }, + }, + }, + ], + }, + }, + ) + print(r.status_code, r.text) + # bolt.client.modal(channel=command['channel_id'], user=command['user_id'], text="Application form for OnBoard Live", blocks=[{ + + +# "type": "header", +# "text": { +# "type": "plain_text", +# "text": "Welcome to OnBoard Live!", +# } +# }, +# { +# "type": "section", +# "text": { +# "type": "mrkdwn", +# "text": "Before you can get designing, we need a little bit of info from you. All fields are required!" +# } +# }, +# { +# "type": "divider" +# }, +# { +# "type": "input", +# "element": { +# "type": "plain_text_input", +# "multiline": True, +# "action_id": "project_ideas_input-action", +# "placeholder": { +# "type": "plain_text", +# "text": "I want to make a..." +# } +# }, +# "label": { +# "type": "plain_text", +# "text": "What do you plan to make with OnBoard Live?\nThis can be changed anytime!", +# } +# }, +# { +# "type": "divider" +# }, +# { +# "type": "actions", +# "elements": [ +# { +# "type": "button", +# "text": { +# "type": "plain_text", +# "text": "Apply!", +# }, +# "value": "apply", +# "style": "primary", +# "action_id": "actionId-0" + +# }]}]) + + +@api.post("/slack/events") +async def slack_event_endpoint(req: Request): + return await bolt_handler.handle(req) diff --git a/stream/backend/migrations/20240719191810_init/migration.sql b/stream/backend/migrations/20240719191810_init/migration.sql new file mode 100644 index 0000000..d50c481 --- /dev/null +++ b/stream/backend/migrations/20240719191810_init/migration.sql @@ -0,0 +1,20 @@ +-- CreateTable +CREATE TABLE "Stream" ( + "id" TEXT NOT NULL PRIMARY KEY, + "key" TEXT NOT NULL, + "active" BOOLEAN NOT NULL DEFAULT false, + "focused" BOOLEAN NOT NULL DEFAULT false, + CONSTRAINT "Stream_key_fkey" FOREIGN KEY ("key") REFERENCES "User" ("slackId") ON DELETE RESTRICT ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "User" ( + "slackId" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "Stream_key_key" ON "Stream"("key"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_slackId_key" ON "User"("slackId"); diff --git a/stream/backend/migrations/migration_lock.toml b/stream/backend/migrations/migration_lock.toml new file mode 100644 index 0000000..e5e5c47 --- /dev/null +++ b/stream/backend/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "sqlite" \ No newline at end of file diff --git a/stream/backend/schema.prisma b/stream/backend/schema.prisma new file mode 100644 index 0000000..a4ff3c8 --- /dev/null +++ b/stream/backend/schema.prisma @@ -0,0 +1,28 @@ +generator client { + provider = "prisma-client-py" + interface = "asyncio" + recursive_type_depth = 5 +} + +datasource db { + provider = "sqlite" + url = "file:./dev.db" +} + +model User { + id String @id @default(cuid()) + created_at DateTime @default(now()) + slack_id String @unique + name String + stream Stream? +} + +model Stream { + id String @id @default(cuid()) + created_at DateTime @default(now()) + is_live Boolean @default(false) + is_focused Boolean @default(false) + key String @unique @default(uuid()) + user User @relation(fields: [user_id], references: [id]) + user_id String @unique +} diff --git a/stream/keygen/main.py b/stream/keygen/main.py new file mode 100644 index 0000000..8d3c18a --- /dev/null +++ b/stream/keygen/main.py @@ -0,0 +1,30 @@ +import secrets +import requests +import pickle + +users = {} + +with open('users.dat', 'rb') as f: + users = pickle.load(f) + +def add_stream(stream): + requests.post('http://127.0.0.1:9997/v3/config/paths/add/' + stream, json={'name': stream}) + +def main(): + print(users) + for user in users.values(): + add_stream(user) + while True: + new_user = input('Enter new user\'s Slack ID: ') + if new_user in users: + print('User already exists.') + continue + users[new_user] = secrets.token_hex(32) + print(users[new_user]) + add_stream(users[new_user]) + with open('users.dat', 'wb') as f: + pickle.dump(users, f) + + +if __name__ == '__main__': + main() diff --git a/stream/tiling-frontend/README.md b/stream/tiling-frontend/README.md new file mode 100644 index 0000000..e6cd94f --- /dev/null +++ b/stream/tiling-frontend/README.md @@ -0,0 +1,47 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/stream/tiling-frontend/bun.lockb b/stream/tiling-frontend/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..e0a9e9a2a72831ce8eb9cd97ab1f99cc1931b86e GIT binary patch literal 104718 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 literal 0 HcmV?d00001 diff --git a/stream/tiling-frontend/index.html b/stream/tiling-frontend/index.html new file mode 100644 index 0000000..b6c5f0a --- /dev/null +++ b/stream/tiling-frontend/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + Svelte + TS + + +
+ + + diff --git a/stream/tiling-frontend/package.json b/stream/tiling-frontend/package.json new file mode 100644 index 0000000..f2b1860 --- /dev/null +++ b/stream/tiling-frontend/package.json @@ -0,0 +1,26 @@ +{ + "name": "onboard-plus-sfa", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.1.1", + "@tsconfig/svelte": "^5.0.4", + "svelte": "^4.2.18", + "svelte-check": "^3.8.1", + "tslib": "^2.6.3", + "typescript": "^5.2.2", + "vite": "^5.3.1" + }, + "dependencies": { + "hls.js": "^1.5.13", + "unocss": "^0.61.3", + "vite-plugin-singlefile": "^2.0.2" + } +} diff --git a/stream/tiling-frontend/public/flag-orpheus-left.svg b/stream/tiling-frontend/public/flag-orpheus-left.svg new file mode 100644 index 0000000..88ba938 --- /dev/null +++ b/stream/tiling-frontend/public/flag-orpheus-left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/stream/tiling-frontend/src/App.svelte b/stream/tiling-frontend/src/App.svelte new file mode 100644 index 0000000..272c917 --- /dev/null +++ b/stream/tiling-frontend/src/App.svelte @@ -0,0 +1,187 @@ + + +
+
+
+

+ OnBoard Live Design Stream +

+ Hack Club + {#if pathData?.map((path) => path.ready).includes(true)} +
+ {#each pathData as path} + {#if path.ready} + + + {/if} + {/each} +
+ {:else} +
+

+ No one is here yet!
Check back later +

+
+ {/if} +

+ Join at
+ https://hack.club/onboard-live +
+

+
+ + diff --git a/stream/tiling-frontend/src/main.ts b/stream/tiling-frontend/src/main.ts new file mode 100644 index 0000000..d5f003c --- /dev/null +++ b/stream/tiling-frontend/src/main.ts @@ -0,0 +1,7 @@ +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app')!, +}) + +export default app diff --git a/stream/tiling-frontend/src/vite-env.d.ts b/stream/tiling-frontend/src/vite-env.d.ts new file mode 100644 index 0000000..4078e74 --- /dev/null +++ b/stream/tiling-frontend/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/stream/tiling-frontend/svelte.config.js b/stream/tiling-frontend/svelte.config.js new file mode 100644 index 0000000..b0683fd --- /dev/null +++ b/stream/tiling-frontend/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/stream/tiling-frontend/tsconfig.json b/stream/tiling-frontend/tsconfig.json new file mode 100644 index 0000000..7c608fc --- /dev/null +++ b/stream/tiling-frontend/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true, + "moduleDetection": "force" + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], +} diff --git a/stream/tiling-frontend/tsconfig.node.json b/stream/tiling-frontend/tsconfig.node.json new file mode 100644 index 0000000..6c2d870 --- /dev/null +++ b/stream/tiling-frontend/tsconfig.node.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noEmit": true + }, + "include": ["vite.config.ts"] +} diff --git a/stream/tiling-frontend/vite.config.ts b/stream/tiling-frontend/vite.config.ts new file mode 100644 index 0000000..40a1bf0 --- /dev/null +++ b/stream/tiling-frontend/vite.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import { viteSingleFile } from 'vite-plugin-singlefile'; + +export default defineConfig(({ command }) => ({ + plugins: [ + svelte({ + /* plugin options */ + }), + command === 'build' && + viteSingleFile({ + removeViteModuleLoader: true + }) + ], + build: { + minify: true + } +}));