mirror of
https://github.com/MichaByte/OnBoard-Live.git
synced 2025-12-06 08:13:41 -05:00
minor bugfixes
This commit is contained in:
parent
8f274fe1e0
commit
ffc81adb8f
5 changed files with 266 additions and 211 deletions
|
|
@ -5,3 +5,4 @@ requests
|
||||||
python-dotenv
|
python-dotenv
|
||||||
prisma
|
prisma
|
||||||
fastapi-utils
|
fastapi-utils
|
||||||
|
httpx
|
||||||
|
|
@ -1,25 +1,52 @@
|
||||||
from random import choice
|
import json
|
||||||
from fastapi import FastAPI, Request, Response
|
|
||||||
from prisma import Prisma
|
|
||||||
from secrets import token_hex
|
|
||||||
from slack_bolt import Ack, App
|
|
||||||
from fastapi_utils.tasks import repeat_every
|
|
||||||
from slack_bolt.adapter.fastapi import SlackRequestHandler
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
import os
|
import os
|
||||||
import requests
|
from contextlib import asynccontextmanager
|
||||||
|
from random import choice
|
||||||
|
from secrets import token_hex
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
import uvicorn
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from fastapi import FastAPI, Request, Response
|
||||||
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
|
from fastapi_utils.tasks import repeat_every
|
||||||
|
from prisma import Prisma
|
||||||
|
from slack_bolt.adapter.fastapi.async_handler import AsyncSlackRequestHandler
|
||||||
|
from slack_bolt.async_app import AsyncAck, AsyncApp
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
api = FastAPI()
|
|
||||||
|
@asynccontextmanager
|
||||||
|
async def lifespan(app: FastAPI):
|
||||||
|
await db.connect()
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
|
for stream in await db.stream.find_many():
|
||||||
|
await client.post(
|
||||||
|
"http://127.0.0.1:9997/v3/config/paths/add/" + stream.key,
|
||||||
|
json={"name": stream.key},
|
||||||
|
)
|
||||||
|
yield
|
||||||
|
await db.disconnect()
|
||||||
|
|
||||||
|
|
||||||
|
api = FastAPI(lifespan=lifespan)
|
||||||
|
|
||||||
|
api.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
db = Prisma()
|
db = Prisma()
|
||||||
|
|
||||||
bolt = App(
|
|
||||||
|
bolt = AsyncApp(
|
||||||
token=os.environ["SLACK_TOKEN"], signing_secret=os.environ["SLACK_SIGNING_SECRET"]
|
token=os.environ["SLACK_TOKEN"], signing_secret=os.environ["SLACK_SIGNING_SECRET"]
|
||||||
)
|
)
|
||||||
|
|
||||||
bolt_handler = SlackRequestHandler(bolt)
|
bolt_handler = AsyncSlackRequestHandler(bolt)
|
||||||
|
|
||||||
active_stream = None
|
active_stream = None
|
||||||
|
|
||||||
|
|
@ -42,9 +69,14 @@ async def get_user_by_id(user_id: str):
|
||||||
return user if user else Response(status_code=404, content="404: User not found")
|
return user if user else Response(status_code=404, content="404: User not found")
|
||||||
|
|
||||||
|
|
||||||
|
@api.get("/api/v1/active_stream")
|
||||||
|
async def get_active_stream():
|
||||||
|
return active_stream
|
||||||
|
|
||||||
|
|
||||||
@bolt.event("app_home_opened")
|
@bolt.event("app_home_opened")
|
||||||
def handle_app_home_opened_events(body, logger, event, client):
|
async def handle_app_home_opened_events(body, logger, event, client):
|
||||||
client.views_publish(
|
await client.views_publish(
|
||||||
user_id=event["user"],
|
user_id=event["user"],
|
||||||
# the view object that appears in the app home
|
# the view object that appears in the app home
|
||||||
view={
|
view={
|
||||||
|
|
@ -64,45 +96,100 @@ def handle_app_home_opened_events(body, logger, event, client):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bolt.action("approve")
|
@bolt.action("deny")
|
||||||
def approve(ack, body):
|
async def deny(ack, body):
|
||||||
ack()
|
await ack()
|
||||||
message = body["message"]
|
message = body["message"]
|
||||||
applicant_slack_id = message["blocks"][len(message) - 3]["text"]["text"].split(": ")[1] # I hate it. You hate it. We all hate it. Carry on.
|
applicant_slack_id = message["blocks"][len(message) - 3]["text"]["text"].split(
|
||||||
applicant_name = message["blocks"][len(message) - 6]["text"]["text"]
|
": "
|
||||||
print(applicant_slack_id, applicant_name)
|
)[
|
||||||
# new_user = await db.user.create(
|
1
|
||||||
# {"slack_id": applicant_slack_id, "name": user["name"]}
|
] # I hate it. You hate it. We all hate it. Carry on.
|
||||||
# )
|
applicant_name = message["blocks"][len(message) - 7]["text"]["text"].split(
|
||||||
# print(new_user.id)
|
"Name: "
|
||||||
# new_stream = await db.stream.create(
|
)[
|
||||||
# {"user": {"connect": {"id": new_user.id}}, "key": token_hex(16)}
|
1
|
||||||
# )
|
] # oops i did it again
|
||||||
# print(new_user, new_stream)
|
await bolt.client.chat_delete(
|
||||||
|
channel=body["container"]["channel_id"], ts=message["ts"]
|
||||||
|
)
|
||||||
|
await bolt.client.chat_postMessage(
|
||||||
|
channel=body["container"]["channel_id"],
|
||||||
|
text=f"{applicant_name}'s application has been denied! Remember to reach out to them if this is a fixable issue. Their username is <@{applicant_slack_id}>.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bolt.action("approve")
|
||||||
|
async def approve(ack, body):
|
||||||
|
await ack()
|
||||||
|
await db.connect()
|
||||||
|
message = body["message"]
|
||||||
|
applicant_slack_id = message["blocks"][len(message) - 3]["text"]["text"].split(
|
||||||
|
": "
|
||||||
|
)[
|
||||||
|
1
|
||||||
|
] # I hate it. You hate it. We all hate it. Carry on.
|
||||||
|
applicant_name = message["blocks"][len(message) - 7]["text"]["text"].split(
|
||||||
|
"Name: "
|
||||||
|
)[
|
||||||
|
1
|
||||||
|
] # oops i did it again
|
||||||
|
await bolt.client.chat_delete(
|
||||||
|
channel=body["container"]["channel_id"], ts=message["ts"]
|
||||||
|
)
|
||||||
|
await bolt.client.chat_postMessage(
|
||||||
|
channel=body["container"]["channel_id"],
|
||||||
|
text=f"{applicant_name}'s application has been approved! Their username is <@{applicant_slack_id}>.",
|
||||||
|
)
|
||||||
|
if applicant_slack_id in [d.slack_id for d in await db.user.find_many()]: # type: ignore
|
||||||
|
return
|
||||||
|
new_user = await db.user.create(
|
||||||
|
{"slack_id": applicant_slack_id, "name": applicant_name}
|
||||||
|
)
|
||||||
|
new_stream = await db.stream.create(
|
||||||
|
{"user": {"connect": {"id": new_user.id}}, "key": token_hex(16)}
|
||||||
|
)
|
||||||
|
sumbitter_convo = await bolt.client.conversations_open(
|
||||||
|
users=applicant_slack_id, return_im=True
|
||||||
|
)
|
||||||
|
await bolt.client.chat_postMessage(
|
||||||
|
channel=sumbitter_convo["channel"]["id"],
|
||||||
|
text=f"Your application has been approved! Your stream key is `{new_stream.key}`. Keep this safe and do not share it with anyone!",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bolt.view("apply")
|
@bolt.view("apply")
|
||||||
def handle_application_submission(ack, body):
|
async def handle_application_submission(ack, body):
|
||||||
ack()
|
await ack()
|
||||||
user = body["user"]["id"]
|
user = body["user"]["id"]
|
||||||
sumbitter_convo = bolt.client.conversations_open(users=user, return_im=True)
|
sumbitter_convo = await bolt.client.conversations_open(users=user, return_im=True)
|
||||||
user_real_name = bolt.client.users_info(user=user)["user"]["real_name"]
|
user_real_name = (await bolt.client.users_info(user=user))["user"]["real_name"]
|
||||||
|
user_verified = ""
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
user_verified = (
|
user_verified = (
|
||||||
"Eligible L"
|
"Eligible L"
|
||||||
not in requests.get(
|
not in (
|
||||||
"https://verify.hackclub.dev/api/status", json={"slack_id": user}
|
await client.request(
|
||||||
|
url="https://verify.hackclub.dev/api/status",
|
||||||
|
method="GET",
|
||||||
|
content=json.dumps({"slack_id": user}),
|
||||||
|
)
|
||||||
).text
|
).text
|
||||||
)
|
)
|
||||||
bolt.client.chat_postMessage(
|
await bolt.client.chat_postMessage(
|
||||||
channel=sumbitter_convo["channel"]["id"],
|
channel=sumbitter_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, or you forgot something in your application, please message <@{os.environ['ADMIN_SLACK_ID']}>! Here's a copy of your responses for your reference:\nSome info on your project(s): {body['view']['state']['values']['project-info']['project-info-body']['value']}{f'\nPlease fill out <https://forms.hackclub.com/eligibility?program=Onboard%20Live&slack_id={user}|the verification form>! We can only approve your application once this is done.' if not user_verified else ''}",
|
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, or you forgot something in your application, please message <@{os.environ['ADMIN_SLACK_ID']}>! Here's a copy of your responses for your reference:\nSome info on your project(s): {body['view']['state']['values']['project-info']['project-info-body']['value']}{f'\nPlease fill out <https://forms.hackclub.com/eligibility?program=Onboard%20Live&slack_id={user}|the verification form>! We can only approve your application once this is done.' if not user_verified else ''}",
|
||||||
)
|
)
|
||||||
admin_convo = bolt.client.conversations_open(
|
admin_convo = await bolt.client.conversations_open(
|
||||||
users=os.environ["ADMIN_SLACK_ID"], return_im=True
|
users=os.environ["ADMIN_SLACK_ID"], return_im=True
|
||||||
)
|
)
|
||||||
bolt.client.chat_postMessage(
|
will_behave = False
|
||||||
|
boxes = body['view']['state']['values']['c+wGI']['checkboxes']['selected_options']
|
||||||
|
if len(boxes) == 1 and boxes[0]["value"] == 'value-1':
|
||||||
|
will_behave = True
|
||||||
|
await bolt.client.chat_postMessage(
|
||||||
channel=admin_convo["channel"]["id"],
|
channel=admin_convo["channel"]["id"],
|
||||||
text=":siren-real: New OnBoard Live application! :siren-real:",
|
text="New OnBoard Live application!",
|
||||||
blocks=[
|
blocks=[
|
||||||
{
|
{
|
||||||
"type": "section",
|
"type": "section",
|
||||||
|
|
@ -139,7 +226,7 @@ def handle_application_submission(ack, body):
|
||||||
"type": "section",
|
"type": "section",
|
||||||
"text": {
|
"text": {
|
||||||
"type": "plain_text",
|
"type": "plain_text",
|
||||||
"text": f":pray: Will behave on stream: Yes",
|
"text": f":pray: Will behave on stream: {will_behave}",
|
||||||
"emoji": True,
|
"emoji": True,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -179,10 +266,12 @@ def handle_application_submission(ack, body):
|
||||||
|
|
||||||
|
|
||||||
@bolt.command("/onboard-live-apply")
|
@bolt.command("/onboard-live-apply")
|
||||||
def apply(ack: Ack, command):
|
async def apply(ack: AsyncAck, command):
|
||||||
ack()
|
await ack()
|
||||||
|
async with httpx.AsyncClient() as client:
|
||||||
print(
|
print(
|
||||||
requests.post(
|
(
|
||||||
|
await client.post(
|
||||||
"https://slack.com/api/views.open",
|
"https://slack.com/api/views.open",
|
||||||
headers={
|
headers={
|
||||||
"Authorization": f"Bearer {os.environ['SLACK_TOKEN']}",
|
"Authorization": f"Bearer {os.environ['SLACK_TOKEN']}",
|
||||||
|
|
@ -198,8 +287,16 @@ def apply(ack: Ack, command):
|
||||||
"text": "OnBoard Live Application",
|
"text": "OnBoard Live Application",
|
||||||
"emoji": True,
|
"emoji": True,
|
||||||
},
|
},
|
||||||
"submit": {"type": "plain_text", "text": "Submit", "emoji": True},
|
"submit": {
|
||||||
"close": {"type": "plain_text", "text": "Cancel", "emoji": True},
|
"type": "plain_text",
|
||||||
|
"text": "Submit",
|
||||||
|
"emoji": True,
|
||||||
|
},
|
||||||
|
"close": {
|
||||||
|
"type": "plain_text",
|
||||||
|
"text": "Cancel",
|
||||||
|
"emoji": True,
|
||||||
|
},
|
||||||
"blocks": [
|
"blocks": [
|
||||||
{
|
{
|
||||||
"type": "section",
|
"type": "section",
|
||||||
|
|
@ -280,65 +377,14 @@ def apply(ack: Ack, command):
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
)
|
||||||
).text
|
).text
|
||||||
)
|
)
|
||||||
# bolt.client.modal(channel=command['channel_id'], user=command['user_id'], text="Application form for OnBoard Live", blocks=[{
|
|
||||||
|
|
||||||
|
|
||||||
@bolt.action("checkboxes")
|
@bolt.action("checkboxes")
|
||||||
def handle_some_action(ack):
|
async def handle_some_action(ack):
|
||||||
ack()
|
await ack()
|
||||||
|
|
||||||
|
|
||||||
# "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")
|
@api.post("/slack/events")
|
||||||
|
|
@ -350,6 +396,7 @@ async def slack_event_endpoint(req: Request):
|
||||||
async def change_active_stream():
|
async def change_active_stream():
|
||||||
global active_stream
|
global active_stream
|
||||||
streams = []
|
streams = []
|
||||||
|
await db.connect()
|
||||||
for stream in await db.stream.find_many():
|
for stream in await db.stream.find_many():
|
||||||
streams.append(stream.id)
|
streams.append(stream.id)
|
||||||
if len(streams) == 0:
|
if len(streams) == 0:
|
||||||
|
|
|
||||||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 6.3 KiB |
|
|
@ -1,5 +1,4 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
// import 'uno.css'
|
|
||||||
import hls from "hls.js";
|
import hls from "hls.js";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
let videos: { [key: string]: HTMLVideoElement } = {};
|
let videos: { [key: string]: HTMLVideoElement } = {};
|
||||||
|
|
@ -7,9 +6,9 @@
|
||||||
| {
|
| {
|
||||||
ready: boolean;
|
ready: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
focused?: boolean;
|
|
||||||
}[]
|
}[]
|
||||||
| null = null;
|
| null = null;
|
||||||
|
let activeStream: string;
|
||||||
let newData:
|
let newData:
|
||||||
| {
|
| {
|
||||||
bytesSent: any;
|
bytesSent: any;
|
||||||
|
|
@ -22,8 +21,14 @@
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("http://localhost:9997/v3/paths/list");
|
const activeStreamResponse = await fetch(
|
||||||
newData = (await response.json())["items"];
|
"http://localhost:8000/api/v1/active_stream",
|
||||||
|
);
|
||||||
|
activeStream = await activeStreamResponse.text();
|
||||||
|
const pathListResponse = await fetch(
|
||||||
|
"http://localhost:9997/v3/paths/list",
|
||||||
|
);
|
||||||
|
newData = (await pathListResponse.json())["items"];
|
||||||
if (newData) {
|
if (newData) {
|
||||||
for (let i = 0; i < newData.length; i++) {
|
for (let i = 0; i < newData.length; i++) {
|
||||||
delete newData[i].readyTime;
|
delete newData[i].readyTime;
|
||||||
|
|
@ -33,7 +38,7 @@
|
||||||
}
|
}
|
||||||
console.log(videos);
|
console.log(videos);
|
||||||
videos = Object.fromEntries(
|
videos = Object.fromEntries(
|
||||||
Object.entries(videos).filter(([_, v]) => v != null)
|
Object.entries(videos).filter(([_, v]) => v != null),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (JSON.stringify(newData) !== JSON.stringify(pathData)) {
|
if (JSON.stringify(newData) !== JSON.stringify(pathData)) {
|
||||||
|
|
@ -44,7 +49,7 @@
|
||||||
console.log(video);
|
console.log(video);
|
||||||
const hlsInstance = new hls({ progressive: false });
|
const hlsInstance = new hls({ progressive: false });
|
||||||
hlsInstance.loadSource(
|
hlsInstance.loadSource(
|
||||||
`http://localhost:8888/${video}/index.m3u8`
|
`http://localhost:8888/${video}/index.m3u8`,
|
||||||
);
|
);
|
||||||
hlsInstance.attachMedia(videos[video]);
|
hlsInstance.attachMedia(videos[video]);
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +70,10 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div style="width: 100vw; height: 100vw; overflow: hidden; position: absolute; top: 0; left: 0"><div class="gradient"></div>
|
<div
|
||||||
|
style="width: 100vw; height: 100vw; overflow: hidden; position: absolute; top: 0; left: 0"
|
||||||
|
>
|
||||||
|
<div class="gradient"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container2">
|
<div class="container2">
|
||||||
<h2
|
<h2
|
||||||
|
|
@ -88,7 +96,7 @@
|
||||||
autoplay
|
autoplay
|
||||||
id={path.name}
|
id={path.name}
|
||||||
bind:this={videos[path.name]}
|
bind:this={videos[path.name]}
|
||||||
class:focused={path.focused}
|
class:active={path.name === activeStream}
|
||||||
class:video={Object.keys(videos).length > 1}
|
class:video={Object.keys(videos).length > 1}
|
||||||
class:only-video={!(Object.keys(videos).length > 1)}
|
class:only-video={!(Object.keys(videos).length > 1)}
|
||||||
></video>
|
></video>
|
||||||
|
|
@ -172,7 +180,7 @@
|
||||||
padding-left: 10px;
|
padding-left: 10px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
.focused {
|
.active {
|
||||||
width: 75vw;
|
width: 75vw;
|
||||||
height: 75vh;
|
height: 75vh;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue