From c1ef5871c2294bf023f9d7fba0dda8658333bae6 Mon Sep 17 00:00:00 2001 From: Noloquideus Date: Sun, 10 May 2026 08:41:16 +0300 Subject: [PATCH] init commit --- .env.example | 9 + backend/Dockerfile | 15 + .../app/__pycache__/config.cpython-312.pyc | Bin 0 -> 3529 bytes backend/app/__pycache__/main.cpython-312.pyc | Bin 0 -> 25105 bytes .../app/__pycache__/schemas.cpython-312.pyc | Bin 0 -> 4229 bytes backend/app/config.py | 44 + backend/app/livekit_service.py | 45 + backend/app/main.py | 495 ++++++ backend/app/models.py | 42 + backend/app/probe_blocker.py | 37 + backend/app/schemas.py | 79 + backend/app/store.py | 127 ++ backend/requirements.txt | 5 + backend/static/favicon.ico | Bin 0 -> 4286 bytes backend/static/icons/attachment.png | Bin 0 -> 4619 bytes backend/static/icons/camera_off.png | Bin 0 -> 4377 bytes backend/static/icons/camera_on.png | Bin 0 -> 3644 bytes backend/static/icons/favicon.ico | Bin 0 -> 4286 bytes backend/static/icons/favicon.png | Bin 0 -> 101530 bytes backend/static/icons/micro_off.png | Bin 0 -> 4005 bytes backend/static/icons/micro_on.png | Bin 0 -> 3060 bytes docker-compose.yml | 51 + frontend/.dockerignore | 3 + frontend/Dockerfile | 16 + frontend/index.html | 13 + frontend/nginx.conf | 37 + frontend/package-lock.json | 1336 +++++++++++++++++ frontend/package.json | 17 + frontend/src/main.jsx | 730 +++++++++ frontend/src/styles.css | 535 +++++++ frontend/vite.config.js | 15 + livekit.yaml | 11 + 32 files changed, 3662 insertions(+) create mode 100644 .env.example create mode 100644 backend/Dockerfile create mode 100644 backend/app/__pycache__/config.cpython-312.pyc create mode 100644 backend/app/__pycache__/main.cpython-312.pyc create mode 100644 backend/app/__pycache__/schemas.cpython-312.pyc create mode 100644 backend/app/config.py create mode 100644 backend/app/livekit_service.py create mode 100644 backend/app/main.py create mode 100644 backend/app/models.py create mode 100644 backend/app/probe_blocker.py create mode 100644 backend/app/schemas.py create mode 100644 backend/app/store.py create mode 100644 backend/requirements.txt create mode 100644 backend/static/favicon.ico create mode 100644 backend/static/icons/attachment.png create mode 100644 backend/static/icons/camera_off.png create mode 100644 backend/static/icons/camera_on.png create mode 100644 backend/static/icons/favicon.ico create mode 100644 backend/static/icons/favicon.png create mode 100644 backend/static/icons/micro_off.png create mode 100644 backend/static/icons/micro_on.png create mode 100644 docker-compose.yml create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/index.html create mode 100644 frontend/nginx.conf create mode 100644 frontend/package-lock.json create mode 100644 frontend/package.json create mode 100644 frontend/src/main.jsx create mode 100644 frontend/src/styles.css create mode 100644 frontend/vite.config.js create mode 100644 livekit.yaml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9c74f8f --- /dev/null +++ b/.env.example @@ -0,0 +1,9 @@ +APP_BASE_URL=https://linkra.ru + +LIVEKIT_URL=ws://livekit:7880 +LIVEKIT_PUBLIC_URL=wss://rtc.linkra.ru + +LIVEKIT_API_KEY=linkra_key +LIVEKIT_API_SECRET=8edc959cc8517b864f73c99c86305a1d3b3fe509309e0a6e6e35172cc6695d87 + +CORS_ALLOW_ORIGINS=https://linkra.ru \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..f942fbd --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,15 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY app ./app + +EXPOSE 8000 + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/backend/app/__pycache__/config.cpython-312.pyc b/backend/app/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..daa86241ac30c3ca3c3b762bd70f5f797e10cf8a GIT binary patch literal 3529 zcmai1O>7(25#C)cDcYh$OQK}`S&?N)F&)QtY{ya@#{nhM5>0AJldCkAY&|Ub*3#Nb zF1x#uEkZ6-AO!+6K;=VW6(|s=CmA+S-P#_C`rgYbB%ta6MN_mr_~yj9w3l|?lH9D- z)P0B9+4*MXy*D#&-tHe;S`IQW9*h50{CboAa>@$4oJp|AfI_+55y(^D)=NF>=$By2CmDsxRF1oW6xw!lxy3 z37+07imc)=M*V|oTJe^$7*+CSzV63<@b#CM(;Qu;%*?Tvnd4?* z9kK_rn0xAZ0tg**yzG^In7;(Pje4=qg*Mq}lY{#40T=4G(Sr`!i~}z8fQ_~|Xe$o7 z(1SL5$U)n1y9;fW1F)(N2Mys)7usT@T@HE}ce~J58|`t>UfkzGgZ8}r4tfL+xX?p# z8_fHLgAU@OF0|dY9de<^Txf@l4m;=w9(AE1Ie@k}+dvB^wKB#vjQT+@3_j}Zw?Mv_S+rV=p$iDD8>r)D!*5`xgE$kgu0MP!;P zTGEzvL-`miNN*;UnnAIdw0Iqf@tIg^R-}`pglLxZ>Y7$Sa-n3dB2y{I+OkO}(~8)5 zj_GV&Gm(!`L=+>F(=#yv4C8Y#G&4cE3er6!nWmIqD#%4JQpz$aQWlR{-?$}MF#99PMyJL{k%-a6RAxCd=IwGQYlpJ!j@=KD56fBT7M@dYjA)BDp z=4hE(36iN`k+e-DQ;@}v!pEtg?I;*bS)>N67){!k&~%R7Iu?N{Q#vh z@u|3wCGB}lH((p8b{A>7vZxdd;!_rjnl3}Jw&rPJ8gkK4OsGlXmG7ClM0`*V%X%@- zLhKuZW}UY2m!m))GHcB32I6{RwhY%rjb@oJCnyXw<}j-dfYM`V@`kM5GN{|Ze|6@h zJk$xk0SDv;iu>ssE|d3$BfBAnVLm!H(VFiJjnyEpaFK z&USPsIBxmJUjoLwvN5_Tdt)bodB~W~reTZq8-v<3#*;dph5ZO&PN$~&QA*AOsqIa_ z04xbK%8h2H-03XdEv9iXI)JP*e-CzSM0Z2OJE7r9aK!SD=;I)NWvLL$+ERZB%>Q5N zJyyTK(o9jied9K?<^7}4Lcy-rwu4WB{o{3Z--SlM2zFsF;d7d%>c`+kr)5LDhN&wh z{Wulu4_BX4_s*e{RwPBG=dL{LMDI0PL*Uk+cZCzovpb=)Uxw~&o4aGe&X}+}Chm-h zm9dXNX3eAB`O?mOX?K2QXMUwJf3Ff;wfw999d-HvWEaSg4+-D;^c)QPKfwDGtmkINN zehU2Q!$1goGVCEui?Rt_Qiu4LRK?UU0}}S=?@|SiF5M-*dTXG|9~>O4*RS0=>WHg; z-C~+m<3k`2^487`Z1tbn9;&py`>E$oZ=d<~^~cw@ji(EhpzwI%(S_fx{9)~PYrp@| zhVNnELEz`DTMIiu!SW0L{4yvQ^!xLR&Pag&O*@eAAn_wqlnOFJ%Hl#mFkEbu8kC23&$WVpSibYBYfQ`;^e25MEVaVOM~C z%-DrxM^>lj$|m#>8lOW)`3bYveZ(65;Mqd8TU<|W9INo+-r;_0Wc*o6^{}v>*yyP6 z!rs6!>tw`=->eQSSbW!}r@}An^$l)yTkl=1_9fO+8`%n<0IjWQ>r%QpaILO%ZEtX7 zOR~mhs)K^XcW;7sVQ=)U?Mdsy`ReEmiywFdu5RoNy}9kN-p^KtM2qj;oUE>@ z^>DPdgeWzOS&2iRwU-iosvfGoirqHMZjXF@7-4ZEQW*xB1)=|!zVmI-lbH7l&VJL5F ze9cj|mOGj@A$))|(T1)nIXl}>0jpRlno8a-N7B}Kg=@9;@1oN~uG8AFb58sYK>w(| zD+}VkRIBsL`YZtSo-t@CzVNUt`)8*6A58CGn9JY#hS(JQ>DsppeSUqFWdfm}Ui`7& G_VXWp(~$-M literal 0 HcmV?d00001 diff --git a/backend/app/__pycache__/main.cpython-312.pyc b/backend/app/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a69778af8b36eb0b25d71681a8ecd9d0d83ca3e GIT binary patch literal 25105 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 z