moving website to fastapi as well
|
|
@ -9,3 +9,4 @@ spectre/
|
|||
velconnect_backup.sql
|
||||
discord_bot/graph.png
|
||||
discord_bot/config.py
|
||||
env_win/
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
export FLASK_APP="velconnect"
|
||||
export FLASK_ENV=development
|
||||
source env/bin/activate
|
||||
flask run
|
||||
|
|
@ -1,210 +0,0 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#b91d47">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<title>VEL Connect</title>
|
||||
|
||||
<link rel="stylesheet" href="/css/spectre.min.css">
|
||||
<script src="/js/util.js"></script>
|
||||
<style>
|
||||
.container {
|
||||
max-width: 30em;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 1em;
|
||||
box-shadow: 0 0 2em #0003;
|
||||
}
|
||||
|
||||
input.btn {
|
||||
cursor: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.centered {
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div id="loading" class="loading loading-lg"></div>
|
||||
<div id="failure" style="display: none;">☹️</div>
|
||||
|
||||
|
||||
<div id="headset_details" style="display: none;">
|
||||
<div class="panel card">
|
||||
<div class="panel-header text-center">
|
||||
<figure class="avatar avatar-lg"><img src="/favicons/android-chrome-192x192.png"
|
||||
alt="Avatar"></figure>
|
||||
<div class="panel-title h5 mt-10">Headset Info</div>
|
||||
<div class="panel-subtitle hw_id">---</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">Current Room</div>
|
||||
<input class="btn current_room" type="text" id="current_room" placeholder="----">
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_room_id"
|
||||
data-tooltip="Set Room ID">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">First Added</div>
|
||||
<div class="tile-subtitle date_created">---</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">Last Used</div>
|
||||
<div class="tile-subtitle last_used">---</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">User Name</div>
|
||||
<input class="btn user_name" type="text" id="user_name" placeholder="----">
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_user_name"
|
||||
data-tooltip="">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">TV URL</div>
|
||||
<input class="btn tv_url" type="text" id="tv_url" placeholder="----">
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_tv_url"
|
||||
data-tooltip="">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">User Color</div>
|
||||
<input class="btn user_color" type="color" id="user_color" placeholder="#ffffff">
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_user_color"
|
||||
data-tooltip="Set User Color">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">Carpet Color</div>
|
||||
<input class="btn carpet_color" type="color" id="carpet_color" placeholder="#ffffff">
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_carpet_color"
|
||||
data-tooltip="Set Carpet Color">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
let submit_button = document.getElementById('submit_pairing_code');
|
||||
let pair_code_input = document.getElementById('pair_code');
|
||||
let loading = document.getElementById('loading');
|
||||
let enter_pairing_id = document.getElementById('enter_pairing_id');
|
||||
let headset_details = document.getElementById('headset_details');
|
||||
let hw_id_field = document.getElementById('hw_id');
|
||||
let failure = document.getElementById('failure');
|
||||
let set_room_id = document.getElementById('set_room_id');
|
||||
let current_room = document.getElementById('current_room');
|
||||
|
||||
|
||||
// check cookie
|
||||
let hw_id = getCookie('hw_id');
|
||||
loading.style.display = "none";
|
||||
if (hw_id != "") {
|
||||
|
||||
httpGetAsync('https://connect.vel.workers.dev/api/get_state/' + hw_id, (resp) => {
|
||||
console.log(resp);
|
||||
let respData = JSON.parse(resp);
|
||||
|
||||
writeClass('hw_id', respData['user']['hw_id']);
|
||||
writeValue('current_room', respData['user']['current_room']);
|
||||
writeClass('date_created', respData['user']['date_created']);
|
||||
writeClass('last_used', respData['user']['last_used']);
|
||||
writeValue('user_color', respData['user']['user_color']);
|
||||
writeValue('user_name', respData['user']['user_name']);
|
||||
if (respData['room']) {
|
||||
writeValue('tv_url', respData['room']['tv_url']);
|
||||
writeValue('carpet_color', respData['room']['carpet_color']);
|
||||
}
|
||||
|
||||
headset_details.style.display = "block";
|
||||
}, (status) => {
|
||||
failure.style.display = "block";
|
||||
});
|
||||
|
||||
function setUserData(endpoint, data) {
|
||||
httpPostAsync('https://connect.vel.workers.dev/api/set_headset_details/' + hw_id + '/' + endpoint,
|
||||
data,
|
||||
(resp) => {console.log('success');},
|
||||
(status) => {console.log('fail');}
|
||||
);
|
||||
}
|
||||
function setRoomData(endpoint, data) {
|
||||
httpPostAsync('https://connect.vel.workers.dev/api/set_room_details/' + current_room.value + '/' + endpoint,
|
||||
data,
|
||||
(resp) => {console.log('success');},
|
||||
(status) => {console.log('fail');}
|
||||
);
|
||||
}
|
||||
|
||||
set_room_id.addEventListener('click', () => {
|
||||
setUserData('current_room', {"current_room": current_room.value});
|
||||
});
|
||||
document.getElementById('set_user_color').addEventListener('click', () => {
|
||||
setUserData('user_color', {"user_color": document.getElementById('user_color').value});
|
||||
});
|
||||
document.getElementById('set_user_name').addEventListener('click', () => {
|
||||
setUserData('user_name', {"user_name": document.getElementById('user_name').value});
|
||||
});
|
||||
document.getElementById('set_tv_url').addEventListener('click', () => {
|
||||
setRoomData('tv_url', {"tv_url": document.getElementById('tv_url').value});
|
||||
});
|
||||
document.getElementById('set_carpet_color').addEventListener('click', () => {
|
||||
setRoomData('carpet_color', {"carpet_color": document.getElementById('carpet_color').value});
|
||||
});
|
||||
|
||||
} else {
|
||||
window.location.href = "/pair";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -34,6 +34,8 @@ CREATE TABLE `Headset` (
|
|||
`avatar_url` VARCHAR(128),
|
||||
-- Stuff like player color, nickname, whiteboard state
|
||||
`user_details` JSON,
|
||||
`streamer_stream_id` VARCHAR(64),
|
||||
`streamer_control_id` VARCHAR(64),
|
||||
CHECK (JSON_VALID(`user_details`))
|
||||
);
|
||||
DROP TABLE IF EXISTS `APIKey`;
|
||||
|
|
@ -8,6 +8,8 @@ from fastapi.security import OAuth2PasswordBearer
|
|||
from db import query, insert
|
||||
from pydantic import BaseModel
|
||||
from typing import Union
|
||||
from pyppeteer import launch
|
||||
from enum import Enum
|
||||
|
||||
|
||||
# APIRouter creates path operations for user module
|
||||
|
|
@ -219,3 +221,43 @@ def get_user_count(hours: float = 24):
|
|||
WHERE TIMESTAMP > DATE_SUB(NOW(), INTERVAL """ + str(hours) + """ HOUR);
|
||||
""")
|
||||
return values
|
||||
|
||||
|
||||
class QuestRift(str, Enum):
|
||||
quest = "quest"
|
||||
rift = "rift"
|
||||
|
||||
|
||||
@router.get('/get_store_details/{quest_rift}/{app_id}', tags=["Oculus API"])
|
||||
async def get_version_nums(quest_rift: QuestRift, app_id: int):
|
||||
browser = await launch(headless=True, options={'args': ['--no-sandbox']})
|
||||
page = await browser.newPage()
|
||||
await page.goto(f'https://www.oculus.com/experiences/{quest_rift}/{app_id}')
|
||||
|
||||
ret = {}
|
||||
|
||||
# title
|
||||
title = await page.querySelector(".app-description__title")
|
||||
ret["title"] = await page.evaluate("e => e.textContent", title)
|
||||
|
||||
# description
|
||||
desc = await page.querySelector(".clamped-description__content")
|
||||
ret["description"] = await page.evaluate("e => e.textContent", desc)
|
||||
|
||||
# versions
|
||||
await page.evaluate("document.querySelector('.app-details-version-info-row__version').nextElementSibling.firstChild.click();")
|
||||
elements = await page.querySelectorAll('.sky-dropdown__link.link.link--clickable')
|
||||
|
||||
versions = []
|
||||
for e in elements:
|
||||
v = await page.evaluate('(element) => element.textContent', e)
|
||||
versions.append({
|
||||
'channel': v.split(':')[0],
|
||||
'version': v.split(':')[1]
|
||||
})
|
||||
|
||||
ret["versions"] = versions
|
||||
|
||||
await browser.close()
|
||||
|
||||
return ret
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import uvicorn
|
|||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi import FastAPI
|
||||
from api import router as api_router
|
||||
from website import router as website_router
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
|
@ -21,7 +23,10 @@ app.add_middleware(
|
|||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
|
||||
app.include_router(api_router)
|
||||
app.include_router(website_router)
|
||||
|
||||
if __name__ == '__main__':
|
||||
uvicorn.run("main:app", host='127.0.0.1', port=8005,
|
||||
|
|
|
|||
|
|
@ -2,3 +2,5 @@ fastapi
|
|||
autopep8
|
||||
uvicorn
|
||||
pymysql
|
||||
pyppeteer
|
||||
jinja2
|
||||
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 815 B After Width: | Height: | Size: 815 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 977 B After Width: | Height: | Size: 977 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
|
@ -96,3 +96,60 @@ function writeSrc(className, data) {
|
|||
e.src = data;
|
||||
});
|
||||
}
|
||||
|
||||
function timeSince(date) {
|
||||
|
||||
let seconds = Math.floor((new Date() - date) / 1000);
|
||||
|
||||
let interval = seconds / 31536000;
|
||||
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " years";
|
||||
}
|
||||
interval = seconds / 2592000;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " months";
|
||||
}
|
||||
interval = seconds / 86400;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " days";
|
||||
}
|
||||
interval = seconds / 3600;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " hours";
|
||||
}
|
||||
interval = seconds / 60;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " minutes";
|
||||
}
|
||||
return Math.floor(seconds) + " seconds";
|
||||
}
|
||||
|
||||
function timeSinceString(date) {
|
||||
|
||||
date = Date.parse(date);
|
||||
let seconds = Math.floor((new Date() - date) / 1000);
|
||||
|
||||
let interval = seconds / 31536000;
|
||||
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " years";
|
||||
}
|
||||
interval = seconds / 2592000;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " months";
|
||||
}
|
||||
interval = seconds / 86400;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " days";
|
||||
}
|
||||
interval = seconds / 3600;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " hours";
|
||||
}
|
||||
interval = seconds / 60;
|
||||
if (interval > 1) {
|
||||
return Math.floor(interval) + " minutes";
|
||||
}
|
||||
return Math.floor(seconds) + " seconds";
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
|
||||
<div slot="nav-logo" style="display: flex; align-items: center; justify-content: center;">
|
||||
<img src = "/favicons/android-chrome-256x256.png" style="width:10em; margin: auto;" />
|
||||
<img src = "/static/favicons/android-chrome-256x256.png" style="width:10em; margin: auto;" />
|
||||
</div>
|
||||
</rapi-doc>
|
||||
</body>
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
<head>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/static/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#b91d47">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/static/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#b91d47">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<title>VEL Connect</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/css/spectre.min.css">
|
||||
<script src="/static/js/util.js"></script>
|
||||
<style>
|
||||
.container {
|
||||
max-width: 30em;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 1em;
|
||||
box-shadow: 0 0 2em #0003;
|
||||
}
|
||||
|
||||
input.btn {
|
||||
cursor: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.centered {
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
|
||||
<div id="loading"><br><br><div class="loading loading-lg"></div></div>
|
||||
<div id="failure" style="display: none;"><br><br><br>☹️</div>
|
||||
|
||||
|
||||
<div id="headset_details" style="display: none;">
|
||||
<div class="panel card">
|
||||
<div class="panel-header text-center">
|
||||
<figure class="avatar avatar-lg"><img src="/static/favicons/android-chrome-192x192.png" alt="Avatar"></figure>
|
||||
<div class="panel-title h5 mt-10">Headset Info</div>
|
||||
<div class="panel-subtitle hw_id">---</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">Current Room</div>
|
||||
<input class="btn current_room" type="text" id="current_room" placeholder="----">
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_room_id"
|
||||
data-tooltip="Set Room ID">Set</button>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">First Seen</div>
|
||||
<div class="tile-subtitle date_created">---</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">Last Login</div>
|
||||
<div class="tile-subtitle last_used">---</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">User Name</div>
|
||||
<input class="btn user_name" type="text" id="user_name" placeholder="----">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_user_name" data-tooltip="">Set</button>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">TV URL</div>
|
||||
<input class="btn tv_url" type="text" id="tv_url" placeholder="----">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_tv_url" data-tooltip="">Set</button>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">User Color</div>
|
||||
<input class="btn user_color coloris" type="text" id="user_color" placeholder="#ffffff">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_user_color" data-tooltip="Set User Color">Set</button>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="tile tile-centered">
|
||||
<div class="tile-content">
|
||||
<div class="tile-title text-bold">Carpet Color</div>
|
||||
<input class="btn carpet_color coloris" type="text" id="carpet_color" placeholder="#ffffff">
|
||||
<button class="btn btn-primary btn-lg tooltip tooltip-left" id="set_carpet_color" data-tooltip="Set Carpet Color">Set</button>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript" src="/static/js/coloris.min.js"></script>
|
||||
<script>
|
||||
|
||||
let submit_button = document.getElementById('submit_pairing_code');
|
||||
let pair_code_input = document.getElementById('pair_code');
|
||||
let loading = document.getElementById('loading');
|
||||
let enter_pairing_id = document.getElementById('enter_pairing_id');
|
||||
let headset_details = document.getElementById('headset_details');
|
||||
let hw_id_field = document.getElementById('hw_id');
|
||||
let failure = document.getElementById('failure');
|
||||
let set_room_id = document.getElementById('set_room_id');
|
||||
let current_room = document.getElementById('current_room');
|
||||
|
||||
|
||||
// check cookie
|
||||
let hw_id = getCookie('hw_id');
|
||||
if (hw_id != "") {
|
||||
|
||||
httpGetAsync('/api/get_state/' + hw_id, (resp) => {
|
||||
console.log(resp);
|
||||
let respData = JSON.parse(resp);
|
||||
|
||||
writeClass('hw_id', respData['user']['hw_id']);
|
||||
writeValue('current_room', respData['user']['current_room']);
|
||||
writeClass('date_created', respData['user']['date_created'] + "<br>" + timeSinceString(respData['user']['date_created']) + " ago");
|
||||
writeClass('last_used', respData['user']['last_used'] + "<br>" + timeSinceString(respData['user']['last_used']) + " ago");
|
||||
writeValue('user_color', respData['user']['user_color']);
|
||||
writeValue('user_name', respData['user']['user_name']);
|
||||
if (respData['room']) {
|
||||
writeValue('tv_url', respData['room']['tv_url']);
|
||||
writeValue('carpet_color', respData['room']['carpet_color']);
|
||||
}
|
||||
|
||||
loading.style.display = "none";
|
||||
headset_details.style.display = "block";
|
||||
}, (status) => {
|
||||
loading.style.display = "none";
|
||||
failure.style.display = "block";
|
||||
});
|
||||
|
||||
function setUserData(endpoint, data) {
|
||||
httpPostAsync('/api/set_headset_details/' + hw_id + '/' + endpoint,
|
||||
data,
|
||||
(resp) => { console.log('success'); },
|
||||
(status) => { console.log('fail'); }
|
||||
);
|
||||
}
|
||||
function setRoomData(endpoint, data) {
|
||||
httpPostAsync('/api/set_room_details/' + current_room.value + '/' + endpoint,
|
||||
data,
|
||||
(resp) => { console.log('success'); },
|
||||
(status) => { console.log('fail'); }
|
||||
);
|
||||
}
|
||||
|
||||
set_room_id.addEventListener('click', () => {
|
||||
setUserData('current_room', { "current_room": current_room.value });
|
||||
});
|
||||
document.getElementById('set_user_color').addEventListener('click', () => {
|
||||
setUserData('user_color', { "user_color": document.getElementById('user_color').value });
|
||||
});
|
||||
document.getElementById('set_user_name').addEventListener('click', () => {
|
||||
setUserData('user_name', { "user_name": document.getElementById('user_name').value });
|
||||
});
|
||||
document.getElementById('set_tv_url').addEventListener('click', () => {
|
||||
setRoomData('tv_url', { "tv_url": document.getElementById('tv_url').value });
|
||||
});
|
||||
document.getElementById('set_carpet_color').addEventListener('click', () => {
|
||||
setRoomData('carpet_color', { "carpet_color": document.getElementById('carpet_color').value });
|
||||
});
|
||||
|
||||
} else {
|
||||
window.location.href = "/pair";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Coloris({
|
||||
el: '.coloris',
|
||||
swatches: [
|
||||
'#264653',
|
||||
'#2a9d8f',
|
||||
'#e9c46a',
|
||||
'#f4a261',
|
||||
'#e76f51',
|
||||
'#d62828',
|
||||
'#023e8a',
|
||||
'#0077b6',
|
||||
'#0096c7',
|
||||
'#00b4d8',
|
||||
'#48cae4',
|
||||
]
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
@ -2,19 +2,19 @@
|
|||
|
||||
<head>
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/static/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<meta name="msapplication-TileColor" content="#b91d47">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<title>VEL Connect | Pair</title>
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/css/spectre.min.css">
|
||||
<script src="/js/util.js"></script>
|
||||
<link rel="stylesheet" href="/static/css/spectre.min.css">
|
||||
<script src="/static/js/util.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
--primary-color: #bc1f2d;
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="/img/pair_code_screenshot.png" class="img-responsive">
|
||||
<img src="/static/img/pair_code_screenshot.png" class="img-responsive">
|
||||
</div>
|
||||
<div class="card-header">
|
||||
<div class="card-title h5">Enter Pairing Code</div>
|
||||
|
|
@ -75,7 +75,7 @@
|
|||
let submit_button = document.getElementById('submit_pairing_code');
|
||||
let pair_code_input = document.getElementById('pair_code');
|
||||
submit_button.addEventListener('click', () => {
|
||||
httpGetAsync('https://connect.vel.workers.dev/api/pair_headset/' + pair_code_input.value, (resp) => {
|
||||
httpGetAsync('/api/pair_headset/' + pair_code_input.value, (resp) => {
|
||||
console.log(resp);
|
||||
let respData = JSON.parse(resp);
|
||||
if (respData['hw_id'] != '') {
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
from fastapi import APIRouter
|
||||
from fastapi.responses import FileResponse
|
||||
|
||||
|
||||
# APIRouter creates path operations for user module
|
||||
router = APIRouter(
|
||||
prefix="",
|
||||
tags=["Website"],
|
||||
)
|
||||
|
||||
|
||||
@router.get('/')
|
||||
def index():
|
||||
return FileResponse("templates/index.html")
|
||||
|
||||
|
||||
@router.get('/pair')
|
||||
def pair():
|
||||
return FileResponse("templates/pair.html")
|
||||
|
||||
|
||||
@router.get('/success')
|
||||
def success():
|
||||
return FileResponse("templates/success.html")
|
||||
|
||||
|
||||
@router.get('/failure')
|
||||
def failure():
|
||||
return FileResponse("templates/failure.html")
|
||||