minor bugfixes

This commit is contained in:
Micha Albert 2024-07-28 21:24:45 +00:00
parent 8f274fe1e0
commit ffc81adb8f
5 changed files with 266 additions and 211 deletions

View file

@ -5,3 +5,4 @@ requests
python-dotenv
prisma
fastapi-utils
httpx

View file

@ -1,25 +1,52 @@
from random import choice
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 json
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()
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()
bolt = App(
bolt = AsyncApp(
token=os.environ["SLACK_TOKEN"], signing_secret=os.environ["SLACK_SIGNING_SECRET"]
)
bolt_handler = SlackRequestHandler(bolt)
bolt_handler = AsyncSlackRequestHandler(bolt)
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")
@api.get("/api/v1/active_stream")
async def get_active_stream():
return active_stream
@bolt.event("app_home_opened")
def handle_app_home_opened_events(body, logger, event, client):
client.views_publish(
async def handle_app_home_opened_events(body, logger, event, client):
await client.views_publish(
user_id=event["user"],
# the view object that appears in the app home
view={
@ -64,45 +96,100 @@ def handle_app_home_opened_events(body, logger, event, client):
)
@bolt.action("approve")
def approve(ack, body):
ack()
@bolt.action("deny")
async def deny(ack, body):
await ack()
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) - 6]["text"]["text"]
print(applicant_slack_id, applicant_name)
# new_user = await db.user.create(
# {"slack_id": applicant_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)
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 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")
def handle_application_submission(ack, body):
ack()
async def handle_application_submission(ack, body):
await ack()
user = body["user"]["id"]
sumbitter_convo = bolt.client.conversations_open(users=user, return_im=True)
user_real_name = bolt.client.users_info(user=user)["user"]["real_name"]
sumbitter_convo = await bolt.client.conversations_open(users=user, return_im=True)
user_real_name = (await bolt.client.users_info(user=user))["user"]["real_name"]
user_verified = ""
async with httpx.AsyncClient() as client:
user_verified = (
"Eligible L"
not in requests.get(
"https://verify.hackclub.dev/api/status", json={"slack_id": user}
not in (
await client.request(
url="https://verify.hackclub.dev/api/status",
method="GET",
content=json.dumps({"slack_id": user}),
)
).text
)
bolt.client.chat_postMessage(
await bolt.client.chat_postMessage(
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 ''}",
)
admin_convo = bolt.client.conversations_open(
admin_convo = await bolt.client.conversations_open(
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"],
text=":siren-real: New OnBoard Live application! :siren-real:",
text="New OnBoard Live application!",
blocks=[
{
"type": "section",
@ -139,7 +226,7 @@ def handle_application_submission(ack, body):
"type": "section",
"text": {
"type": "plain_text",
"text": f":pray: Will behave on stream: Yes",
"text": f":pray: Will behave on stream: {will_behave}",
"emoji": True,
},
},
@ -179,10 +266,12 @@ def handle_application_submission(ack, body):
@bolt.command("/onboard-live-apply")
def apply(ack: Ack, command):
ack()
async def apply(ack: AsyncAck, command):
await ack()
async with httpx.AsyncClient() as client:
print(
requests.post(
(
await client.post(
"https://slack.com/api/views.open",
headers={
"Authorization": f"Bearer {os.environ['SLACK_TOKEN']}",
@ -198,8 +287,16 @@ def apply(ack: Ack, command):
"text": "OnBoard Live Application",
"emoji": True,
},
"submit": {"type": "plain_text", "text": "Submit", "emoji": True},
"close": {"type": "plain_text", "text": "Cancel", "emoji": True},
"submit": {
"type": "plain_text",
"text": "Submit",
"emoji": True,
},
"close": {
"type": "plain_text",
"text": "Cancel",
"emoji": True,
},
"blocks": [
{
"type": "section",
@ -280,65 +377,14 @@ def apply(ack: Ack, command):
],
},
},
)
).text
)
# bolt.client.modal(channel=command['channel_id'], user=command['user_id'], text="Application form for OnBoard Live", blocks=[{
@bolt.action("checkboxes")
def handle_some_action(ack):
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"
# }]}])
async def handle_some_action(ack):
await ack()
@api.post("/slack/events")
@ -350,6 +396,7 @@ async def slack_event_endpoint(req: Request):
async def change_active_stream():
global active_stream
streams = []
await db.connect()
for stream in await db.stream.find_many():
streams.append(stream.id)
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

View file

@ -1,5 +1,4 @@
<script lang="ts">
// import 'uno.css'
import hls from "hls.js";
import { onMount } from "svelte";
let videos: { [key: string]: HTMLVideoElement } = {};
@ -7,9 +6,9 @@
| {
ready: boolean;
name: string;
focused?: boolean;
}[]
| null = null;
let activeStream: string;
let newData:
| {
bytesSent: any;
@ -22,8 +21,14 @@
onMount(() => {
const fetchData = async () => {
try {
const response = await fetch("http://localhost:9997/v3/paths/list");
newData = (await response.json())["items"];
const activeStreamResponse = await fetch(
"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) {
for (let i = 0; i < newData.length; i++) {
delete newData[i].readyTime;
@ -33,7 +38,7 @@
}
console.log(videos);
videos = Object.fromEntries(
Object.entries(videos).filter(([_, v]) => v != null)
Object.entries(videos).filter(([_, v]) => v != null),
);
if (JSON.stringify(newData) !== JSON.stringify(pathData)) {
@ -44,7 +49,7 @@
console.log(video);
const hlsInstance = new hls({ progressive: false });
hlsInstance.loadSource(
`http://localhost:8888/${video}/index.m3u8`
`http://localhost:8888/${video}/index.m3u8`,
);
hlsInstance.attachMedia(videos[video]);
}
@ -65,7 +70,10 @@
});
</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 class="container2">
<h2
@ -88,7 +96,7 @@
autoplay
id={path.name}
bind:this={videos[path.name]}
class:focused={path.focused}
class:active={path.name === activeStream}
class:video={Object.keys(videos).length > 1}
class:only-video={!(Object.keys(videos).length > 1)}
></video>
@ -172,7 +180,7 @@
padding-left: 10px;
padding-right: 10px;
}
.focused {
.active {
width: 75vw;
height: 75vh;
}