diff --git a/.gitignore b/.gitignore
index 2b8d4cd..4a8bc6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ env_win/
velconnect.db
velconnect*.db
.idea/
+velconnect/data/
diff --git a/velconnect/CreateDB.sql b/velconnect/CreateDB.sql
index b509a19..412dcf4 100644
--- a/velconnect/CreateDB.sql
+++ b/velconnect/CreateDB.sql
@@ -19,6 +19,28 @@ CREATE TABLE `UserCount` (
`platform` VARCHAR(64),
PRIMARY KEY (`timestamp`, `hw_id`)
);
+CREATE TABLE `User` (
+ -- TODO user is defined by uuid, to which an email can be added without having to migrate.
+ -- then the data that is coming from a user vs device is constant
+ -- the user's email
+ `email` TEXT NOT NULL PRIMARY KEY,
+ `username` TEXT,
+ -- the first time this device was seen
+ `date_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ -- the last time this device data was modified
+ `last_modified` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ -- JSON containing arbitrary data
+ `data` TEXT
+);
+CREATE TABLE `UserDevice` (
+ -- Unique identifier for the device
+ `hw_id` TEXT NOT NULL,
+ -- the user's email
+ `email` TEXT NOT NULL,
+ -- when this connection was created
+ `date_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`hw_id`, `email`)
+);
CREATE TABLE `Device` (
-- Unique identifier for this device
`hw_id` TEXT NOT NULL PRIMARY KEY,
diff --git a/velconnect/Dockerfile b/velconnect/Dockerfile
index c190a86..77e1458 100644
--- a/velconnect/Dockerfile
+++ b/velconnect/Dockerfile
@@ -1,3 +1,4 @@
+# syntax=docker/dockerfile:1
FROM python:3.10
WORKDIR /usr/src/velconnect
COPY ./requirements.txt /usr/src/requirements.txt
diff --git a/velconnect/main.py b/velconnect/main.py
index cf5c444..8d761e1 100644
--- a/velconnect/main.py
+++ b/velconnect/main.py
@@ -4,9 +4,7 @@ from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from routes.api import router as api_router
-from routes.api_v2 import router as api_v2_router
from routes.user_count import router as user_count_router
-from routes.user_count_v2 import router as user_count_v2_router
from routes.oculus_api import router as oculus_api_router
from routes.website import router as website_router
@@ -17,6 +15,8 @@ origins = [
"https://velconnect.ugavel.com",
"http://localhost",
"http://localhost:8080",
+ "http://localhost:8000",
+ "http://localhost:8005",
]
app.add_middleware(
@@ -30,9 +30,7 @@ app.add_middleware(
app.mount("/static", StaticFiles(directory="static"), name="static")
app.include_router(api_router)
-app.include_router(api_v2_router)
app.include_router(user_count_router)
-app.include_router(user_count_v2_router)
app.include_router(oculus_api_router)
app.include_router(website_router)
diff --git a/velconnect/rebuild.sh b/velconnect/rebuild.sh
old mode 100644
new mode 100755
index 27d157e..307ff9d
--- a/velconnect/rebuild.sh
+++ b/velconnect/rebuild.sh
@@ -1,4 +1,4 @@
-docker build -t velconnect .
+docker build --tag velconnect .
docker rm web
docker run -p 8081:80 --name web velconnect
diff --git a/velconnect/requirements.txt b/velconnect/requirements.txt
index 5b9411b..4137720 100644
--- a/velconnect/requirements.txt
+++ b/velconnect/requirements.txt
@@ -3,4 +3,6 @@ autopep8
uvicorn
pymysql
pyppeteer
-jinja2
\ No newline at end of file
+jinja2
+python-multipart
+aiofiles
\ No newline at end of file
diff --git a/velconnect/routes/api.py b/velconnect/routes/api.py
index 1d71dd7..8ac03c0 100644
--- a/velconnect/routes/api.py
+++ b/velconnect/routes/api.py
@@ -1,34 +1,23 @@
-from fastapi import APIRouter
-from fastapi import Depends, HTTPException, status
+import secrets
+import json
+import string
+import aiofiles
+
+import fastapi
from fastapi.responses import HTMLResponse
-from fastapi.security import OAuth2PasswordBearer
-from pydantic import BaseModel
+from fastapi import FastAPI, File, UploadFile
import db
db = db.DB("velconnect.db")
# APIRouter creates path operations for user module
-router = APIRouter(
+router = fastapi.APIRouter(
prefix="/api",
tags=["API"],
responses={404: {"description": "Not found"}},
)
-oauth2_scheme = OAuth2PasswordBearer(
- tokenUrl="token") # use token authentication
-
-
-def api_key_auth(api_key: str = Depends(oauth2_scheme)):
- return True
- values = db.query(
- "SELECT * FROM `APIKey` WHERE `key`=:key;", {'key': api_key})
- if not (len(values) > 0 and values['auth_level'] < 0):
- raise HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED,
- detail="Forbidden"
- )
-
@router.get("/", response_class=HTMLResponse, include_in_schema=False)
async def read_root():
@@ -36,7 +25,7 @@ async def read_root():
-
+
API Reference
@@ -58,138 +47,204 @@ async def read_root():
"""
-@router.get('/get_all_headsets')
-def get_all_headsets():
- """Returns a list of all headsets and details associated with them."""
- values = db.query("SELECT * FROM `Headset`;")
+def parse_device(device: dict):
+ if 'data' in device and device['data'] is not None and len(device['data']) > 0:
+ device['data'] = json.loads(device['data'])
+
+
+@router.get('/get_all_devices')
+def get_all_devices():
+ """Returns a list of all devices and details associated with them."""
+ values = db.query("SELECT * FROM `Device`;")
+ values = [dict(v) for v in values]
+ for device in values:
+ parse_device(device)
return values
-@router.get('/pair_headset/{pairing_code}')
-def pair_headset(pairing_code: str):
- values = db.query("SELECT * FROM `Headset` WHERE `pairing_code`=:pairing_code;",
- {'pairing_code': pairing_code})
+@router.get('/get_device_by_pairing_code/{pairing_code}')
+def get_device_by_pairing_code(pairing_code: str):
+ values = db.query("SELECT * FROM `Device` WHERE `pairing_code`=:pairing_code;",
+ {'pairing_code': pairing_code})
if len(values) == 1:
- return values[0]
+ device = dict(values[0])
+ parse_device(device)
+ return device
return {'error': 'Not found'}, 400
-class UpdatePairingCode(BaseModel):
- hw_id: str
- pairing_code: int
-
-
-@router.post('/update_pairing_code')
-def update_pairing_code(data: UpdatePairingCode):
- """This also creates a headset if it doesn't exist"""
-
- print("Update pairing code")
- print(data)
-
- create_headset(data.hw_id)
-
+def create_device(hw_id: str):
db.insert("""
- UPDATE `Headset`
- SET `pairing_code`=:pairing_code, `last_used`=CURRENT_TIMESTAMP
- WHERE `hw_id`=:hw_id;
- """, data.dict())
-
- return {'success': True}
-
-
-def create_headset(hw_id: str):
- db.insert("""
- db.insert IGNORE INTO Headset(hw_id) VALUES (:hw_id);
+ INSERT OR IGNORE INTO `Device`(hw_id) VALUES (:hw_id);
""", {'hw_id': hw_id})
-@router.get('/get_state/{hw_id}')
-def get_headset_details(hw_id: str):
- data = get_headset_details_db(hw_id)
- if data is None:
- return {'error': "Can't find headset with that id."}
- else:
- return data
+@router.get('/device/get_data/{hw_id}')
+def get_state(request: fastapi.Request, hw_id: str):
+ """Gets the device state"""
-
-def get_headset_details_db(hw_id):
- headsets = db.query("""
- SELECT * FROM `Headset` WHERE `hw_id`=:hw_id;
+ devices = db.query("""
+ SELECT * FROM `Device` WHERE `hw_id`=:hw_id;
""", {'hw_id': hw_id})
- if len(headsets) == 0:
- return None
+ if len(devices) == 0:
+ return {'error': "Can't find device with that id."}
+ block = dict(devices[0])
+ if 'data' in block and block['data'] is not None:
+ block['data'] = json.loads(block['data'])
- room = get_room_details_db(headsets[0]['current_room'])
+ room_key: str = f"{devices[0]['current_app']}_{devices[0]['current_room']}"
+ room_data = get_data(room_key)
- return {'user': headsets[0], 'room': room}
+ if "error" in room_data:
+ set_data(request, data={}, key=room_key, modified_by=None, category="room")
+ room_data = get_data(room_key)
+
+ return {'device': block, 'room': room_data}
-@router.post('/set_headset_details/{hw_id}')
-def set_headset_details_generic(hw_id: str, data: dict):
- print("Data:")
- print(data)
+@router.post('/device/set_data/{hw_id}')
+def set_state(request: fastapi.Request, hw_id: str, data: dict, modified_by: str = None):
+ """Sets the device state"""
- # create_headset(hw_id)
+ create_device(hw_id)
- allowed_keys = [
+ # add the client's IP address if no sender specified
+ if 'modified_by' in data:
+ modified_by = data['modified_by']
+ if modified_by is None:
+ modified_by: str = str(request.client) + "_" + str(request.headers)
+
+ allowed_keys: list[str] = [
+ 'os_info',
+ 'friendly_name',
+ 'current_app',
'current_room',
'pairing_code',
- 'user_color',
- 'user_name',
- 'avatar_url',
- 'user_details',
- 'streamer_stream_id',
- 'streamer_control_id',
- ]
- for key in data:
- if key in allowed_keys:
- if key == 'current_room':
- create_room(data['current_room'])
- db.insert(f"UPDATE `Headset` SET {key}=:value, modified_by=:sender_id WHERE `hw_id`=:hw_id;", {
- 'value': data[key], 'hw_id': hw_id, 'sender_id': data['sender_id']})
- return {'success': True}
-
-
-@router.post('/set_room_details/{room_id}')
-def set_room_details_generic(room_id: str, data: dict):
- print(data)
- allowed_keys = [
- 'modified_by',
- 'whitelist',
- 'tv_url',
- 'carpet_color',
- 'room_details',
]
for key in data:
if key in allowed_keys:
- db.insert("UPDATE `Room` SET " + key +
- "=:value, modified_by=:sender_id WHERE `room_id`=:room_id;",
- {'value': data[key], 'room_id': room_id, 'sender_id': data['sender_id']})
+ db.insert(f"""
+ UPDATE `Device`
+ SET {key}=:value,
+ last_modified=CURRENT_TIMESTAMP,
+ modified_by=:modified_by
+ WHERE `hw_id`=:hw_id;
+ """,
+ {
+ 'value': data[key],
+ 'hw_id': hw_id,
+ 'modified_by': modified_by
+ })
+ if key == "data":
+ new_data = data['data']
+ # get the old json values and merge the data
+ old_data_query = db.query("""
+ SELECT data
+ FROM `Device`
+ WHERE hw_id=:hw_id
+ """, {"hw_id": hw_id})
+
+ if len(old_data_query) == 1:
+ old_data: dict = {}
+ if old_data_query[0]['data'] is not None:
+ old_data = json.loads(old_data_query[0]["data"])
+ new_data = {**old_data, **new_data}
+
+ # add the data to the db
+ db.insert("""
+ UPDATE `Device`
+ SET data=:data,
+ last_modified=CURRENT_TIMESTAMP
+ WHERE hw_id=:hw_id;
+ """, {"hw_id": hw_id, "data": json.dumps(new_data)})
return {'success': True}
-@router.get('/get_room_details/{room_id}')
-def get_room_details(room_id: str):
- return get_room_details_db(room_id)
+def generate_id(length: int = 4) -> str:
+ return ''.join(
+ secrets.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for i in range(length))
-def get_room_details_db(room_id):
- values = db.query("""
- SELECT * FROM `Room` WHERE room_id=:room_id;
- """, {'room_id': room_id})
- if len(values) == 1:
- return values[0]
- else:
- return None
+@router.post('/set_data')
+def set_data_with_random_key(request: fastapi.Request, data: dict, modified_by: str = None,
+ category: str = None) -> dict:
+ """Creates a little storage bucket for arbitrary data with a random key"""
+ return set_data(request, data, None, modified_by, category)
-def create_room(room_id):
+@router.post('/set_data/{key}')
+def set_data(request: fastapi.Request, data: dict, key: str = None, modified_by: str = None,
+ category: str = None) -> dict:
+ """Creates a little storage bucket for arbitrary data"""
+
+ # add the client's IP address if no sender specified
+ if 'modified_by' in data:
+ modified_by = data['modified_by']
+ if modified_by is None:
+ modified_by: str = str(request.client) + "_" + str(request.headers)
+
+ # generates a key if none was supplied
+ if key is None:
+ key = generate_id()
+
+ # regenerate if necessary
+ while len(db.query("SELECT id FROM `DataBlock` WHERE id=:id;", {"id": key})) > 0:
+ key = generate_id()
+
+ # get the old json values and merge the data
+ old_data_query = db.query("""
+ SELECT data
+ FROM `DataBlock`
+ WHERE id=:id
+ """, {"id": key})
+
+ if len(old_data_query) == 1:
+ old_data: dict = json.loads(old_data_query[0]["data"])
+ data = {**old_data, **data}
+
+ # add the data to the db
db.insert("""
- db.insert IGNORE INTO `Room`(room_id)
- VALUES(
- :room_id
- );
- """, {'room_id': room_id})
- return {'room_id': room_id}
+ REPLACE INTO `DataBlock` (id, category, modified_by, data, last_modified)
+ VALUES(:id, :category, :modified_by, :data, CURRENT_TIMESTAMP);
+ """, {"id": key, "category": category, "modified_by": modified_by, "data": json.dumps(data)})
+ return {'key': key}
+
+
+@router.get('/get_data/{key}')
+def get_data(key: str) -> dict:
+ """Gets data from a storage bucket for arbitrary data"""
+
+ data = db.query("""
+ SELECT *
+ FROM `DataBlock`
+ WHERE id=:id
+ """, {"id": key})
+
+ db.insert("""
+ UPDATE `DataBlock`
+ SET last_accessed = CURRENT_TIMESTAMP
+ WHERE id=:id;
+ """, {"id": key})
+
+ try:
+ if len(data) == 1:
+ block = dict(data[0])
+ if 'data' in block and block['data'] is not None:
+ block['data'] = json.loads(block['data'])
+ return block
+ return {'error': 'Not found'}
+ except Exception as e:
+ print(e)
+ return {'error': 'Unknown. Maybe no data at this key.'}
+
+
+@router.post("/upload_file/{key}")
+async def upload_file(request: fastapi.Request, file: UploadFile, key: str,modified_by: str = None):
+ async with aiofiles.open('data/' + key, 'wb') as out_file:
+ content = await file.read() # async read
+ await out_file.write(content) # async write
+ # add a datablock to link to the file
+ set_data(request, {'filename': file.filename}, key, 'file')
+ return {"filename": file.filename}
diff --git a/velconnect/routes/api_v2.py b/velconnect/routes/api_v2.py
deleted file mode 100644
index a2f0398..0000000
--- a/velconnect/routes/api_v2.py
+++ /dev/null
@@ -1,232 +0,0 @@
-import secrets
-import json
-import string
-
-import fastapi
-from fastapi.responses import HTMLResponse
-
-import db
-
-db = db.DB("velconnect_v2.db")
-
-# APIRouter creates path operations for user module
-router = fastapi.APIRouter(
- prefix="/api/v2",
- tags=["API V2"],
- responses={404: {"description": "Not found"}},
-)
-
-
-@router.get("/", response_class=HTMLResponse, include_in_schema=False)
-async def read_root():
- return """
-
-
-
-
-
- API Reference
-
-
-
-
-

-
-
-
-
-"""
-
-
-@router.get('/get_all_devices')
-def get_all_devices():
- """Returns a list of all devices and details associated with them."""
- values = db.query("SELECT * FROM `Device`;")
- values = [dict(v) for v in values]
- for device in values:
- if 'data' in device and len(device['data']) > 0:
- device['data'] = json.loads(device['data'])
- return values
-
-
-@router.get('/get_device_by_pairing_code/{pairing_code}')
-def get_device_by_pairing_code(pairing_code: str):
- values = db.query("SELECT * FROM `Device` WHERE `pairing_code`=:pairing_code;",
- {'pairing_code': pairing_code})
- if len(values) == 1:
- return values[0]
- return {'error': 'Not found'}, 400
-
-
-def create_device(hw_id: str):
- db.insert("""
- INSERT OR IGNORE INTO `Device`(hw_id) VALUES (:hw_id);
- """, {'hw_id': hw_id})
-
-
-@router.get('/device/get_data/{hw_id}')
-def get_state(request: fastapi.Request, hw_id: str):
- """Gets the device state"""
-
- devices = db.query("""
- SELECT * FROM `Device` WHERE `hw_id`=:hw_id;
- """, {'hw_id': hw_id})
- if len(devices) == 0:
- return {'error': "Can't find device with that id."}
- block = dict(devices[0])
- if 'data' in block and block['data'] is not None:
- block['data'] = json.loads(block['data'])
-
- room_key: str = f"{devices[0]['current_app']}_{devices[0]['current_room']}"
- room_data = get_data(room_key)
-
- if "error" in room_data:
- set_data(request, data={}, key=room_key, modified_by=None, category="room")
- room_data = get_data(room_key)
-
- return {'device': block, 'room': room_data}
-
-
-@router.post('/device/set_data/{hw_id}')
-def set_state(request: fastapi.Request, hw_id: str, data: dict, modified_by: str = None):
- """Sets the device state"""
-
- create_device(hw_id)
-
- # add the client's IP address if no sender specified
- if 'modified_by' in data:
- modified_by = data['modified_by']
- if modified_by is None:
- modified_by: str = str(request.client) + "_" + str(request.headers)
-
- allowed_keys: list[str] = [
- 'os_info',
- 'friendly_name',
- 'current_app',
- 'current_room',
- 'pairing_code',
- ]
-
- for key in data:
- if key in allowed_keys:
- db.insert(f"""
- UPDATE `Device`
- SET {key}=:value,
- last_modified=CURRENT_TIMESTAMP,
- modified_by=:modified_by
- WHERE `hw_id`=:hw_id;
- """,
- {
- 'value': data[key],
- 'hw_id': hw_id,
- 'modified_by': modified_by
- })
- if key == "data":
- new_data = data['data']
- # get the old json values and merge the data
- old_data_query = db.query("""
- SELECT data
- FROM `Device`
- WHERE hw_id=:hw_id
- """, {"hw_id": hw_id})
-
- if len(old_data_query) == 1:
- old_data: dict = {}
- if old_data_query[0]['data'] is not None:
- old_data = json.loads(old_data_query[0]["data"])
- new_data = {**old_data, **new_data}
-
- # add the data to the db
- db.insert("""
- UPDATE `Device`
- SET data=:data,
- last_modified=CURRENT_TIMESTAMP
- WHERE hw_id=:hw_id;
- """, {"hw_id": hw_id, "data": json.dumps(new_data)})
- return {'success': True}
-
-
-def generate_id(length: int = 4) -> str:
- return ''.join(
- secrets.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for i in range(length))
-
-
-@router.post('/set_data')
-def set_data_with_random_key(request: fastapi.Request, data: dict, modified_by: str = None,
- category: str = None) -> dict:
- """Creates a little storage bucket for arbitrary data with a random key"""
- return set_data(request, data, None, modified_by, category)
-
-
-@router.post('/set_data/{key}')
-def set_data(request: fastapi.Request, data: dict, key: str = None, modified_by: str = None,
- category: str = None) -> dict:
- """Creates a little storage bucket for arbitrary data"""
-
- # add the client's IP address if no sender specified
- if 'modified_by' in data:
- modified_by = data['modified_by']
- if modified_by is None:
- modified_by: str = str(request.client) + "_" + str(request.headers)
-
- # generates a key if none was supplied
- if key is None:
- key = generate_id()
-
- # regenerate if necessary
- while len(db.query("SELECT id FROM `DataBlock` WHERE id=:id;", {"id": key})) > 0:
- key = generate_id()
-
- # get the old json values and merge the data
- old_data_query = db.query("""
- SELECT data
- FROM `DataBlock`
- WHERE id=:id
- """, {"id": key})
-
- if len(old_data_query) == 1:
- old_data: dict = json.loads(old_data_query[0]["data"])
- data = {**old_data, **data}
-
- # add the data to the db
- db.insert("""
- REPLACE INTO `DataBlock` (id, category, modified_by, data, last_modified)
- VALUES(:id, :category, :modified_by, :data, CURRENT_TIMESTAMP);
- """, {"id": key, "category": category, "modified_by": modified_by, "data": json.dumps(data)})
-
- return {'key': key}
-
-
-@router.get('/get_data/{key}')
-def get_data(key: str) -> dict:
- """Gets data from a storage bucket for arbitrary data"""
-
- data = db.query("""
- SELECT *
- FROM `DataBlock`
- WHERE id=:id
- """, {"id": key})
-
- db.insert("""
- UPDATE `DataBlock`
- SET last_accessed = CURRENT_TIMESTAMP
- WHERE id=:id;
- """, {"id": key})
-
- try:
- if len(data) == 1:
- block = dict(data[0])
- if 'data' in block and block['data'] is not None:
- block['data'] = json.loads(block['data'])
- return block
- return {'error': 'Not found'}
- except Exception as e:
- print(e)
- return {'error': 'Unknown. Maybe no data at this key.'}
diff --git a/velconnect/routes/user_count.py b/velconnect/routes/user_count.py
index 1a072fc..f51d0d9 100644
--- a/velconnect/routes/user_count.py
+++ b/velconnect/routes/user_count.py
@@ -28,27 +28,41 @@ post_user_count_example = {
@router.post('/update_user_count')
-def update_user_count(data: dict):
+def update_user_count(data: dict = fastapi.Body(..., examples=post_user_count_example)) -> dict:
+ if 'app_id' not in data:
+ data['app_id'] = ""
+
db.insert("""
- REPLACE INTO `UserCount`
+ REPLACE INTO `UserCount` (
+ timestamp,
+ hw_id,
+ app_id,
+ room_id,
+ total_users,
+ room_users,
+ version,
+ platform
+ )
VALUES(
CURRENT_TIMESTAMP,
- %(hw_id)s,
- %(room_id)s,
- %(total_users)s,
- %(room_users)s,
- %(version)s,
- %(platform)s
+ :hw_id,
+ :app_id,
+ :room_id,
+ :total_users,
+ :room_users,
+ :version,
+ :platform
);
""", data)
return {'success': True}
@router.get('/get_user_count')
-def get_user_count(hours: float = 24):
+def get_user_count(app_id: str = None, hours: float = 24) -> list:
values = db.query("""
- SELECT timestamp, total_users
- FROM `UserCount`
- WHERE TIMESTAMP > DATE_SUB(NOW(), INTERVAL """ + str(hours) + """ HOUR);
- """)
- return values
\ No newline at end of file
+ SELECT timestamp, total_users
+ FROM `UserCount`
+ WHERE app_id = :app_id AND
+ timestamp > datetime('now', '-""" + str(hours) + """ Hour');
+ """, {"app_id": app_id})
+ return values
diff --git a/velconnect/routes/user_count_v2.py b/velconnect/routes/user_count_v2.py
deleted file mode 100644
index 68ac0fa..0000000
--- a/velconnect/routes/user_count_v2.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import fastapi
-
-import db
-
-db = db.DB("velconnect_v2.db")
-
-# APIRouter creates path operations for user module
-router = fastapi.APIRouter(
- prefix="/api/v2",
- tags=["User Count V2"],
- responses={404: {"description": "Not found"}},
-)
-
-post_user_count_example = {
- "default": {
- "summary": "Example insert for user count",
- "value": {
- "hw_id": "1234",
- "app_id": "example",
- "room_id": "0",
- "total_users": 1,
- "room_users": 1,
- "version": "0.1",
- "platform": "Windows"
- }
- }
-}
-
-
-@router.post('/update_user_count')
-def update_user_count(data: dict = fastapi.Body(..., examples=post_user_count_example)) -> dict:
- if 'app_id' not in data:
- data['app_id'] = ""
-
- db.insert("""
- REPLACE INTO `UserCount` (
- timestamp,
- hw_id,
- app_id,
- room_id,
- total_users,
- room_users,
- version,
- platform
- )
- VALUES(
- CURRENT_TIMESTAMP,
- :hw_id,
- :app_id,
- :room_id,
- :total_users,
- :room_users,
- :version,
- :platform
- );
- """, data)
- return {'success': True}
-
-
-@router.get('/get_user_count')
-def get_user_count(app_id: str = None, hours: float = 24) -> list:
- values = db.query("""
- SELECT timestamp, total_users
- FROM `UserCount`
- WHERE app_id = :app_id AND
- timestamp > datetime('now', '-""" + str(hours) + """ Hour');
- """, {"app_id": app_id})
- return values
diff --git a/velconnect/routes/website.py b/velconnect/routes/website.py
index 0e3ae10..413ce54 100644
--- a/velconnect/routes/website.py
+++ b/velconnect/routes/website.py
@@ -29,8 +29,8 @@ def success():
@router.get('/failure')
-def failure():
- return FileResponse("templates/failure.html")
+def failure(request: fastapi.Request, code: int = 0):
+ return templates.TemplateResponse("failure.html", {"request": request, "code": code})
@router.get('/join/{app_id}/{link}')
diff --git a/velconnect/static/js/device_details.js b/velconnect/static/js/device_details.js
index f5eadc0..3bbc9d2 100644
--- a/velconnect/static/js/device_details.js
+++ b/velconnect/static/js/device_details.js
@@ -4,7 +4,7 @@
if (hw_id !== "" && hw_id !== undefined && hw_id !== "undefined") {
- httpGetAsync('/api/v2/device/get_data/' + hw_id, (resp) => {
+ httpGetAsync('/api/device/get_data/' + hw_id, (resp) => {
console.log(resp);
let respData = JSON.parse(resp);
diff --git a/velconnect/static/js/velconnect_util.js b/velconnect/static/js/velconnect_util.js
index b0a4dff..3bde111 100644
--- a/velconnect/static/js/velconnect_util.js
+++ b/velconnect/static/js/velconnect_util.js
@@ -1,6 +1,6 @@
function setDeviceField(device) {
let hw_id = getCookie('hw_id');
- fetch('/api/v2/device/set_data/' + hw_id, {
+ fetch('/api/device/set_data/' + hw_id, {
method: 'POST',
headers: {
'Accept': 'application/json',
@@ -15,7 +15,7 @@ function setDeviceField(device) {
function setDeviceData(data, successCallback, failureCallback) {
let hw_id = getCookie('hw_id');
- fetch('/api/v2/device/set_data/' + hw_id, {
+ fetch('/api/device/set_data/' + hw_id, {
method: 'POST',
headers: {
'Accept': 'application/json',
@@ -35,7 +35,7 @@ function setDeviceData(data, successCallback, failureCallback) {
}
function setRoomData(data) {
- fetch('/api/v2/set_data/' + current_app.value + "_" + current_room.value, {
+ fetch('/api/set_data/' + current_app.value + "_" + current_room.value, {
method: 'POST',
headers: {
'Accept': 'application/json',
diff --git a/velconnect/templates/failure.html b/velconnect/templates/failure.html
index 21f3dfd..3a5c9da 100644
--- a/velconnect/templates/failure.html
+++ b/velconnect/templates/failure.html
@@ -1,7 +1,9 @@
-
+
+
+ Failure
@@ -27,9 +29,17 @@
-
- 🤮 FAIL 🤡
-
+
+ 🤮 FAIL 🤡
+
+
+
+ {% if code==1 %}
+
Pairing code not recognized. Go back and try again.
+ {% else %}
+
Unknown error
+ {% endif %}
+
\ No newline at end of file
diff --git a/velconnect/templates/index.html b/velconnect/templates/index.html
index dcdff1c..6dcab85 100644
--- a/velconnect/templates/index.html
+++ b/velconnect/templates/index.html
@@ -259,7 +259,7 @@
if (hw_id !== "" && hw_id !== undefined && hw_id !== "undefined") {
- httpGetAsync('/api/v2/device/get_data/' + hw_id, (resp) => {
+ httpGetAsync('/api/device/get_data/' + hw_id, (resp) => {
console.log(resp);
let respData = JSON.parse(resp);
@@ -309,7 +309,7 @@
function setDeviceField(data) {
- fetch('/api/v2/device/set_data/' + hw_id, {
+ fetch('/api/device/set_data/' + hw_id, {
method: 'POST',
headers: {
'Accept': 'application/json',
@@ -323,7 +323,7 @@
}
function setDeviceData(data) {
- fetch('/api/v2/device/set_data/' + hw_id, {
+ fetch('/api/device/set_data/' + hw_id, {
method: 'POST',
headers: {
'Accept': 'application/json',
@@ -337,7 +337,7 @@
}
function setRoomData(data) {
- fetch('/api/v2/set_data/' + current_app.value + "_" + current_room.value, {
+ fetch('/api/set_data/' + current_app.value + "_" + current_room.value, {
method: 'POST',
headers: {
'Accept': 'application/json',
diff --git a/velconnect/templates/pair.html b/velconnect/templates/pair.html
index ef9ab58..95161b7 100644
--- a/velconnect/templates/pair.html
+++ b/velconnect/templates/pair.html
@@ -1,3 +1,4 @@
+
@@ -69,7 +70,7 @@
You can find the code in the bottom left of your menu tablet in conVRged.