From 83c902d6c36acce5dff6bcd92cb9d057523e1678 Mon Sep 17 00:00:00 2001 From: Xatiko <107261855+Anymorexxx@users.noreply.github.com> Date: Mon, 18 Nov 2024 00:49:14 +0300 Subject: [PATCH] Initial commit --- .idea/.gitignore | 3 + .idea/Dog_Academy.iml | 10 + .../inspectionProfiles/profiles_settings.xml | 6 + .idea/misc.xml | 7 + .idea/modules.xml | 8 + __pycache__/config.cpython-313.pyc | Bin 0 -> 460 bytes config.py | 16 ++ database/DogAcademy.db | Bin 0 -> 24576 bytes database/__init__.py | 0 database/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 141 bytes .../__pycache__/db_events.cpython-313.pyc | Bin 0 -> 1915 bytes .../__pycache__/db_session.cpython-313.pyc | Bin 0 -> 1309 bytes database/__pycache__/models.cpython-313.pyc | Bin 0 -> 2526 bytes database/db_events.py | 28 +++ database/db_session.py | 24 ++ database/models.py | 55 +++++ requirements | 2 + src/__pycache__/auth.cpython-313.pyc | Bin 0 -> 976 bytes src/auth.py | 19 ++ src/main.py | 16 ++ src/ui/__pycache__/admin_ui.cpython-313.pyc | Bin 0 -> 2867 bytes src/ui/__pycache__/auth_ui.cpython-313.pyc | Bin 0 -> 10171 bytes src/ui/__pycache__/user_ui.cpython-313.pyc | Bin 0 -> 2628 bytes src/ui/admin_ui.py | 59 +++++ src/ui/auth_ui.py | 222 ++++++++++++++++++ src/ui/user_ui.py | 56 +++++ 26 files changed, 531 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/Dog_Academy.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 __pycache__/config.cpython-313.pyc create mode 100644 config.py create mode 100644 database/DogAcademy.db create mode 100644 database/__init__.py create mode 100644 database/__pycache__/__init__.cpython-313.pyc create mode 100644 database/__pycache__/db_events.cpython-313.pyc create mode 100644 database/__pycache__/db_session.cpython-313.pyc create mode 100644 database/__pycache__/models.cpython-313.pyc create mode 100644 database/db_events.py create mode 100644 database/db_session.py create mode 100644 database/models.py create mode 100644 requirements create mode 100644 src/__pycache__/auth.cpython-313.pyc create mode 100644 src/auth.py create mode 100644 src/main.py create mode 100644 src/ui/__pycache__/admin_ui.cpython-313.pyc create mode 100644 src/ui/__pycache__/auth_ui.cpython-313.pyc create mode 100644 src/ui/__pycache__/user_ui.cpython-313.pyc create mode 100644 src/ui/admin_ui.py create mode 100644 src/ui/auth_ui.py create mode 100644 src/ui/user_ui.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/Dog_Academy.iml b/.idea/Dog_Academy.iml new file mode 100644 index 0000000..b6731d8 --- /dev/null +++ b/.idea/Dog_Academy.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..65f5335 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0a731dc --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..700288bc1b374adfd68c41be5e138a3b5d34ce3b GIT binary patch literal 460 zcmXw#PfG$p7{+J)yZ%|zkSHuLy5vPMBSj)uT@^`pWoM-VVOe)aGt{kFBlNU=h(3hh zrsFcusgpOsTc<|b-orf4Z{Xp5csCpu26UEsdHBTu@V$lqp}d>TIh79p0S1u44D?_R z^kOgcVITBkKMddi4B{YUF*^)p!i(V9poH=$zcqua!ex<~Qc*{!PyBC>qZ!J0ez>YR z8R==LO|5hru8!!2j0bzEthU>TUo$47DPeb#zbGuy*2|bi%eh?6&}Ld+vrtYjhrF&C zXfn?leK8Xv@d{tPZOBqr6x6EJl4QblfgM00v-ZZ8ugZkvCdUgEBXd~`{=jT7qN z#*gE7aOK1iJ6*DdNs~CPdab&3?YQ;(II5Jk`+HrP2s#KOpC@#KJRpWaUQtR2si?ZB zYF5gsp=(x*tZ~C*g*-j|QLFzUm3wbVeXaiUzNmFo69obgfB*y_009U<00I!W)dG{R zl_hg!#rU?9@FP#0j76NtFo^TU;-QZrZFaXHRVD(oV0>wwXnHyM5X_ z=yspb>arUi&kX6Fd`2S96WV7V)xk3pq|c9qJ&rv3p>1uxX+PZjHUNTM7 z_&8s1LV)Xu_0a+MMV6>=xF=49m(l5!b7v@3pD%)`&b6qQ zZ+{N0a5_vkp;c{7){JR@XK4WKq3c2+ zz*OnxZS}%q8Dt3x*+x8$&%!8=R~Rg;YIYwEdY!!kMw{vDs)asYSTtWW3?c(poX01g zy0*8~y2A9iZVl~qeP2=^HFxyKO-)s!{)?y^3Irek0SG_<0uX=z1Rwwb2tWV=w_TuN zl*#I&PvM9M^0Q37_#!-8f4)&wxs3X6qHZVZnOhkz;&q%vyL3J@h2q)H%Ji@kQ-_=n8e zr5qxWO07UiMK6_ds9N=yn?s9&QiaMn^*E~_fwn=a)LweC>K>|c>6=}zOq z?`JggzS(*p;6or|+Hj^%Lg-gMa7An=^#M@6L~#@sCeXM*1(oaKggA~VwskxqjT1^h zm%@m4#0j*XOh?4?I}Z^NEPqBXB@Ep#vc&=nrC7Oi6M7|nV=|UY-qiCe?@(H#NjD{T zBk*DP>X!wcejZv!1{-}r>_PL~!j=z&xG*FZ@SHfqJ=tT&1QwpQWf;0q?RDj} z^$fm*=4IEygS0+`3evpaor#NcQV?Ag|CKS|uD1GC#$FW11t}&?U32=hkVd1p7o~+u ze7C3W#+5s zZK~`M_&nwwj`LIVp809?p=gm@F_SG=@{(p4%SDZLUH5N9+l!Kv;8?ZL8*8 zh}z1%ePX&{bt)oLesvUz4p~@BrL2x*F`v(tD8D_6EYWPCWXZIc%PnfjTNX*?iiRE` zlpj3xavM*hpe(tdFDJ@|PAx$&?#iK>4|zK`0_%a#mB0S*KAXPrlfi=V zU3nH9_T-Q$hxX*KDTfbh1gs8ga?|;5BLcbaUx|58)#Hl|;p*9**Z{7+L1H7QIzaf$ z5a#+w*H{oA&(6Rp>_BBT>48iQnddiRi(9|P(c;iH!|$O@+^Pl=aa^1fAWM^smZ@u{ zqE`{nbjDq2($uW^IBus2Xc0Lr{}(wUId*L{ow}PQO{6>rdt%=}VRKTpptmdi2pcDs zHz&x3s=_vbupJHua8WTogMK?o`Rg-vB1JY#t(?H)3D6F!*BcaB2nCyl$%96`cE zLi@_g8+X?4d^P)AxxA0~LM0IG9b4>CGIF@tzHQEbv i{6}Mips8U&5Dw652S`0YSN@RvLZ}}02_f18i~j%x@BE|y literal 0 HcmV?d00001 diff --git a/database/__pycache__/db_session.cpython-313.pyc b/database/__pycache__/db_session.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba1385189e246748847a235c7786842f83b9c564 GIT binary patch literal 1309 zcmZ`&-Afcv6u+|{v$MO7m8C`y4JDKhji5-Zl%QFG8&W$(!7eVdyVJV0A9iOJGJ0^e zfPa*o~UQgOT7;EMty^R>UXd&Dh>u{z`_2gM5Tmq znk4+1s0AV(8ccXW3u;nCpdl@Ig3z!Q0@;xDw}*e=h3$eZr>UV^M$#x|b43FT4W?n5 zxl*y9KQJij1AVvp`unsi$=k8(p!@oD(-^vi$ViWr-ou{C6*Fnf=Pn-rsF2jwLCli4 zYbPZrvVU7O~O z2nxyi_ht6|%?y1K%fsNyUb79h!k@DhHpkXLF0(n*__V_2!L-b$6t)OpgKh9B{;Wsg z6}AapyS5d!r0}P3yb8f{3R_Y51ZeY^ia%E$w`6onPeEHd21?n!w4N~vV`?T#OhBQ@dZh`s`a~v`tdmb29kTF&1FFfCW*ElJ^$^7bB+l#kN+Z+P1OS-MP*LWToO zMLs%AZ2-X-6>RhFwNYWonY5&r#$<9NZ+?OoLlINsZ8RXdnBxaM4oJ~P$HVx@f=1a_F zW))EQJUOS%W+6K&6|-Z~MC&u44M}5?l^T((bWxi~3Nz^3nnA15VKul_MQgUhYI3WF zR=vZTs~81yn|-d3rkP8=7gcLixmpWJg#gW1A-J^))n0mEY5?(^ z(DiG_sOarB>{G$h4H51)SWMiW10{1PM!qq?LeFF+C;~Ggi_{ zolStkH5IkAl{uS)Y)emD3VOAojyIuN3G`;sYgihX6}@24)Ws-V-d6DdnsRWu@K~n$ z3b<7V*6dqkZKjZ*nW*O8jtEt2k>@#!9(gQ758ILcG9VD(irk`8x@E8UD-otg0;)s- z@!TMMEX@~kRJHAzQzf=dHQTQG<;Y`m!?tfnj@R;Z+4hnPLFl&Bk{GZ zTz>uQ#<6DZRD5~M=v|+DbnHog)0m1s-RkOJUwRZZyWWkj{FRZ6p}O)U^EBPmXYNeH zo9*wt9P*#h{VK?d3WAxOkZ}qAtdx~TNL4`x?#r}&6A7`VMF-7NEEVaXx2Th~G}H{P zne9E0D|X@cb<40!^mcPChty$OkJSaemF_|h^x>Dcdr{CdyX@e5gVATa1=?D0+*CKyH&#U-xuqEu_Dq4cJ zrwbPB>w*XSy2*L5uM1vad*Llb@Iq~AJysTZp%rvEiGgi1JZTE=G!R4(*LVu8P++d? z7ZC|~AN)T+zs>fGs$T>`$^y}@(lU0?Qb+(Bj#~<-x=5CtRo4faEjd7Jx3=WdoKvp4 zHM`_j8S;UE{y2{XTU#rZQFZ`p4;=(x`S7GzPQeWn?Yd`ZH}Xw$9D!zae{UX<9XMQH z*zn@d8T93QKg3tIx(C+74I{p~)qkiyy-|$k5p;97KGz&E3Zy%}&C!`L220cTOP z5I%uZQR4izIL<9_dtal9sosWxwRT?89By8;=AJLacT`Xyi%(RA*b#WtSSH@eQsi-@ z1+tuKqb$V#z{z6g39$Hs>nIqUN3ou z_6^sMZJdukLqPRGtlV2o?OeNZ**WutE~*8$J;y68hAQegv0KLAz$DgHtrtD${(z!{+4jy G)cqGDk4{Da literal 0 HcmV?d00001 diff --git a/database/db_events.py b/database/db_events.py new file mode 100644 index 0000000..38d4ac7 --- /dev/null +++ b/database/db_events.py @@ -0,0 +1,28 @@ +from database.db_session import get_session +from database.models import Auth +from sqlalchemy.exc import SQLAlchemyError + +def create_user(login, password): + """Создание нового пользователя в базе данных.""" + session = get_session() + try: + new_user = Auth(login=login, password=password) + session.add(new_user) + session.commit() + except SQLAlchemyError as e: + print(f"Ошибка при создании пользователя: {e}") + session.rollback() + finally: + session.close() + +def check_user(login, password): + """Проверка данных пользователя для авторизации.""" + session = get_session() + try: + user = session.query(Auth).filter_by(login=login, password=password).first() + return user is not None + except SQLAlchemyError as e: + print(f"Ошибка при проверке пользователя: {e}") + return False + finally: + session.close() diff --git a/database/db_session.py b/database/db_session.py new file mode 100644 index 0000000..7e8b40e --- /dev/null +++ b/database/db_session.py @@ -0,0 +1,24 @@ +# database/db_session.py +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from config import DATABASE_URL +from database.models import Base +import os + +# Создание движка SQLAlchemy +engine = create_engine(DATABASE_URL, echo=True) + +# Создание фабрики сессий +Session = sessionmaker(bind=engine) + +def init_db(): + """Инициализация базы данных: создание файла и таблиц.""" + if not os.path.exists("database/DogAcademy.db"): + print("База данных не найдена. Создаём новую...") + Base.metadata.create_all(bind=engine) + else: + print("База данных уже существует.") + +def get_session(): + """Возвращает сессию для работы с базой данных.""" + return Session() diff --git a/database/models.py b/database/models.py new file mode 100644 index 0000000..4198539 --- /dev/null +++ b/database/models.py @@ -0,0 +1,55 @@ +from sqlalchemy import Column, Integer, String, ForeignKey, Text +from sqlalchemy.orm import relationship +from sqlalchemy.ext.declarative import declarative_base + +Base = declarative_base() + + +class Auth(Base): + __tablename__ = 'auth' + user_id = Column(Integer, primary_key=True) + login = Column(String, unique=True, nullable=False) + password = Column(String, nullable=False) + + # Связь с таблицей Users + user = relationship("Users", back_populates="auth", uselist=False) + + +class Users(Base): + __tablename__ = 'users' + user_id = Column(Integer, ForeignKey('auth.user_id'), primary_key=True) + dog_id = Column(Integer, ForeignKey('dogs.dog_id')) + username = Column(String, nullable=False) + level = Column(Integer, default=1) + achievement = Column(Text) + + # Связи + auth = relationship("Auth", back_populates="user") # Обратная связь с Auth + dog = relationship("Dogs", back_populates="users") # Связь с таблицей Dogs + + +class Dogs(Base): + __tablename__ = 'dogs' + dog_id = Column(Integer, primary_key=True) + breed = Column(String) + characteristics = Column(Text) + behavior = Column(Text) + care_info = Column(Text) + admin_comments = Column(Text) + + # Связь с таблицей Users + users = relationship("Users", back_populates="dog") + # Связь с таблицей Questions + questions = relationship("Questions", back_populates="dog") + + +class Questions(Base): + __tablename__ = 'questions' + question_id = Column(Integer, primary_key=True) + dog_id = Column(Integer, ForeignKey('dogs.dog_id')) + question_text = Column(Text, nullable=False) + image_url = Column(String) + helpful_info = Column(Text) + + # Связь с таблицей Dogs + dog = relationship("Dogs", back_populates="questions") diff --git a/requirements b/requirements new file mode 100644 index 0000000..5c10195 --- /dev/null +++ b/requirements @@ -0,0 +1,2 @@ +sqlalchemy +tk diff --git a/src/__pycache__/auth.cpython-313.pyc b/src/__pycache__/auth.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f21debcb03bab5bb42cabff7ebe8bc1268c4bed GIT binary patch literal 976 zcmZuv&1(}u6rb6h-J~u_L~~G~uznoeg9Ralno6NG6q`uVE5&|1M%~xMx zgnr3nWO@t+1ps@?B4*f>SScw*m8pPL2iwFUw&swWZtFMD24UK0HAn13w4zs& z*2Hf)(!wHPQ_kzbCO}f=lnKRO7s(c&O}9x!a?9oXMZkPdm4w(dh%z6%1hMre+Bq(-^ zyWtO#JvK6((f~-vQ>2eg&We=X1+XVo8f!ahL1=Z%80q;xEl;~vM(^iz1S;eFBZS8M zi8G}bj_v|f#>M8O2bI3we@xs z<-=lGC>ikad*C|g*hsybc{B5&@OJLVFnfmiDf@ZyF?(dp_l)^NW8phl zU>RU6TM3co+YPtj)!>Sz0@h?wH<9t(&|P;qooWU?ZSeR(@Njrn(Y{|%G-G(Y4t%LLp9R-fF~%q8)(JBEM8lWgSNjOUm#b0urv8yxKaFt#??3A!84uLIQH+NF E1GaCw$N&HU literal 0 HcmV?d00001 diff --git a/src/auth.py b/src/auth.py new file mode 100644 index 0000000..90be51b --- /dev/null +++ b/src/auth.py @@ -0,0 +1,19 @@ +from database.db_session import session +from database.models import Auth, Users + +def register_user(login, password, username): + if session.query(Auth).filter_by(login=login).first(): + return False, "Логин уже используется." + new_auth = Auth(login=login, password=password) + session.add(new_auth) + session.commit() + new_user = Users(user_id=new_auth.user_id, username=username) + session.add(new_user) + session.commit() + return True, "Регистрация успешна." + +def login_user(login, password): + user = session.query(Auth).filter_by(login=login, password=password).first() + if user: + return True, user.user_id + return False, "Неверный логин или пароль." diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..2fce195 --- /dev/null +++ b/src/main.py @@ -0,0 +1,16 @@ +from tkinter import Tk +from src.ui.auth_ui import DogAcademyApp # Изменил на правильный путь +from database.db_session import init_db + +def main(): + """Основной запуск приложения.""" + # Инициализируем базу данных + init_db() + + # Запускаем графический интерфейс + root = Tk() + app = DogAcademyApp(root) + root.mainloop() + +if __name__ == "__main__": + main() diff --git a/src/ui/__pycache__/admin_ui.cpython-313.pyc b/src/ui/__pycache__/admin_ui.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02613964fd730ed34ec9804a7c0eeb84c71f4b88 GIT binary patch literal 2867 zcmbtWTW=Fb6rNr0+8f6v37C>5ge;IymV$c`R1HNHfk4$j9psIrphQ|Z_Qq^+>~wam zlD9xn3n~(*QdHE3LfZ%64YiHRt>G{1wjf8NNUcPrinoyT^4fF8UMD1hR_Y`^b32!B zX3l)G3(;tpK>0bdH}`vpkVn|@i&Ska?1RQ6(TOe`Ayj}`JR+7 z)o$cKs=vQ4QSCKVd;Nz7`m00I;l4zFrsBLJg=%Nvb!beIA&!xXx%ExZb1k_=VTgjWh-_vT6Ioa4}7@IBT2v5gGw28)K;|+i`gB&@ozk z-^@7nP){*ubZ638b98*jrkSCVHB|9Yvf^XoOfd|rU^#}tn*24y{h=WGTnA!;%*2{6 z)XgZ7va;DzHa}FhF2FF!_&bN4I{5L0?gto?xVWXWr~zehaf7u@O8R+HQQ>k6+GG4> zWl-@4bfHU3kv#4PaqX|9-dr8i#Y17@NRCM(#e(w~X#qS)W9jU8=_R!P#=Vd3-EZByU{w3TWE+-i8^hcoTesAxI%s2D6$)*@aCkde zTa9>DV>rBm_Fo_-$gjvh&7RWyKxvt6Yrit^#lY3egHg zpATOa&xJju6^yoaUemtTmKg1wZD^fsP{9Z&u^iL9nD!(Z+8Ty1bB&}(7ySK^@X*>L(kJ5I=xsYcxVR?t>|H6Sy4Sjy*lhF>Q9PB@p?bSv&gEPXK^bh z3A~PCX*V=iPofn`33-aQ=sU>Ysd(ZBxgqe=w9#$#R63x^UaXzU^7F-qYyq={pU8g$ z_!g+I4)8fyUd8Es8c)!d!2#U~Vkyv0=(F|9f$}899ied)D>e}Kjc?!tG$zSl?U_o! z2a5mMu^r~Hq<8Umy7pLAMp4!@TA!tntUXSPR*Mf{PQ*VgP{O6TUwWTZ=nEtg9lz~& zypO!|a9Foh?<}5|d)vJirz+?tv;Yg8NZV=0p?rXavT#{xaeT!lwShW|)i!AfYrF|F zHj>)}`K^BKrQMg?%k`R9uU*fUB^)I=VdGfqMa z3nsj!7xTFYCCzWU>1soLGcOYJU}t+C>|;0kk=cA z?W7$mW8fk!AQjUFeVzz-rWFRkuMUa=_u9ty=3_E1igL%i(jo7dKPrfFbY21RrxK7W zu(>*Xw1u3LR>3hT-2_%Fm?;)UtQ=>~3Ok}lPKcZ*xz)1hOxagi=GzoMaWRo>r1-gj ZAPA30>=$zUAvylH^oF3#6A(NX{{h_A(Axk2 literal 0 HcmV?d00001 diff --git a/src/ui/__pycache__/auth_ui.cpython-313.pyc b/src/ui/__pycache__/auth_ui.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..452c1572627318b42e5ac0334b57e2570cf0d835 GIT binary patch literal 10171 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 RT*Ei^ew(F!fkVmq{10QHAQ}Jw literal 0 HcmV?d00001 diff --git a/src/ui/__pycache__/user_ui.cpython-313.pyc b/src/ui/__pycache__/user_ui.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b3c551e9c6594d2810e39bf101712831a873a1e GIT binary patch literal 2628 zcmbtW-ES0C6u81fqvy=*Y}Z=k!D)N%x#ymb-#Pc5 zbGw{KL(pp+7`J{b3rG zNE_Ks6t06P{9e}AredCvg#}!sWWjAd*mvmY+v$N!>acof;MhRgO&m|Z^KM`IL~R*A zm>C=#NYz#?wbkHTLxVLIe`FvvnDveOBU4)}?*?L;jCdF+t1y&P*bYK@L_`IJhcToG zFou;7;0nv48_t+I?JJiTFxV_tvxF1k$8|0Gq2>Z|y>Cb=1U^ZIq=kULGViUC63G*p zNy(hc(^AQDn{uVRs%5pDK0cvp<+9sqo-BQ+Rse*W)6A2jC5`4#+SChUG!9m10tOR- zNRs5rNA`~#r=|DxtYwZI23vi;tr3%EM=HjMXQ*QIlqXzKRgI!ysjAyti?Ju*AYii{ zhDkD)Y`Ykl>*{$dZk`k4RZ((8>4~^~88%6_9waOx@aLst5E3(uVK?rgID9K%57&;L zkaTd3d=YQlj{2bnMvWX61D?Y4vKdmSrxxVBiyG|va~hMg>Qh*S>t!U;fMDG!5mfKf!@meOwZ!*#z1PgtxnZFLk2nm?#ir0 zdP7Av!>)-Z`oHkRo{MMm3XXtEZw;uG*~7?Xxc|bKkIRY5>!4#_wIAAd?Hl$F_6_H( zb5XKy+Yg+x_AO`9IcMLp?>J{9`w__8b1s6+L;EJm!Nxu3Qjg5I>}Y-vrjUNRtQB*W zO=$8<`yLp)X+Hq*TatYrq#rn+$-K*3`e}=902!AZ%e(wosc0>{21~HOm$lqP1xwJL zwZC&FeK@i}(WIwC@sudmksHpI#>c_m0v>n;@0ESox!`;Z4!=*y&2B7P&^4-#QEgmz zS?iQ596{2ra4ah~k*!dw7pO>YP^=&d-I=(dgB8mv6)DyQ#R768<$^Y$ z=Fu1ygS*aaDC3$@RLAvVMdoP}vIWbq3c4Hfq(?m?ZlX}imnxR(FHQ6UJw~E4q9N1G$IJr+CWw{%?{x-xVv_l@zj@p#W+XUkhtJn+5l(&305 zRk6zvyRKO_&bxmPk(SmO@v=AiW%#6KYL-Pkh8xc5 zrbSB=6abUPJYk=4TZ23`lo!51Cf4vI`7O5o^F6a&)tKzW^Op8!r@R&wbb-a|T6p)Uq>IW6AP}^xz)iHyb zR>3Ih#geMh769SZ5yeBL9^wtEYFe6QWL1pOfYQ@V5XJvoJnw$-;bTj2z(X~$;e0}t zSWein6x}K8Tsp>ZLgJ4oC-{gxNdOtPP8mf@r?d+c+)%bu95eD1?}Xn$>P^GzC7#wQ q$F6w55AF@RAJp&)nb_nOIfh|=BFUf0i6`X5pZp$1ULr7fkpBkE7DX=r literal 0 HcmV?d00001 diff --git a/src/ui/admin_ui.py b/src/ui/admin_ui.py new file mode 100644 index 0000000..b94d102 --- /dev/null +++ b/src/ui/admin_ui.py @@ -0,0 +1,59 @@ +# admin_ui.py +import tkinter as tk +from config import BACKGROUND_COLOR, PRIMARY_COLOR, BUTTON_COLOR, BUTTON_TEXT_COLOR, FONT + +class AdminApp: + def __init__(self, root): + self.root = root + self.show_admin_dashboard() + + def show_admin_dashboard(self): + """Показать интерфейс администратора.""" + self.clear_frame() + self.current_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) + self.current_frame.pack(expand=True) + + # Заголовок + title = tk.Label( + self.current_frame, + text="Админ-Панель", + bg=BACKGROUND_COLOR, + fg=PRIMARY_COLOR, + font=FONT, + ) + title.pack(pady=50) + + # Кнопка для управления вопросами + manage_questions_button = tk.Button( + self.current_frame, + text="Управление вопросами", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.manage_questions, + ) + manage_questions_button.pack(pady=20) + + # Кнопка для управления пользователями + manage_users_button = tk.Button( + self.current_frame, + text="Управление пользователями", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.manage_users, + ) + manage_users_button.pack(pady=20) + + def manage_questions(self): + """Управление вопросами в игре.""" + pass + + def manage_users(self): + """Управление пользователями игры.""" + pass + + def clear_frame(self): + """Очистить текущий фрейм.""" + if hasattr(self, 'current_frame') and self.current_frame: + self.current_frame.destroy() diff --git a/src/ui/auth_ui.py b/src/ui/auth_ui.py new file mode 100644 index 0000000..7e0f3ae --- /dev/null +++ b/src/ui/auth_ui.py @@ -0,0 +1,222 @@ +import tkinter as tk +from tkinter import messagebox +from config import BACKGROUND_COLOR, PRIMARY_COLOR, BUTTON_COLOR, BUTTON_TEXT_COLOR, FONT, BIG_FONT, ADMIN_LOGIN, ADMIN_PASSWORD +from src.ui.admin_ui import AdminApp # Импорт интерфейса администратора +from database.db_events import create_user, check_user +from src.ui.user_ui import UserApp + +class DogAcademyApp: + def __init__(self, root): + self.root = root + self.root.title("Dog Academy Game") + self.root.geometry("1920x1080") + self.root.configure(bg=BACKGROUND_COLOR) + self.current_frame = None + self.show_main_menu() + + def clear_frame(self): + """Очистить текущий фрейм.""" + if self.current_frame: + self.current_frame.destroy() + + def show_main_menu(self): + """Показать главное меню с названием игры и кнопками.""" + self.clear_frame() + self.current_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) + self.current_frame.pack(expand=True) + + # Название игры + title = tk.Label( + self.current_frame, + text="Dog Academy Game", + bg=BACKGROUND_COLOR, + fg=PRIMARY_COLOR, + font=BIG_FONT, + ) + title.pack(pady=50) + + # Кнопка "Войти" + login_button = tk.Button( + self.current_frame, + text="Войти", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.show_login_screen, + ) + login_button.pack(pady=20) + + # Кнопка "Зарегистрироваться" + register_button = tk.Button( + self.current_frame, + text="Зарегистрироваться", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.show_registration_screen, + ) + register_button.pack(pady=20) + + def show_login_screen(self): + """Показать экран авторизации.""" + self.clear_frame() + self.current_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) + self.current_frame.pack(expand=True) + + # Заголовок + title = tk.Label( + self.current_frame, + text="Авторизация", + bg=BACKGROUND_COLOR, + fg=PRIMARY_COLOR, + font=BIG_FONT, + ) + title.pack(pady=50) + + # Логин + self.login_entry = tk.Entry(self.current_frame, font=FONT) + self.login_entry.pack(pady=10) + + # Пароль + self.password_entry = tk.Entry(self.current_frame, show="*", font=FONT) + self.password_entry.pack(pady=10) + + # Кнопка "Показать пароль" + show_password_button = tk.Button( + self.current_frame, + text="Показать пароль", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.toggle_password, + ) + show_password_button.pack(pady=10) + + # Кнопка "Войти" + login_button = tk.Button( + self.current_frame, + text="Войти", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.login_user, + ) + login_button.pack(pady=20) + + # Кнопка "Вернуться на главную" + back_button = tk.Button( + self.current_frame, + text="Вернуться на главную", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.show_main_menu, + ) + back_button.pack(pady=20) + + def toggle_password(self): + """Переключение видимости пароля.""" + if self.password_entry.cget('show') == '*': + self.password_entry.config(show='') + else: + self.password_entry.config(show='*') + + def login_user(self): + """Проверка данных для авторизации.""" + login = self.login_entry.get() + password = self.password_entry.get() + + if login == ADMIN_LOGIN and password == ADMIN_PASSWORD: + messagebox.showinfo("Успех", "Вы успешно авторизованы как администратор!") + self.show_admin_panel() # Переходим к админ-панели + elif check_user(login, password): + messagebox.showinfo("Успех", "Вы успешно авторизованы!") + self.show_user_dashboard() # Переходим к панели пользователя + else: + messagebox.showerror("Ошибка", "Неверные данные. Попробуйте снова.") + + def show_admin_panel(self): + """Отображение интерфейса администратора.""" + self.clear_frame() + AdminApp(self.root) # Создаем экземпляр админ-панели + + def show_registration_screen(self): + """Показать экран регистрации.""" + self.clear_frame() + self.current_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) + self.current_frame.pack(expand=True) + + # Заголовок + title = tk.Label( + self.current_frame, + text="Регистрация", + bg=BACKGROUND_COLOR, + fg=PRIMARY_COLOR, + font=BIG_FONT, + ) + title.pack(pady=50) + + # Логин + self.reg_login_entry = tk.Entry(self.current_frame, font=FONT) + self.reg_login_entry.pack(pady=10) + + # Пароль + self.reg_password_entry = tk.Entry(self.current_frame, show="*", font=FONT) + self.reg_password_entry.pack(pady=10) + + # Кнопка "Показать пароль" + show_password_button = tk.Button( + self.current_frame, + text="Показать пароль", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.toggle_registration_password, + ) + show_password_button.pack(pady=10) + + # Кнопка "Зарегистрироваться" + register_button = tk.Button( + self.current_frame, + text="Зарегистрироваться", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.register_user, + ) + register_button.pack(pady=20) + + # Кнопка "Вернуться на главную" + back_button = tk.Button( + self.current_frame, + text="Вернуться на главную", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.show_main_menu, + ) + back_button.pack(pady=20) + + def toggle_registration_password(self): + """Переключение видимости пароля для регистрации.""" + if self.reg_password_entry.cget('show') == '*': + self.reg_password_entry.config(show='') + else: + self.reg_password_entry.config(show='*') + + def register_user(self): + """Регистрация нового пользователя.""" + login = self.reg_login_entry.get() + password = self.reg_password_entry.get() + + if login and password: + create_user(login, password) + messagebox.showinfo("Успех", "Вы успешно зарегистрированы!") + self.show_login_screen() + else: + messagebox.showerror("Ошибка", "Пожалуйста, заполните все поля.") + + def show_user_dashboard(self): + """Перейти к главному меню пользователя после авторизации.""" + UserApp(self.root, self) + diff --git a/src/ui/user_ui.py b/src/ui/user_ui.py new file mode 100644 index 0000000..703daba --- /dev/null +++ b/src/ui/user_ui.py @@ -0,0 +1,56 @@ +import tkinter as tk +from config import BACKGROUND_COLOR, PRIMARY_COLOR, BUTTON_COLOR, BUTTON_TEXT_COLOR, FONT + +class UserApp: + def __init__(self, root, dog_academy_app): + self.root = root + self.dog_academy_app = dog_academy_app # Сохраняем ссылку на DogAcademyApp + self.show_user_dashboard() + + def show_user_dashboard(self): + """Показать интерфейс пользователя.""" + self.clear_frame() + self.current_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) + self.current_frame.pack(expand=True) + + # Заголовок + title = tk.Label( + self.current_frame, + text="Главное меню", + bg=BACKGROUND_COLOR, + fg=PRIMARY_COLOR, + font=FONT, + ) + title.pack(pady=50) + + # Кнопка "Играть" + play_button = tk.Button( + self.current_frame, + text="Играть", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.play_game, + ) + play_button.pack(pady=20) + + # Кнопка "Выход" + logout_button = tk.Button( + self.current_frame, + text="Выход", + bg=BUTTON_COLOR, + fg=BUTTON_TEXT_COLOR, + font=FONT, + command=self.dog_academy_app.show_main_menu, # Вызываем метод из DogAcademyApp + ) + logout_button.pack(pady=20) + + def play_game(self): + """Запуск игры.""" + # TODO: Логика игры + pass + + def clear_frame(self): + """Очистить текущий фрейм.""" + if hasattr(self, 'current_frame') and self.current_frame: + self.current_frame.destroy()