From 52598ce2b53defa1f654bbf8c80cced1093f5c95 Mon Sep 17 00:00:00 2001 From: a2-imeri <Alfret2.imeri@live.uwe.ac.uk> Date: Wed, 15 May 2024 18:33:50 +0100 Subject: [PATCH] Base Implementation --- MisplaceAI/.env | 13 ++ MisplaceAI/.gitignore | 3 + MisplaceAI/Dockerfile | 28 ++++ MisplaceAI/MisplaceAI/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 120 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 203 bytes .../__pycache__/settings.cpython-310.pyc | Bin 0 -> 2518 bytes .../__pycache__/settings.cpython-39.pyc | Bin 0 -> 2426 bytes .../__pycache__/urls.cpython-310.pyc | Bin 0 -> 374 bytes .../__pycache__/urls.cpython-39.pyc | Bin 0 -> 983 bytes .../__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 529 bytes .../__pycache__/wsgi.cpython-39.pyc | Bin 0 -> 612 bytes MisplaceAI/MisplaceAI/asgi.py | 16 ++ MisplaceAI/MisplaceAI/settings.py | 143 ++++++++++++++++++ MisplaceAI/MisplaceAI/urls.py | 10 ++ MisplaceAI/MisplaceAI/wsgi.py | 16 ++ MisplaceAI/authentication/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 124 bytes .../__pycache__/admin.cpython-310.pyc | Bin 0 -> 165 bytes .../__pycache__/apps.cpython-310.pyc | Bin 0 -> 419 bytes .../__pycache__/forms.cpython-310.pyc | Bin 0 -> 1645 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 162 bytes .../__pycache__/urls.cpython-310.pyc | Bin 0 -> 373 bytes .../__pycache__/views.cpython-310.pyc | Bin 0 -> 1666 bytes MisplaceAI/authentication/admin.py | 3 + MisplaceAI/authentication/apps.py | 5 + MisplaceAI/authentication/forms.py | 29 ++++ .../authentication/migrations/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 135 bytes MisplaceAI/authentication/models.py | 3 + .../static/authentication/js/registration.js | 64 ++++++++ .../templates/authentication/login.html | 36 +++++ .../templates/authentication/logout.html | 11 ++ .../templates/authentication/register.html | 86 +++++++++++ MisplaceAI/authentication/tests.py | 3 + MisplaceAI/authentication/urls.py | 8 + MisplaceAI/authentication/views.py | 49 ++++++ MisplaceAI/core/__init__.py | 0 .../core/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 114 bytes .../core/__pycache__/admin.cpython-310.pyc | Bin 0 -> 155 bytes .../core/__pycache__/apps.cpython-310.pyc | Bin 0 -> 389 bytes .../core/__pycache__/models.cpython-310.pyc | Bin 0 -> 152 bytes .../core/__pycache__/urls.cpython-310.pyc | Bin 0 -> 243 bytes .../core/__pycache__/views.cpython-310.pyc | Bin 0 -> 290 bytes MisplaceAI/core/admin.py | 3 + MisplaceAI/core/apps.py | 6 + MisplaceAI/core/migrations/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 125 bytes MisplaceAI/core/models.py | 3 + MisplaceAI/core/templates/core/base.html | 21 +++ .../core/templates/core/head_includes.html | 7 + MisplaceAI/core/templates/core/home.html | 8 + MisplaceAI/core/templates/core/navbar.html | 29 ++++ MisplaceAI/core/tests.py | 3 + MisplaceAI/core/urls.py | 6 + MisplaceAI/core/views.py | 4 + MisplaceAI/db.sqlite3 | 0 MisplaceAI/docker-compose.yml | 25 +++ MisplaceAI/docker-web-entrypoint.sh | 21 +++ MisplaceAI/manage.py | 22 +++ MisplaceAI/requirements.txt | 50 ++++++ MisplaceAI/rules/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 115 bytes .../rules/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 198 bytes .../rules/__pycache__/admin.cpython-310.pyc | Bin 0 -> 156 bytes .../rules/__pycache__/admin.cpython-39.pyc | Bin 0 -> 239 bytes .../rules/__pycache__/apps.cpython-310.pyc | Bin 0 -> 373 bytes .../rules/__pycache__/apps.cpython-39.pyc | Bin 0 -> 454 bytes .../rules/__pycache__/forms.cpython-310.pyc | Bin 0 -> 1154 bytes .../rules/__pycache__/models.cpython-310.pyc | Bin 0 -> 549 bytes .../rules/__pycache__/models.cpython-39.pyc | Bin 0 -> 630 bytes .../rules/__pycache__/urls.cpython-310.pyc | Bin 0 -> 499 bytes .../rules/__pycache__/utils.cpython-310.pyc | Bin 0 -> 2064 bytes .../rules/__pycache__/views.cpython-310.pyc | Bin 0 -> 1714 bytes MisplaceAI/rules/admin.py | 3 + MisplaceAI/rules/apps.py | 7 + MisplaceAI/rules/forms.py | 25 +++ MisplaceAI/rules/migrations/0001_initial.py | 23 +++ MisplaceAI/rules/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-310.pyc | Bin 0 -> 684 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 126 bytes MisplaceAI/rules/models.py | 9 ++ .../rules/templates/rules/add_rule.html | 11 ++ .../rules/templates/rules/confirm_delete.html | 18 +++ .../rules/templates/rules/list_rules.html | 28 ++++ .../rules/templates/rules/rule_detail.html | 4 + .../rules/templates/rules/update_rule.html | 6 + MisplaceAI/rules/tests.py | 3 + MisplaceAI/rules/urls.py | 12 ++ MisplaceAI/rules/utils.py | 40 +++++ MisplaceAI/rules/views.py | 52 +++++++ 91 files changed, 975 insertions(+) create mode 100644 MisplaceAI/.env create mode 100644 MisplaceAI/.gitignore create mode 100644 MisplaceAI/Dockerfile create mode 100644 MisplaceAI/MisplaceAI/__init__.py create mode 100644 MisplaceAI/MisplaceAI/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/__init__.cpython-39.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/settings.cpython-39.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/urls.cpython-39.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/wsgi.cpython-310.pyc create mode 100644 MisplaceAI/MisplaceAI/__pycache__/wsgi.cpython-39.pyc create mode 100644 MisplaceAI/MisplaceAI/asgi.py create mode 100644 MisplaceAI/MisplaceAI/settings.py create mode 100644 MisplaceAI/MisplaceAI/urls.py create mode 100644 MisplaceAI/MisplaceAI/wsgi.py create mode 100644 MisplaceAI/authentication/__init__.py create mode 100644 MisplaceAI/authentication/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/authentication/__pycache__/admin.cpython-310.pyc create mode 100644 MisplaceAI/authentication/__pycache__/apps.cpython-310.pyc create mode 100644 MisplaceAI/authentication/__pycache__/forms.cpython-310.pyc create mode 100644 MisplaceAI/authentication/__pycache__/models.cpython-310.pyc create mode 100644 MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc create mode 100644 MisplaceAI/authentication/__pycache__/views.cpython-310.pyc create mode 100644 MisplaceAI/authentication/admin.py create mode 100644 MisplaceAI/authentication/apps.py create mode 100644 MisplaceAI/authentication/forms.py create mode 100644 MisplaceAI/authentication/migrations/__init__.py create mode 100644 MisplaceAI/authentication/migrations/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/authentication/models.py create mode 100644 MisplaceAI/authentication/static/authentication/js/registration.js create mode 100644 MisplaceAI/authentication/templates/authentication/login.html create mode 100644 MisplaceAI/authentication/templates/authentication/logout.html create mode 100644 MisplaceAI/authentication/templates/authentication/register.html create mode 100644 MisplaceAI/authentication/tests.py create mode 100644 MisplaceAI/authentication/urls.py create mode 100644 MisplaceAI/authentication/views.py create mode 100644 MisplaceAI/core/__init__.py create mode 100644 MisplaceAI/core/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/core/__pycache__/admin.cpython-310.pyc create mode 100644 MisplaceAI/core/__pycache__/apps.cpython-310.pyc create mode 100644 MisplaceAI/core/__pycache__/models.cpython-310.pyc create mode 100644 MisplaceAI/core/__pycache__/urls.cpython-310.pyc create mode 100644 MisplaceAI/core/__pycache__/views.cpython-310.pyc create mode 100644 MisplaceAI/core/admin.py create mode 100644 MisplaceAI/core/apps.py create mode 100644 MisplaceAI/core/migrations/__init__.py create mode 100644 MisplaceAI/core/migrations/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/core/models.py create mode 100644 MisplaceAI/core/templates/core/base.html create mode 100644 MisplaceAI/core/templates/core/head_includes.html create mode 100644 MisplaceAI/core/templates/core/home.html create mode 100644 MisplaceAI/core/templates/core/navbar.html create mode 100644 MisplaceAI/core/tests.py create mode 100644 MisplaceAI/core/urls.py create mode 100644 MisplaceAI/core/views.py create mode 100644 MisplaceAI/db.sqlite3 create mode 100644 MisplaceAI/docker-compose.yml create mode 100644 MisplaceAI/docker-web-entrypoint.sh create mode 100644 MisplaceAI/manage.py create mode 100644 MisplaceAI/requirements.txt create mode 100644 MisplaceAI/rules/__init__.py create mode 100644 MisplaceAI/rules/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/__init__.cpython-39.pyc create mode 100644 MisplaceAI/rules/__pycache__/admin.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/admin.cpython-39.pyc create mode 100644 MisplaceAI/rules/__pycache__/apps.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/apps.cpython-39.pyc create mode 100644 MisplaceAI/rules/__pycache__/forms.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/models.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/models.cpython-39.pyc create mode 100644 MisplaceAI/rules/__pycache__/urls.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/utils.cpython-310.pyc create mode 100644 MisplaceAI/rules/__pycache__/views.cpython-310.pyc create mode 100644 MisplaceAI/rules/admin.py create mode 100644 MisplaceAI/rules/apps.py create mode 100644 MisplaceAI/rules/forms.py create mode 100644 MisplaceAI/rules/migrations/0001_initial.py create mode 100644 MisplaceAI/rules/migrations/__init__.py create mode 100644 MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc create mode 100644 MisplaceAI/rules/migrations/__pycache__/__init__.cpython-310.pyc create mode 100644 MisplaceAI/rules/models.py create mode 100644 MisplaceAI/rules/templates/rules/add_rule.html create mode 100644 MisplaceAI/rules/templates/rules/confirm_delete.html create mode 100644 MisplaceAI/rules/templates/rules/list_rules.html create mode 100644 MisplaceAI/rules/templates/rules/rule_detail.html create mode 100644 MisplaceAI/rules/templates/rules/update_rule.html create mode 100644 MisplaceAI/rules/tests.py create mode 100644 MisplaceAI/rules/urls.py create mode 100644 MisplaceAI/rules/utils.py create mode 100644 MisplaceAI/rules/views.py diff --git a/MisplaceAI/.env b/MisplaceAI/.env new file mode 100644 index 0000000..4942f2e --- /dev/null +++ b/MisplaceAI/.env @@ -0,0 +1,13 @@ +# Django settings +DJANGO_SECRET_KEY=your-secret-key +DJANGO_DEBUG=True +DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1 + +# Database settings +MYSQL_DATABASE=misplaceai +MYSQL_USER=user +MYSQL_PASSWORD=password +MYSQL_HOST=db +MYSQL_PORT=3306 + +# Other environment variables can go here as needed diff --git a/MisplaceAI/.gitignore b/MisplaceAI/.gitignore new file mode 100644 index 0000000..a4537bc --- /dev/null +++ b/MisplaceAI/.gitignore @@ -0,0 +1,3 @@ +__pycache__/ +**/migrations/* +!**/migrations/__init__.py diff --git a/MisplaceAI/Dockerfile b/MisplaceAI/Dockerfile new file mode 100644 index 0000000..2751409 --- /dev/null +++ b/MisplaceAI/Dockerfile @@ -0,0 +1,28 @@ +# Use the full Python runtime as a parent image +FROM python:3.10 + +# Set the working directory in the container +WORKDIR /app + +# Copy the current directory contents into the container at /app +COPY . /app + +# Install system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + libpq-dev \ + libblas-dev \ + liblapack-dev \ + libatlas-base-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install Python dependencies +RUN pip install --no-cache-dir -r requirements.txt + +# Expose port 8000 for the Django app +EXPOSE 8000 + +# Run the Django server +CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] + + diff --git a/MisplaceAI/MisplaceAI/__init__.py b/MisplaceAI/MisplaceAI/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/MisplaceAI/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..078d38eb0b2f9da48d54dafc99a299f50e6a6d41 GIT binary patch literal 120 zcmd1j<>g{vU|?9e(IpK;KL!!Vn2~{j!GVE+p_qk%fgyz<m_d`#ZzV$!NEku<lGaZw wDA4!KEH21NOip$5)Q^wP%*!l^kJl@xyv1RYo1apelWGUjRLsP{z`())09vgUq5uE@ literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/__init__.cpython-39.pyc b/MisplaceAI/MisplaceAI/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39514c299e2d96eba915cae5ecd252866f8493fb GIT binary patch literal 203 zcmYe~<>g{vU|?9e(IpK;KL!!Vn2~{j!GVE+p_qk%fgyz<m_d`#ZzV$!NEku<DsZ-n z2`x@7Dvoh0N=-?L@y|<jDatHMjd96OF3nBND=Cg~%gjs6QK(E!EQ-lYNzE(COv_A8 zEXmBz)6GxQ&CM(>$Vp62P0`IPNzE;e@rCjoJ&~F5@tJv<CGqik1(mlrY;yBcN^?@} KKrZ<Vaxnmid^msr literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2fb8276f5548c1496a1d219646b6814fa3f04da GIT binary patch literal 2518 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 REKFd?%ErXT$nuYa3jlWGS@-|| literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-39.pyc b/MisplaceAI/MisplaceAI/__pycache__/settings.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd1fcc2fe9624981c3f5eb4b052d9f815ce76c9d GIT binary patch literal 2426 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 OZ!E$rOkl{y!U_QT97BQt literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..824207fc5694350a0be5912936807940285d2970 GIT binary patch literal 374 zcmd1j<>g{vU|?vt<&x&e$iVOz#6iaF3=9ko3=9m#Aq)%*DGVu$ISjdsQH+crHd78$ zE^`!fE=v>(BSR{43UexB7Hbw;GgB&a3QH<W3TrbXn9Y{TlEMyUbELAQaDv$BEK%$! zT)_;Q+%G})X)@koO-#wn%+qAL#Zr)1l5vYYGcP%(G$pl)4J@u-#a2|BlUl4_#RaDI zN{e!et5_3DOEUDUgh5nlUP)$hVo7Fx9$4-cLltLoeo-oz<EP0H#g~$mn3tZfmz<wh zQk0og#KgeBaElu%2r{jRnSp_!hy^6fQk+?mdW!`ldW*ZXD5oH?q$IT{uXrUx5h%RC z#4mCE#DW5S-^}8IoW$f*M^Al_a=n7eTO2mI`6;D2sdkK@kmF-uVBld8VB}%uVd7!r IVdVG?08T<<KmY&$ literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-39.pyc b/MisplaceAI/MisplaceAI/__pycache__/urls.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca21d865f36b19dcd688c5f867e9b328b683660d GIT binary patch literal 983 zcmYe~<>g{vU|?9e(It(QnStRkh=Yuo85kHG7#J9e4Hy_0QW&BbQW#U1au{=&qL>&# zY~~#1T$U&nMut?D6qZz`EY>WxW~Ow;DE1WAU<OUL#9}4}2H(u$f}F(UR7X#R&>$ZL z=ls01%=FTt#FEVXJT9(~j8uh$(xRM##FCQKqP*e+g`CXd5{07t(vs9-kcMJ~l6-}- z%+&H?Jq5S?B8A-iqEv;<ytMqHT(A)e1v#mS#i<I#si{_63JMAe86_nJ#a8<IDf!98 zdMR0ndFlBDMfq8&$t8Np`MLV3dHN=L2KpuW1)0gk`XI&nrA0Z#`dqFRiMa(isl`@Y zZl!t2AlE^x1siIpr{I{9qL7%UkeOSMUsPhHppaISpR15t8J}2C02M@1Zv<5j@&U*L zNItYuP$)<&$<R<&*MVrz%gE17)ltYx%uTgb2eH*Pxtwzni;H!W5{pw)Ad2w1BEKXf zwFu-8J#aw5oa2$7n+n!Pq-#Lx^%9HYL565(qPfU3FFB_)B{MHwAu$hZAINLT`FUwz z8w~XnJi!5@P?7<P9+28p4NZkKXi!=~f(sHIdY}M@IWiM$ZmJGAP{3vp<JzR0{B(VF z9R;Xv4Rw$J*j#l@O|F-qG_1*Zi#0JNH#1L@@fHgx#H-lATzx-Hj$7>U@hSPq@$pf7 zP$wnl=am#?CKWL;FfiQWh6;k*Sp>=hw^)iZOHyyKfCO%FBSq#)h9XV|1_<#h$Jr_- zv^ce>IL56gH6<m+KQGm#D6=dz#w9<wG&eP`q&UVcGcPemp)xhGC?+!{HLoNyEi)OM zjCJ$VbaSCOB}F&0BsI4<29a}+nIJdl6;$5hu*uC&Da}c>V+3VT4h9AW7JeQ^9%i2Z E0P<!vzyJUM literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/wsgi.cpython-310.pyc b/MisplaceAI/MisplaceAI/__pycache__/wsgi.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b278dc80a278b11c6c991a62d86ae58e828dba23 GIT binary patch literal 529 zcmd1j<>g{vU|?9e(IsszBLl-@5C<8vFfcGUFfcF_8!#|1q%cG=q%fv1<uFDurZA>3 z=P>0mM=>)pq%vl)EMQGxNnu^c#K@4!+{_TgmckUwpvhKsiz__X-BTesKQApaT_G*M zNWnL=xF9DnIn~iqp`a)~D>b=9kBiH*L?N}JAip@ZSfL~%RRN+WF()T6DJNASu~;Ed zAvZszG$&OzC$%g!N1-gSC=)D|mzbNHqL7e~SWu9YnVeXXnV*-CpvT4KmS3chn_rZw zkeQd3Uz7`$P{_|yD9OkyR!GatN!3v(PEF;?C@Co@w$j&6$xklUOUX*iOV5Y7DLFq^ zKQ&L^M9)A!Bfq>PUq2<aASb^vH#M(Bzq~j-Q=jW4D4hH>8E=WCr<TNn#Nv^haZAj_ z%hAu>KR(zsB*fFtJviRi-zC(?wMrNf0D8r#B_)}8>BXAtx7g$3Q}UDJ<8LwL7vB<q zxJ55HzbI7?WO5M`0|Ub?_SC$x%%c3fTU^DdB`K+CiKRIux44lkUCB@cicT=`OI$y( kpg<pC8`#-;1(mlrY#@PY#|Vm8kOme84o)5>J|-?E0L0Rv<^TWy literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/__pycache__/wsgi.cpython-39.pyc b/MisplaceAI/MisplaceAI/__pycache__/wsgi.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9509d845c199b794b0e7c9fafe1ee38151d0b04 GIT binary patch literal 612 zcmYe~<>g{vU|?9e(IsszBLl-@5C<8vFfcGUFfcF_8!#|1q%cG=q%fv1<uFDurZA>3 z=P>0mM=>)pq%vl)EMQGxNnu^c#K@4!+{_TgmckUwpvhKsiz__X-BTesKQApaT_G*M zNWnL=xF9DnIn~iqp`a)~D>b=9kBiH*L?N}JAip@ZSfL~%RRN+WF()T6DJNASu~;Ed zAvZszG$&OzC$%g!N1-gSC=)D|mzbNHqL7e~SWu9YnVeXXnV*-CpvT4KmS3chn_rZw zkeQd3Uz7`$P{_|yD9OkyR!GatN!3v(PEF;?C@Co@w$j&6$xklUOUX*iOV5Y7DLFq^ zKQ&L^M9)A!Bfq>PUq2<aASb^vH#M(Bzq~j-Q=jW4D4hH>8E=WCr<TNn#Nv^haZAj_ z%hAu>KR(zsB*fFtJviRi-zC(?wMrNf0D8r#B_)}8>BXAtx7g$3Q}UDJ<8LwL7vB<q zxJ55HzbI7?WO5M`0|Ub?_SC$x%%c3fTU^DdB`K+CiKRIux44lkUCB@cicT=`E63R? zCbT%Us5r*0C^aP|#y>CBr6{v3HO3`BxfJA&;uyEgyu=)Z%GAW7n9P*aypqf`Xdvq5 xr|ITGBPvBVvm`aQI0oTvWG2XUdIgoYIBXy>WXA|fEgTFC3@n@+Ogv0{OaSjj!#)52 literal 0 HcmV?d00001 diff --git a/MisplaceAI/MisplaceAI/asgi.py b/MisplaceAI/MisplaceAI/asgi.py new file mode 100644 index 0000000..b5ced38 --- /dev/null +++ b/MisplaceAI/MisplaceAI/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for MisplaceAI project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MisplaceAI.settings') + +application = get_asgi_application() diff --git a/MisplaceAI/MisplaceAI/settings.py b/MisplaceAI/MisplaceAI/settings.py new file mode 100644 index 0000000..a445cda --- /dev/null +++ b/MisplaceAI/MisplaceAI/settings.py @@ -0,0 +1,143 @@ +# misplaceai/settings.py +""" +Django settings for MisplaceAI project. + +Generated by 'django-admin startproject' using Django 4.0.2. + +For more information on this file, see +https://docs.djangoproject.com/en/4.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.0/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-34gsb7^)t!ltchc4#2^sn_#+$(4i=ts107$(2yjy#ung+%mrn2' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + + + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'rules.apps.RulesConfig', + 'authentication.apps.AuthenticationConfig', + 'core.apps.CoreConfig', + +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'MisplaceAI.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'MisplaceAI.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'misplaceai', + 'USER': 'user', + 'PASSWORD': 'password', + 'HOST': 'db', # Use service name defined in docker-compose.yml + 'PORT': '3306', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + 'OPTIONS': { + 'min_length': 8, + } + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.0/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.0/howto/static-files/ +STATIC_URL = '/static/' +STATICFILES_DIRS = [ + BASE_DIR / "static", + BASE_DIR / "authentication/static", +] + + + +# Default primary key field type +# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/MisplaceAI/MisplaceAI/urls.py b/MisplaceAI/MisplaceAI/urls.py new file mode 100644 index 0000000..7603c75 --- /dev/null +++ b/MisplaceAI/MisplaceAI/urls.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + # path('detection/', include('detection.urls')), + path('rules/', include('rules.urls')), + path('auth/', include('authentication.urls')), + path('', include('core.urls')), +] diff --git a/MisplaceAI/MisplaceAI/wsgi.py b/MisplaceAI/MisplaceAI/wsgi.py new file mode 100644 index 0000000..9c90901 --- /dev/null +++ b/MisplaceAI/MisplaceAI/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for MisplaceAI project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MisplaceAI.settings') + +application = get_wsgi_application() diff --git a/MisplaceAI/authentication/__init__.py b/MisplaceAI/authentication/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/authentication/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..017e4bdf241bb7481d92ba991272552173d611a9 GIT binary patch literal 124 zcmd1j<>g{vU|{%o-6ah~KL!!Vn2~{j!GVE+p_qk%fgyz<m_d`#ZzV$!NEku<lGjfx zD9}$VEy+mDE6GewEXmBz(~pnO%*!l^kJl@xyv1RYo1apelWGUjSj@!0z`())026>2 AJOBUy literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/__pycache__/admin.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dac94ce94b5a58d1b5f8e701ed95f2e27c9f3dcf GIT binary patch literal 165 zcmd1j<>g{vU|{%o-6hSQfq~&Mh=Yuo7#J8F7#J9e1sE6@QW#Pga~N_NqZk<(Qka4n zG?`z5)M_%`VoglR&CK)DWQyWT$x6&i&(}-N&nqd)Oez8yu#%yOnSlX9{F2d6EGW=V pEG@}M%`3@FPAtjH&(jBM*DI*J#bJ}1pHiBWYR3q&6r@>z0RRQ%B$5CC literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/__pycache__/apps.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d7bbc9a78b073b047dfd0b96999c880a622acb1 GIT binary patch literal 419 zcmd1j<>g{vU|{IF;gU9=fq~&Mh=Yt-7#J8F7#J9e6&M&8QW#Pga~N_NqZk<(+!<1s zQkYv9QkYX2o0+4SQdoi+G+AGQ^lCER;&d!1aL&(5%S=xOi6CP}n290`3=F9ZQH&`J zQA{a}QOqe!Q7kFU!3>%#w?rIEOEOaPN-~oZOEUBGASPAGrer1NrRVFVB<bbmr=;c- z>p5knJC>H@yJe>4q(t#0qG<BdWWB`^AD@?)n;IW~iz_}pH$SB`2gK%yk1s4u%z?@X zrKF}MmgbbiCzh7v$ESgey2S#LTggzw$-n?1eo5;m78K~C+5i$N)+?wiVrF1q0O4Xb z1_lNW1{OvRMzENlCi5+BsG}1L3W|%EK<0r|B20#`K#_2Z!v^9+J5Uf6gF>E%L4*ka D{MTjo literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/__pycache__/forms.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/forms.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54a0fe0e954d3449bd542c7c9fb000510ea1a227 GIT binary patch literal 1645 zcmd1j<>g{vU|`67;*xfNnStRkh=Yt-7#J8F7#J9eV;C41QW#Pga~N_NqZk=MY^EHh zT;?d|T$U&nFrPVxHJ2@ljgi5fA%!J{wS^&tHI=!UIf~t#A%!i4y@er#J(Z=IIf}!b zA%!D_vxOmr6D-e}!WGP*$^8;!uO{Oy*0lVh++t0pTLPiQsYT93sfi_-`FU>nMY*?x z97{_wQu9hOli^~TjJH@o>XJdakufvO<w^_;45<uJj42FJOsUKZSQauwvAQ#)Fs3lI zFr+XwGexnbFb6YevfSbcN=?r!E=er{*@a;q6U;mb6!W53(iu`17coY$rZ5FFXfjs` zBAcS;n_7~%lI0dhX>n>%USe+QE!NcB#LS#qoCS%+#pU@$DTWB9k>5(TTO9H6Aa(Ka zx47ctbMsS5b5i5uZ}G&(7nUaGKxB$o85kIDvF7Hdq~_dWOUq2nNhw~*P$a~_03m+K z=qDBw=qI9tl|DFB^$IF)v4Gsf0g6*L1_lNW1{Ovh#v&001_nP(_99-8A$%Z$A4GsW zeT&N#<YYIHJw==#QIKMUbr6;?NCIRa$Z^FW1_uKNqYzUOh=~!H@W@d^3Ct`OP_*<i zMzN+cXR)L*XR)O)_cBJYr?3PwXtLho^vO@p1gC^34p5wff&-LbauSnLb2J%mv6W}0 zq^FknX>wro2d8sJViCj}An)Je4S>dhXI?>R$t@08lt4TL56&X6*TfhY7<dqY#=|JY zSOgNo@EXYfpmbR5hT*kT<}B6}rWEE(#uS!b#uV0GrYJT<-e_iuVo%{}XGmiN=MK&& zj&=qXhA2)@-nb>^Tv}X`p9}Iea*hbO#hRRxSX^Ai1BzbV<ovvnqI^(LuqKw26oE1k zM^S2FX=YJsN)agCVz`zOma0K<ipV8VEGdW-Esfo7aM~_n2PK>$P{?2nHjuF(3{4R% zj2w`(mJCW+pkM-FP-=kTVm$^1h7yJn#u|oZrYt5%dZ=ZpVaQ@mVU}d5VTxy|VJs4@ zVOqenkb#k*29)Vo{M<mXpPZkYn^^)*qMEF?Sc^*wQj3aYKzW6wII%4C7Ef|cYGPh$ zN_<LUNg_lU^DUO*)SR>;1+XemCSA#Ri!(kR9H{Z}5HEq_A5@BfLa-QAUJ5btFoL|o z!dQhXa6mR{GKOe!VM~fdq9FSq`3ju)z^(yj!Xl7Gw|JpWNKVbkfjI-5AVK*Bk|04I z69gqlP+I0-kYeOx5@P{-*H4q{7F$YIVqSWF5h$2%NkTY!;N+2+qz5V)^gs!wxCj*N zMW90dmJ~Kc;4-EdT;PB+GC0YDErA3L*iB#p6iBx?Y#=3;9Vl59gAxS~g8(BBqX3ft Hy9g@)Sn_AA literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/__pycache__/models.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c15e23552ddbd9dd2781f899dc8b825c73916fd GIT binary patch literal 162 zcmd1j<>g{vU|{%o-6hSEfq~&Mh=Yuo7#J8F7#J9e1sE6@QW#Pga~N_NqZk<(Qka4n zG?`z5)M_%`V$01>NzEzt(`35EnUa;5m!7Yel2ioJypo}ag@FM={F2pAEGW=VEG@}M l%`3@FPAtjH&(nu!)hnpH#bJ}1pHiBWYR3q&5u{sy0RWuKBh~-_ literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..184fa57b1b865e05ab0820c3e8c10e2a3499ea50 GIT binary patch literal 373 zcmd1j<>g{vU|>*x;F89{$iVOz#6iaF3=9ko3=9m#J`4;DDGVu$ISjdsQH+cXDNHHM zIZV0CQOvn4Q7pNvQLKy%sf;Nssmv*?DQvyWsf;P?sVpfRP&Q{OYYG>Loz5J^mckv( zpvm(RWRE7}EtZ1Bl8l#(3=9mK%(r-pQqwbwOHzyC%Q92TZ*k@1r)TCt*xWh!>G`E4 zU``b$Or8EM4j2<;R$gLmY84w;m;NnQFkQtC(Wrk5B%WVd;-|@ei#sJNF)uw|ue2zq zxQK~?f#DV_$im_x76t}}B32N=1`_2iEy^iKEGbDX$}3*UP{aq401>~W^%DyU^b<=< zGE(zOGLsWaGV}BFL8j>yRNmsS$<0qG%}KQb`Kp+Qfq{XCL4=WqnTL^wk>f7_cSB?* literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/__pycache__/views.cpython-310.pyc b/MisplaceAI/authentication/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ad850b7d1b4592afc569793dfbc107f5ec30cfa8 GIT binary patch literal 1666 zcmd1j<>g{vU|{Hc;*!?P&cN^(#6iYP3=9ko3=9m#ISdR8DGVu$ISjdsQH;4vQA~^= zK2r{JE=v?kE^8EPE?X2ESd2M`J(nYjBbPIZlaV2XC51JIE0;TpJC`Sl2h3;7;mYNW z;$>t=VNc;`VTj^O;Y{IbVTj^S;ZEUcVTck);SFZc<a-HnhbGf4wxZO$l+>bI97U-q znMJ9|C7R5)Sab5zGxKioB$k$Bq~?`mCMTAp-eSwiPtPwc(PX+M<cJW@%+GVnFUq|o z5L%pC<Xn`RSOOJ!$;iOKpviQLCnz;Nv$!O+2&|0L2V^pcsmXXt%(=9<BtI8jXEI19 z$aNsh%)r3F%D}+j3<{-n3=9l43|R~*jM+>@G9`>P3|UOgjJ1q4j0>0-G89SIFfL$O z$WY5v!dk;n!_>^g$WX$T!qm(d%#g=i!r06JQklh`!Ys*<#gWCifD06QnT!h=85wFA zv)EJEaEP<x5a+-YFX66X0EKrAV<uxWb1;J@x8E(60RP~STPzv*xv94}N{dsA@)C1X zZ?PulBo-I{;z`Rd%GFKI&nqd)&$-2#nwyxJbBnVevADQAzbM5J!8EFpL5hyd{5<_4 zXu#@al;q~zVgVVX$#aV>H?<@qKc$F=fq|ijmw|!d7Dr}rd|6^nX38y=;>5DlA{LMg zC|qx`rDdk(q!iy`E6+?xPc6B{npjd&RD6rAv>+w1B((^XIyISZu@|KlmZlb$6p4aN zV*&YKB}0)s0|Ub^8U4h90(~@hm1U-u7wZ*N-r|M1Fdiht28ux`1_lN$MlMDUMh-B^ z^p}lQf?0wQ1O=Fi6d4#8P@*3c^&kw6{$<F~ZvcvZPy$F{>SY2&EI0}1*Dz+WEMQGx zUdUL>1ZA@<WUOT_VXI-PVNPM~WvXSVVM$>qWh~M!VXtARVF4!-jubYuWWotfCR|zE z3wS^o37$+iQ&=P!ve3j!crl_K9QK-ww^&jVOA?FtK|#j>i&jl0ut1SAC?@zogaC*T zWME*Zl0*wla8?9IF*y7+`HI9qYS}>qD0+*;K}Pc==cFd)rKZG#Y`evro?21_3N}Ps z7fFINfP%kB8pM(T5#R`BEs_PXL6M8(DmjoCD2~AqU8DfAgbVBzaAbl^D+Zat#mL9V z!N>!K&?s$SV**8~08^0~dUS$vHYnwRqf-SrI(b3S+04kuP{IVsu_eqk3@OabOu-DA zEPmj?1be1R3Nw82OH053q{#va8&FCs0$Bq|!Hf_OqIrfJQk;Q(qYFx!9N?r0Nti|I z3=9l@nu50kQnC{B()0C-GxCc{l1od9!A61&za<Qn183gMBt4MBz;1*DJ;)WeB(bQ` z1Lf4>B5(|XEWO1F5dc*cMcklp2j^W-UI2$6*fEf3K=T8KO>TZlX-=vgC|rv{X-I%U Qgi(M|fRP83!-RQ60Pa(T!~g&Q literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/admin.py b/MisplaceAI/authentication/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/MisplaceAI/authentication/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/MisplaceAI/authentication/apps.py b/MisplaceAI/authentication/apps.py new file mode 100644 index 0000000..924a9cc --- /dev/null +++ b/MisplaceAI/authentication/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + +class AuthenticationConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'authentication' diff --git a/MisplaceAI/authentication/forms.py b/MisplaceAI/authentication/forms.py new file mode 100644 index 0000000..c589bc6 --- /dev/null +++ b/MisplaceAI/authentication/forms.py @@ -0,0 +1,29 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm, AuthenticationForm +from django.contrib.auth.models import User + +class RegisterForm(UserCreationForm): + email = forms.EmailField() + + class Meta: + model = User + fields = ['username', 'email', 'password1', 'password2'] + +class LoginForm(AuthenticationForm): + username = forms.CharField(label='Username') + password = forms.CharField(widget=forms.PasswordInput) + + +class CustomUserCreationForm(UserCreationForm): + email = forms.EmailField(required=True, widget=forms.EmailInput(attrs={'class': 'form-control'})) + + class Meta: + model = User + fields = ("username", "email", "password1", "password2") + + def save(self, commit=True): + user = super(CustomUserCreationForm, self).save(commit=False) + user.email = self.cleaned_data["email"] + if commit: + user.save() + return user \ No newline at end of file diff --git a/MisplaceAI/authentication/migrations/__init__.py b/MisplaceAI/authentication/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/authentication/migrations/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/authentication/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c4a76f0095b0ff00c141a39653ff241428bc140 GIT binary patch literal 135 zcmd1j<>g{vU|{%o-6ah~KL!!Vn2~{j!GVE+p_qk%fgyz<m_d`#ZzV$!NEku<($Y^X zD9}$VEy+mDE6GewEXmBz)6dOJF9NfQ_2c6+^D;}~<Mj$EZ*kb<=BJeAq}qYZC}v_{ IU|?YY0CnLVvj6}9 literal 0 HcmV?d00001 diff --git a/MisplaceAI/authentication/models.py b/MisplaceAI/authentication/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/MisplaceAI/authentication/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/MisplaceAI/authentication/static/authentication/js/registration.js b/MisplaceAI/authentication/static/authentication/js/registration.js new file mode 100644 index 0000000..ebd1822 --- /dev/null +++ b/MisplaceAI/authentication/static/authentication/js/registration.js @@ -0,0 +1,64 @@ +document.addEventListener('DOMContentLoaded', function () { + const password1 = document.querySelector('#id_password1'); + const password2 = document.querySelector('#id_password2'); + const togglePassword1 = document.querySelector('#togglePassword1'); + const togglePassword2 = document.querySelector('#togglePassword2'); + const passwordMatchMessage = document.querySelector('#passwordMatchMessage'); + + togglePassword1.addEventListener('click', function () { + const type = password1.type === 'password' ? 'text' : 'password'; + password1.type = type; + this.classList.toggle('fa-eye'); + this.classList.toggle('fa-eye-slash'); + }); + + togglePassword2.addEventListener('click', function () { + const type = password2.type === 'password' ? 'text' : 'password'; + password2.type = type; + this.classList.toggle('fa-eye'); + this.classList.toggle('fa-eye-slash'); + }); + + // Password requirements validation + const requirements = { + length: { regex: /.{8,}/, element: document.querySelector('#passwordHelpBlock li:nth-child(1)') }, + uppercase: { regex: /[A-Z]/, element: document.querySelector('#passwordHelpBlock li:nth-child(2)') }, + lowercase: { regex: /[a-z]/, element: document.querySelector('#passwordHelpBlock li:nth-child(3)') }, + number: { regex: /[0-9]/, element: document.querySelector('#passwordHelpBlock li:nth-child(4)') } + }; + + function validatePassword() { + const value = password1.value; + let allValid = true; + for (const requirement in requirements) { + if (requirements[requirement].regex.test(value)) { + requirements[requirement].element.classList.add('text-success'); + requirements[requirement].element.classList.remove('text-muted'); + } else { + requirements[requirement].element.classList.remove('text-success'); + requirements[requirement].element.classList.add('text-muted'); + allValid = false; + } + } + return allValid; + } + + function checkPasswordMatch() { + if (validatePassword()) { + if (password1.value === password2.value) { + passwordMatchMessage.textContent = 'Passwords match'; + passwordMatchMessage.classList.remove('text-muted', 'text-danger'); + passwordMatchMessage.classList.add('text-success'); + } else { + passwordMatchMessage.textContent = 'Passwords do not match'; + passwordMatchMessage.classList.remove('text-muted', 'text-success'); + passwordMatchMessage.classList.add('text-danger'); + } + } else { + passwordMatchMessage.textContent = ''; + } + } + + password1.addEventListener('input', validatePassword); + password2.addEventListener('input', checkPasswordMatch); +}); diff --git a/MisplaceAI/authentication/templates/authentication/login.html b/MisplaceAI/authentication/templates/authentication/login.html new file mode 100644 index 0000000..d723ead --- /dev/null +++ b/MisplaceAI/authentication/templates/authentication/login.html @@ -0,0 +1,36 @@ +{% extends 'core/base.html' %} + +{% block title %}Login{% endblock %} + +{% block content %} +<div class="container mt-5"> + <div class="row justify-content-center"> + <div class="col-md-6"> + <div class="card"> + <div class="card-header"> + <h3 class="text-center">Login</h3> + </div> + <div class="card-body"> + <form method="post"> + {% csrf_token %} + <div class="form-group"> + <label for="id_username">Username</label> + {{ form.username }} + </div> + <div class="form-group"> + <label for="id_password">Password</label> + {{ form.password }} + </div> + <div class="form-group text-center"> + <button type="submit" class="btn btn-primary btn-block">Login</button> + </div> + </form> + </div> + <div class="card-footer text-center"> + <small>Don't have an account? <a href="{% url 'register' %}">Register here</a></small> + </div> + </div> + </div> + </div> +</div> +{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/authentication/templates/authentication/logout.html b/MisplaceAI/authentication/templates/authentication/logout.html new file mode 100644 index 0000000..c3c30b2 --- /dev/null +++ b/MisplaceAI/authentication/templates/authentication/logout.html @@ -0,0 +1,11 @@ +{% extends 'core/base.html' %} + +{% block title %}Logout{% endblock %} + +{% block content %} +<h2>Are you sure you want to logout?</h2> +<form method="post"> + {% csrf_token %} + <button type="submit">Logout</button> +</form> +{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/authentication/templates/authentication/register.html b/MisplaceAI/authentication/templates/authentication/register.html new file mode 100644 index 0000000..c8b4694 --- /dev/null +++ b/MisplaceAI/authentication/templates/authentication/register.html @@ -0,0 +1,86 @@ +{% extends 'core/base.html' %} +{% load static %} +{% block title %}Register{% endblock %} + +{% block content %} +<div class="container mt-5"> + <div class="row justify-content-center"> + <div class="col-md-6"> + <div class="card"> + <div class="card-header"> + <h3 class="text-center">Register</h3> + </div> + <div class="card-body"> + <form method="post" id="registration-form"> + {% csrf_token %} + {% if form.errors %} + <div class="alert alert-danger"> + <ul> + {% for field in form %} + {% for error in field.errors %} + <li>{{ error }}</li> + {% endfor %} + {% endfor %} + {% for error in form.non_field_errors %} + <li>{{ error }}</li> + {% endfor %} + </ul> + </div> + {% endif %} + <div class="form-group"> + <label for="id_username">Username</label> + {{ form.username }} + </div> + <div class="form-group"> + <label for="id_email">Email</label> + {{ form.email }} + </div> + <div class="form-group position-relative"> + <label for="id_password1">Password</label> + <div class="input-group"> + {{ form.password1 }} + <div class="input-group-append"> + <span class="input-group-text"> + <i class="fa fa-eye" id="togglePassword1" style="cursor: pointer;"></i> + </span> + </div> + </div> + <small id="passwordHelpBlock" class="form-text text-muted"> + Your password must meet the following requirements: + <ul> + <li>At least 8 characters</li> + <li>At least one uppercase letter</li> + <li>At least one lowercase letter</li> + <li>At least one number</li> + </ul> + </small> + </div> + <div class="form-group position-relative"> + <label for="id_password2">Confirm Password</label> + <div class="input-group"> + {{ form.password2 }} + <div class="input-group-append"> + <span class="input-group-text"> + <i class="fa fa-eye" id="togglePassword2" style="cursor: pointer;"></i> + </span> + </div> + </div> + <small id="passwordMatchMessage" class="form-text text-muted"></small> + </div> + <div class="form-group text-center"> + <button type="submit" class="btn btn-primary btn-block">Register</button> + </div> + </form> + </div> + <div class="card-footer text-center"> + <small>Already have an account? <a href="{% url 'login' %}">Login here</a></small> + </div> + </div> + </div> + </div> +</div> +{% endblock %} + +{% block extra_js %} +<script src="{% static 'authentication/js/registration.js' %}"></script> +{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/authentication/tests.py b/MisplaceAI/authentication/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/MisplaceAI/authentication/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/MisplaceAI/authentication/urls.py b/MisplaceAI/authentication/urls.py new file mode 100644 index 0000000..ff3c624 --- /dev/null +++ b/MisplaceAI/authentication/urls.py @@ -0,0 +1,8 @@ +from django.urls import path +from .views import register_view, login_view, logout_view + +urlpatterns = [ + path('register/', register_view, name='register'), + path('login/', login_view, name='login'), + path('logout/', logout_view, name='logout'), +] diff --git a/MisplaceAI/authentication/views.py b/MisplaceAI/authentication/views.py new file mode 100644 index 0000000..b45f8b9 --- /dev/null +++ b/MisplaceAI/authentication/views.py @@ -0,0 +1,49 @@ +from django.shortcuts import render, redirect +from django.contrib.auth import login, authenticate, logout +from django.contrib.auth.forms import AuthenticationForm, UserCreationForm +from .forms import RegisterForm, LoginForm +from .forms import CustomUserCreationForm +def register_view(request): + if request.method == 'POST': + form = CustomUserCreationForm(request.POST) + if form.is_valid(): + user = form.save() + login(request, user) + return redirect('home') + else: + form = CustomUserCreationForm() + + # Add Bootstrap classes to form fields + form.fields['username'].widget.attrs.update({'class': 'form-control'}) + form.fields['email'].widget.attrs.update({'class': 'form-control'}) + form.fields['password1'].widget.attrs.update({'class': 'form-control'}) + form.fields['password2'].widget.attrs.update({'class': 'form-control'}) + + return render(request, 'authentication/register.html', {'form': form}) + + +def login_view(request): + if request.method == 'POST': + form = AuthenticationForm(request, data=request.POST) + if form.is_valid(): + username = form.cleaned_data.get('username') + password = form.cleaned_data.get('password') + user = authenticate(username=username, password=password) + if user is not None: + login(request, user) + return redirect('home') + else: + form = AuthenticationForm() + + # Add Bootstrap classes to form fields + form.fields['username'].widget.attrs.update({'class': 'form-control'}) + form.fields['password'].widget.attrs.update({'class': 'form-control'}) + + return render(request, 'authentication/login.html', {'form': form}) + + +def logout_view(request): + if request.method == 'POST': + logout(request) + return redirect('login') + return render(request, 'authentication/logout.html') \ No newline at end of file diff --git a/MisplaceAI/core/__init__.py b/MisplaceAI/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/core/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/core/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a6cc05a9f2f9243c326a74d3dd83339163e3305 GIT binary patch literal 114 zcmd1j<>g{vU|>+c>5>MbAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_iRvd7 q6zC`C7p3aQ$7kkcmc+;F6;$5hu*uC&Da}c>11T?NVqjokVE_Q4g%mRY literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/__pycache__/admin.cpython-310.pyc b/MisplaceAI/core/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71ba20137e12e7da54b297f9c2f89e7ac555f52e GIT binary patch literal 155 zcmd1j<>g{vU|>+c>5^v8z`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>eu_mVEX6E^6GDY#FWF_XM=j$cs=am#?CKZ7USjkYt%)kI4ehKL(78K|w f=NF~wgEi?DRNmsS$<0qG%}KRm1X%^rBESFu1v?*! literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/__pycache__/apps.cpython-310.pyc b/MisplaceAI/core/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..93cc4d30411ee392704c2ab4e350c5cdcbb12a32 GIT binary patch literal 389 zcmd1j<>g{vU|>+c>5|sNz`*br#6iX^3=9ko3=9m#3JeSkDGVu$ISjdsQH+cX?hGkR zDa<VlDa@&i&CF3uDJ;PZnyfEDdNmnuaXJ<hIOpf3Wu_;CM36Bf%tR3e28L9ID8>|q zD5ey~DCQKVD3%oFU<OT=TU^fhMX3<|RkA5riFxVydMQbIx%nxnImLQTndy$DCHZcd zsW~aPSd#OLQvEbpZ*j!O=OyN*#>d~{ijU9DPbtj-v3cU-3riDopfW-!scDI&IVJIl zr6u|CX%GWIaw{2%K;Zx;ehKO)78K}%%mp!u^$IGBm>C!tKtWN=#=yY9!N9`E!3Y-f u(`3HI4Rv5*K|yg569WSSSO#nq62Z;Dz;KJh2I4R~P#_e84CG-DVFm!?AX!HM literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/__pycache__/models.cpython-310.pyc b/MisplaceAI/core/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa61354c3319e28acd74b5ca588900e26b257778 GIT binary patch literal 152 zcmd1j<>g{vU|>+c>5^v2z`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>evE}Bcq~;X+X)@j7Ovy^jOV8I!Nh$(qUdd3z!oUC_ehKR*78K|w=NF~w bLp10WRNmsS$<0qG%}KRm1la@9BftOvrd}S+ literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/__pycache__/urls.cpython-310.pyc b/MisplaceAI/core/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f202e656e5806acf4e4d41b19da4ed61228bf9a GIT binary patch literal 243 zcmd1j<>g{vU|?v!<&sv(z`*br#6iZa3=9ko3=9m#It&a9DGVu$ISjdsQH+cXDNHHM zIZV0CQOt}Csf;Nssmv*?DQvyW>5Ne<DeS=vnj9}d=4dkBVkt;0$#}`gz`&r%c#AV5 zKQ}eLEHkzI7Q-zT5C^0pFEKaOPm}c)cS=@bUV6S>X;Dsb5fcLg!!1^j(&8c(5SzQS zD5oH?q$IT{uXrUx5jO(^g!m<>pIA_!pPXNmst?ksS5SG2!zMRBr8Fni4rFgJ2Ll5G M4+9S)4>QMq06>#EjsO4v literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/__pycache__/views.cpython-310.pyc b/MisplaceAI/core/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa105ff2feb5e2260633aab16d392395d62eb820 GIT binary patch literal 290 zcmd1j<>g{vU|^Vd(<Lp7fq~&Mh=Yuo7#J8F7#J9eB^VeOQW#Pga~N_NqZk<(QkYVh zTNt94Qdoi+G+AGQ^sHpO#a5J>my%kP%n0H`F^J8~z`)=PG6rN@2}2D-3S%=<FoPzO zUlm_+eo?A^Mt*LpUPei7P7%mPO~za7MX80Qsl_EL8H!jL7#MyD=_eKx=!4akWu}%F z>lIYq;soi62XR5>7lU+iF&42iFfjOOGT#zN$x6&i&(|x?$S*2ME-fi80;vK^gN;NY e*cccXZgJS;=BJeAq}qWTT+G72z`(=6!vp|~G&)HD literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/admin.py b/MisplaceAI/core/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/MisplaceAI/core/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/MisplaceAI/core/apps.py b/MisplaceAI/core/apps.py new file mode 100644 index 0000000..8115ae6 --- /dev/null +++ b/MisplaceAI/core/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CoreConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'core' diff --git a/MisplaceAI/core/migrations/__init__.py b/MisplaceAI/core/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/core/migrations/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/core/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8eda8e962a61d1c433f852036d60dfeb04f99ce GIT binary patch literal 125 zcmd1j<>g{vU|>+c>5>MbAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_Dd;B_ z6zC`C7p3awW~LV<mSpDV73;^xXXa&=#K-FuRNmsS$<0qG%}KQb=`3bqU|?Wj007Mu B7^(mO literal 0 HcmV?d00001 diff --git a/MisplaceAI/core/models.py b/MisplaceAI/core/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/MisplaceAI/core/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/MisplaceAI/core/templates/core/base.html b/MisplaceAI/core/templates/core/base.html new file mode 100644 index 0000000..10a9baa --- /dev/null +++ b/MisplaceAI/core/templates/core/base.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{% block title %}MisplaceAI{% endblock %}</title> + {% include 'core/head_includes.html' %} + {% block extra_head %}{% endblock %} +</head> + +<body> + {% include 'core/navbar.html' %} + <div class="container"> + {% block content %}{% endblock %} + </div> + {% block extra_js %}{% endblock %} + +</body> + +</html> \ No newline at end of file diff --git a/MisplaceAI/core/templates/core/head_includes.html b/MisplaceAI/core/templates/core/head_includes.html new file mode 100644 index 0000000..558bc0d --- /dev/null +++ b/MisplaceAI/core/templates/core/head_includes.html @@ -0,0 +1,7 @@ +<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> +<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> + + +<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> +<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script> +<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> \ No newline at end of file diff --git a/MisplaceAI/core/templates/core/home.html b/MisplaceAI/core/templates/core/home.html new file mode 100644 index 0000000..4058e85 --- /dev/null +++ b/MisplaceAI/core/templates/core/home.html @@ -0,0 +1,8 @@ +{% extends 'core/base.html' %} + +{% block title %}Home{% endblock %} + +{% block content %} +<h1>Welcome to MisplaceAI</h1> +<p>This is the home page of the MisplaceAI application.</p> +{% endblock %} \ No newline at end of file diff --git a/MisplaceAI/core/templates/core/navbar.html b/MisplaceAI/core/templates/core/navbar.html new file mode 100644 index 0000000..4f58696 --- /dev/null +++ b/MisplaceAI/core/templates/core/navbar.html @@ -0,0 +1,29 @@ +<nav class="navbar navbar-expand-lg navbar-light bg-light"> + <a class="navbar-brand" href="{% url 'home' %}">MisplaceAI</a> + <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" + aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> + <span class="navbar-toggler-icon"></span> + </button> + <div class="collapse navbar-collapse" id="navbarNav"> + <ul class="navbar-nav ml-auto"> + <li class="nav-item"> + <a class="nav-link" href="{% url 'home' %}">Home</a> + </li> + {% if user.is_authenticated %} + <li class="nav-item"> + <form method="post" action="{% url 'logout' %}" class="form-inline"> + {% csrf_token %} + <button type="submit" class="btn btn-link nav-link" style="padding: 0;">Logout</button> + </form> + </li> + {% else %} + <li class="nav-item"> + <a class="nav-link" href="{% url 'login' %}">Login</a> + </li> + <li class="nav-item"> + <a class="nav-link" href="{% url 'register' %}">Register</a> + </li> + {% endif %} + </ul> + </div> +</nav> \ No newline at end of file diff --git a/MisplaceAI/core/tests.py b/MisplaceAI/core/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/MisplaceAI/core/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/MisplaceAI/core/urls.py b/MisplaceAI/core/urls.py new file mode 100644 index 0000000..049a4a5 --- /dev/null +++ b/MisplaceAI/core/urls.py @@ -0,0 +1,6 @@ +from django.urls import path +from .views import home_view + +urlpatterns = [ + path('', home_view, name='home'), +] diff --git a/MisplaceAI/core/views.py b/MisplaceAI/core/views.py new file mode 100644 index 0000000..0cecdb1 --- /dev/null +++ b/MisplaceAI/core/views.py @@ -0,0 +1,4 @@ +from django.shortcuts import render + +def home_view(request): + return render(request, 'core/home.html') diff --git a/MisplaceAI/db.sqlite3 b/MisplaceAI/db.sqlite3 new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/docker-compose.yml b/MisplaceAI/docker-compose.yml new file mode 100644 index 0000000..216683c --- /dev/null +++ b/MisplaceAI/docker-compose.yml @@ -0,0 +1,25 @@ +version: '3.7' + +services: + web: + build: . + command: python manage.py runserver 0.0.0.0:8000 + volumes: + - .:/app + ports: + - "8000:8000" + depends_on: + - db + + db: + image: mysql:5.7 + environment: + MYSQL_DATABASE: misplaceai + MYSQL_USER: user + MYSQL_PASSWORD: password + MYSQL_ROOT_PASSWORD: rootpassword + volumes: + - mysql_data:/var/lib/mysql + +volumes: + mysql_data: diff --git a/MisplaceAI/docker-web-entrypoint.sh b/MisplaceAI/docker-web-entrypoint.sh new file mode 100644 index 0000000..6bfacd7 --- /dev/null +++ b/MisplaceAI/docker-web-entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +echo "Waiting for MySQL to be available" +max_attempts=30 +count=0 +while ! mysqladmin ping -h"$DATABASE_HOST" --silent; do + count=$((count+1)) + if [ $count -ge $max_attempts ]; then + echo "ERROR: MySQL not available after $max_attempts attempts" + exit 1 + fi + sleep 1 +done +echo "MySQL is available and ready" + +# Run Django migrations +python manage.py migrate + +# Execute the command passed to this script +echo "Executing command: $@" +exec "$@" diff --git a/MisplaceAI/manage.py b/MisplaceAI/manage.py new file mode 100644 index 0000000..9b7c10d --- /dev/null +++ b/MisplaceAI/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MisplaceAI.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/MisplaceAI/requirements.txt b/MisplaceAI/requirements.txt new file mode 100644 index 0000000..cc29688 --- /dev/null +++ b/MisplaceAI/requirements.txt @@ -0,0 +1,50 @@ +# # TensorFlow and essential machine learning libraries +# tensorflow==2.10.1 +# tensorflow-addons==0.22.0 +# tensorflow-datasets==4.9.0 +# tensorflow-estimator==2.10.0 +# tensorflow-hub==0.16.1 +# tensorflow-io==0.31.0 +# tensorflow-io-gcs-filesystem==0.31.0 +# tensorflow-metadata==1.13.0 +# tensorflow-model-optimization==0.8.0 +# tensorflow-object-detection-api==0.1.1 +# tensorflow-text==2.10.0 + +# # Other essential libraries +# numpy==1.24.4 +# pandas==2.2.0 +# scikit-learn==1.4.1.post1 +# scipy==1.12.0 +# matplotlib==3.8.3 +# seaborn==0.12.2 +# pillow==10.2.0 +# opencv-python==4.9.0.80 +# h5py==3.10.0 +# protobuf==3.19.6 + +# # Additional useful libraries +# absl-py==1.4.0 +# six==1.16.0 +# wrapt==1.16.0 +# termcolor==2.4.0 +# tqdm==4.66.2 +# requests==2.31.0 + +# # Flask for web applications +# flask==2.2.5 + +# # PyYAML for configuration files +# pyyaml==6.0 + +# # Essential Python utilities +# ipython==8.15.0 +# setuptools==68.2.2 +# wheel==0.41.2 + +## +Django==3.2 +mysqlclient==2.1.0 + + + diff --git a/MisplaceAI/rules/__init__.py b/MisplaceAI/rules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/rules/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/rules/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c4ce198000f324a5cc3cfbd2b0a16952a95ba4e GIT binary patch literal 115 zcmd1j<>g{vU|=ZR=aL4ZAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_iRmX6 r6zCU~=A;(u$H!;pWtPOp>lIYq;;_lhPbtkwwF9XyW@2DqU||3N(^wSc literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/__init__.cpython-39.pyc b/MisplaceAI/rules/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf5573c4ac264229497c6125f1ed0780162d5844 GIT binary patch literal 198 zcmYe~<>g{vU|=ZR=aL4ZAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_WjkBN zgche3700+0rKY6B_~)g%6lIpB#<=7sm*%GCl@!OgW#%R3C{(5<7R6+yq~?`mre!84 zmSpDV>E@^D=4KWb<Rm7irs!stq~;dK_(J)Po-swGIjO}l@$s2?nI-Y@dIgoYIBatB PQ%ZAE?LdzB400?0PM$Wy literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/admin.cpython-310.pyc b/MisplaceAI/rules/__pycache__/admin.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5013b1ba1b0ae3a96269e865e48d81bc01ef099 GIT binary patch literal 156 zcmd1j<>g{vU|=ZR=aS~cz`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>eu_mVEX6E^6GDY#FWF_XM=j$cs=am#?CKZ7USjkYt%)kI4ehKR*78K|g gmFA=t>w|Ua6;$5hu*uC&Da}c>V+7d+(j&kC07@+&J^%m! literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/admin.cpython-39.pyc b/MisplaceAI/rules/__pycache__/admin.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bf9591e9ac3cc1c8238693e6444b34c1696be78 GIT binary patch literal 239 zcmYe~<>g{vU|=ZR=aS~cz`*br#6iYP3=9ko3=9m#0t^fcDGVu$ISjdsQH+cXDNMl( zn#?ajYBd>eu_mVEX6E^6GDY#FWF_XM=j$cs=am#?CKZ7USjkYt%)kI4eq}gY#e^28 z78S?16{V)6#Q5i>x)f!WrN+4ACzs}?=9Lu3xMk)g<|tIACKknHrljVTWTs^%CzfR9 z=jrCB>E>n@7vv-+r>5v;mZatu$M{0|j-D|^r8%j^F<__Y6;$5hu*uC&Da}c>V`N}p I_zZF>0BYVs5C8xG literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/apps.cpython-310.pyc b/MisplaceAI/rules/__pycache__/apps.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b7ecebdbaaabc1b1d67e235fb902e6c9eeee389 GIT binary patch literal 373 zcmd1j<>g{vU|<lt;gYtIfq~&Mh=Yt-7#J8F7#J9e6&M&8QW#Pga~N_NqZk<(+!<1s zQkYv9QkYX2o0+4SQdoi+G+AGQ^lCER;&d!1aL&(5%S=xOi6CP}n290`3=F9ZQH&`J zQA{a}QOqe!Q7kFU!3>%#x445!b5e^T21KzIfjCtHU@-;X#Jt4x)ZEm(5<gAWTO9H6 zd5O8H@$t8~;^TAkQ%Z9{Y@Yb|!qUVXs0<5;zQt3PT9lMuoC;RIlA(x`fdNAN64FmB zD9{I60%8^G6;u{6GcYiKa4{PL0|N&G3nK?3Sj<n8`4)FdR$^XyzFuNML2(fi$QY1H agn<wiC|GZC*g)K52l8|=C@gsxM3?{>$Wt%? literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/apps.cpython-39.pyc b/MisplaceAI/rules/__pycache__/apps.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6520755d5f9651200136cc640dbc0a6f74f0d904 GIT binary patch literal 454 zcmYe~<>g{vU|_I6>ypO6$iVOz#6iX^3=9ko3=9m#3JeSkDGVu$ISjdsQH+cX?hGkR zDa<VlDa@&i&CF3uDJ;PZnyfEDdNmnuaXJ<hIOpf3Wu_;CM36Bf%tR3e28L9ID8>|q zD5ey~DCQKVD3%oFU<OT=TiijVIjO}E1EN@qK%6Q8u$Y2xVqRi;YHn&?iJvCxEsps3 zyu{qp`1o5~@$tF&DWy3eHcxzfVQFFxRE7ma-{L7tElSESP6ex9$xy_}zyKkBr8`^2 zgche3700+0rKY6B_~)g%6lIpB#<=7smx3%Rj&aM(OUzNIOie6`$xKPjE6GgDOinDx z%+J%!Pt(oKEH21NOioSF%`8dHEspVp@*O>6z%GwTEGQ_}E2u1DW?*0d;bKsraxk(m vf<^o^nQw8YWF_XM=j(w~7BPWb22zJ`BZLKtsaqU25O3On!m${nmWK%d4%2hu literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/forms.cpython-310.pyc b/MisplaceAI/rules/__pycache__/forms.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7417812a7a9b27f25d270f78b952272824883522 GIT binary patch literal 1154 zcmd1j<>g{vU|{%l!6hw;nStRkh=Yt-7#J8F7#J9e^%xi!QW#Pga~N_NqZk<(QkYVh zbC`0OqnH^P+!<0>QdnCUQdm<Nvsjv$qgYeef*CZ~UxG~1WW2?imS2=x{F0G@fkBh; z7E4fRPHHkp3K=uQEHYwXU`S<%VoYI(Vsd9lVN79aVMt+WW{P4?VNPLbVTfW$VNGFc zVTfW)VNc;`VTfW&;S6Tb<hsQHGS@A?C>O(QCYae0NM@%pN3o<cq%baGjABh;3TDt` zuHuE6py!)flBmgiizP2HH}w{0a(-S)W=Up#-YvGoWDxDA$##n)J{}|+AAgH0K0Y@; zr8FlsKK>R@e0*VPVh%*62o!p^Sab7JQgd#xrDdk(q!h1YDB@#afDpfg^%DyU^ovS! zQj7J$VWd}3d5Z;PIV&j4*%%lYI2c$Mc^HcX7#J9mK>-L0GmxJ^Vdl)h!0=g)fq|ih zA&X%FV+!L!##+W2#$w(QrUlF?ObZ#C7;6|ozVj;r8CRtel98$aa-IU%JqpQ*d3pII z3Q4I7IjLzS3Q0MMdD(g^S#I$p=cFd)rKZHEB$g!JVopyjDFRt}i$5$eCo?4x6bi0I zMfpXVOt)ByQ*+Y5rX##o#LvLMaEl9U2soTLLGI*WU|`^3WMSlDWMQllhKDvn6;3Y} z34#(2vtJQA0|P^qCdd=;Si$F$A|a4IrXn#=n1l49JCPq^IovRiyNf{Sq)GzKeQ+g& z9SQPhl^V#Akn}>d3qcyuT?mPZc!)`&Ab)_JCyM4gh`gUBdl4w8i$K}Bh#RCDlyr*3 zK`coSAq67fNf2Tg*wdgS2THKTAgvq>e2g3{9Be#nMIdodf@e#~O3X{oha>|waH1}T oq;O7OPzncSJ+NYknFuRDrr+YQf#eZ8P$Dh{B}E<v9!4=H0I`z&aR2}S literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/models.cpython-310.pyc b/MisplaceAI/rules/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ead1e8c47db6a427658e77d0ddc21653b3388760 GIT binary patch literal 549 zcmd1j<>g{vU|<N??~?Y8fq~&Mh=Yt-7#J8F7#J9el^7TpQW#Pga~N_NqZk<(+!<1s zQkYv9QkYX2vzVHhqnJ}zf*CYfUxIXNGTvg#%}+_qDNY7)kulsrBL)VBRE8+V6ox3K zROT#}6h@GNy-ZQ8smu%57BWP!Lurl_mK4?&hA7SywqOQL_FF7Lr8%iD|1&T!glIC| z;>t~|h|fvQOE1Z|#a5b^Sy-By%!p(mhz-KdAWyI{Ffi0GWHAIYXfpa~GTvgzOUz9L z(Z#7bX)76uI2jlieu?NO78K|gmFA=t>q9)DS5SG2JwCp;q$oa~17r>p0|NsaV-*j` zC3;W^KTWP%9P#lW6XWA=amB~y=BJeAq{heJ;)#zhEKSUT$P|I}-r{u5NGx*8OwCCt zVrO7rxWyTgT2TV#-{MTp&r8WH$;{8Y#g>>1qKmj07$9x~I}k#EqOFLTfq?;pi$OdN z20lg(Mh-?ECa}1lCd)0(l&r+O^nAUPB#5=FzMx0}OG8Wnc^JY1nQ)842I6QtP>2<S KqKbz>j0pgm0C@HQ literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/models.cpython-39.pyc b/MisplaceAI/rules/__pycache__/models.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f0a1653bc660437e4e5e302b81d9b463a2ebb6f GIT binary patch literal 630 zcmYe~<>g{vU|<N??~?Y8fq~&Mh=Yt-7#J8F7#J9el^7TpQW#Pga~N_NqZk<(+!<1s zQkYv9QkYX2vzVHhqnJ}zf*CYfUxIXNGTvg#%}+_qDNY7)kulsrBL)VBRE8+V6ox3K zROT#}6h@GNy-ZQ8smu%57BWP!Lurl_mK4?&hA7SywqOQL_FF7Lr8%iD|1&T!glIC| z;>t~|h|fvQOE1Z|#a5b^Sy-By%!p(mhz-KdAWyI{Ffi0GWHAIYXfpa~GTvgzOUz9L z(Z#7bX)76uI2jlieq}ma#e^2878S?16{V)6#Q5i>x)f!WrN+4ACzs}?=9Lu3xMk)g z<|tIACKknHrljVTWTs^%CzfR9=jrCB>E>n@7vv-+r>5v;mZatu$M{0|j-D|^r8%j^ zF_4haE2zB19v@#^QWPK00dgD@$kmKhJRtAsK_&b&xo&a9$Ag?1AAgH0K0Y@;r8Fls zKK>R@e0*VPVh%*62&DHGr*lSPky~bJPD&9w0|Ub?&XClK5-|T3XL5dCN+!sKx7ZSs zL39x}0|UgvU|&NBP+BNrW?*0d;bM@hI2idDIT$&Zz@mPdEVnpQvJ&&s^Yv1aAeOTF fg5nu04KV{0h7cCWv|AiD5GUJ#BB2=MP97!zpJ19U literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/urls.cpython-310.pyc b/MisplaceAI/rules/__pycache__/urls.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7704261dde59232899a80cb1f727c50b2b5ad46f GIT binary patch literal 499 zcmd1j<>g{vU|`U`;*z$Tk%8ech=Ytd85kHG7#J9e3m6y}QW#Pga~N_NqZk<(QkYVh zbC`0OqnLA9qF8cSqgZp<qS$iTqu3c4QdpumQW;ZNQ<+oPQrLT$QyEh@Qdv?sp=_>H z))a0in<temg%`@^OJz^t2eH#xqc~Fpf*CXgUxM7C$#{#UAh9IlB_jg^gC^@OuAI!` zlK7(1oYdl59Em9@VCF53^i+u8E$*V!-2Adsh%k3)K}uo?l*0<q#8AWnGKujPOI~7b zY86XjN{W6FD+2>Vm4HogNs$#uRXj+_PQQo^BrFawQ6EE=9V`p60#lZQfq}tKlj|0D zN>*ZCdcIz1QBH9Y69WUoE!MKk)be7mGr$&uttkSTRs_;?izBh10PKQW+@(c11&Jjk zsYQ9kD;bIe7#JYLFCqQJf&zVzQ;YRM2J016-r}&y%}*)KNwouoRIv~P0|O6(3?mB@ M4-*d~1akZa00CTr3jhEB literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/utils.cpython-310.pyc b/MisplaceAI/rules/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ec72ae2621dab37e52edba017451b6382a1ca8f GIT binary patch literal 2064 zcmd1j<>g{vU|>kv?~?YEm4V?gh=Yuo85kHG7#J9e<ro+kQW#Pga~N_NqZk<(+!<1s zQkYv9Qka{WqL@-xf*CYfUotW<FlaK~VhJkENlivJ2E=B98Rf#jz>vxi#hAhn#gxLB z!qmbL#hk*N!qUPJ#gf9B!q&nN#hSvN!qLJI#g@XE!qvhM#h${Q!qdVK#gW3B!q>tO z#hJn%%%CZ7iw9&=v2S8tVtQ&(GRS(6O&|<ngKTsLIi8P!fuV+B0mDLu8ishr6oz01 zO-4UWrdwP&`H3m<MWs2Z#kW|&)Jn!%EXAogX)76uI2afhehKR*78K}%rSwZnGINUc z3My}L#K&jmWtPOpvw#c-*}}(IC5r46J(vm%H-Q2a>?RRVfP#Hr!jQ$dfN3Fv3qvzw zFoPy@m7-66Vv0gZMydkXVuiG#{9G_MC9xziDX}<J55-uJ1K1cC7=l5r0mV}$Lk&YL zcP(QLV-`aVV-|>JN@1A8G?}T83FP&aOt(0b^Yc<NOEUBGZm}gMgJ@0WTP%5rxv51w z3=9lKyr7t5y2YetaEk@x2ykdX2u=nDhFe@VDVfP7$@#ejb|8K+$PID~RoW<lfCybZ zo1FaQ#GGO~J%m0@<|2@;TkQEsS*gh-#kZIfb8?D69)Z{c3jZRI;YFZeW(Ro=q+W!n zN*sqR$smQG$OmDNL97f64B)`lV_;wa1#=ct4Py;c4RZ?P9HtbeUZxnPT9#T?m`Dvn z7IO`w4MPfZFoPybl}vDAS*k)JI1&^}@=;@;h#MS2MWCd0iz6j9EwMDGq}WfB1?;IJ zAy6O*loq5UmZZk#7sV$Rr6!i77J(e3$yNmN3|J>3u!{shI@lrVQqV%+7H4r{St>Z8 zf~+kD`BREXgt1BtB_!aAl0g9l3Iq@au|a_W4hT^40Of=l#uP?Lh8o5cCNRk?$*_=_ zkpYs8tK=P1QWO#u@>0uj_#NbFgwy>r8H>arp#k<7$S3F?;7Ck?WHgW@B(*T1Wf_<X z6vu;n3Q7oI$47v(aTdb@#u~<jjI~TPOvPGNVkJyj%%C)$!r04L%Ur{p#ZtqZ#hSu2 zhY6&jh5?iZY#72BYM6o<SQtu}ve+s$85uw@5**XzU>Q(+2c?!2Wu_wHJgHJ4v!qx7 zlq>XBGD0E@6#jmi?BJNZ#hjj6f{1TKh}`0F$xkiz%P(=Q$Sf|=WC2I`ElyBIiU*kn zj_fE7Fh4&j3nQ@7Q%k^+4Jspw#TXbEc$ioinHc#P`51W^S(y3$u`x3JXF(4@m@bq6 z1jRnQ%+Ub_AR{P9${317Ky(eGEkg-o785Apg92~?%R&Z5h7_h?FxF(Qk_t-A&Bq=j zMUo5*41Sud;IKdh!!5S7%$$<cqFZb!sX3`7shUh+?-$8{$`w#tLc9yg*|)fhz@~#e zs{qR3AbBn(4n{FXmVZ?eD5)DsDN6AND(T@q1f|Rph8hM)i3%=H8LRkxGK)(T5_59E z$+=h$RMh2U7MFk>ev7RvF{d=O7+cA6iwmR-?7Ct#kn=#H$%jz@WfnuCtJqJI3sgCP zqBuVO7FT?HZhlH>PHKGoEuQ%J!qUVXh)fZv&IOlh;Cxdg0SXye5CIB<B4rQ@6cCVr z0<%D&RRr=S2p5Ag5eEYYBL_1F3kNF)3kMGm8(7v)llc}~ZhlH?PBA1xK+2Jfftz)U S!v^9uJ5ca}3lts(AtnG&-M&Bo literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/__pycache__/views.cpython-310.pyc b/MisplaceAI/rules/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd89d7edaaf8a661c4e0e1a21b9d143d4661a98e GIT binary patch literal 1714 zcmd1j<>g{vU|`U>;*z$Boq^#oh=Yuo7#J8F7#J9ea~K#HQW#Pga~N_NqZo6UqL^}- zqnH^%VoW(KxvWvFj0`EvDJ(f`x$IHwU^Z(GM=oa+CnG}&TMBy%LljpEM+#>PLlk!k zR|<CvLljR6PYQ1fLlkccUkZN<Llj?%0F*Bn%%Cas666j|=38t<sd*`>MYlMLQd2UE zQj<$=38tr(#OEhvr6!le=NHAB7?@}>-s15p&d&=<EiTB<D^7jM$iTp$$#{z;s5B>4 zlkpY@h<3{_%1s7IfD8s<kmpz#7#N&E9+YBWU?^e8VqCzqkfD~bgt>+xg)xPxhB1?| znK_t2li9CIw5T*EwOBtVv$!N4%+$*$$<4XN3TA7v6tOcfFx+B?xU2XUb7D?T5y%Ej zrd#YqsfDGf#U(|Y3=9k_8H#ur7#MyD>n9cz=z}%umu04w7wZ*N-r_=-&IWQ73j+fK z7oz}U5kCV118&C$F)%RHFk~^LFlI9q$(1nHFk~?`GuATJFfL$T$WSC!!?=KDAp;{r z32O>dGh;AA30n;~wqV{XVQdC@8ckG_)$bNdfPZkvF9EPKtq_i@5(bOtC#Ix;!vYc% zENS^gxti>^*m6@#GV)W3I2afhiUdHx!jV}VUzV7YnR1JzII%3Xh#4dU37sMy5L*aD zfWieFI7NJ5O)%3zX|xz*4i_UABL^4?FtITSFcyh{f(2v_C_X_LWH3BVWx#P-!dSzY z!r04H%T&Tt!;r$1!d$}yja3%Em5jGo@)C1XtHdB40+I14sU?Y-IZ!`=L^PR;KrsQ1 zVsNCcWClC?7AHtH9%Mj~BsL#_QYuIZ$eqO?BX~fO33695E?0jxLvuAKGE<ncnTmvK zm_X6V$WX$P!VHc^)*6NsmK0W)e^#>j6^VnK0Sc=kK?VkfDoK#-#rnzld1;wNx$!Bf zIjJS7V4r~<ypj#cW5S?7XM-p~#843^XFy^F96#Ww;Vw$e%`Zy@$2~~?GboC9ps^#s zSfq#^FCf2zQZzWP72xur7AW6kvD7f7F!wUmGS@IKU|q;iq*%kefDN2{*;80*n6fxh zSbLd*8A>>77*g13m}{6)*yk{Ta%l;O&D_ga%Zw?f$$=C$pdukNuec;JFFCb}4;(~R zu&B~xERqI=95g|c7NjJWKs*W#Hch4?a9RaLw<Z@_=pj;kkq9UrL_q{7Nft?fSfD7^ zWC5ofupQtifEWi3S}*|#UnFZmVOb2a6BNFD;MC8@D8$6YB*a*xf*#Hw%V6ohNET$N z9Egwy5uk`di%4)p>4PMd7#JA*H2I?hQnC{B()0C-GxCc{l1od9!RZ~696*tHiyNvS zqokyu2xQeQw%q)b)SO~)?zqJYDg%lk0Rbwsz*)2il;Xj5fnAK`2!xk8Y;yBcN^?@} cKt*&hDELGeco;#DgNcKMgNK8KgPn&D07O||>;M1& literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/admin.py b/MisplaceAI/rules/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/MisplaceAI/rules/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/MisplaceAI/rules/apps.py b/MisplaceAI/rules/apps.py new file mode 100644 index 0000000..ed63476 --- /dev/null +++ b/MisplaceAI/rules/apps.py @@ -0,0 +1,7 @@ +from django.apps import AppConfig + +class RulesConfig(AppConfig): + name = 'rules' + verbose_name = 'Rules Management' # Optional: human-readable name for the app + + diff --git a/MisplaceAI/rules/forms.py b/MisplaceAI/rules/forms.py new file mode 100644 index 0000000..f45d524 --- /dev/null +++ b/MisplaceAI/rules/forms.py @@ -0,0 +1,25 @@ +from django import forms +from .models import Rule + +class RuleForm(forms.ModelForm): + class Meta: + model = Rule + fields = ['name', 'condition', 'action'] # Include all the fields you want from the model + + def clean_name(self): + name = self.cleaned_data.get('name') + if not name: + raise forms.ValidationError("The name field cannot be left blank.") + return name + + def clean_condition(self): + condition = self.cleaned_data.get('condition') + if not condition: + raise forms.ValidationError("The condition field cannot be left blank.") + return condition + + def clean_action(self): + action = self.cleaned_data.get('action') + if not action: + raise forms.ValidationError("The action field cannot be left blank.") + return action diff --git a/MisplaceAI/rules/migrations/0001_initial.py b/MisplaceAI/rules/migrations/0001_initial.py new file mode 100644 index 0000000..30eb830 --- /dev/null +++ b/MisplaceAI/rules/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2 on 2024-05-15 15:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Rule', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255, unique=True)), + ('condition', models.TextField()), + ('action', models.TextField()), + ], + ), + ] diff --git a/MisplaceAI/rules/migrations/__init__.py b/MisplaceAI/rules/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc b/MisplaceAI/rules/migrations/__pycache__/0001_initial.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cbc07602d64ef4ef2f9a6599d6144f132f80e71 GIT binary patch literal 684 zcmd1j<>g{vU|>i-?~)eE#K7<v#6iX^3=9ko3=9m#Y77hvDGVu$ISjdsQH;4vQA~^s z?hGkRDa<VlDa@&iS<KDMQOqeU!3>(LFF__~GTq|J%}g&!EXmBzE55~+o1c=JQ=ANv zLdKjh3t|`;7*ZLc7*iOcm{J&{n9~`eSW;QD*g#gKvS)FmFs3l3u%xi2u=TQ}F{QAl zvS)FofJ8ZanbMe2xKh~{a4lp=V@lzMvC>&mczT)A8KbyUc!L=<`EGIg!rT*bizTQu zC-oLnW{TS_CQlblmRmfDr6u|C$wjG&C8;U5xC@Fha}$dy<FivMZ*dl<7G);pWLBl# z;weilO3E)zjn7NWO})heB47SzU|<0IHnAc;Cp9m<B;yuaX<lYwY3eP`<ovvpOi&2i zVoOX0(V9#}JPZsBx7gA$Q*%;^{WN)Qam0g7i;us>6(66QpHiBW8Xtd)CqBNgG%*Kc zLwx)#_RPG@lFY=MTRbVL1*v%{sd>qnsl`Q1AfvdQ!H)I?1#l5FNQB2JGu^SYB;O5W z$1P6hjKm@+GbFX51j6LXFGz((&Ps+NSq26O@k>=dv7kV|s5B?FSRWC8`UVCDhVf8G z=oM5Jff5EAC}Bu2Ffed1urRSOv9K^PiZBT<axro-GW}us$MGMm%1@K!7H3LUVqSW_ jUP=<!$zWH4B@q@wSaKlebJ##a!HyAR0mvo+CNX9JB3!wM literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/migrations/__pycache__/__init__.cpython-310.pyc b/MisplaceAI/rules/migrations/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5d74a725a7fc9f83c4875323be05214b129899b GIT binary patch literal 126 zcmd1j<>g{vU|=ZR=aL4ZAA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_De5N{ z6zCU~=A;(u=VqoCC6;97=N0S6$7kkcmc+;F6;$5hu*uC&Da}c>18FU0VqjokVE_OH Cs2N-U literal 0 HcmV?d00001 diff --git a/MisplaceAI/rules/models.py b/MisplaceAI/rules/models.py new file mode 100644 index 0000000..a11306e --- /dev/null +++ b/MisplaceAI/rules/models.py @@ -0,0 +1,9 @@ +from django.db import models + +class Rule(models.Model): + name = models.CharField(max_length=255, unique=True) + condition = models.TextField() + action = models.TextField() + + def __str__(self): + return self.name diff --git a/MisplaceAI/rules/templates/rules/add_rule.html b/MisplaceAI/rules/templates/rules/add_rule.html new file mode 100644 index 0000000..078583c --- /dev/null +++ b/MisplaceAI/rules/templates/rules/add_rule.html @@ -0,0 +1,11 @@ +<h1>Add Rule</h1> +<form method="post"> + {% csrf_token %} + <label for="name">Name:</label> + <input type="text" id="name" name="name"><br> + <label for="condition">Condition:</label> + <textarea id="condition" name="condition"></textarea><br> + <label for="action">Action:</label> + <textarea id="action" name="action"></textarea><br> + <input type="submit" value="Submit"> +</form> \ No newline at end of file diff --git a/MisplaceAI/rules/templates/rules/confirm_delete.html b/MisplaceAI/rules/templates/rules/confirm_delete.html new file mode 100644 index 0000000..6e2fa10 --- /dev/null +++ b/MisplaceAI/rules/templates/rules/confirm_delete.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <title>Delete Rule</title> +</head> + +<body> + <h1>Are you sure you want to delete "{{ rule.name }}"?</h1> + <form method="post"> + {% csrf_token %} + <input type="submit" value="Confirm Delete"> + <a href="{% url 'rules:list_rules' %}">Cancel</a> + </form> +</body> + +</html> \ No newline at end of file diff --git a/MisplaceAI/rules/templates/rules/list_rules.html b/MisplaceAI/rules/templates/rules/list_rules.html new file mode 100644 index 0000000..2be2586 --- /dev/null +++ b/MisplaceAI/rules/templates/rules/list_rules.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <title>List of Rules</title> +</head> + +<body> + <h1>List of Rules</h1> + <ul> + {% for rule in rules %} + <li> + {{ rule.name }} + {% if rule.name %} + : <a href="{% url 'rules:get_rule' rule.name %}">View</a> + | <a href="{% url 'rules:update_rule' rule.name %}">Edit</a> + | <a href="{% url 'rules:remove_rule' rule.name %}">Delete</a> + {% else %} + : Name unavailable + {% endif %} + </li> + {% endfor %} + </ul> + <a href="{% url 'rules:add_rule' %}">Add New Rule</a> +</body> + +</html> \ No newline at end of file diff --git a/MisplaceAI/rules/templates/rules/rule_detail.html b/MisplaceAI/rules/templates/rules/rule_detail.html new file mode 100644 index 0000000..5b35231 --- /dev/null +++ b/MisplaceAI/rules/templates/rules/rule_detail.html @@ -0,0 +1,4 @@ +<h1>Rule Details</h1> +<p><strong>Name:</strong> {{ rule.name }}</p> +<p><strong>Condition:</strong> {{ rule.condition }}</p> +<p><strong>Action:</strong> {{ rule.action }}</p> \ No newline at end of file diff --git a/MisplaceAI/rules/templates/rules/update_rule.html b/MisplaceAI/rules/templates/rules/update_rule.html new file mode 100644 index 0000000..0a5843e --- /dev/null +++ b/MisplaceAI/rules/templates/rules/update_rule.html @@ -0,0 +1,6 @@ +<h1>Update Rule</h1> +<form method="post"> + {% csrf_token %} + {{ form.as_p }} + <button type="submit">Save changes</button> +</form> \ No newline at end of file diff --git a/MisplaceAI/rules/tests.py b/MisplaceAI/rules/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/MisplaceAI/rules/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/MisplaceAI/rules/urls.py b/MisplaceAI/rules/urls.py new file mode 100644 index 0000000..a556df6 --- /dev/null +++ b/MisplaceAI/rules/urls.py @@ -0,0 +1,12 @@ +from django.urls import path +from .views import list_rules, add_rule, get_rule, remove_rule, update_rule + +app_name = 'rules' +urlpatterns = [ + path('', list_rules, name='list_rules'), + path('add/', add_rule, name='add_rule'), + path('<str:rule_name>/', get_rule, name='get_rule'), + path('remove/<str:rule_name>/', remove_rule, name='remove_rule'), + path('update/<str:rule_name>/', update_rule, name='update_rule'), + +] diff --git a/MisplaceAI/rules/utils.py b/MisplaceAI/rules/utils.py new file mode 100644 index 0000000..fd8fbcd --- /dev/null +++ b/MisplaceAI/rules/utils.py @@ -0,0 +1,40 @@ +from .models import Rule + +class RulesManager: + def __init__(self): + self.rules = self.load_rules() + + def load_rules(self): + """Load the rules from the database.""" + return {rule.name: {'condition': rule.condition, 'action': rule.action} for rule in Rule.objects.all()} + + def save_rule(self, name, condition, action): + """Save a rule to the database.""" + rule, created = Rule.objects.update_or_create(name=name, defaults={'condition': condition, 'action': action}) + self.rules[name] = {'condition': condition, 'action': action} + + def add_rule(self, rule): + """Add a new rule to the database.""" + self.save_rule(rule["name"], rule["condition"], rule["action"]) + + def get_rule(self, rule_name): + """Retrieve a rule by its name.""" + rule = self.rules.get(rule_name) + if not rule: + try: + rule_obj = Rule.objects.get(name=rule_name) + rule = {'condition': rule_obj.condition, 'action': rule_obj.action} + self.rules[rule_name] = rule + except Rule.DoesNotExist: + return None + return rule + + def remove_rule(self, rule_name): + """Remove a rule by its name.""" + if rule_name in self.rules: + del self.rules[rule_name] + Rule.objects.filter(name=rule_name).delete() + + def list_rules(self): + """List all rules.""" + return list(self.rules.values()) diff --git a/MisplaceAI/rules/views.py b/MisplaceAI/rules/views.py new file mode 100644 index 0000000..9ef5872 --- /dev/null +++ b/MisplaceAI/rules/views.py @@ -0,0 +1,52 @@ +from django.shortcuts import render, redirect, get_object_or_404 +from django.http import JsonResponse +from .models import Rule +from .forms import RuleForm + +def list_rules(request): + rules = Rule.objects.all() + return render(request, 'rules/list_rules.html', {'rules': rules}) + +def add_rule(request): + if request.method == 'POST': + form = RuleForm(request.POST) + if form.is_valid(): + form.save() + return redirect('rules:list_rules') + else: + return render(request, 'rules/add_rule.html', {'form': form}) + else: + form = RuleForm() # An unbound form for GET requests + return render(request, 'rules/add_rule.html', {'form': form}) + +def get_rule(request, rule_name): + rule = get_object_or_404(Rule, name=rule_name) + return render(request, 'rules/rule_detail.html', {'rule': rule}) + +def remove_rule(request, rule_name): + rule = get_object_or_404(Rule, name=rule_name) + if request.method == 'POST': + rule.delete() + return redirect('rules:list_rules') + return render(request, 'rules/confirm_delete.html', {'rule': rule}) + +def update_rule(request, rule_name): + rule = get_object_or_404(Rule, name=rule_name) + if request.method == 'POST': + form = RuleForm(request.POST, instance=rule) + if form.is_valid(): + form.save() + return redirect('rules:get_rule', rule_name=rule.name) + else: + return render(request, 'rules/update_rule.html', {'form': form, 'rule': rule}) + else: + form = RuleForm(instance=rule) + return render(request, 'rules/update_rule.html', {'form': form, 'rule': rule}) + + +def remove_rule(request, rule_name): + rule = get_object_or_404(Rule, name=rule_name) + if request.method == 'POST': + rule.delete() + return redirect('rules:list_rules') + return render(request, 'rules/confirm_delete.html', {'rule': rule}) -- GitLab