From b7eef3e2c7cf1c40f4d7e8e800bab240ed0ec9cb Mon Sep 17 00:00:00 2001 From: Nathan Baker <nathan2.baker@live.uwe.ac.uk> Date: Mon, 24 Feb 2025 12:50:08 +0000 Subject: [PATCH] many eddits, removed dupe loginAttempt started on listing display funcs remaining bug: calling staffUser.__str__ causes recursion error... --- GUI.py | 5 +- __pycache__/main.cpython-312.pyc | Bin 6324 -> 6627 bytes main.py | 114 +++++++++++--------- src/__pycache__/__init__.cpython-312.pyc | Bin 512 -> 549 bytes src/__pycache__/adminUser.cpython-312.pyc | Bin 823 -> 1002 bytes src/__pycache__/bookingObj.cpython-312.pyc | Bin 818 -> 855 bytes src/__pycache__/cinemaObj.cpython-312.pyc | Bin 2719 -> 2756 bytes src/__pycache__/constants.cpython-312.pyc | Bin 601 -> 638 bytes src/__pycache__/dbfunc.cpython-312.pyc | Bin 8557 -> 8696 bytes src/__pycache__/managerUser.cpython-312.pyc | Bin 994 -> 1173 bytes src/__pycache__/reportObj.cpython-312.pyc | Bin 701 -> 738 bytes src/__pycache__/screenObj.cpython-312.pyc | Bin 3543 -> 3580 bytes src/__pycache__/staffUser.cpython-312.pyc | Bin 5463 -> 4867 bytes src/adminUser.py | 6 +- src/dbfunc.py | 28 +++-- src/managerUser.py | 6 +- src/staffUser.py | 35 +++--- 17 files changed, 104 insertions(+), 90 deletions(-) diff --git a/GUI.py b/GUI.py index 24a0776..9797740 100644 --- a/GUI.py +++ b/GUI.py @@ -74,7 +74,7 @@ def open_dashboard(user): dashboard.geometry("500x400") # Display Welcome Message Using `user.username` - welcome_label = Label(dashboard, text=f"Welcome, {user['username']}!", font=("Arial", 16)) + welcome_label = Label(dashboard, text=f"Welcome, {user.userName}!", font=("Arial", 16)) welcome_label.pack(pady=20) if isinstance(user, StaffUser): @@ -106,9 +106,10 @@ def gui_login(): # Call loginAttempt() from main.py user = loginAttempt(username, password) + #logging.debug(user) if user: - messagebox.showinfo("Login", f"Login successful! Welcome {user['username']}.") + messagebox.showinfo("Login", f"Login successful! Welcome {user.userName}.") window.destroy() # Close login window open_dashboard(user) # Open appropriate dashboard based on user role else: diff --git a/__pycache__/main.cpython-312.pyc b/__pycache__/main.cpython-312.pyc index 219c7b89736cb328d9b6f143a51c28993ccb875c..70f66fef1605820f3ec72c7edf20cf23200504d0 100644 GIT binary patch delta 2900 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 delta 2428 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 PC&;uf44jMt;Gh5imr7Z? diff --git a/main.py b/main.py index b9d3f43..5ba6806 100644 --- a/main.py +++ b/main.py @@ -1,8 +1,10 @@ import logging -logging.basicConfig(level=0, format="{asctime} - {levelname} - {message}", style="{", datefmt="%Y-%m-%d %H:%M") +logging.basicConfig(level=logging.DEBUG, format="{asctime} - {levelname} - {message}", style="{", datefmt="%Y-%m-%d %H:%M") from src import * from src.dbfunc import get_connection import json +import pandas as pd +import datetime as dt from src.staffUser import StaffUser from src.adminUser import AdminUser from src.managerUser import ManagerUser @@ -21,37 +23,37 @@ from src.managerUser import ManagerUser def loginAttempt(username: str, password: str): - """Check if the user exists in the database and return the appropriate user object""" + """Check if the user exists in the database and return the appropriate user object - conn = get_connection() - if conn: - cursor = conn.cursor(dictionary=True) - - # Fetch user details from the database - cursor.execute("SELECT username, password_hash, role FROM users WHERE username = %s AND password_hash = %s", - (username, password)) - user_data = cursor.fetchone() - - cursor.close() - conn.close() - - if user_data: - logging.info(f"User {user_data['username']} logged in successfully.") - - # Return an instance of the correct user class - if user_data['role'] == 'Staff': - return StaffUser(username=user_data['username']) - elif user_data['role'] == 'Admin': - return AdminUser(username=user_data['username']) - elif user_data['role'] == 'Manager': - return ManagerUser(username=user_data['username']) - else: - logging.error("Unknown role in database.") - return None - else: - logging.warning("Invalid username or password.") + Arguments: + username (str) -- username for login. + password (str) -- password for login, plaintext? + Returns: + User object of type: StaffUser or AdminUser or ManagerUser + or None if failed login. + """ + # dbug shortcut + if username=="debug" and password=="debug": + return ManagerUser(15, "manager", "password", [1], "Manager") + # using dbfuncs to do this: cursor.execute("SELECT username, password_hash, role FROM users WHERE username = %s AND password_hash = %s", (username, password)) + user_data = select_from_table_where("tblUsers", f"username = {username} AND password_hash = {password}", "username", "password_hash", "role") - return None # Return None if no user found + if user_data: + logging.info(f"User {user_data['username']} logged in successfully.") + + # Return an instance of the correct user class + if user_data['role'] == 'Staff': + return StaffUser(username=user_data['username']) + elif user_data['role'] == 'Admin': + return AdminUser(username=user_data['username']) + elif user_data['role'] == 'Manager': + return ManagerUser(username=user_data['username']) + else: + logging.error("Unknown role in database.") + return None + else: + logging.warning("Invalid username or password.") + return None # Return None if no user found def staffUser_options_cli(user:StaffUser) -> None: while True: @@ -82,6 +84,7 @@ def staffUser_options_cli(user:StaffUser) -> None: exit() def managerUser_options_cli(user:ManagerUser) -> None: + logging.debug("loaded into managerUser_options_cli.") while True: selection = input("Menu options:\n" " 1. View Listings \n" @@ -121,6 +124,17 @@ def adminUser_options_cli(user:AdminUser) -> None: user.logout() exit() +def fetch_movies() -> dict: + raise NotImplementedError() + select_from_table("tblMovies") + +def get_listings(): + currentTime = dt.datetime.now() + listings = select_from_table_where("tblShowings", f"[{currentTime}] + show_time > sysdatetime()") # returns all data that matches today + +def display_listings_cli(): + strListings = pd.DataFrame(get_listings()) + return def load_cinema(cinemaID) -> Cinema: raise NotImplementedError() @@ -149,36 +163,32 @@ def main_cli() -> None: while True: username = encrypt(sanitize(input("Username: "))) password = encrypt(sanitize(input("Password: "))) - #user = loginAttempt(username=username, password=password) - user = ManagerUser(impBool=1) # dev remove later - if user is None: + user = loginAttempt(username=username, password=password) + + if username=="debug" and password=="debug": + logging.warning("Entered as debug user") + user = ManagerUser(15, "manager", "password", [1], "Manager") + #logging.debug(f"user object loaded as: {user}") + managerUser_options_cli(user) + break + elif user is None: print("Login attempt failed please try again.") else: + logging.debug(f"failed login, returned value: {user}") break - logging.info("successful login, loading menu...") + logging.info(f"successfuly loged in as {user.userName}, loading menu...") # based on the different user permision levels, load different menus. - match user.permissionLevel: - case 1: - managerUser_options_cli(user) - case 2: - adminUser_options_cli(user) - case _: - staffUser_options_cli(user) + if user.role=="Manager": + managerUser_options_cli(user) + elif user.role=="Admin": + adminUser_options_cli(user) + elif user.role=="Staff": + staffUser_options_cli(user) # following code will only execute if run directly from this file. if __name__ == "__main__": logging.debug("STARTING main_cli") main_cli() logging.debug("main_cli finished, program exiting. bye bye!") - -def loginAttempt(username: str, password: str): - """Check if the user exists in the database""" - conn = get_connection() - if conn: - cursor = conn.cursor(dictionary=True) - cursor.execute("SELECT * FROM Users WHERE username = %s AND password_hash = %s", (username, password)) - user = cursor.fetchone() - conn.close() - return user # Returns user details if found - return None \ No newline at end of file + diff --git a/src/__pycache__/__init__.cpython-312.pyc b/src/__pycache__/__init__.cpython-312.pyc index aaa784897475dad772c7a61107c760b558fdf570..22aab0c5e549be1de01acbc9f1c13180be82681e 100644 GIT binary patch delta 85 zcmZo*S<1qFnwOW0fq{WR)pO5A?kYx`SZAx4(Bjmh;+Q;3-K50q)S?*wyi}K>%(7Gk oU4_taR|Th{%;J*#oEVqX;_Q<Af|$tE#3BWw7{_3j$#WP}073v8Q~&?~ delta 48 zcmZ3=(!j!fnwOW0fq{YH{Pe9GxvLn(Et0KbLW@(2iepMri&FDqTvCg(OY#dQA7o4c E0ARKdJpcdz diff --git a/src/__pycache__/adminUser.cpython-312.pyc b/src/__pycache__/adminUser.cpython-312.pyc index e862f6391397e9c67c1dd92ae1fbf20e7b084608..8cd0a263f4650f94ec2f3445ba63e1247b555380 100644 GIT binary patch delta 621 zcmdna_KKbNG%qg~0|NuYo3K6Uk0<i>xr2EO3=E$w7#JAZ8KyI&GDI<^Fhnt>Fh((_ zFr~7jFsHJnu%xo4u%@!5u%)u3adj}HF{ZG$@I<k9FjO!`aRf7Ha!foE5Oa$uGvyXb zUSe+QE!Kj>;^OjK?8%vVskw>8w^)kub5fJpKsG}$I|Bm)Gss>m1_p+yjMEuPpb`uW zooqD>y{rrjH4HV3HB2?kH7u)HC;KrP*B5~ttI2+gr8qSwtq5dV5y+S#4h9B>B2Ewi zQgDkiK0Y}ovA8%sz8EB}00s@e;*zamLW@(2ievIDb(0daQ;TB!^HN=kGRsmGbQMCw zT@{>)GK)*{b7EXli?d7e3t}Qu6N?m#VjP2AViHrz5+|QzlxO6f{E|^dOP+y&;YS0* z9S+`3_KO@6Gel+-EihRjx`F))hs6yM(GHeg&d(tKXmU<gW74g^#hjT}a*MgRr05n) zPG)gQ5ibJ+!!2H@JCjp$a^mAP8H@NC7#NBf85kHGiUdHuVTBQ(fGRcx+1bMIk%@(s z;{z8HtJn<X4-8DKVhfzX)QVy-wZjEW9Vq?|lKTiEiWmhaFJRKn5dvAtT3Vc1WO$3U zpeQr1WF<q9Ajl4oZNE5da`RJ4b5iY!K)wSxqu7vvf#Cx)BO~Ko28Ayy9E@TUIKMD( mFp7Q9VqoFvsJg@~`H)An+q=Q_CJSeWYOBu&b_NzHu#o^}N1!qQ delta 411 zcmaFGzMYNtG%qg~0|NuY`RQBJXHVqqGh_ns7#J8nD={!Iv@=X+NM(p(Oks#(N@0v* z?qEn`Okrx_h+^qrs9=m@4Q9|}p7<!hD47we3q&z9Fff4dX9ETXhN+Cx8A?E+VBE=A z!_dphz_6NOav!6y^DX{@)S}$X;^NHwJfGCE)ErHwTP($?Icc{z<KvTa5{rxD<BLHK zQfT;PnQRpkTAW%`98;27l$sagl3JWyl3y^{nn{I`V{!tMjG`C=1H+F7hC3X*o$MDm zB(88s-H=!4V7ba6^BH8hCfnp?OuD{B91IK$w|JrEC#UA*#K&tg7I8B$FcgD);ZVfG zz`#(%3L`*1DHZ}5-NNvZiG`KpI~NnH;s*vMR>dOT$-&IpUVI<}SxbvkiwtkE78GUX zm8@ha;sxmkne>apCO1E&G$+-rNP>ZZ0c1t7Ap--$2WCb_#=8s(UsyO86(?|hVc=j? MoP2^=js>I>0IwrrJ^%m! diff --git a/src/__pycache__/bookingObj.cpython-312.pyc b/src/__pycache__/bookingObj.cpython-312.pyc index 4678c08d458aad37f39f436e7a08d250feb3dad2..a95cc5867d0668f4171d2ea00ba38fac6bad3dc5 100644 GIT binary patch delta 86 zcmdnQcAbs;G%qg~0|Ntts^^}K+>VSk@y=E;p~b01#W8u7x=D%IsYNmVd8sZ%nPsU8 qx(cD;t_n^?nZ+gfIWaD&#n~nK1u>DSiA4%VF^<75o0A#OGXel{$s5=J delta 49 zcmcc4wuz1VG%qg~0|NuY`RQ9Xayv4LTP0h?gche36~~mM7NzFJxTF?mm*f|0?qEF6 F2mpRl5WxTd diff --git a/src/__pycache__/cinemaObj.cpython-312.pyc b/src/__pycache__/cinemaObj.cpython-312.pyc index e889a025d413312cfd167d1a991a2a5909f13fd5..dfc88c86489f19e676778ae90beb1d855c1faffb 100644 GIT binary patch delta 86 zcmbO)dPJ1_G%qg~0|Ntts^^}K+{>A4;+(BwLW@(2ievIDb(0daQ;TB!^HN=kGRsmG qbQMCwT@{>)GK)*{b7EXli?d7e3t}Qu6N?m#VjP2AHlJj=#ts0B%p9r! delta 49 zcmX>iI$xCgG%qg~0|NuY`RQ9XaxZ5Rw@kK*2`x@7Dvl{hElSOcaY-%CF3B(0{Eq1w FI{=En5t9G_ diff --git a/src/__pycache__/constants.cpython-312.pyc b/src/__pycache__/constants.cpython-312.pyc index d3bc49915e4b08b2493f7d0b87854b992d1d9ce7..3bb21f47a4f77a6782ebd8e3d633e0f1b851c44f 100644 GIT binary patch delta 85 zcmcb~@{fi4G%qg~0|Ns?LHM4H+}(^eamiLOp~b01#W8u7x=D%IsYNmVd8sZ%nPsU8 px(cD;t_n^?nZ+gfIWaD&#n~nK1u>DSiA4%VF^<75lh-n?0RW<K9O?i7 delta 48 zcmeyza+8JoG%qg~0|Ns?*@mqfxw{#~EuF1mLW@(2iepMri&FDqTvCg(OY#dQUt(MX E0C(RI`Tzg` diff --git a/src/__pycache__/dbfunc.cpython-312.pyc b/src/__pycache__/dbfunc.cpython-312.pyc index 55dfe2f82b5871a26d95ff2418ec5379258e663c..5ba53e9ca58e4129c6cef290ff49a41264c7c450 100644 GIT binary patch delta 1382 zcmaFs^uw9&G%qg~0|NuYhxk3|>qRE=Nic4ksNQXm%9p~K%9qBH!qvhO#h=36!Vo2p z!qdVKC78n7!Vo2t!q>tOC7i<F!Vo1=$*3u?@y2szo9JY#n9$<XqT-l5OWmZz?9`$d z|GZR}qRg^X1zm;Ea90JVqRirw{G1q<)Z*-t{DPRs)WjkMqZr3vm(AB$6d9Sgm?j&@ zinB9uGSo0-F;8}67v5~dX2-;+Ik}J{kcTC)D80Byl7WGtNM-Ux4qI_u1_lOs1_p-W zlMD<D4Gd4XB`<SJH@HmJ<&=<G88Sm<zUEBL1uk>+HxyrxwBBKMK=pw51p&{=37nH6 zdK~#3Z5R&P$U4h1ACi=GmS8?)#0X*=vp6d-9F|~pmSsLH%M4;GD7i2(7ilsuFx=uy z&d*E9EXmBzOJ)Lv8WgiJFfgz)Ffe@fVg$K=av;}wfnWw@h7xelf)r)(Or9tyJeh-C zm_vo3NU4^+L~!y&5t+%exP=rW8B#cF+3VOVIU#g8V>v?wb0kAKqb65kAtM9BWI+y* z$vHf-^;`-H3JQ)z>BUxH7Km4pn3R*Mpix{>q-mv)l30?Mlvtdq01?eg%uUr%NKLm^ zP%25v0mqCITqE2kFwF>o;*z4wymW=kJcZyuABD91qTIw1kU90%3QFM~u0gH}rNya5 zAk!6W6;z8A9Q|Ar3KENp%kzs;;xiJ9Gr+<KtF)5yb4qjbimen<E0R+SN{ST{b8-|C zK>?YUn4^$blwO*fng<fjOHoM9&nrtUDk)Yd$w<vr$jmFr2fL!MG_}a7QXwrrCnvug z<ho#2A6MrPg~VcnejSC(G=;qUyi~A`;*!LY)ZDxhkYkG#wDiC}pWMmgC9TO-Bm+)F zAVL*HsDTJ|1_p-7^EspxIlz%!qz4kz0uhiT2V!Z12%Sm1CQ*hA3=AM#JQtkyzVI>d zNP$z|O>X`h{DK{vA6Ph8MQ#X+PM4l2y@F+e^kqTa4z?RYk~k9P3HA#CkteDz2t-d# z;FR_6;QMihTcF>*)BZZQ!bNU{PYg_~B6m3W`*}NgFG$$z2;Sj(LCon2hw~kN;ol!v znOH@B6-zKMFidb1a#UtGs4VNG#C(WB!bz6-kSwc{(q@0YY-TYPkn2GnzQvNAT3LLH zIVUx*NNw^3K~+YL$@yXuY7n2_VgV&2Xhs7idv<697MX(#(4K4{WW?yTIa%lvvlQ4! zaPV1x<b*(kFo*ydC?yKYHIRTr3d70s#0(e{H=h@aVbKHY2RW(81f&aWk{O5vwhD`x z61tp_=&=N;0>=^D=v&O$sg<|5ic?GClXDV5iBx;?JZU|~vdw3ujhSS?c7bgGMRkz| z0|SF5Gt`@tW#lv&yEnVZO=4tJnS4`Tn{n!7R)r)+(a9MKN!*}<<`#2tNl}sE<O>SM uT!9P>42+<HCv7sXqLl<cqv!_}VMdV!${!en8AUb-e+E&Xj3x&v$^ZZzh-~Zt delta 981 zcmez2{ML!@G%qg~0|Ns?($=l%Q-mk-NieRNsNSvC!Vtxm!r8(Q#h=2}!Vo2p!rj6U zC78m~!Vo2t!rQ_SC0xm<$+z**b7pZfXRDad;?$zzn3B|@)Vvs%)Z*-t{DRG_tcr|` zLX!<dWLTNf8G;!$JFtZ_F|M3EgCmfiJvl$8G&irfNRokpp-6S|R}R}CJq88_c?JfC z;!6w+3=IrVxFs)hOE<XO<mSJ@FWABPfrXn@^oF45bm@uGD_AB-Ul!EuV7nnCxsiQ_ z%6!e4nhV^oNa^edz98v%K<otTf$|Fi{*$XYC%I2><ac6VIK&|9tjK&wR?=C9`H&eS zh;7c|tio_uhSgb-`LH50h^?aJ!p5A;1PTr)W@BJrU}s=p_$)EmKty744cB_68kWf$ z_(di=$Z=18$R<Bof!&&seX@dp!sK>t0lsvGWTr@l6wX@qI`(=Lg<`=_;c~`uh6?6L zhH^$_22>@JbvQVgxvC5&@8C9^tjX)8TcpCkz@W)dq{YC%aEmiJKQAS-Br`v+NE;Mr zkdOnhbU=je<deK6QAP|5491`^yhW8TJdu7OEdD}h!UciE$<>_x+%`Lcceq{<bGpLe zJozf8h5iIbAtz>rL(H<yD$IuzB%S4%4_PvT*j6mg>I{eFS)Emw534YP*y>6yoSP5x zWiyMZf}E=c@)ApSYGv^)=A6{LBK65GLaL0KlP^k3$U;5Ll9E`G2u&a$Enr_;Og_S^ zF!`{MIHUXK+d`k1rNE}CgXAqigb;`j1`%Mh#M!`sS7ZnhK?<?SV&VquaiD-Y$}st% zkjUmlaVHi%uvs9N6`6w6gH1IDu`ECY7W1V<K~Ym=1(HUxVv>v~qt0Y889laQkQL06 z9|(zVj+c>Sk^$QQHdh0rM-vpk%uqj0o+78o*s*z^+$2Uu)yaVh+KiJX*D542icEf> pki-Vc9YscyeHD$l0vH$=7(oU{Ozu*&;u2&O{iFdVCf`w%0RRBj^&9{I diff --git a/src/__pycache__/managerUser.cpython-312.pyc b/src/__pycache__/managerUser.cpython-312.pyc index 066114c00fe160c03d83e6e6c335ee8c4347c0b7..f0e34ccdc3d8c4845b485f3bf05b7bc54e67f16d 100644 GIT binary patch delta 578 zcmaFFK9!UAG%qg~0|NuY%dkD^u@iawe8D^h28Pde3=9nI4AU7>8KM|d7^0X`7^9d| zm{M6%m{VC(SW;P2SX0?j*iu>2xH=fp7*p6=c%s--I9eE@I64?A7^66Y88kU3Uh<5& z#gv(HizP2HH}w{4L1J-n`7QS3%)Hdx#Nt~lMfo|Y$!s9|p_rY4fq@xhyA=Zi!&JuU z3?)zr28K?y8irn028J4j8pax?8s-|7)vS|!8I9|UKu*?Vzr|9Vnv+%pGOY+?Oc4hI z149ufhyW?L#Tg%;oRe5w93Ni{l2!nNhF=NERxzQ)sYS&xd6v3KiP@<|G5&d}E=8GT zsS3IZq2aCyPDPo;CHXlqE~&-YCHVz0k*SGA3Pv%G!7ee0DP@V1PcSMn@=bolD5osX zz`*dMf#D7ZZzuaj4v85eGl~|NtPtJ6eucy0hKOhfOE2eSC8i)Aeg+1HVnzlA28ANQ z$qh_yY(fkS44Pb%&oJqV-(t?pE4js7TvBw4B`34Eq=*mX1JOy$qLBhHZ4O0(AVF3b z0Sd8VQ;_8?3?G?TSUEm$F|mrxQ2xNc#45JH8BDDx22(p+z|?`_uOPW^989b#MM9Ik znYFdV7#J9Cv6dF678%}REhx&&D_O}<1acVIvR@oFx%nxjIjMF<%99r`+p&OT09+oB Ay8r+H delta 394 zcmbQr`G}qOG%qg~0|NuY`RQBJMJMw1nKOZS3=9mPH5eEe+8L%Zq%uS?rZ7Y?r7%V@ zcQB+erZBZ|M6skWw=hJpb}&>hMzIAmXtGRv;c1l22-ORsm>C!tK=`u(0|UcU#_0?t zAW<;xWUOK6Wo2Mk%`mx_(b)MGe?e+dZf0?DW`3SeYFTQICetmJ;?$h9Tb%Ln$vKI| z#qsgQAZIBw{IX8AiU}=FEh>&FNi9mvi*ZRU&MwI>m~6$Q#>hE2kx5QUjDdmSM+3th z4&F}oiyRVHIHYdKD|E12<&c@Yh$)DNn}LC$801ccBHl^NZftxE3=Ep=lYN+V*^4+C z7#NBKCr@A&HRFLPb132kiL$~7ke7;uKz6h+d}Lx_<@mzI#H#p>gNaq8h;Q;gW^FBy u<So|H;?yF;TdV~|nRz8E8HzyGfKB?vVUwGmQks)$S0pnzn8l6-Bm)5NLt7dE diff --git a/src/__pycache__/reportObj.cpython-312.pyc b/src/__pycache__/reportObj.cpython-312.pyc index 84e9396990ad1e391f3e1c38a0873b3ca6ac71b5..7d4fc47261d2a1e864ba1e853418bb40b86ca611 100644 GIT binary patch delta 86 zcmdnX`iPbLG%qg~0|Ntts^^}K+*XV>an4pTp~b01#W8u7x=D%IsYNmVd8sZ%nPsU8 px(cD;t_n^?nZ+gfIWaD&#n~nK1u>DSiA4%VF^<75n`0Og83A=#8*cyr delta 49 zcmaFFx|fyvG%qg~0|NuY`RQ9Xa$7NqTP9n@gche36~~mM7NzFJxTF?mm*f|0Ze&bk F1OR|25Lf^J diff --git a/src/__pycache__/screenObj.cpython-312.pyc b/src/__pycache__/screenObj.cpython-312.pyc index 404eaa518842cffc596ae0349cfae21c58093a3f..9d274a19a39a94de809bad84c3cc3abafab5b5dc 100644 GIT binary patch delta 86 zcmcaE{YRSnG%qg~0|Ntts^^}K+<Td9;+(BwLW@(2ievIDb(0daQ;TB!^HN=kGRsmG qbQMCwT@{>)GK)*{b7EXli?d7e3t}Qu6N?m#VjP2AHs5FZ!36-jV;y$@ delta 49 zcmew(eO;RSG%qg~0|NuY`RQ9Xa_?mlw@kK*2`x@7Dvl{hElSOcaY-%CF3B(0%)<PG F3jm=&5n%uT diff --git a/src/__pycache__/staffUser.cpython-312.pyc b/src/__pycache__/staffUser.cpython-312.pyc index 1aee61bed589a71284cd861e87f81a6ed12f6fe9..adcc99e4076d9a6c6abcf958eed4ad89ebdd0127 100644 GIT binary patch delta 1286 zcmcbv)vTs|nwOW0fq{XcIC)PxBR>PfV-N?1S)h#1B@@*hHC8i0xKZq>94Q>x8Vn3Y z0!$34?5iQd3{jj+45?hHoD(NG)`QJtU|{%Mz`(#TogtMWiZO*DiYbLLl{tkel_iBa zl_iBGl{JMml{t+og{_4piY-Mjg|meviakXzg{y@niX%lZg}a3%iZg{hl{Jkig{Orj ziYrAhg|~$ziW@4%*TNFTlOmYH-@+2bn<AJZ(83bMSIMC%G&zn@E;KnaFEux@_!di1 zeoksK8`PB`3gi)Hkn6m_uB&0JVTcEbgK-U04MRL5n90DvP{Ulq5D!uh7N}vJ{GL%t zzmh?d(NB~07F%g?YLTbQEe;UvmzbLhVFe@>7Z>p|FfbJHFfcG^vQ6$}lJ_VEIY0pn ze#IqQ#e^2878S?jS?VSwW~Ua#_~)g%6lIpBD(EVNhPx^_6=fEe<mbe=q!wqF<QK$5 zrY06C7{xdSyG*{w<fg64z`)SJ@IXqYgQbW2hKxc7OAqf28ATBFKmsJl`9NH*gQb_} zGs9*b)-#M;w>V0Ya==zj{>$by*^WtKvM;-W5XgN+ActwP6$ybHEHJsAT}@XJlpsLD zVCO0n2{SM-++xkiPtVM&;twuKOiKe9r3V&}oP3FW1Ec8Vc><D~=Wv)Z3QI6BF!*V* z7b$?ulL8Ualb>*EF$zuQ=aOI)o~*%T$f&kCiYuK_10oADoFy|aEx(8#q*{l8fng;h z*g3_ZXiz8;p8T9!mQjB)D~~P2qRBBlPq^Wli+Cn`^U5#^P0rwzV-%j;&TGkNI{6^4 z7o+H89=<v@h`PxW_#{R2LH>f839^+pxhQpVfq)oaa#3nxNvczRes*SFy6xnLe2QSr ziIY?Kr35WNu0qy2xu0K?(Q)!leu%2f$u0uISX5;QXmh)Q^jd=m(arM&PBX$>lP{#L zWd#y80HqLSuy2b%!G4RgI5j6Vxg;|`uNag>6%;`JKO$ty=sB55xT;<hq@Jlr3>?V( zw>aYC^AdAY<Ku5}#mDF7r<CS^*gWy^g{6r(5Sb#78*VWdmlWM%$;m7(DG~wM3rayn zpr9@SxuD1lBnEbnEr?|gB0NA5!B7OU5u5^wI2ahL89*ch2PhyD85kH^7(Os@u*%O+ z{=mS&D!;%POsyyeQ#)M1)Pds9Ai2*9lLJM}WWc6@w1b?Uo0ypwAFs(>1db!w$%{p_ zt-$6Nd4i&c6_l+Ei(EjC@dFWH&7j2ii^B%uS-YYT1_lODlos1g77!IN{LbOW$mq)W okpWD7C}3h>;pwQl#4P!cN3`3!!SyB!XNPL5&j)q}7AdgT0F%%o9{>OV delta 1878 zcmZoxyRM~vnwOW0fq{YH{PeBq(fkYyk3k$5W`#07mrYc6)JkPv%?uHU;z;F8;mFot zU?>t`Vo2p!4H0ID;$mV*<xb_AIKi==7b^C-hJk@$IzuW$6k`fQ6jO?D3S%mB3R5ae z3Uew;3QH<;3TrBB3R@~$8czy)3u_d63P%e=6i13k3U>=j6laP^3Qr456jzE!3U3Qb z6n6?|Dr*{33SSFL6i<ps3V#br6faavpoJxhFGVCpu!SXxA0#Q%!V)D=$)zbeIe<~F zz96+I*QYG!7JG7LUTSV)@h$eu+ybZk{G4QVs8c}{3j+fK$d{k9z|O8=E8;6*1WAB! z3S$b>8s^nZAT|R7BSR%a4Py;MJY2qpsfHmQD$Br7!(77<4>Aj^yuOB|h9MqgJeXU< zTEh?z3txsx22B>fTO1`xIiba=Ma8!mG?{L(mLw+Sq~798&d*E9EXmBz(`36PTAZ4b znp_f}R+OI`Uy_s)U!IX#lzNM;v^cfM)8!Tii1tg&O@*)m5{rv(@q_%GSzOGYnV;vA zT9%qq1d16=_Q^a<@|s0_3=9m#Apa{sz%R>Ws~E5wVoFkrQuAV5Qj4=o@(U&xGr2`r zFfcGQFg)ZIdcvc)f@??8RUXG1JOUrs7~~Z@Tzb53D5!L}^!VOTPz6yB)b%=CuJ9;4 zkXGt&>Gk;x@^vyiq!<_&K*<giI-loE&S8_DJcCb!c{W4J<OD8p#@Unqa>&-#Fl2Fn zbfMze3@I!%3|S!Es1gjb8B$p1as@MJviVhsD1d@OAwMZAHMv9s#P)Qtt>V@J3xh%k z&H)9IZIzIY0yLap!DL(ii&0aP?G|Tzd~!}=adCY7Esps3yu{qp`1m4G1_p*AF%TgR zA|x0X7*;YCNrD0s<VA%dDFz0HTkP@i#U(}Y@l}GsC5dTipkUR53W1dtfWz~Kkl1v+ ziF((CG%pHiUJ%r}pk=qCWPkO}i0U1=C#)}oM_&(5xfq^uAuRPmYQcrV((8qF7Ypky z6x4rUU~pgxV*0?q5X=<L^c_T{Gkt_m9~c;dm@+_e8BCcVN+1hFa%M3V$!vbYbcT_& zNPvNXVe&2(FV-Rv5KEd>Q3#YWir5$!7&O_yo+%QW?8mC6s{`^ENEnhvAf98*$xqMB ztKvs^4J;rtc_HftMw!X^e3F~9*-ROQLDu+bvKMKC0!j@;s88O^uEi)h`5wCjqtxW@ z?1qe*n>9Jo8Py=Nppaw9%uCCMgt9qEiz3Jc(2$+HgHx8#X!12qTZlE2H*gqCj^*0I z4cA`8J6VQXhEZ~|CAS=-)Z_?mOGb;yleoPYWhUR{u499!o1DlaDS~V+$X?#$qSVQb zd}0R4MX8A;sZRO%*_nCi4h#$opFwflz;K6yzn{00_kx(=6%M02e2SO(lrL~77l8~; zoNUS~CFq3V+yq`tMwiK5yozA!GbfAk31d-Z$*0Zj0n+OVB4jq_^POgdxzs^GTgU|@ zYz2xMW=PcNOs*9WXOx;eRlt_fXYyr%s(KlaEMpN9h+-;IW?*3O(-bUH0Qrk6K0Y@; zr8FlsKK>R@e0*VPVh%JV`-7yJi%W`bvE*bHm)v4W%FoX!k_OqP1R@MT1UL>rmKTA7 zq6q93caVf9hzJ6ueuknjkp1AaQ3T4iU;@M_&Szj?Xkqxs#K)>UL-_*(AFJ{LXE3#* z7)<Se@J@(;c^AT?KZDeKQeb4wV*1QBnO(?C25dCQFi;-MP0Y-TkJscW0!O6A<VYdy z`de&}tPZvn;%8P+t~V_51357QM1TzeWz1h3HjvP;D~e|TmE#Ny#r6yg3?G;o85!?0 zh}>n6y~7}SmqGRmM<64kE8_&VFAQMDhcYGx7M_l(OU#lFc|^Ot8(eR)aCWG+`fz<< LXJC;k0@(lnFJ{F! diff --git a/src/adminUser.py b/src/adminUser.py index 069c0d7..7dc9cb7 100644 --- a/src/adminUser.py +++ b/src/adminUser.py @@ -6,9 +6,9 @@ class AdminUser(StaffUser): Args: staffUser (_type_): _description_ """ - def __init__(self): - super().__init__() - self.permissionLevel = 1 + def __init__(self, id:int, name:str, passw:str, cinemas:list, role:int): + super().__init__(self, id, name, passw, cinemas) + self.role = 1 diff --git a/src/dbfunc.py b/src/dbfunc.py index d388d5a..377eeff 100644 --- a/src/dbfunc.py +++ b/src/dbfunc.py @@ -28,15 +28,13 @@ def get_connection(): return None # Function to SELECT data from any table -def select_from_table(table, *columns): +def select_from_table(table, *args): """Fetches data from a given table.""" conn = get_connection() - if not conn: - return [] try: cursor = conn.cursor(dictionary=True) - query = f"SELECT {', '.join(columns) if columns else '*'} FROM {table}" + query = f"SELECT {', '.join(args) if args else '*'} FROM {table}" cursor.execute(query) results = cursor.fetchall() return results @@ -48,24 +46,32 @@ def select_from_table(table, *columns): conn.close() # Function to SELECT data with a WHERE condition -def select_from_table_where(table, condition, *columns): - """Fetches data from a table with a WHERE condition.""" +def select_from_table_where(table:str, condition:str, *args): + """Fetches data from a table with a WHERE condition. + + Arguments: + table (str): database table name, eg; "tblUsers" + condition (str): condition string in SQL format, eg; "WHERE username = %s AND password_hash = %s" + *columns: excepts all aditinal arguments and converts them into SQL query following SELECT as arguments, if none SQL statemnt uses *. + Returns: + dict + """ conn = get_connection() if not conn: return [] try: cursor = conn.cursor(dictionary=True) - query = f"SELECT {', '.join(columns) if columns else '*'} FROM {table} WHERE {condition}" + query = f"SELECT {', '.join(args) if args else '*'} FROM {table} WHERE {condition}" cursor.execute(query) results = cursor.fetchall() return results except mysql.connector.Error as err: logging.error(f"Error fetching data with condition: {err}") - return [] - finally: - cursor.close() - conn.close() + return None + #finally: + # cursor.close() + # conn.close() # Function to INSERT data into any table def insert_into_table(table, data): diff --git a/src/managerUser.py b/src/managerUser.py index f74edda..18d72f2 100644 --- a/src/managerUser.py +++ b/src/managerUser.py @@ -6,9 +6,9 @@ class ManagerUser(AdminUser): Args: userClass (_type_): _description_ """ - def __init__(self): - super().__init__() - self.permissionLevel = 2 + def __init__(self, id:int, name:str, passw:str, cinemas:list, role:int): + super().__init__(self, id, name, passw, cinemas) + self.role = 2 def expand_buisness(self): # creates new cinemaObj and adds it to db. diff --git a/src/staffUser.py b/src/staffUser.py index 27e217a..0fcdd27 100644 --- a/src/staffUser.py +++ b/src/staffUser.py @@ -5,25 +5,22 @@ from .cinemaObj import Cinema # trying to make this a base implementation for all user classes. -class StaffUser(object): - def __init__(self, id:int, name:str, passw:str, permLvl:int, cinemas:list, impBool:bool=0): - # impbool used to switch case on a newly created user or imported from database. - if impBool: - # import user from db - select_from_tbl_where(table="tblUsers", condition="") - pass - else: - # staff id number assigned by manager during onboarding. - self.userID:int = id - self.userName:str = name - self.userPass:str = passw - # staff software level. - self.permissionLevel:int = permLvl - # list of branches active at. - self.cinemas = cinemas - - def __str__(self): - return f"{self.__class__.__name__} user object(userID={self.userID}, userName={self.userName}, userPass={self.userPass}, permissionLevel={self.permissionLevel})" +class StaffUser: + def __init__(self, id:int, name:str, passw:str, cinemas:list, role:int): + # staff id number assigned by manager during onboarding. + self.userID:int = id + self.userName:str = name + self.userPass:str = passw + # staff software level. + self.role:int = role + # list of branches active at. + self.cinemas = cinemas + + + # function not working, causes massive recursion? + #def __repr__(self): + #"""this function returns this object in a string readable format, eg; print(staffUser) returns 'StaffUser user object(userID=1, userName='user', userPass='password'... ' """ + # return f"{self.__class__.__name__} user object(userID={self.userID}, userName={self.userName}, userPass={self.userPass}, permissionLevel={self.role})" def login(self, userName, userPassword) -> None: """get values for self from db""" -- GitLab