From 081d496de9018aa334fe632358456ab1897b465c Mon Sep 17 00:00:00 2001 From: kerem Date: Thu, 29 Aug 2024 18:56:07 +0200 Subject: [PATCH] just adapting user to new templates and form decalarations --- web/instance/test.db | Bin 19292160 -> 19292160 bytes web/minibase/__pycache__/app.cpython-311.pyc | Bin 3238 -> 3238 bytes .../__pycache__/theme.cpython-311.pyc | Bin 3781 -> 3793 bytes web/minibase/app.py | 1 - .../company/__pycache__/forms.cpython-311.pyc | Bin 11557 -> 11610 bytes .../__pycache__/models.cpython-311.pyc | Bin 6725 -> 6725 bytes web/minibase/blueprints/company/forms.py | 8 +- .../__pycache__/utils.cpython-311.pyc | Bin 2842 -> 3116 bytes web/minibase/blueprints/database/utils.py | 4 + .../main/__pycache__/utils.cpython-311.pyc | Bin 5092 -> 5758 bytes web/minibase/blueprints/main/utils.py | 45 +++++--- .../sensor/__pycache__/routes.cpython-311.pyc | Bin 6721 -> 7153 bytes .../sensor/__pycache__/utils.cpython-311.pyc | Bin 4676 -> 4934 bytes web/minibase/blueprints/sensor/routes.py | 11 +- web/minibase/blueprints/sensor/utils.py | 5 + .../user/__pycache__/forms.cpython-311.pyc | Bin 6942 -> 15749 bytes .../user/__pycache__/models.cpython-311.pyc | Bin 5433 -> 5433 bytes .../user/__pycache__/routes.cpython-311.pyc | Bin 10984 -> 11832 bytes .../user/__pycache__/utils.cpython-311.pyc | Bin 1436 -> 1734 bytes web/minibase/blueprints/user/forms.py | 96 +++++++++++++++--- web/minibase/blueprints/user/models.py | 1 - web/minibase/blueprints/user/routes.py | 64 ++++++++---- web/minibase/blueprints/user/utils.py | 2 + web/minibase/static/pics/aab9913add20a59d.png | Bin 0 -> 4045 bytes web/minibase/theme.py | 4 +- 25 files changed, 180 insertions(+), 61 deletions(-) create mode 100644 web/minibase/static/pics/aab9913add20a59d.png diff --git a/web/instance/test.db b/web/instance/test.db index e6b860de416d944b1e33c753d0e1d34ce02e6a56..9093c0e85fc0c07008052ff414e430b40e67e953 100644 GIT binary patch delta 3172 zcmdVbc~n$Y0D$rLW`E9A2?tPIX!7>>9_+ z%7~+;s{JLyBSu-c<3hxkZB!Q{L=qsFK*4*#UnOb)%S^HnjE_D7s;m%J*{eWbLz zxMbE@MxFTE4s+)cIi?{mG^uj3Cp>n1?FgUlIn7ZvsxUau;nNG}hvw+{6_avHM}=zh zCe+Ulmlsbg4@QdI?!5fYGjyqbO>^kFTlHz3N8Fm<<#u>9r&sk^8cS?RQff+y$1_B> z@Y6om?1S5tFE*?2a9h=}eWtNgPVbtzcJyoZ`O@p=)+KU}a_8hJx#My}!3neVF?C}q z$5xD~%`2{Thaxp~syBCJVcqzOx_rl!$yHMplvanvIf9dlW)=MNZF>AJ@o;Ef_Q-kI z5zW$EuteTuNwg~)CFN(ORoSC#R9ciL{};#QNSx$l!I**Z)^z#Mr_tX2+ri@)6>CjB zxZ5_fb+tTDu`5NAvR5fmRw(DOlxApsg>fX_>CyW?MhE*?^}koJ(|NY1T8AE7z)l0) z$f9~#J^wmpYu>Ob$fGMi@e#|v$4A+NeTqgveRTsx-QFdw9L6Q z)dRLBH7TQx-c9(=zV{Ms-Fh#w$|+LnptQ8Xo&hO= zKwwZH5FO1@%jUZMwls6cKHKIVe|=MUoPKwX!=PQoypjNu4i1adJFqi_oHFdC=gG~{Cp#$p@_5JU*$F#!`X z36n7er=t*4F%8pk2F}D;m;nPtn2BPPU=~U-8)Ya*1;U764k|Gh^H7Cq)Swo1sK#!d8V*?(*Mr^`^XvRZ$7>{5x zw%}1bhOKxUPvA*x!&7(~&tN;A#SZMmb9f#v;6=QI7VN^ycm=QGHN1{D@Fw2E+js}9 zco*-X4e#Rve29&MMbbo$5lI)x5XltjC(>UeOWw*oLM}J{1eGr{ApigX delta 1463 zcmW;MX;@Tc6u|L&X9kpkJ9k(VSw;pGbI%z?jZz$O%Wd3OO3-XkRMOHc7jVN}l;pZ^ zspYOHUX4mB_tdN?wJ6+jtJHGK4gDWK{Qe)#^PKZM@0T~Lcu7zea-%K5j~B$YqS!tct89Q{tov9ZarK{9hfmXdh z(XX4%)oSUg`B9cl?ze7?B)F4Yoe z+&rzuTN-%{&r@53v7<~4uzOQR4$n*avOh$>N&EmmtzMwto=tY$`;ZK*RLPto!m zMz>tOjmha0%{f_7BbAuiE?3>egh-#yXKX09)ie%0u@!}Rnz%iQN#2G@UQYvWqSw>- zrJVe78v+oB3aE%6*b$5nXmCJ>6QKx0I3iF9l@W<5h(a`C5DOQoA`WiEqZ+EC1`<#c zFQ67`qYmn#9_ph3UPME9;6)=eMk1P^DVjmvm4uh^3Ywz@lF<@Av_cA6qYc`k9opkn zbU;URLT7Y=A6?N6-O&R*(F?uN2Yt~G{V@Qkcnz;(AkvVIK^TlTFa&SnExe6)Fcia( zf#Dc|k;ufm7=_Vz5AS0P#^M8v!-x0?<1qmfF$r17#$-&vR7}Hk9p7>ke(1Bvcx3ahaOYw-!zVLdkBQ+$Sv*o4j4g00ww?bv~x zD8Mf4Mj`gV#9r*f=P1G#_!3`XKZ@}+zQMORfP*-M!#IMYIEL?V94BxR-{Ta1z>oL| zCHNV?;55$QEPlmrD8=vi17$de^SFSExP(7(8CP%>*Ki$w;cxtd8@P#E_!s}-Htygq z?%_WE#{)dXBRs|vl;i2_{Bm_ZBo>KPVv__&0wonB6(vCuyChf=BGDuci7s(ULM366 ta7l!ulBBXEQc^_{C5e{ANMa=}NmWUl#4U-JRFhPf)KK^HN2o*7p8>!+Hy{82 diff --git a/web/minibase/__pycache__/app.cpython-311.pyc b/web/minibase/__pycache__/app.cpython-311.pyc index fe4b1f25e31af5bf82bdbd68b03012de2ecd41f8..6df611c319d39da2346eb3d500cd2360f1e5090b 100644 GIT binary patch delta 22 ccmZ1`xlEFGIWI340}#}#JCLTek#{B!07JzFGynhq delta 22 ccmZ1`xlEFGIWI340}$}L>`&9)$UBn<06d-rT>t<8 diff --git a/web/minibase/__pycache__/theme.cpython-311.pyc b/web/minibase/__pycache__/theme.cpython-311.pyc index 95a4fc4f6038c31d56c0c00e7d6e47216de10fbe..120340d5d61067d040cd293990e560d74737e715 100644 GIT binary patch delta 200 zcmX>qdr_8mIWI340}%YqzK~YAk#{Qxla%h{BOEj8`BPZuFr~1iuxB!+2&8a>cu+mwg*ivLtWFh)ftN>^sdx}ahgQn`__na$us0kvw3)xeYgBdhcCco!gv3W6<9t!}~6)-FS diff --git a/web/minibase/app.py b/web/minibase/app.py index efb63720..f2850a04 100644 --- a/web/minibase/app.py +++ b/web/minibase/app.py @@ -73,4 +73,3 @@ def create_app(): # (APP) Returning the initialised app return app - diff --git a/web/minibase/blueprints/company/__pycache__/forms.cpython-311.pyc b/web/minibase/blueprints/company/__pycache__/forms.cpython-311.pyc index 00a63282a2d7b7e9884bfc9b36527631155ba8f7..de13d23cfb9aabf26ca2c3e652f507e8560aa1f0 100644 GIT binary patch delta 2343 zcma)7Z%i9y7{B-EmG=6FmeTQOu(2U!ts#WL{#Y2&g<@ zF9+n{NBqNv^*ZptUAa^;8{@e#P7bYda#$gIy|X>CkmllzEJl9HnDuk2v6N9|(=`gl zPP8wp6tYw*E-Zm%WOPF^6n)3rWf>5+!C!YTyxj}F>t1*o5(RUEH^r-xrpl60pt|X$ zN?ulI=FMy6zsQw3fwnr7d95RseQ z{0q8tHXD3Y}F~ly0lBAzq^(V+M`^10#|AI%@XrRYg zXp#&vF*xir_yqgIdGIOrO@qUZljJnJ6LQ?fb8I2(ICGL6Z*-h_hy^2w=rAmM{Gb^q zP&KROCGA2%Rx~yfDG3x`gz}G(cZnPK#*DIG15su~yCMnrtB=9Ht#Df%&)jzX;Aty= z8y(@vaG7s;ukPu4R%|~_o@c)ubTkwM`(A`3SAm4 zl=22$N=b`~PE!~?g)oh95dn9dUP4GCTm~>3E$Mh(F6mY6E8tkBGw6<5?nxypX)ojr z_{dbUUqN5c^1ZxNR4U|ayZJ6Dnq;Vje8rJLN63m!!zZbvS7-@n`UXJlIblYMg>1ioGIsz<_WxizjTcepEZoNCMQ{6cW=`irWVwEv1C-Uuwr*FNwfRit8gH6 z#ggPCdp*|dvsT1ff;3x+^~~Xv6bGT$IK?I@wgg|*!s4O=OX)%izhAV7fahLiD-^V@ zAuJ)ay0;@%FOC1f1B{_n@# P_@j#V@l%2Xic|g#L?_b~ delta 2305 zcma)7O>7%Q6rOS7_;=&h#zf5zByr=!PV6WRCA5Un64LxNX+&s+q9)EJyK&dpYcsp1 zIJhdHRI17W(kB6eB7_93DmYZ~fg|GBTPqa_Rv->=<5C3bp$EjgHEWv)%8u-B-@c#k zy_tDCV=RBZJaAnQyo8U9^{+Q)!-V{dFV=AWE&Tp~>mXA^@@^B!C(~<9gnYsO z)v+9voJ%C;hgJGL-PqY1u6*g3Z1Nl4SH-L%iF%%CaNjw4GUnK7Ir~~7E$dqz{?tXr z#h8P2a2mtIWL1(`>g97r^Ms<8w!*_{IiF@?;cSUZdP>tpUDmcd5mQJh5=P_e_HBHI`Z@2Fgf(_mw ztZ-k*($p)IJUmAXZh7Vc^}M|0xGv&t)cH)^dGB0*-OrCYi<55>c9l7JO`Vu=q|?$g zWF)+Cg@r9)BcCgXYALCTIr$l*wk$KYsS`v0AWU`4R)oP_??al6dJ&=j!kJOV!jY?pBWZtStmJPH^0 z+GU1lYXDY)NxM@#2!o+`&lq3&SeGH>nUYpiF*~1^I5HIBui6^l%Qwh(UHdOJ-*vbD=oW6b4tvW zbti7S6P2&RM;vsla=-0z)5ACTYR6M_9KP+aHGl5xJIc#ohY)PE4+b1V->2;d(BtrH zm)&yc6jUCw?K};yKW^K31}3^~JI{izCq7_qb32>B$xb31N0{PZc$J)(mQ$NbR%X+% z($jWf7Hx9~ClKZl77$J%EFvs%FoLfXWmcL|rJ|;@(gOeNHFgTEr_mZVttaHPn4MI0 z-ab`_m(bQ~+FmRbzbm=3@;jH zE`d4cMbM-DVRKqoI>S=g8H8218EqTOp@_FxbzRp{(hYaR%%M$?5qCUs~ delta 224 zcmZ1@F-weZIWI340}!l^+n?6JGLcV$F>9iFHcK#rCeOw>A6UgTS^SEafbvC3Kthx8 z7HeuwacaEg%lcK%NvxL}u~^F3HIpoEf}& zK&~cp5i^h~(w|(*smf{wWXeun&Ur)zEXM+s11T^75vCx*aB@4BJgWtesW5ppmpvob pVOOS7hNICk2m z>S#6fp%NA9IFkrsOnoTh(!ER-(s)4#_J9x%&J<7-sS*#s121HPz3?#cJ53DZ^6U5a zUwzJJpI_(4;Nw2`hc1_c0Li?mU+!(V?rtUTUk`rn^lcI6{SrA#gt)uE+@l=!coxN$ z6iH6uPb|*{yD9|9bZyf|Ht%jIA1&BAi?&X^suc@Vs%6xKM=fnQK)*XSU?c{hpZDjZ zdyxX)U*!9@=^gvF-RM6qqbA@HrwleVp}|_<`7QG{(@gf_7N&dMYg*_*qBJk*|-zY z{mn#gT|oV7%XuuHzIr12V6ks0!MtC-ah*^{jD7gXn~Iw`KZoEtA&;C z=3@HAq`s&W7q!A%wm6s7+gCsf62DsHS9N~%h(D2keox!aeHy$M`XYLNzHoZFczU|P z&lLF?y{<46d=R#Kss*w^BR4FHvZmriyS`8+HX+g zGl!0bw@B^}Pg+58CY2kNMjRYAg}s0tc{mz7jXSxKf7!o*l~Y{Vhd z#B|oCOxJW~QnIMZLR?8}VqDu0a!M8nYBrNmkS1hgq$+6v)>oBdn^9CXc_}4V-w)Bq zYA`xy0BgW203l16k(b0|syb(A4pOS|D}W8+z?QwLoR(q$Kt6Wd`5NS>;TcyAgrReI zbzgs}EnGU;m4CIuP|mu|gdu5m&K_mu5RmA+N@=6Fpv!o&P~yaE3V?fiFRupbNv(2OsEVd z>S2c=8=qjr9(E9R5}cc`gAPG2Dnc?Mj7m=mUUsMl@gm|&*G(Dh@p#{R@ArG(OI}|7 zM7{;fH0;Fa0^^M<-<+>)cwH(}{(HJ2$td%!yEHjx+%kfMezaUQrI?4p1I~J%C zTfY?4`VF?-WZU(MmPtS=Fm_QJfr#ZsfGM_Wv6T~s7&gW50=4K^a9GSe81GWvrqj^< z5iv*Hv>u}(33Ll7ZrnzP@GLELkwr?)%gG`$l~m)ZsuZbAJe`zm$}wOUX*E8PO5*pl zx2GH8JH!s-yr0*b26V>K67N}>)e?nigAbW}NM}Q3l3)h`!M%2GYZO(QqeIOLbCAKy zc6R{qJxP!=Hp^3{RJxjiBS8U^#2@Xxw*RxV>iEZ*BPyIe+Jk+JJM27+?8isc1ogFoqw@b;+)T;7Y|0rbx@mbVgOI$taSQU~+pygz<&(JbP@u3$nQ_ zFo!3%%6}txOLCyn~`_t;Q%#+s3}BsAzA^lpJP|_ z@wh%YWlpAySlW!Gbx#)55M)!3bwMr(jT)_~h5WPN^K*es@l~_YJ#2Ol8^VYwjOhDX zW(c7Z+Wq8+T5;)&)?XM{Nj#l4YI@C@UVUH7eD!kN-wO zKztE@aRpH;CdD;$4ZjqFPOC<-sLBN16@6R^Tx(5oG3;`G7=)j|hN_0MA=vZ-1EFMv WRl~8UuS^`67ToBGpcXvl3I7H1jrV8( diff --git a/web/minibase/blueprints/main/utils.py b/web/minibase/blueprints/main/utils.py index d63ada75..78dd6f17 100644 --- a/web/minibase/blueprints/main/utils.py +++ b/web/minibase/blueprints/main/utils.py @@ -18,30 +18,33 @@ class accountInfo: # FORM AND MODEL MANAGEMENT -def fill_model(company, form): +def fill_model(cur_model, form): for item in form: - modelFill(company, item) + modelFill(cur_model, item) -def populate_form(form, company): +def populate_form(form, cur_model): for item in form: - item.data = formFill(item, company) + item.data = formFill(item, cur_model) -def formFill(item, table): +def formFill(item, cur_model): if item.type not in ["SubmitField", "CSRFTokenField"]: - return getattr(table, item.name) + # Cheking if the arrtibute exitst, otherwise ignoring + if hasattr(cur_model, item.name): + return getattr(cur_model, item.name) -def modelFill(table, item): - if item.type not in ["SubmitField", "CSRFTokenField"]: - if item.type == "FileField": - if item.data == "None": - print(f"File filed found with no data -> item name {item.name}") - print(f"It will be filled with the existin tbale data -> item name {getattr(table, item.name)}") - setattr(table, item.name, getattr(table, item.name)) - else: - setattr(table, item.name, item.data) +def modelFill(cur_model, item): + if hasattr(cur_model, item.name): + if item.type not in ["SubmitField", "CSRFTokenField"]: + if item.type == "FileField": + if item.data == "None": + print(f"File field found with no data -> item name {item.name}") + print(f"It will be filled with the existin tbale data -> item name {getattr(cur_model, item.name)}") + setattr(cur_model, item.name, getattr(cur_model, item.name)) + else: + setattr(cur_model, item.name, item.data) # PICTURE MANAGEMENT @@ -73,6 +76,18 @@ If you didn't make this request, then simply ingnore this email and no changes w ''' mail.send(msg) +def send_sensor_email(email, data): + msg = Message('You have recived an ALARM', + sender='noreply@demo.com', + recipients=[email]) + msg.body = f'''The Sensor Has the following DATA: + + {data} + + Please contact your support person as soon as possible + ''' + mail.send(msg) + # QUERIES def queryIndustryNames(): diff --git a/web/minibase/blueprints/sensor/__pycache__/routes.cpython-311.pyc b/web/minibase/blueprints/sensor/__pycache__/routes.cpython-311.pyc index 587e7cbfcef5497f8ebb2175f52d3a33914ef44f..bc7cb19c44880cbc7967810c989c12309d9c900c 100644 GIT binary patch delta 1325 zcmY*YO>7%Q6y9CWuD!O`KOu=t>!zFFV!KIPf}r6iG%5;FLt{coh!RV|T0HBrW!Dbl zb*qFxBXO$KN<<@7kpfZEuv_rkb64l7&o9``jm8k6Vj#M3=n{-ahLsR)Z) zE=rT)wd`hOQLol(L@m^?ZoZ~&M#t1fT_>tOZfOP(fBg)Ra$$N~9G`bXpEPu`@#e;y zRX1Fj`Mqx&X5Cdhz5pA*hTRC(uNq~iWncExpKRBczZSPmkyfI<3;Sm+}WkX^(w z)!C_3m8PVn&o_;^i%1l244mM0x~a(m_g$*thI-Lqd!!2;iRsJph&w1cKwXu5gH{{`QFhE))_tlK55 z*&2BR)T!pWwdpc-N^md)=0wz)@2^2XZDHF&zvv34lsgi`-M+5A1^WM`c0 zTq`&aUmF!1RA`}O;dd1H4W)iXsomu^N;@dsLg`2T2>o&3sx$#HbE9;6@O6ou&>g1j z!Q*sq@S!xv)FDv&>F0^K#A@%VeXKk44X=L@lgSAEGLib=W#$nmm8zPhmrAZ!s?>-@ zUSX_AY7JW_tUbL(@!sEi2k&$w&J3&+uSfm~OhLmpO#K|$29Evl^+g&?{!RZ(rf4TA u(SMU`i8P<-Z~#wyoG|Y2V;zAp@6h#UAEaZ<2Ec4*96sL>4jGU3QvC7Z<1JAx8)8yW^NwztV{Visz$51^kt+GKw)JJw`p>3$GKi*$qj z22hWsvwGXG0)PcQVY`ghEPauR+R#UK*|_%wTSqyxzzrCoiNrkm!OgN|9>?gU@scHq zgEqX&zbN#`_}OWvSi8pfSC_Y#u*QUIOt`wi-v#XvTvO+BvMNZTD#9U5N2)1vf{u*g zFiOJ_e86!GWg0^u0QEPRyi!(S5-Umc)H)Ah)dTB212~QD*i}~_mTy_bOr}&Rs_|=T zAs;osF=TSw2Q%ogBhfL53+gtdAm-$AN?x8(ir3+JwCnJIAUbeJ9lA9Or%4$n$xBK` zhO?;XjM)#(Wl2%tRh*r!t~(z9>^{`~6@b2nuE@j`F*lKlLuVS2Zg3Vuv;~rpLo0?l zy9kw{T5m0g#Y$Gps1+zfL6Kk(m0bR*1yXmJz#M@z0geEfy513AjX+}3_`j<$h>`?z zSS^vvCfauS6UlW(i;QZKiJCcypDiY(F{v7p+F|%@#`m4^tbxKn#eysdbymohU;!qG%ED4b zl_B{J^r7mr((g?FHs~M;VxZ6SH$Pe^NtL`j4sT!$;9VZX^KKXb06XZdw->$fI+5mm thc-H|xC0>EpfKzkD0)Bx{SBHZlPJ*jI^-ZZ3?w(Gfp~-dr|7co`4>x%;dKB2 diff --git a/web/minibase/blueprints/sensor/__pycache__/utils.cpython-311.pyc b/web/minibase/blueprints/sensor/__pycache__/utils.cpython-311.pyc index a57fcf86231be8695ce856fd81747c7dc477f944..68d19a68923fd06300c4b56a4c712f184be3f6b7 100644 GIT binary patch delta 448 zcmX@2a!iePIWI340}#Y5yO7o}kynzjWTJW=H&+WolyC}DFoP!d##ydRj4LNUU@~MC z1FGYmEXM3KIi0CES(C|6lkpZyW^Qq2ktk562xLw%Bal!i5(JXBxC={Diz=NeJwYlY zfg=1M1sXu2f#EK<*cEP>>)dLWxYbrTUEo%`$gO{cTmL$@=_PK{i`?c{xXmxHm`{Gs z5;=K3b2_UcP?PXvZk8HxX&_6Jxkv^`70H4KRuCaKIe}Gd@)j0RR%IYpV)8kbYD|@E zFqPU|YCtAfx60R*0hvmh!+4#T8AT?~ z6sU{?*?)_xxG*O%CpjZEx3Y*Gq}T;S2!RMtP=Wni1af*2$W=ukON&4ztz;+?2C+e* w^ozqLH$SB`C)KVf3CINnU-5&<*@D%wT#Srn9~j^S2P2~ehzlVme-R7-0JaZe5dZ)H delta 287 zcmX@6c0`4DIWI340}!b8?@2S5$ScX1H&H#0l_{7(lWXGwS0+Zy$=xF*Xm zJ57Gi>OQ%bC7o3kD8e`SCrgdEIFO~uTqFUciX=e=#HYIj8Ymk)9o97W*-<}#N=;60RUxvI4A%B diff --git a/web/minibase/blueprints/sensor/routes.py b/web/minibase/blueprints/sensor/routes.py index 910c785d..dbed622c 100644 --- a/web/minibase/blueprints/sensor/routes.py +++ b/web/minibase/blueprints/sensor/routes.py @@ -6,6 +6,7 @@ import minibase.blueprints.sensor.utils as sensorUtils from minibase.blueprints.sensor.forms import nbiotDeviceForm import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.main.utils as mainUtils +import minibase.blueprints.user.utils as userUtils from minibase.app import db import json import os @@ -47,10 +48,13 @@ def callback(): "srcPort": src_port, "payload": payload } + sensorUtils.decode_payload(payload) - + sensor = sensorUtils.queryByImsi(src_imsi) + mail=userUtils.queryMailById(sensor.device_user_id) + print(f"Sensor Model: {sensor.model}, user e-mail: {mail}") + #mainUtils.send_sensor_email(mail, data) return jsonify(response_data), 200 -#return 'data recieved', 200 @sensor.route('/data', methods=['GET']) @@ -112,10 +116,9 @@ def edit(deviceId): def add(): device = nbiotDevice() form = nbiotDeviceForm() - print(f"Route : manufacturer_id : { form.manufacturer_id.data }") + print(f"Route : manufacturer_id : { form.company_manufacturer_id.data }") form.populate_for_adding(device) - if request.method == 'GET': form.populate_for_adding(device) diff --git a/web/minibase/blueprints/sensor/utils.py b/web/minibase/blueprints/sensor/utils.py index 89f05815..23fda485 100644 --- a/web/minibase/blueprints/sensor/utils.py +++ b/web/minibase/blueprints/sensor/utils.py @@ -7,10 +7,15 @@ def queryImageById(id): selected = nbiotDevice.query.filter_by(id=id).first() return selected.image_file + def queryById(id): return nbiotDevice.query.filter_by(id=id).first() +def queryByImsi(id): + return nbiotDevice.query.filter_by(imsi=id).first() + + def queryStatusNamesWithDefault(defId): choices = dbUtils.queryNameWithDefaultId(nbiotDeviceStatus, defId) return choices diff --git a/web/minibase/blueprints/user/__pycache__/forms.cpython-311.pyc b/web/minibase/blueprints/user/__pycache__/forms.cpython-311.pyc index 4c4b9cd3856aac42a364a52d6801bc4a44384737..d634aae178012f2e625389e4260a93f59a253a79 100644 GIT binary patch literal 15749 zcmeHOS!@(nm#$vj?Ots+WsF%GHxQa6CTtD_12JB}3y$%M+e_2#Dz_VYG1YCB4kXq; zdGIfx8D}P%F#0EwN6Ijupphf-U?d(KiAWx49&TABVU-kVqZH#P+vOYFi?W?BmWs%L%nxIz0M7L0^^=;KK zTILMHnZ95+Gq1U;W0>#YuUx)uG^`xLEJb14X_ytlY(-%^XqX+s97SPn8s>zsilVTc zG^`TBs*1wuXqXGaHWh_=xUxRR%l?eT_G)BvTO^RU+!hz2UM;+YBYaz!k8rXDolTKQ z{2I@B%VbMmQV7RFN|>!DkVssM3tXDCZ)PGIPAV_f)A4wO55$x=(?D-m+P^)P5t2f!9XO;1(M-- ztW^-=0+ikwoDl>*mh{ggcmXP47=UL&F2{$z7YdT-4yHSZK1}JCjX!IVy?Dl_;TWG* z%kVl*1E{|X1m9(2fRBOGa=HilyFmXP{FN)DePB@g_>43S#NVDq8BGK6x2IvEX&@G- zVOH0!L@ml`Z1Zo7ZK1I-je@*Gnxgiy0+o%!7_X+aQ(BDiYFY@VoZ2_$1Y5})$TS4Tv$xeX}g%e4EiV%wYb2AExyE_o&f7U}LKf3_# zYh_(D90Lekzps(YuPRa(2f5NCrCioGBgDY*+)f4bBX?6U7@vtHpS#lU&GBe-CKe9T zd}JdG9Xy|uwcT-9-xE(HWqorvdE@z}{UJUc5(3jxH^7zjCz63ApLlNeP=`Ov-Pfj! zQ`g^zu#_2|$$$XP`&wZ;6jC;W*mEG{m#@i&K8z`sHDe)!;)H|YWEc`QdBAZ4(v?k_ z@$0#>IUbt~3sHB*M>b8T$F^Wr+95lfmT;)wI84Wlo0^-9A6}JWx=g&?K zoc0SQY0l6y%%#jU$Ef?RrQjXXHD+S@%QCKf-%FVhjS(g}T|q9{981Sgb61JH=`@YG z=JMwB1$kIrUaD8-Va>$P%Y*4-I72}`whY}(&82L)z@2R$^?3Z6wJ{dtV$aJZTe4r3 zOE#9eKHjo!S=YpI!7QIZPAGC!@ZZ=6@HG=+ZZc!eTN=m@-jxg7*%*`BFSWNT`k4DD zqFUf%JxU?E>pzfnLi}0+SgVkf{XL+Zwrd&#rV{B7I4<_Bkq=SbFf11tJ_G>gyx2?-w}d<2kg4B-TN zoCNsom8pZ+8|lh;ZV`Gf9a`x7cJN-`g9~I=gW?4!oC4DS+m-R;Rc6=cgx*Wd3&C$E z?*$)Bk=-9EUVv{vWp-m_4gt(E>kPB2SDTNjF3Jy3+;2ej_Nc12djPAKMOCNe2Pke@ zJ+DKy#f5Mv91BFw#W_AA8xvGnmkp7?1ib2#{Pm=4f|+jluqA-@kI38l03KOT5fkqR`(i})gO;a%~K>C zmBQDh@GY_VGpYGA5LR*5=hCjvf%2SW-AU-ZuFpvXrhkP9S0&*yV2>tktM(Z_dbGbV zOta=ZzTpGHK#0H(5WE1>d9Q18jE5yikmPkBn9-cZI4#<@)1s0?6)gsu_-jTr6_!-8E>k5-m`r9B0Z^}SVx`wYR?*7%;8R7L z&3z#+g&Z{~cX`wCpTHjRjZUr9sNWW{YFaK0ra-L|Dv}ksP)@5(;SaDR1qBHH_jTRR zHM>)u{;6=noz>Lc@Dhl?LivVUVOSpA_sv2NBq^K)kWI+%s2d2VUC0J1FS2nm97*zm zYzRlfmwDL$dM~U6upppQU!a8H*z`~;Z@6FVmbVibJJIrr_Q=nXWc&^`S#>f&xfm?56RK?rPjwC@KA2i(;;~} zL}#bu?0o7xzv?_MI{PGN-#VkQozwip?k0OWMYc;~yNI)E-N0CnK+5Y{3{*(o@)orJ zOLjYuR|D^9Pg_ALTFMA|xXO5GD|U2*_3f2cY66Hp?lhWK!?E zn59&N`ys)Nn*eIQI<{&#Ml8ovd?k4ro_ZQrJ&oi<_wuGETi~JGqURII^NHx}k(@nG zor9~+LD6|Za$Z2L=};K!tjM-YY&&tbBV&C8Nh4!*P{!)eP{!(p<+RD~M}hGB<#NA2 z8s}yr=(hU(Xs=R21RPTYT)POkv=DI7C>#Tj%M!{WT5zD(W%Mdn>I#~76sBpqXclmJ zC7YEOe=IJWr(pr@55iO~;7UX2Md(N9M!>;GIEdf`ke!*uEX1JeTmhGhLOX&FVG<#N zK$U0IUKNFzMHd3DwGvSnBxkd~|6q5{UtV~3sd1_C(aFarR~l9t$lwqe^OMetV&_Gv z^CI~uK-dY9osigx*|Teue$QfLG4g%vVQhJFd6Jy(B^P|8ZA5Gvk=jPckx{~qiR_rf zj?K0x^xmbdOIsgpf4qH#U13T802vu0?c-wmxYRyQj`|6EQDiSl?8VtLl%CWbT(&M- zf3QEXlb!*%#hxLlXNa7-K-giC9hTVP*>h>iqsx)y$Pck6F)}y;w>UT^4UUo4al-mV z)-SRC*$$-)dzY+B)<^cocJkpF!U9{ImDsbhZEI}Zd}QJ9;^^Y&_u~)8$>A2lwu)@4 z#J0}1D}fD*Hy3Yy|JlRONJAT8&xq_9i9LgX*mT*ZAV*rsXaXk5W^FglmA#rz@*dT6 zb_Rr*6EI!Tg?APw2zyLqk4fyYOyg!7iyS>m{8u5VHkjMtF`!K9=|?r4+W|4fUM*JB zGap^(Sn68pder^6n;h>XY?m^uV$u)@tDEJn<*pyPpLCP{5xhqy#r}}gA0nWJuwju6 zOKh0vU9@UnM!$;AwyoS*(+o0*!VAC$hYR( zB6H$f^DXd2&P?z7pP6qran;=BP=R(x9)w*8xPTV+AiRUH7Xh_50ZmfEdkF6%)Fa^Zo3bgHx|^=T3Q&-Bm!?CqZaNkc zK0uNK2si<@Wb8pMq|VGc3K-ZCt_tn5E2_=1Lnz-VZy(NrR`Xeu&IrpGgJsm89_Usjj~42>!c3v0wZYJS6QsUk~e$l!G){0UuheD zr4jVE*M=&XO;Dsap|GD|Ih)^*!k))+w!R^Sr7MmznZkM<)a0NnDUjcVPJ}K1S+V=& z+Yu>FNZ|!)%LU6sV9ZwiV;&B8HAfJ)x3Owa0X56f$ zBxB2?!VtnV=pGX&QrW8vTsrt~yfvEkF+vzxLb!xb)Yxe0NbP+|W2>x9BbY`M0b9J= z>lR}85=WRuK!viDaYwj<0S*K-><9uv0s+lALK0yH!HPf!Jv!de85Spg0nOHOc{myf z!A2__#40fC2v?CPXUq93e4RwV8W!4euA?8q5%?!kz&USiIsY$hIXmXV3y!6crID50 zBI%nI80cd$oeGKm$mqa?0$*epJ(GavwUWyLu?t6T82n-&Sv(%W7t7v z48lKqWtL_e--6fc8FuahWp1$yXW6vs6Cm_NUKyu@g>~_%u|irrFK6cT>LsKP%_$bn zP~dCjjIanVlg*Jh?5onnHx+fd+Qvn2%F@e6`RD|ktUAZ1j9u}NyFJ$JwY_-w!1%I( z4nBF3Zbn~|kWMR4+#4W(j!BBGb`D<=F2X;7V^mJQ*R0iZop;Lajour*KmK5RX<%vK z(a_@|@?I;kwu#m@$=WvCy5`tAck7NX-=67c6&f zkvp43Tb*R9n{C6NQWPwJs!wrv!fT@rbgkFx)8FB&Wmyql6rR*nPDqwMW%=sZcs8<} z!!#_MnJa${^HBPvV*wZ0IXDjNb8t35Cuawaa>x~m9^0gBu4K(RKkJ|s3(PtxTPxkL zNz3V-fL1eRVyJEW$Ol4eY1Q7OI05~t!i7XY7?u@N>yj)TGkv@xSi!wwzDoM z+aJU^yk5pw4?-&IdJI%Ziq*+Cg9l(={#Wq8eGOH`Qtwe7pd)RL0l2vPMtsIS6}XDs z?+ygxK{!e3KBek^s>x;hU-%p7o?OqTchH4DV$Y$Rr2Aa9XFHeXnR36R`zZx#cGS|wgwTrG!$<;XrgSiVk zc2Md2evuuJ*a6}kz`lpw_e0qCgS77lGh3MzFP@p~SWQ0yN?V>fiz2S5sb$mYVFd?# z#Snm;F8m!r!Blk{{Sa^=llU`0-c;q-GWY47|SnLZdM%=VpyygmMVrpFS1w9g~{d*mM$+{UO7T~hgRyvlf%-?5LmM6!>- z7MyzeTQ}+rC`fr|*Bh{TOQSMXVgm%>pS_G}*Txh$UT>;YkBBc;f7GL^&x8kfeP+%8 z6OIuNgu~g8M6#Dp@JY2MlVb6E3<%2}jdoM2(zC_i({kg&CUfPEtuExv8<|iBPxjzA zL$9Ja0GX@kQr8%d$<8{GxS&d3rRM+`|AjAsB6Xr4Ms*&AJ{HfMSa)B8V`c6n9}iI7z*x-y zvrPK*!tPb)?#0%J9mKg?be@u&r=B`nSDme*^Ni#?GiQL~G;=3@s@zHH0%GNaR5?Mc z6YDz0S~GWo@>aLE{KdjdMHq*uJYBMslwxlR2)E#$z*8c5QuAT^{{m{K+^O7{z-mBo0hT15>0WOsX%5)t98|OStk= zy3s4z_DQyV`N}@#t?I0-vcCc$g`I_JeOOcY5tUC*y9YbTpq6dgJw~qVfl0ljgDx_w zeSFF%Q@BtoordK#(x8h!bqRdsoE1h$n`~F+Yy6Z9dsx=Cx5y?goCr)r;7c|5fKGT9 zDlF@fpw#xOY-!;WK_NViU#SyRV>hfGNvN;aNK~^JA)68jT?$EU6|<3rlfXGqdT|o!#x7 zjW*E|g%*71gW*7tQuXe0%Tx z?z#7zbH8)v^Yh;v2!9s})d=`mxc*B%8JP<=h)r|5`)5VL5DZT-U?W-=WV69$%5xxyS}?E9YvF(>HL9#-=eL9(_!{#YIOQF6Qhr!)0d0 zB}av?#m%A@ein~FL^=g!sa|Rlp*gV!u1iPZRQoPjHGJ?;Zu8Yhf~gvQ*df=c0Ykke zV#Fd`k{e;AU1_Ot`>P2MGGPNF%xFdsF=B+!fiO&ak9b)Kr@$p;mpbDcE0iW<;}y8l zQ4h=AwokesF|8Vao2@ZzULHYT{ZqEdN;%7fPm*0j^9rj)YsdTXl*y(YHD4%JO_n`9 z?Rbn_HRpKq1!h;7hI8g+$77qtJljbI9$Lnx4nb)ZYTkb#B36&U&6l62(a7MJHrhxk53Uo0uq1m8x)IUvfWd!QJO27RNuw%XwSE zb}YvB(opzpu2{gp%q-_-n&J1_tpVO{K;BM+-kXfm#-pxJCzkY+%lgU1;7Rgnl>0O) zvJRX)60e0D(Zp;3+bl>xiQ$LAx~b(OXeJ0FIFU-uw$GKBk)0@)Fs&Bz)39Psowf>9 z)=m?95atEGJa?EyX_P?4$9{xx@x}Lnw)OJ)tI*VyfM0vt0QPQ&Py4!#T-~x1YFQ4o zTpV6eWG|(04F+W|1@U@x_l<%laVtQYVvPjb;eKM9(M!z(1bqYw0gs$dTo*4n>-d>z znbv8O@i^H*vN%LQ$#bJiQH!7nAG-uU_I6_!11g_E<5WC9J=vQQ>*}!gnB>Mb6VPd~ zMi}fE&>i`s%A_M#N|TN#7 z6$@*Jr^!8H2eforh;y9}kFidi^vat1$@GnDcF~$^^vBP4CI-)vjS3fC4>a$$W+_}$ z6MJKh*Qtv(b!zwms3pr{9`eFVqrOUEqB_OQH93DFto7L+AS(n(Xal9|UxjCV0Oank zln_yk@NM@kaUa+{gAKf}*v5F^QBSLQ7(%`2F*k~uH%Gx2o_zV_+xfEFo{l1l1M`dQoz+3aoIma_vE}E9sn=t`itC?Fm+>R14+O z;~O|K5)ZsCSB_LL+{y})nTO$mPQZ9+yx#37KR3GG*vNB8!v_bi201}vBk^tU>|i?O z=;x|=d`sEM)qAka?3a7FR~Ow?yds=Hp5AKNVtKMqViA}-)RyK-r)%E5n0Wni8SyjY zY2!Y;n$M^HlvOsSissuai?;Zd6YM`lc&EQRKDH?Quistxtv?1g`&D?*pXgapbdj#H W*W;DxC!G0bEuVldQ-66VBmV)@IP!S_ diff --git a/web/minibase/blueprints/user/__pycache__/models.cpython-311.pyc b/web/minibase/blueprints/user/__pycache__/models.cpython-311.pyc index df776b20ce40be1ffd3670cf1fe4149d10c4969b..4b17b730d9b73211cb0e4c906c7f82415252dedf 100644 GIT binary patch delta 63 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 diff --git a/web/minibase/blueprints/user/forms.py b/web/minibase/blueprints/user/forms.py index f70b0e21..76521eb1 100644 --- a/web/minibase/blueprints/user/forms.py +++ b/web/minibase/blueprints/user/forms.py @@ -1,32 +1,98 @@ from flask_wtf import FlaskForm from flask_wtf.file import FileField, FileAllowed -from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField +from wtforms import StringField, PasswordField, SubmitField, BooleanField, URLField, IntegerField, SelectField from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError from flask_login import current_user from minibase.blueprints.user.models import Users, User_Roles +import minibase.blueprints.geography.utils as geoUtils class registrationForm(FlaskForm): # Defines the form class to be used for the user registretion # Decalarion of the fields for the form and it's propereties - username = StringField('User Name', validators=[DataRequired(), Length(min=4, max=20)]) - email = StringField('Email', validators=[DataRequired(), Email()]) - password = PasswordField('Password', validators=[DataRequired()]) - password_confirm = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')]) - submit = SubmitField('Sing Up') + username = StringField('User Name', validators=[DataRequired(), Length(min=4, max=20)]) + name = StringField('Name', validators=[DataRequired(), Length(min=4, max=20)]) + surname = StringField('Surname', validators=[DataRequired(), Length(min=4, max=20)]) + email_account = StringField('Email: Account', validators=[DataRequired(), Email()]) + email_comm = StringField('Email: Communication', validators=[DataRequired(), Email()]) + street = StringField('Street', validators=[DataRequired()]) + street_no = IntegerField('No', validators=[DataRequired()]) + post_code = IntegerField('Post', validators=[DataRequired()]) + city_id = SelectField('City', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_states", "hx-target": "#state_id"}) + state_id = SelectField('State', validators=[]) + country_id = SelectField('Country', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_cities", "hx-target": "#city_id"}) + password = PasswordField('Password', validators=[DataRequired()]) + password_confirm= PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')]) + submit = SubmitField() + + def populate_for_adding(self, user): + self.originalModel = user + self.submit.label.text = "Add" + self.country_id.choices = [(row.id, row.name) for row in geoUtils.queryCountryNames()] + + # This is for the htmx implementation. please be careful how of there is data we first take from the database an then from the from(containing th htmx call) + if self.country_id.data: + self.city_id.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryId(self.country_id.data)] + self.state_id.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryId(self.country_id.data)] + else: + self.city_id.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryIdWithDefault(user.city_id, user.country_id)] + self.state_id.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryIdWithDefault(user.state_id, user.country_id)] # Queries to be made in order to validate the form : If username exists - def validate_username(self, username): - user = Users.query.filter_by(username=username.data).first() # Database Querry - if user: - raise ValidationError('That username is taken please choose another one') + def validate_username(self, input): + if input.data != self.originalModel.username: + if (Users.query.filter(Users.username.ilike(f'%{input.data}%')).first()): + raise ValidationError('This User Name is alredy registered') - # Queries to be made in order to validate the form : If Email exists - def validate_email(self, email): - email = Users.query.filter_by(email_account=email.data).first() # Database Querry - if email: - raise ValidationError('That email is taken do you have an acocunt ?') + # Queries to be made in order to validate the form : If username exists + def validate_email_account(self, input): + if input.data != self.originalModel.email_account: + if (Users.query.filter(Users.email_account.ilike(f'%{input.data}%')).first()): + raise ValidationError('This E-mail is alredy registered') +class accountUpdateForm(FlaskForm): # Defines the form class to be used for the user registretion + # Decalarion of the fields for the form and it's propereties + username = StringField('User Name', validators=[DataRequired(), Length(min=4, max=20)]) + name = StringField('Name', validators=[DataRequired(), Length(min=4, max=20)]) + surname = StringField('Surname', validators=[DataRequired(), Length(min=4, max=20)]) + email_account = StringField('Email: Account', validators=[DataRequired(), Email()]) + email_comm = StringField('Email: Communication', validators=[DataRequired(), Email()]) + street = StringField('Street', validators=[DataRequired()]) + street_no = IntegerField('No', validators=[DataRequired()]) + post_code = IntegerField('Post', validators=[DataRequired()]) + city_id = SelectField('City', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_states", "hx-target": "#state_id"}) + state_id = SelectField('State', validators=[]) + country_id = SelectField('Country', validators=[DataRequired()], render_kw={"hx-get": "/geography/get_cities", "hx-target": "#city_id"}) + image_file = FileField('Update Avatar', validators=[FileAllowed(['jpg', 'png'])]) + password = PasswordField('Password') + password_confirm= PasswordField('Confirm Password', validators=[EqualTo('password')]) + submit = SubmitField() + + def populate_for_update(self, user): + self.originalModel = user + self.submit.label.text = "Update" + self.country_id.choices = [(row.id, row.name) for row in geoUtils.queryCountryNamesWithDefault(user.country_id)] + + # This is for the htmx implementation. please be careful how of there is data we first take from the database an then from the from(containing th htmx call) + if self.country_id.data: + self.city_id.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryId(self.country_id.data)] + self.state_id.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryId(self.country_id.data)] + else: + self.city_id.choices = [(row.id, row.name) for row in geoUtils.queryCityNamesWithCountryIdWithDefault(user.city_id, user.country_id)] + self.state_id.choices = [(row.id, row.name) for row in geoUtils.queryStateNamesWithCountryIdWithDefault(user.state_id, user.country_id)] + + # Queries to be made in order to validate the form : If username exists + def validate_username(self, input): + if input.data != self.originalModel.username: + if (Users.query.filter(Users.username.ilike(f'%{input.data}%')).first()): + raise ValidationError('This User Name is alredy registered') + + # Queries to be made in order to validate the form : If username exists + def validate_email_account(self, input): + if input.data != self.originalModel.email_account: + if (Users.query.filter(Users.email_account.ilike(f'%{input.data}%')).first()): + raise ValidationError('This E-mail is alredy registered') + class loginForm(FlaskForm): # Defines the form class to be used for the user login email = StringField('Email', validators=[DataRequired(), Email()]) password = PasswordField('Password', validators=[DataRequired()]) diff --git a/web/minibase/blueprints/user/models.py b/web/minibase/blueprints/user/models.py index fdc2d516..758de6a8 100644 --- a/web/minibase/blueprints/user/models.py +++ b/web/minibase/blueprints/user/models.py @@ -4,7 +4,6 @@ from minibase.app import db, login_manager from flask_login import UserMixin from datetime import datetime - # The Default User Loading proccess @login_manager.user_loader def load_user(user_id): diff --git a/web/minibase/blueprints/user/routes.py b/web/minibase/blueprints/user/routes.py index 5ae22103..6f19a85d 100644 --- a/web/minibase/blueprints/user/routes.py +++ b/web/minibase/blueprints/user/routes.py @@ -5,26 +5,32 @@ import minibase.theme as theme from minibase.blueprints.user.models import Users, User_Roles import minibase.blueprints.database.utils as dbUtils import minibase.blueprints.user.utils as UserUtils -from minibase.blueprints.user.forms import registrationForm, loginForm, updateAccountForm, resetPasswordForm, requestResetForm, updateRoleForm +from minibase.blueprints.user.forms import registrationForm, loginForm, updateAccountForm, resetPasswordForm, requestResetForm, updateRoleForm, accountUpdateForm import minibase.blueprints.main.utils as mainUtils # Declaring a blueprint user = Blueprint('user', __name__, template_folder='templates') - @user.route("/register", methods=['GET', 'POST']) def register(): if current_user.is_authenticated: + flash('You are already logged in', 'success') return redirect(url_for('main.index')) + user = Users() form = registrationForm() + form.populate_for_adding(user) + + if request.method == 'GET': + form.populate_for_adding(user) + if form.validate_on_submit(): - hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8') - dbUtils.dbAddAndCommit(Users(username=form.username.data, email_account=form.email.data, email_comm=form.email.data, password=hashed_pw)) - flash(f'{"Your account has been created you can now log in!"}', 'success') - return redirect(url_for('user.login')) + mainUtils.fill_model(user, form) + user.password = bcrypt.generate_password_hash(form.password.data).decode('utf-8') + dbUtils.dbAddAndCommit(user) + flash('User has been successfully added', 'success') - return render_template('user/register.html', + return render_template('edit.html', theme=theme, form=form) @@ -57,27 +63,41 @@ def logout(): @user.route("/account", methods=['GET', 'POST']) @login_required def account(): - form = updateAccountForm() + form = accountUpdateForm() + form.populate_for_update(current_user) + _accountInfo = mainUtils.accountInfo( + title=current_user.username, + description=current_user.email_account, + short=current_user.role, + status=current_user.name, + image_file=mainUtils.imageFileLink(current_user.image_file) + ) + if form.validate_on_submit(): - if form.picture.data: - picture_file = mainUtils.save_picture(form.picture.data) + mainUtils.fill_model(current_user, form) + + if form.image_file.data: + picture_file = mainUtils.save_picture(form.image_file.data) current_user.image_file = picture_file - current_user.username = form.username.data - current_user.email_account = form.email_account.data - current_user.email_comm = form.email_comm.data + + if form.password.data: + print(f"Passsword is : {form.password.data}") + print(f"User pass id : {current_user.password}") + hashed = bcrypt.generate_password_hash(form.password.data).decode('utf-8') + current_user.password = hashed + print(f"Hashed is : {hashed}") + print(f"Hashed is : {current_user.password}") db.session.commit() flash('Your account has been updated!', 'success') - return redirect(url_for('user.account')) + return redirect(url_for('user.accountt')) + elif request.method == 'GET': - form.username.data = current_user.username - form.email_account.data = current_user.email_account - form.email_comm.data = current_user.email_comm - image_file = url_for('static', filename='pics/' + current_user.image_file) - return render_template('user/account.html', - theme=theme, - image_file=image_file, - form=form) + mainUtils.populate_form(form, current_user) + return render_template('account.html', + theme=theme, + accountInfo=_accountInfo, + form=form) @user.route("/reset_password", methods=['GET', 'POST']) diff --git a/web/minibase/blueprints/user/utils.py b/web/minibase/blueprints/user/utils.py index a7259424..46408f5b 100644 --- a/web/minibase/blueprints/user/utils.py +++ b/web/minibase/blueprints/user/utils.py @@ -6,6 +6,8 @@ from sqlalchemy import case def dbGetMailFirst(mail): return Users.query.filter_by(email_account=mail).first() +def queryMailById(id): + return (Users.query.filter_by(id=id).first()).email_comm def queryRoleById(id): return User_Roles.query.get_or_404(id) diff --git a/web/minibase/static/pics/aab9913add20a59d.png b/web/minibase/static/pics/aab9913add20a59d.png new file mode 100644 index 0000000000000000000000000000000000000000..c4f57038c58e0e8c55b3f16dc6dfb4aff4b10f90 GIT binary patch literal 4045 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