From 79ff48915dad98b882dc79ece8a78c4b4c488d69 Mon Sep 17 00:00:00 2001 From: Anton Franzluebbers Date: Fri, 15 Oct 2021 23:14:35 -0400 Subject: [PATCH] add api spec, add fetching of headset details, improve website flow --- velconnect/routes/api.py | 45 +++++- velconnect/static/api_spec.json | 134 ++++++++++++++++++ .../favicons/android-chrome-192x192.png | Bin 0 -> 6078 bytes .../favicons/android-chrome-256x256.png | Bin 0 -> 6563 bytes .../static/favicons/apple-touch-icon.png | Bin 0 -> 1526 bytes velconnect/static/favicons/browserconfig.xml | 9 ++ velconnect/static/favicons/favicon-16x16.png | Bin 0 -> 815 bytes velconnect/static/favicons/favicon-32x32.png | Bin 0 -> 1294 bytes velconnect/static/favicons/favicon.ico | Bin 0 -> 15086 bytes velconnect/static/favicons/mstile-150x150.png | Bin 0 -> 1727 bytes .../static/favicons/safari-pinned-tab.svg | 20 +++ velconnect/static/favicons/site.webmanifest | 19 +++ velconnect/static/js/util.js | 31 ++++ velconnect/templates/api_spec.html | 24 ++++ velconnect/templates/failure.jinja | 10 ++ velconnect/templates/index.jinja | 78 ++++++++-- velconnect/templates/pair.jinja | 27 ++-- velconnect/templates/success.jinja | 10 ++ 18 files changed, 377 insertions(+), 30 deletions(-) create mode 100644 velconnect/static/api_spec.json create mode 100644 velconnect/static/favicons/android-chrome-192x192.png create mode 100644 velconnect/static/favicons/android-chrome-256x256.png create mode 100644 velconnect/static/favicons/apple-touch-icon.png create mode 100644 velconnect/static/favicons/browserconfig.xml create mode 100644 velconnect/static/favicons/favicon-16x16.png create mode 100644 velconnect/static/favicons/favicon-32x32.png create mode 100644 velconnect/static/favicons/favicon.ico create mode 100644 velconnect/static/favicons/mstile-150x150.png create mode 100644 velconnect/static/favicons/safari-pinned-tab.svg create mode 100644 velconnect/static/favicons/site.webmanifest create mode 100644 velconnect/static/js/util.js create mode 100644 velconnect/templates/api_spec.html diff --git a/velconnect/routes/api.py b/velconnect/routes/api.py index cf91253..a414abb 100644 --- a/velconnect/routes/api.py +++ b/velconnect/routes/api.py @@ -1,7 +1,8 @@ +from flask.helpers import send_from_directory from velconnect.auth import require_api_key from velconnect.db import connectToDB from velconnect.logger import logger -from flask import Blueprint, request, jsonify +from flask import Blueprint, request, jsonify, render_template, url_for import time import simplejson as json from random import random @@ -9,6 +10,20 @@ from random import random bp = Blueprint('api', __name__) + +@bp.route('/', methods=['GET']) +@require_api_key(0) +def api_home(): + return render_template('api_spec.html') + + +@bp.route('/api_spec.json', methods=['GET']) +@require_api_key(0) +def api_spec(): + return send_from_directory('static', 'api_spec.json') + + + @bp.route('/get_all_headsets', methods=['GET']) @require_api_key(0) def get_all_headsets(): @@ -48,8 +63,6 @@ def update_paring_code(): return 'Must supply hw_id', 400 if 'pairing_code' not in data: return 'Must supply pairing_code', 400 - if 'pairing_code' not in data: - return 'Must supply pairing_code', 400 conn, curr = connectToDB() @@ -73,6 +86,24 @@ def update_paring_code(): return 'Success' + + +@bp.route('/get_headset_details/', methods=['GET']) +@require_api_key(10) +def get_headset_details(hw_id): + return jsonify(get_headset_details_db(hw_id)) + + +def get_headset_details_db(hw_id): + conn, curr = connectToDB() + query = """ + SELECT * FROM `Headset` WHERE hw_id=%(hw_id)s; + """ + curr.execute(query, {'hw_id': hw_id}) + values = [dict(row) for row in curr.fetchall()] + curr.close() + return jsonify(values) + @bp.route('/get_room_details/', methods=['GET']) @require_api_key(10) @@ -91,13 +122,13 @@ def get_room_details_db(room_id): return jsonify(values) -@bp.route('/create_room', methods=['GET']) +@bp.route('/update_room/', methods=['POST']) @require_api_key(10) -def create_room(): - return jsonify(create_room_db()) +def update_room(room_id): + return jsonify(update_room_db(room_id, request.json)) -def create_room_db(): +def update_room_db(room_id, data): room_id = random.randint(0, 9999) conn, curr = connectToDB() query = """ diff --git a/velconnect/static/api_spec.json b/velconnect/static/api_spec.json new file mode 100644 index 0000000..1b041d3 --- /dev/null +++ b/velconnect/static/api_spec.json @@ -0,0 +1,134 @@ +{ + "openapi": "3.0.0", + "info": { + "version": "1.0", + "title": "VEL Connect API", + "description": "This API provides an interface with the database for pairing and controlling headsets while within a VEL app." + }, + "servers": [ + { + "url": "http://3.23.79.32/api/" + } + ], + "tags": [ + { + "name": "Read" + }, + { + "name": "Write" + } + ], + "paths": { + "/get_all_headsets": { + "get": { + "summary": "Get all headset data", + "description" : "Gets a list of all headset data that has been stored", + "tags": ["Read"], + "parameters": [ + ] + } + }, + "/pair_headset/{pairing_code}": { + "get": { + "summary": "Pair a headset by code", + "description" : "Tries to pair to a headset with a supplied pairing code. Returns the hw_id if successfully paired. Used by the website for pairing.", + "tags": ["Write"], + "parameters": [ + { + "name": "pairing_code", + "example": "1234", + "in": "path", + "description": "Pairing Code", + "required": true, + "schema": { + "type": "integer" + } + } + ] + } + }, + "/update_pairing_code": { + "post": { + "summary": "Update Pairing Code", + "description": "This is called by the VR application on login or when the pairing code is reset. If this is the first time this headset is seen, it also creates this headset in the database. A JSON body must be submitted with hw_id and pairing_code defined.", + "tags": ["Write"], + "parameters": [ + + ] + } + }, + "/get_headset_details/{hw_id}": { + "get": { + "summary": "Get Headset Details", + "description" : "Gets the info associated with a specific hardware id.", + "tags": ["Read"], + "parameters": [ + { + "name": "hw_id", + "example": "123456789", + "in": "path", + "description": "Hardware id of the device", + "required": true, + "schema": { + "type": "string" + } + } + ] + } + }, + "/get_room_details/{room_id}": { + "get": { + "summary": "Get Room Details", + "description" : "Gets the info associated with a specific room id. Used by the website to show initial data, and polled often by the headset.", + "tags": ["Read"], + "parameters": [ + { + "name": "room_id", + "example": "1234", + "in": "path", + "description": "Room id", + "required": true, + "schema": { + "type": "string" + } + } + ] + } + }, + "/update_room/{room_id}": { + "post": { + "summary": "Update Room Details", + "description" : "Sets the info associated with a specific room id. The room id is specified in the url and the data is specified in the JSON body. Used by both the website and headset.", + "tags": ["Write"], + "parameters": [ + { + "name": "room_id", + "example": "1234", + "in": "path", + "description": "Room id", + "required": true, + "schema": { + "type": "string" + } + } + ] + } + } + }, + "components": { + "schemas": { + }, + "securitySchemes": { + "api_key": { + "type": "apiKey", + "name": "x-api-key", + "in": "query" + } + } + }, + "security": [ + { + "BasicAuth": [] + } + ] + } \ No newline at end of file diff --git a/velconnect/static/favicons/android-chrome-192x192.png b/velconnect/static/favicons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..b3cd1715955f6ca91ea7ddb65e133f2192c8792c GIT binary patch literal 6078 zcmcIobx_n%*Z#3IEJ#R*lypmXcS%aaN=PH3bcd86sjPH|)Kb#5E3v>*0us^<5=(

SbW#%jog`t%I|h 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 L_0?+b*+%{sHBsEn literal 0 HcmV?d00001 diff --git a/velconnect/static/favicons/apple-touch-icon.png b/velconnect/static/favicons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ef6f509afbd4953e04ea62e2b18cf67a1c1cd015 GIT binary patch literal 1526 zcmZ`%doLKBK9aWILZ@)27t7a0FZeX0JasUObGzoum%9> zWdMMe0Kn0N(oTOT08nc4^Ts0A*VhFNEz^b6>4&uGqQ`=!)-{Ply0FMEt(GbUE?A+YkoSYmYk;r1PRyc3xY8uwW;`!E>EH|GneMmP1zP7q58XWF9b%t@mMlP4* z@pwfv2n3=~C>*aK>6~D(gTZq3?zV6cz8~(fIm0l73L0BuVq%n)m8Tw*aLxyIn>)x? zrHh>mrupf`PA1D0z4W@9X=abZ;mBliR#uj|xw(~LhLmb!Y_2;ZrK;w47URDSUi^9|F~ZYsZsX=1m;>}4bUCi5P$k^UtmB^V3_i^T>7 z1vNJ}FL(E`&tWF-6|RZIlaxZX2WFD|V7aGn`3;Lor3MBDhJ=I!2M33Rg|)P_Op@+1 zjcu2E*%PD!j%NS|g`FT4tO-TSy_^;H+o8CmE(5ETK8{c*6bJ-j#f*;27MC(JGtJD* zAP@+{7{(2cSz-0}I(qaud9HBYalC{3(INdlAzffghS4b{B_$OVl|E;bkUKO(E$36q z#p4t0?d>EIX{G<&OmXRls+!&1UE}z~dc|{0x#ti=m#^d7Vs3-{pqk zTZRi)-o2uKb4f1WitpeirOs_7qRM~G)pXlyaQDB!Z}4#>OZry~&-Y8)tBA1F>lQ8y zf>V^pLX5MwD;lCkl}yoQbq_noXH>QpckXe~e%VfyX;1DtUZkfG>#F6|ww#q054g(t zY2Vab8Dsfr6LCp1v=>I7;YMjYr#quIFtrQ#P=@sbqxGQty3LK^`=b|llE#QCQwTHKM(;S!CT(`}n)v40ha+%! zZkXHny7Rzhc7E|h*?QbDd3C|)!=Y_#(%B2V?-zL%BN-D;BfPdtSbe`bYQ;`%M@6l% zEPU`Mv}$#zeqzukSFV)OMmxlRP1B+sBufn$2jhb9p=Gic^YTw_0rUP=aX37AyQGZv zGi`gD{hjXvsmd=uT`S?O)>WDQ(Uf;f9C=EnhMf&Ci1z>FaUo{z!+<_IxjIzi z$n4iDq2r09W+aI2B>TQkZ=^L$gI-9pryYL^L(JA2k7($drdw3zlv7|PI<=i?ky?L# zo=HN^jh$(?Y6X$DFJ(K*f=yNF-DPC2W_PB0gA|;OcqF(>c@~Lrhuu4AiwOAGn2kp@ z?xUTXkImKQxiT{;Drojr6i$C&o|b|A9IJcv1jni9>qR}-?Qc3(Tk`bPuO7?3NIAMX zDPt!uUFKUf@;|lHbhDLO&7yQ%k}J_S72P)?AVUaOA_&p&sKjUm0XEh)Pzcl-0=2_h z+rXg?a2q>wYiqc*_2i^v;$McV@mFGTssC?yPWFpc7=qKVAp}fBGB_bI9vAytG?N~T01D}YXmY!J=WjaS)1LqU literal 0 HcmV?d00001 diff --git a/velconnect/static/favicons/browserconfig.xml b/velconnect/static/favicons/browserconfig.xml new file mode 100644 index 0000000..e8b57e5 --- /dev/null +++ b/velconnect/static/favicons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #b91d47 + + + diff --git a/velconnect/static/favicons/favicon-16x16.png b/velconnect/static/favicons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..c9c768a00defd4c298704bcfa6e7f4559304cb96 GIT binary patch literal 815 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU$g(vPY0F z14ES>14Ba#1H&(%P{RubhEf9thF1v;3|2E37{m+a>L3?YlH{-ks~$@7%g|zHjo; z(D>_n_uqZ==+fLp2eXRi&7VJI>eP)hXCIGEzkTWQ`TnU#L*i~6ICOd8(*2o*UESTa zb#+U6`%fff9*symTi3cjt7vKOgxgoI-F@)j{KV-8jO`C*6wIAJe=^XJS#yr~M_!mR z>*Ab+Hx3`YbNkMvISY?Wo}QALI;*e$TvO-ivbxjdb=S6RzkC1Q|NsBHWtRX$gF&<; z$S;^R?%Lm5Y3%WDK4e~f@aN{^&xH@4a{8JIEdwfGO!9Vj37yQc!x+e6FY)wsWq-;g zz$7fkG2u8cco~*?x;TbNTuwdrl33hm%FE^7z5Dj>{Grqd8(KfVugSc{ zl(EI?kK1x_7Xyhv!O4<3E4oB;vK$=Tjz~;8|6ZA=U_pY0%)$(vc^=CyeR5HoeOkP0 zY0=WC)%zP2vrVGk_FZ}V_4Rz&7`DR`ugHE^4^C>xpLtgN^wp}(ci(n0Pe1%o#6EuA z_TSEIdj3Ck1ULOZ{^r#?hJ#Dq_=$I!C8<`) zMX5lF!N|bKP}k5v*U&7)z{twb(#qIC+rYrez@T!?-9i)%x%nxXX_dG&aC}TX3)B!^ z6%tVrlvu7%P?VpRnUkteQdy9ykXcZY%)n4F=kX^Vj>0evjZ^-o&v-r!VqjM0)=TCV zRu=Z2EW#|T;L>1nIE7hxbBMy}8&^&oIdeqj2>a;|^+ew_dS literal 0 HcmV?d00001 diff --git a/velconnect/static/favicons/favicon-32x32.png b/velconnect/static/favicons/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..fd5a65ed9421e4ec475a516c54371071840a6078 GIT binary patch literal 1294 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081LK1LpAc7|g1Z9_?%lh4 z|NfmjckbT5cmMwVo5xRF+p+8V{zG?e-M)G9)b-u_u3fmebLY-2TefW9zWvID3)lDV zzj^G$)peT=I{552v_0QH^>k&!K~tyQa~G(nsc~^}@$m3)b8}0}%5IuF|FEs+$?W3G zi=wA-t0a;l(WpSsD>r7N;>a-yQ5qNAfz)6x#CTzx>_=6GWE-8*+KFIlnQ$nJdq zlsmWYoGPrmwr%JAhY#;RcyQz3;eC46$CI-68`+=ln{s8#_DffQZn<#r;>AmsFJIkv z@bZ$Cd(}+t+`hd}!)*WjMGj6*T3T8B>_@m5$C%me$rM z^UJU8Ke*r6ey@h<0dwcQnr8POKDY-AihFnW8$0Zl(%h$Io&t26q3r=n*ONJ=Cv!{B zbx*u=^X36-_k$KLyXP&Ck(E8{;Bzc8`OftlH;x>;zGvU|9XoF9J8*s1o@+bz+&Fyn z|Ns9FED+Dr6+p2IEGl9 zPEJTjNl8jeyn2iw=Z(yqm>wRUo|ro}du~NA%3JSeP-b4dV1k*Sg3h563R=s0**m-q z3_d>!UZ8tYp*1`%x}#BaKT|GSZkEP{i&rmRV=nws@?|TpgG01CyJzFPg%dY&y0osG zxwCcY(xp?k_O6w4YV4c4w|TLgM{D2Y&E2bK?`~f{eS5#$Ch3~Le-3JuFflbZIXgKY zI;5;LQN$(lwaf7z$B$*YzdZ6=U4?1xgeh|-b>%R5xX!AtnqwB==#~~%7Urk7ifKaE zo-KdAF#Y{;Xwjodmo|Os@(N*95Dj$@y>+$K)iiZ!>Q)J^1zIw%8^Ti3)1O~izCfE{ zbw)-`mS09@ZZ4~3Q1tS(ys9f4wQgBkHQwXle986x-OIPHKfj#cAS13IDy;6y#(G6$ z{mQv#&z}8xdD&u@uqoTV^~`**U|yi7Vy9 z>C;99A0CD(99QVS&cW)+=2n+@=hGUm7@i&`rBgeegiZ-Lcr)5JNOty?wmHkhl$jY~ zvoG1@J=@|3j4#y^*NBpo#FA92ez~vnOb=!YHNHJOVo~O#{eePMrZyx$-!ahkqo(pTD<)_nc_&hFX0yX+PSAZ~^`^W(es z?m6fCo$q|-aldmgi~u9ZSianV3^A^J!7x@Ch7l6tc%E+PdId6WuuAMLUDhmTVgj>Nch4M z30+Vud%smLr6uLEV8H^xGRrHTcygPRmv+m#hsq`Vv&9NwpD7kkgyP+b&zDNUwJx#2 zP7~qknb*ucGPpz@T3jL#sKfr<^-@_`Ez!}@5*ivR;o;$KSh{qnq@)}cOIf!>FE5wK zMI{owqFiD(RVX{q78;M^e*4#}q_ntuQteOfH(+;`9|7)BpL6lw`*f}J_V!D2bFIY2{=VBXI5;_L1;zbsckVl5t7Y>VtAxQ9$iKgz z`UZW1zF_A6YWgi19`>Dns<^Z5pLwbVzT6{EK2|C8SIvKTco>{~;9c7Y{*&$B-u(Rr z?f$6UXUIM2n>Er<-zS|N1MiU#k`mW~B{##aNk>KE92@DLBpr9Z(a7@~<;~UQYOaGrr{^VX*(B)=# z&7EU1ebX2JfPeru?yL*>Z@)+UHTSKac8AZ9JAKTPzsrAqA@mhbAF}(;wJG;CO&f6afq>hxT^+Hb_`lnA_TcYYDY}c+Rzcn5^-KJo2x0$z#!0 zH4kx3vnS#Ib2r;ResiTP`SkeLZ(Q?bq)lx6C-=_I0XdP;q}ITP_teQNsf}uG^7MCY zcP*K>yK6vkIGE^KKPM(83fIb9Lz@vB8!H(ZKUVAKm#}{3n)~vFcISAe%l#;l>lQ?z z@y%f$7ug5LRSxp$^xnQ(^gEqKNmCxT_cPzAPFv2{#pPEsws6|wKYnft?q&F^kADd6 zm43|sx8R-zupa){2HfX;7_j*v|M$U}d+Y(gF+b!_+dqi!IPO6P12ukB2kx;iBX@n_ zc{ShYpWC4u9JiV|d*0*sg#i1*FmS(&OPr&)$IfFlqh3fC2yk5D z*vk2V`S0aCeHZ$;FUq}L?oY1;KH-h{hkSX|F#b)s*f8FwoM#v|%1;`Gg)+!6(kXFb zLQ6i*Tn>A{5a~3A$vzf7!)`W8*iqY6+nE6{+MNy+0>l8$b6TUEbV6Iwx3YovfXSY> z|AaDs39JE}XJkN+<2?QPDWD&iY`vc4-GL6CHFEkb?sow9a=-r{(09O5_b}Xd0-ijl z`uSbxWdD5)n6B~gB6Lqj-L-B12>l-b`gunBfh`#GA{ali*=!@g_bLtc78tX1!_YWm zP9}RWmPXW8_eyz5kF>RROHomg6ciLVQCL_gt*xCZeqUPDt@bv#zo~%dnyOwE{~E8) zQ7`NC*5wY_vfhgQzzWGbUxIk)5}7@Fw#=P7SLV!_Ba0RVOYXVrh|yNb>WDH~9qz)) z&@#k4Yo(`WK-FWc9L&07R$A14^qPorxpJvS4j(=!2?+_ZYu7F%_wG%WU%zFQ4J)kj z)wNbhO=)oAd)RCL>G5Xi8^?aBS@&1IWRX>2WwLp-Rn?1oyu-sou!{?PuBzyj^$(W| z9p=&QTG?^y3f4cqU!U57aC!Qa=DOekxiQ(mB`3QiHeF+a{c;saxt$Ed)HPK zyY(!0EYBl!qpoL8wJ5)(559cFrGF#zM?^%J^sk+ees8)n9lG^z)K6bF+n;SfOvL`W ze5cK!!>pUO)AgtRBKjZps@?t1=Jdbuwm<#!%Efl{9kjO>-DdrdggW|P${}a}V;|hN z&))yOyv#DL_8&yMUi(d_+S}oI4f?r`)0=&U_5UHxLu_2-Yy4R#9DlwRT_x=A=Defb z*Vpz*G0yr_Sb7|197gt4wozk4pBjH#)%be@`|bH^{H4_6uLb+>b+x_Y($Bi7xdM`U zeDPK3RGLxdAEfbB#>{)CeYqB%E<17E+dPf>b)59>G;!d!UI;K9XSMsFSH;R8w*a)o zz48No>+R(Cm%bbvZbIG#riussjj_P(K%myGCEhItjsh*fWcG`Hp*((P@mnuc>!U>c zV4e+;1Ph`H=_=BIms515qg)`s0$n!fM9g9y;}i@_gaFPs#VkB{T;TlxZ~$QZZmjJ? zpL!nn6p#!sHa^z8I^Exq=LpdI5%TIX7<2gV1oG>0+@xNw*ykhH8d%Ryl)mOMzUTaY z;at09y-_7EzL+Y>$+eVzN)p^fieZg~HJR9-CA&ZJ9h@< z!ufXSckn-ZM&8W1D*JYO$qyUcZ0wVhuQsW?JP$-}W%v%vIa@8MsdoFFI+-K6+3h~R zv6#oRPWE^1?Ps>P<9?$4Gm$t8_rZ1p{J$7CUl_wP`yBf%|DTLyaQwRqj8+cQaE@TV UeZaz4v0K#8V}S7S$UMyZKZj1H2mk;8 literal 0 HcmV?d00001 diff --git a/velconnect/static/favicons/mstile-150x150.png b/velconnect/static/favicons/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..145dcc22c611c548ad15be18a3ab50444c15829c GIT binary patch literal 1727 zcmbtUc~H^`6#gMOo_S=OXh>+~Sq8$kd6g1|7n(|Dhp7SH3MT4L*)cKDER{;hOszJ$ zQ(Cf2vn>xi63ry9Xtfp8)HDOLENgdv`{(|#Gdt7Fd-LXdZ@%x%ym|8#><%EU)HT-y z0AQt$H!&ChUg-~9waS}Y&3m)3-?k%kHSsY+e}0Gc!( zq9+BE&y7eK6go0r^(LvI;1tC}enjUoHktLNg*fEs?@viS6t-*_tH~93>YN=Nw(Gq5 zyS+|(jo*m5iBP03;noKkRa+rkVh)+=56f_@0M{3|Hy=JH%BNpl$b2)z7?nOPcSif1 z+3>v~d!(D0@kh2Q4rO%>Uzln~srZ1b*oT{NZf`(XN$75E3jh3D?^Ek_u)mfMgcN5M zMG(4K)pfPD^9KG4Zu8>v%T%NK7SR$N*Ja^4MYR#IcT9~tj2_k)mLS~mexwoo$d5>N3Y?N#xZv!brssu+jA|jsNBF|>0;@%mB`6GN^FE2gEX>7MnzPCg$Vv< z+1arhWJh)p>9HJ-yx%9xb~}Va)eL1f3fP2=DA;!Ymko)L2!$zm2j8gt5pg|*?Pb9+M<5#0C>+A)&l#bC1$q9gl|dW zhuRUhMI+pIA>H>2(PKHg$HJ<>YU;TfG3L&dZMqbhnPO~Q#?sU!CC!N&liljf_>=aO zZRici7{jAi@HN!qNdb;Ml={Pi)@4~LW}KYJ)9cVzA)*_Fq}qF*rx#e31sxoC^@YKH zDO$2n>v|JawxI9l6u#4?IdE*(=whsZkOzkjA?#`{g%%$->g}EJT_hLwRoEf-g5~oI zqFuLF*Zz}zO-pnt+c*DM;J6lvy%`_^{%BRiF}uo}$HZhCgL%yS5px_3$=kE@(j z#QTP9**S|rrG~s$^SCCn0YxN3crgT*6c8*%)dc0rc-)dSMPDoW&RYIU``Kjr-BXg1 zrsmQrKSQ`=Df5_Xnf-%$L7W2{*E-S33pv5;R~S2Y3SXShLTr$T^AsuN7UhAt;oZyk z9|ZWcz$^=dyKPYL=iY8DkQ9eSjtKe>%vf?YWi9;|6`HKO^h!0T|}| zMBh-+DdvgrG(}2h-}(yK54SmeLJ1=>Q6$^s{g>$((0nRz-}&@ZZG^Nj-z%tv*^S^A ztBcBNg1VR<-U>UbZ`DP5yyXzHUu<+>j3{_UJcT z(W-nnLGYrXO}K)6Sr*`s!Hsu=-%Q}IPSNa*e&qjt>ucVV-~(A8*1EiSk+I}*(S9IA z&FoKi++)x;(zJy^D;@P;x6Bfh%^ZyUs?ke-Yx_hE7V~_AzA!y*wAZfqvi3MBGNt{* zCJ~#HqUGn5j(>Gs)O#%Wj`KU+J{VW9nxmh zJc8f8`4S{_kWVgOF1GRo11G?8FP)?x0`zI34Uv@N;NyZwy<}4($#WN ziC?G*9kn=jR9s>c=4^-Lq&N;FD;H^#ufXu?k@mOP&>mIw6mbbVFZcd_L;61oyie=Q za8V9zVsRy8!5dj#VJun{WFFKbbf^GM7$@vzEM_xyD+S}^f^~MmIXPf3E*Q)^TzA;N z2uTcDTy*At6D}sR#v#JqEJ_$FI4T3pJi>^MOQfS&nM^u5j>)0|09dJ1>uaZk+S+yn zO1pg~f&ut?Jx8jZ$$AsNlGSh%G%*L?N`tSjrJ$w5{hg9-2~wgZ&GEkE>j=!48ne`d R9|h0~z{e|qC?Z7W{tXJ}`_=#e literal 0 HcmV?d00001 diff --git a/velconnect/static/favicons/safari-pinned-tab.svg b/velconnect/static/favicons/safari-pinned-tab.svg new file mode 100644 index 0000000..1cd7cf2 --- /dev/null +++ b/velconnect/static/favicons/safari-pinned-tab.svg @@ -0,0 +1,20 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + + + diff --git a/velconnect/static/favicons/site.webmanifest b/velconnect/static/favicons/site.webmanifest new file mode 100644 index 0000000..de65106 --- /dev/null +++ b/velconnect/static/favicons/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/velconnect/static/js/util.js b/velconnect/static/js/util.js new file mode 100644 index 0000000..8396602 --- /dev/null +++ b/velconnect/static/js/util.js @@ -0,0 +1,31 @@ + +function httpGetAsync(theUrl, callback, failCallback) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = function () { + if (xmlHttp.readyState == 4) { + if (xmlHttp.status == 200) { + callback(xmlHttp.responseText); + } else { + failCallback(xmlHttp.status); + } + } + } + xmlHttp.open("GET", theUrl, true); // true for asynchronous + xmlHttp.send(null); +} + +function getCookie(cname) { + let name = cname + "="; + let decodedCookie = decodeURIComponent(document.cookie); + let ca = decodedCookie.split(';'); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length); + } + } + return ""; +} \ No newline at end of file diff --git a/velconnect/templates/api_spec.html b/velconnect/templates/api_spec.html new file mode 100644 index 0000000..081387a --- /dev/null +++ b/velconnect/templates/api_spec.html @@ -0,0 +1,24 @@ + + + + + + + + + + +

+ +
+ + + \ No newline at end of file diff --git a/velconnect/templates/failure.jinja b/velconnect/templates/failure.jinja index cc196a0..b9f3a2f 100644 --- a/velconnect/templates/failure.jinja +++ b/velconnect/templates/failure.jinja @@ -1,6 +1,16 @@ + + + + + + + + + + -
- Headset pairing. Wow so cool! 😋😎 +
+ +
+
â˜šī¸
+ + +
+ + \ No newline at end of file diff --git a/velconnect/templates/pair.jinja b/velconnect/templates/pair.jinja index 3df22c7..f5b3990 100644 --- a/velconnect/templates/pair.jinja +++ b/velconnect/templates/pair.jinja @@ -1,7 +1,19 @@ + + + + + + + + + + + +