From 80b0d02b025ad7fafc3d8e95c7be7ba73bbd5755 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Tue, 21 Jan 2025 12:54:43 +0200 Subject: [PATCH 01/43] new changes --- AUTHORS | 2 ++ console.py | 8 ++++---- models/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 369 bytes models/__pycache__/amenity.cpython-312.pyc | Bin 0 -> 441 bytes models/__pycache__/base_model.cpython-312.pyc | Bin 0 -> 2906 bytes models/__pycache__/city.cpython-312.pyc | Bin 0 -> 511 bytes models/__pycache__/place.cpython-312.pyc | Bin 0 -> 697 bytes models/__pycache__/review.cpython-312.pyc | Bin 0 -> 536 bytes models/__pycache__/state.cpython-312.pyc | Bin 0 -> 464 bytes models/__pycache__/user.cpython-312.pyc | Bin 0 -> 558 bytes .../engine/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 156 bytes .../__pycache__/file_storage.cpython-312.pyc | Bin 0 -> 2977 bytes 12 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 models/__pycache__/__init__.cpython-312.pyc create mode 100644 models/__pycache__/amenity.cpython-312.pyc create mode 100644 models/__pycache__/base_model.cpython-312.pyc create mode 100644 models/__pycache__/city.cpython-312.pyc create mode 100644 models/__pycache__/place.cpython-312.pyc create mode 100644 models/__pycache__/review.cpython-312.pyc create mode 100644 models/__pycache__/state.cpython-312.pyc create mode 100644 models/__pycache__/user.cpython-312.pyc create mode 100644 models/engine/__pycache__/__init__.cpython-312.pyc create mode 100644 models/engine/__pycache__/file_storage.cpython-312.pyc diff --git a/AUTHORS b/AUTHORS index 6fb53b5277cf..5ebca7498776 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,3 +2,5 @@ Ezra Nobrega Justin Majetich +Manzi David +Isingizwe Keza Milka diff --git a/console.py b/console.py index 13a8af68e930..4ab26752f646 100755 --- a/console.py +++ b/console.py @@ -73,7 +73,7 @@ def precmd(self, line): pline = pline[2].strip() # pline is now str if pline: # check for *args or **kwargs - if pline[0] is '{' and pline[-1] is'}'\ + if pline[0] == '{' and pline[-1] == '}'\ and type(eval(pline)) is dict: _args = pline else: @@ -272,7 +272,7 @@ def do_update(self, args): args.append(v) else: # isolate args args = args[2] - if args and args[0] is '\"': # check for quoted arg + if args and args[0] == '\"': # check for quoted arg second_quote = args.find('\"', 1) att_name = args[1:second_quote] args = args[second_quote + 1:] @@ -280,10 +280,10 @@ def do_update(self, args): args = args.partition(' ') # if att_name was not quoted arg - if not att_name and args[0] is not ' ': + if not att_name and args[0] != ' ': att_name = args[0] # check for quoted val arg - if args[2] and args[2][0] is '\"': + if args[2] and args[2][0] == '\"': att_val = args[2][1:args[2].find('\"', 1)] # if att_val was not quoted arg diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c3b0f3c61159e58895d9a62ef16e461d788c8e9 GIT binary patch literal 369 zcmX@j%ge<81a~U?)3*WX#~=<2FhLogoq&w#3@Hpz3@MB$OgW6XOi@gX3``8EOskevp8WI5j0Gmk)e`VlcmZ$BqOs}AvZszG$&OdGq1QLF|Q;uu_U!vAu&%OKPf9U zxkMp9O(8iavA9^lEi)%IxFo+QF+KGq$V5%XTii%uewwVe*yH0<@{{A^Z%F~oOwB3Q zOU+Bq%uCfv18R*ghUhI~2I{@V4&~iqD@x7DPfS_K@EK(0FB500n9$yEjS>%-G6rY@vpO+e6W)uT4Iwn3oGcU6wK3=b&@)w5<#1D2w+(1JZfw))>NPJ*s kWMq8EV0)Lr=p!2gw^+As1N#jI_IAETzN-uZMWFBj0J!O79smFU literal 0 HcmV?d00001 diff --git a/models/__pycache__/amenity.cpython-312.pyc b/models/__pycache__/amenity.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..463e2597353dc0b6e0e2afbefd78de4794324096 GIT binary patch literal 441 zcmXv~Jxjzu5S`uJmv5#gesjn{}x2rMzX%E=}aUQ@gXs#A2?%fr4yT-;JhhFY*$+iDO!EQ;cCBbJ7WtuItY|Y9mJ^Y88N11R zInUIze}<_Rp6wp)dFP2xiI*XIzRb4!L*+yc3uGJ#cDv)DjF5?kO?pmmlq>y=5*kR7 zCc+rrI_CY6>Mk;RnI>aA4siZzCDFUU3-wk)D*dBMr=wZfXCj-m_N%oIls;HrpR6JL X7=(~d*!Y0W-v%Me55qq|S2q3wc;{^# literal 0 HcmV?d00001 diff --git a/models/__pycache__/base_model.cpython-312.pyc b/models/__pycache__/base_model.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b55dec37878e7cc590fa0fddc0c9eb48e6a6bae4 GIT binary patch literal 2906 zcma)8O-vg{6rTODSsceEf20_ZZej?S29j2!QYj>XL`fq8m71hdU84yC8&n0qg=Xk>Rwq(n^*xm8f95|{S9vDa%7SLsNec{B6g z%=4S?dvAZ$*MN08=5J{S#$* z)(tt8rtF2x%Y#bTteWCTNJ4TXcU&onE2XouL~$*5I(mtKBe|nv2^QsZt^aFL>ztDn68jw4 z9kayoha=N96{ps_I*yd(RiObUs_48quJpjlYwbL**m=+n?7h7tOA>E5cerDs(Ul!3 z%U60EkunYE4bzHQhNS~k5NC!qRRk7ASl;LC8q-SA*qCPf(vyfMRf$=dy)B<~v`log zsFzwk=x!P8Zn@amGHUzcR4ZxNwTi;fswhK|fbA{9f@1h>!L+C?rqjA=d$8}ad0nLf z+cHv96uCt)?6v^j*b=BuB8qKEQB*x{DT?ha`VtXs(bSTowiu&hrtSTF3P*N}iKvsI zZM}QCd-$@cQFAyA{ctRq?&#BLztIm40$Y@;?+h2c8%B;POzxbV#@lp5hubo{%gFC^ z*3dokTj*xVv*5lb{=@6_4R@NC+ZWrHj;z(U&Yih=ZvDXF<>X>=$$-g++a?A7p80_r z1GmM;{-)>QxANhxT)1oX;|CXV$Ilmz4{Qot^B^~O_Et~MFTZa8XD z9&<9OTecUH?L^F?b+AMCLKopFGTRp7Nz+7%$TG#hXV)kSI00zcRf!h1g!|?N=w`|D z;O=j_Zi`=cfB8i|*qjSC-@UjNjNChv3wGoKUAaKl>ZP?n_k*`{f!;Zx5NvXk?lu3= zdcSqG>!;oyd)I<}kEA||^xpQo=nZ?`5fGsAVAa7K%T?ys1k|gSTSb0E*07f45<48( z9UV=`bwWhU^j>Bu!Ia(9AW!MmxExPY3a=m|ZRM$P%_zTt48<)z9y7)?mAwH)NDM*j z{V+1-vP?jC;glr-(TrWyN?|WjyCUrLFz96hZpcyj0IZo9o>}sTbZ9+vX!*$Ek)_T# z@n*0f1?T-Y{9grL4Ig5Vh3_mYQ#v3Pf>7oN?3Nnf6+L*VIcVodbt{#tR_Lnmtz2;2 z3)FJjE*6kPH679MKxM^3FLM+;s>-EAxdgg5IS-uWR4*$qq*_6Jjb#n9E5#~FC09#J&0ucMLpMvF?%O}-D@eQZQbSH^xZS+mvDop8)aI_d zzutJ@j&=9UQfBF7zVTSD@!0B~wZ`MCBe}-+@}X0?(5Z)e*Ft9>Ude^d|0!^d1KeMP ztG&QI4Yz)O^1GAya8EAWvlc!v=Yv!)$%X$|4mLcJ8W>)OA`+G*BQ~Ky5%eiotl%>d zWWSj(bMV U{YG{?Ax(dKTe#2$fsR@J3tpmDrT_o{ literal 0 HcmV?d00001 diff --git a/models/__pycache__/city.cpython-312.pyc b/models/__pycache__/city.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cdf2aca54276da804a688138c7befcc9119052d GIT binary patch literal 511 zcmXw0F-ycS6i(V+Jx{CLq?2S2q@p4Yf+B+TKpnhEmr@9|iF%T2&!i{RNx{L*@qUB& zQ~U#WMF(+m6HXT=U)sAszW2T4z3;ueygE(|!FtP{E(TyfwKHCo5g9H6=^=)E#4s}i zZX3RVk%0~nGanGMxbb3^vA&sAT>Ex`?6=a494D+RI5|%wIrN$y>B!`YM=ANz!7k1x zy-;xo;vy>3OT;5*I1i+UIPx*nHW>CzX80EDN@luNZs{VoE9B&olStQ#M5xpXiIO-C zTd^W44O32z8YGMviNiK0IcmCgUZqrfl;$-`+eMSWrzySehGKLxK`BcjIIb2dw8e5u zUp=FtZtrh>e>*r;T&kc87=)s`y4R9k?9oUhF{d{h0Vs2!0^QnLCzE=d1=v8;EWiUA zSeyOX`rToF%DHdInQ=tZwWR)+yk2Uooxz}Vr(8%q=~BzltjN(~f7PAxDZ8=`t{$SA Z1Nb&E#vf?$9WDLXCZ2iR`bA)h#DC2kgERmD literal 0 HcmV?d00001 diff --git a/models/__pycache__/place.cpython-312.pyc b/models/__pycache__/place.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfb850751915af5458493538819357822fed5684 GIT binary patch literal 697 zcmXw1OK;RL5Vn)-`_bL)_8~Zs3qp%TB{-sj)CH-n3M(#LqLr*{Y|>PDEOvrOPpQ-c zH;(-ch@ZlRW3b?WIB`Q-xb(z0-dg&`-`F#r&mMp2_1Xx=_xz)Off4$poSRWwlhu77 zSBN49QA~{xM}}iyWS~Pt%}YcrW_&hvtYhZ2N&Wne{VH@lX1`2m7Bc%y!tJB!Y-%rg za>l&W{;i@XShl9FU=YMYPv>h3LaMRahv^D28W06 zMecjzXH2BBzvO|($Ra0k;Gd?l8M12pFN(x1_@%W zgv{MAdvFl&X*?w!Br@{u(H!o=LNTviU~ido)!NF`fruwyF3~sZcG({khuU;{#q)AB zE>6nLaq*(u+5Kvb%fYZXF1NOeS-CMPj>^F%xTEpK3E#OnZ#J>G`cZPIOYSY8!|Ewn y$kiXwmA4hEa(01TH}~~hKjpW;RoxeA^N)!!{)z7XK==OEyLjuv@jnDpmG~dT#KSEB literal 0 HcmV?d00001 diff --git a/models/__pycache__/review.cpython-312.pyc b/models/__pycache__/review.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2079022a1cadbaa2bbde018c0d847222c414337d GIT binary patch literal 536 zcmXw0y-wpm5Z<*NC;TLk6A}%@7AGMiK>-~?NcfPTAq5fzmZg>P4q&vg!`cBt6(ox5 zD0zm{J<7d6u%JLxbVz}Q>SnXaNHg=z&d$uYv;XS#X@c_HdpP?*|E7b9RK{Sqg5Z$| z5)eU!C289VEJ`f0M}&P(gag)J+uRN8Ud3~7f3ickO5mEcGtrg6PBX=db71>^%V!;x zT|iv0cU|Jqa>|c#ILHLZ*fcSgj)UP6f=2=*pvb@yG_ZvgIH(m=w`Y4!>6&r3-ehhp zqdYG%hN^%mLncX)M>{H#EM+BWdDXJUc^b8W^KzPV!xix?=a=0`jx$xxMHb_6ts|ot zcp}PbHwUGGQ@~B}hYU5<@AY4s;SnbCP^ZI4c2{>2<)=Q6WtIZJS`Tpq$UHQB);c|< zS3EKV@?X|6Xjn4k+*G)Aa=Hmv-h-DZz9T!5A3$zz8!0=^DO4 zz<^_5<_MU@jc2o{_06>6R)=fO`5+u{=PYK4;LcSnofEI)Iei)5@@U|E>uQ%|i(aTW z7I6_3{6dq`nXV!j0|%eraDx%wWQK30rfX%De8SK!Cq*Ju%E_SPRWpRXIO9v(})gx!yhr7Xr;!*_(>L3)!*1?VRdLE5L+~f3qC%}GO zs6gra+Wl1OC*`V&KO|?sfeCERvu{;ZSLCB; zfiBu9=}D@xyg(X*fyz3?KxhNIabzOK`e{!vX6lSN%7~{JJ1$cB=9yrO=UsdbMK8^y ziH@+5(_C>=-_MjDR2j@9w&&mtj4l6{?;9&^OHH>ei*_oDuj`p=^;@hf^S)pwKiXJP zNatTVDwUmiWoiiYJemvm8!V5eJ`FcVGmYWasL>q$8qLm~Z>!n&*xfi#c8#XtvMqIR zsI%84wr-A4tT6N8?sU}|S#Pw%1Pd*{!9v1$=;&Uw|&CBKgfJgQ572pS! ACjbBd literal 0 HcmV?d00001 diff --git a/models/engine/__pycache__/__init__.cpython-312.pyc b/models/engine/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b267e757d82cfd1b0d17c027f6f2499dcfac319 GIT binary patch literal 156 zcmX@j%ge<81a~U?(?RrO5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!vUawL2`x@7Dvl`y zk}-)nrMixpMNWB6@yR*)d8zSbMlrehDXBTdF{yd!nR%%(@$s2?nI-Y@dIgogIBbA& br8%i~MXW%x7=gGL#Q4a}$jDg43}gWS{8T3E literal 0 HcmV?d00001 diff --git a/models/engine/__pycache__/file_storage.cpython-312.pyc b/models/engine/__pycache__/file_storage.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4d3265600f97ef975d03e4447859fa2d6b1db31 GIT binary patch literal 2977 zcma)8U2Ggz6~1?Vc4qb`_BzD*aek)uChfS`r7;#2DIl*++t{f=H3-Er8f|uFlikej zxOc`jyV{lf(1%1I;y@)QxKfHhs!?A2gu)Xc@WxA5E%J6qBoO6+H^)Y@WL`Mu&W``e z19x}NJ@@aNbIxCjLd%nx~ zz-9W4Yn5xT%dOb|LV1(Z z72m0%1#K@G0>gL&$IN|~F-`Yc$@Bnz1X_Aw)BHGqbH}aJCwVImfAW?9(&|6A6&*9RadPKJPfS-jQi` zWIk3iTQEcN`|pZ|a*x~sW|`DUX}`a4JG6&kM@qQ!P^;6Dd}s=W(Fu#5gpnoGfWl6I z?co-#6zRjZUP`K>A=S>0SeB<(>;*k^8v-%{;a(sD%>*|AUQKg{4o(^p(?EU@o13+A zz8xsOYvSfWC|VE{1=mE7=b;C5ovC~RlpORQOmx7C_f;T^~toAf}h98N|o=cDNzc2i*(Cis|od5XL_+QishIx7bcX)5^Eo z{oPoUFcOEFMWd7*CJkC74WTZS@D_*KJ}G#mLv7Eqa2kPes70|FBR@Pr$P8H25F1im zDy0r>gkiL|F4V=>Vf>R*67kVlyp=j5Zm)-(ySJc#1pGv|f>;ZE5ZVMOLe&(t1FiFfznVl0-)9WGoYO}|7^sS z^oZN*t#||sfP38Ui&jdRh}-My@d(xpt*(_`+*^sb2&w>UIL~37Xe0$vSL;bDfn|x8 zrc{yClfR}vrBM2e=%HRUpw9gdh!>b!<{)QSBH+=`vN_Lw8(%woLGa0dUjD9=%iG9I`B3q2Wwhv5 zp;t!Ab|qwE@7VK2d%;kc4x-o#NP3Z=hZ#DTokwy3NI)4wBu)N?7~MfSe0m12fohZU zTttv)&*PKD<3o7=^Xp@kBX zZX{5tAblP19y^X>UiZ_OlasFhhC5fWzRj4+j1$P2uoT3YjV9E(_7{V24$pdj08&I-7Z}NJqbPOWBAkTAJ62r|Dzw-(2q=Xm$^*dY`0+Hi(#-plk0wJ>Iiiy<7b- z{qy>g)Y3B_#eW(9RT9cadV=14Yiab}(N_QH>WgcAYd4!0v(5g|X8-u(Jdk_R1NFYT z68~`M7ah+<+`cWN$Zan8Ij8^mw@Nx+0AX7Cvt%b!9xc7&;lH`xp3V-FKXi?xvWECX zS7GqPkh2$+CxasL7dai)MydEmLV->i@jx}r3WU})gSd$Rg1?%;Cr$I+xt!BpQB2cv z^QIXF7Hc$*ChI~D3kDlP@)8n!S-I;&C?Fp2fR_RC9{Ehlwz|$NPP96^7B6o~f_#2c z733>)Q&r@1TV369IuwA%43T{eIu4{z*g*w5>g%Ds-(;`BK76q~#2`3?(!Y~8|4I_u Nu`ko~CIQ05{uf|Eo2UQ) literal 0 HcmV?d00001 From ff0821303b847f501f2e9c629399d611d862fb6b Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Tue, 21 Jan 2025 13:10:44 +0200 Subject: [PATCH 02/43] new changes --- console.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/console.py b/console.py index 4ab26752f646..17142e83187d 100755 --- a/console.py +++ b/console.py @@ -115,13 +115,34 @@ def emptyline(self): def do_create(self, args): """ Create an object of any class""" + args = args.split() if not args: print("** class name missing **") return - elif args not in HBNBCommand.classes: + elif args[0] not in HBNBCommand.classes: print("** class doesn't exist **") return - new_instance = HBNBCommand.classes[args]() + + kwargs = {} + for arg in args[1:]: + if '=' in arg: + key, value = arg.split('=', 1) + key = key.replace('_', ' ') + if value[0] == '"': + value = value[1:-1].replace('\\"', '"') + elif '.' in value: + try: + value = float(value) + except ValueError: + continue + else: + try: + value = int(value) + except ValueError: + continue + kwargs[key] = value + + new_instance = HBNBCommand.classes[args[0]](**kwargs) storage.save() print(new_instance.id) storage.save() From ffc82703e76124026a0873ddc0f73a6fdcf678fe Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Tue, 21 Jan 2025 13:20:24 +0200 Subject: [PATCH 03/43] new changes --- console.py | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/console.py b/console.py index 17142e83187d..9bb3cfc1c83e 100755 --- a/console.py +++ b/console.py @@ -113,40 +113,40 @@ def emptyline(self): """ Overrides the emptyline method of CMD """ pass - def do_create(self, args): - """ Create an object of any class""" - args = args.split() - if not args: - print("** class name missing **") - return - elif args[0] not in HBNBCommand.classes: - print("** class doesn't exist **") - return + def do_create(self, line): + """Usage: create = = ... + Create a new class instance with given keys/values and print its id. + """ + try: + if not line: + raise SyntaxError() + my_list = line.split(" ") - kwargs = {} - for arg in args[1:]: - if '=' in arg: - key, value = arg.split('=', 1) - key = key.replace('_', ' ') + kwargs = {} + for i in range(1, len(my_list)): + key, value = tuple(my_list[i].split("=")) if value[0] == '"': - value = value[1:-1].replace('\\"', '"') - elif '.' in value: - try: - value = float(value) - except ValueError: - continue + value = value.strip('"').replace("_", " ") else: try: - value = int(value) - except ValueError: + value = eval(value) + except (SyntaxError, NameError): continue kwargs[key] = value - new_instance = HBNBCommand.classes[args[0]](**kwargs) - storage.save() - print(new_instance.id) - storage.save() + if kwargs == {}: + obj = eval(my_list[0])() + else: + obj = eval(my_list[0])(**kwargs) + storage.new(obj) + print(obj.id) + obj.save() + except SyntaxError: + print("** class name missing **") + except NameError: + print("** class doesn't exist **") + def help_create(self): """ Help information for the create method """ print("Creates a class of any type") From 5a2920d8822ee46a079e3ef5b24dde5108ac3a0d Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 12:30:45 +0200 Subject: [PATCH 04/43] Console file --- console.py | 617 +++++++++++++++++++++++------------------------------ 1 file changed, 272 insertions(+), 345 deletions(-) diff --git a/console.py b/console.py index 9bb3cfc1c83e..14404c83e445 100755 --- a/console.py +++ b/console.py @@ -1,345 +1,272 @@ -#!/usr/bin/python3 -""" Console Module """ -import cmd -import sys -from models.base_model import BaseModel -from models.__init__ import storage -from models.user import User -from models.place import Place -from models.state import State -from models.city import City -from models.amenity import Amenity -from models.review import Review - - -class HBNBCommand(cmd.Cmd): - """ Contains the functionality for the HBNB console""" - - # determines prompt for interactive/non-interactive modes - prompt = '(hbnb) ' if sys.__stdin__.isatty() else '' - - classes = { - 'BaseModel': BaseModel, 'User': User, 'Place': Place, - 'State': State, 'City': City, 'Amenity': Amenity, - 'Review': Review - } - dot_cmds = ['all', 'count', 'show', 'destroy', 'update'] - types = { - 'number_rooms': int, 'number_bathrooms': int, - 'max_guest': int, 'price_by_night': int, - 'latitude': float, 'longitude': float - } - - def preloop(self): - """Prints if isatty is false""" - if not sys.__stdin__.isatty(): - print('(hbnb)') - - def precmd(self, line): - """Reformat command line for advanced command syntax. - - Usage: .([ [<*args> or <**kwargs>]]) - (Brackets denote optional fields in usage example.) - """ - _cmd = _cls = _id = _args = '' # initialize line elements - - # scan for general formating - i.e '.', '(', ')' - if not ('.' in line and '(' in line and ')' in line): - return line - - try: # parse line left to right - pline = line[:] # parsed line - - # isolate - _cls = pline[:pline.find('.')] - - # isolate and validate - _cmd = pline[pline.find('.') + 1:pline.find('(')] - if _cmd not in HBNBCommand.dot_cmds: - raise Exception - - # if parantheses contain arguments, parse them - pline = pline[pline.find('(') + 1:pline.find(')')] - if pline: - # partition args: (, [], [<*args>]) - pline = pline.partition(', ') # pline convert to tuple - - # isolate _id, stripping quotes - _id = pline[0].replace('\"', '') - # possible bug here: - # empty quotes register as empty _id when replaced - - # if arguments exist beyond _id - pline = pline[2].strip() # pline is now str - if pline: - # check for *args or **kwargs - if pline[0] == '{' and pline[-1] == '}'\ - and type(eval(pline)) is dict: - _args = pline - else: - _args = pline.replace(',', '') - # _args = _args.replace('\"', '') - line = ' '.join([_cmd, _cls, _id, _args]) - - except Exception as mess: - pass - finally: - return line - - def postcmd(self, stop, line): - """Prints if isatty is false""" - if not sys.__stdin__.isatty(): - print('(hbnb) ', end='') - return stop - - def do_quit(self, command): - """ Method to exit the HBNB console""" - exit() - - def help_quit(self): - """ Prints the help documentation for quit """ - print("Exits the program with formatting\n") - - def do_EOF(self, arg): - """ Handles EOF to exit program """ - print() - exit() - - def help_EOF(self): - """ Prints the help documentation for EOF """ - print("Exits the program without formatting\n") - - def emptyline(self): - """ Overrides the emptyline method of CMD """ - pass - - def do_create(self, line): - """Usage: create = = ... - Create a new class instance with given keys/values and print its id. - """ - try: - if not line: - raise SyntaxError() - my_list = line.split(" ") - - kwargs = {} - for i in range(1, len(my_list)): - key, value = tuple(my_list[i].split("=")) - if value[0] == '"': - value = value.strip('"').replace("_", " ") - else: - try: - value = eval(value) - except (SyntaxError, NameError): - continue - kwargs[key] = value - - if kwargs == {}: - obj = eval(my_list[0])() - else: - obj = eval(my_list[0])(**kwargs) - storage.new(obj) - print(obj.id) - obj.save() - - except SyntaxError: - print("** class name missing **") - except NameError: - print("** class doesn't exist **") - - def help_create(self): - """ Help information for the create method """ - print("Creates a class of any type") - print("[Usage]: create \n") - - def do_show(self, args): - """ Method to show an individual object """ - new = args.partition(" ") - c_name = new[0] - c_id = new[2] - - # guard against trailing args - if c_id and ' ' in c_id: - c_id = c_id.partition(' ')[0] - - if not c_name: - print("** class name missing **") - return - - if c_name not in HBNBCommand.classes: - print("** class doesn't exist **") - return - - if not c_id: - print("** instance id missing **") - return - - key = c_name + "." + c_id - try: - print(storage._FileStorage__objects[key]) - except KeyError: - print("** no instance found **") - - def help_show(self): - """ Help information for the show command """ - print("Shows an individual instance of a class") - print("[Usage]: show \n") - - def do_destroy(self, args): - """ Destroys a specified object """ - new = args.partition(" ") - c_name = new[0] - c_id = new[2] - if c_id and ' ' in c_id: - c_id = c_id.partition(' ')[0] - - if not c_name: - print("** class name missing **") - return - - if c_name not in HBNBCommand.classes: - print("** class doesn't exist **") - return - - if not c_id: - print("** instance id missing **") - return - - key = c_name + "." + c_id - - try: - del(storage.all()[key]) - storage.save() - except KeyError: - print("** no instance found **") - - def help_destroy(self): - """ Help information for the destroy command """ - print("Destroys an individual instance of a class") - print("[Usage]: destroy \n") - - def do_all(self, args): - """ Shows all objects, or all objects of a class""" - print_list = [] - - if args: - args = args.split(' ')[0] # remove possible trailing args - if args not in HBNBCommand.classes: - print("** class doesn't exist **") - return - for k, v in storage._FileStorage__objects.items(): - if k.split('.')[0] == args: - print_list.append(str(v)) - else: - for k, v in storage._FileStorage__objects.items(): - print_list.append(str(v)) - - print(print_list) - - def help_all(self): - """ Help information for the all command """ - print("Shows all objects, or all of a class") - print("[Usage]: all \n") - - def do_count(self, args): - """Count current number of class instances""" - count = 0 - for k, v in storage._FileStorage__objects.items(): - if args == k.split('.')[0]: - count += 1 - print(count) - - def help_count(self): - """ """ - print("Usage: count ") - - def do_update(self, args): - """ Updates a certain object with new info """ - c_name = c_id = att_name = att_val = kwargs = '' - - # isolate cls from id/args, ex: (, delim, ) - args = args.partition(" ") - if args[0]: - c_name = args[0] - else: # class name not present - print("** class name missing **") - return - if c_name not in HBNBCommand.classes: # class name invalid - print("** class doesn't exist **") - return - - # isolate id from args - args = args[2].partition(" ") - if args[0]: - c_id = args[0] - else: # id not present - print("** instance id missing **") - return - - # generate key from class and id - key = c_name + "." + c_id - - # determine if key is present - if key not in storage.all(): - print("** no instance found **") - return - - # first determine if kwargs or args - if '{' in args[2] and '}' in args[2] and type(eval(args[2])) is dict: - kwargs = eval(args[2]) - args = [] # reformat kwargs into list, ex: [, , ...] - for k, v in kwargs.items(): - args.append(k) - args.append(v) - else: # isolate args - args = args[2] - if args and args[0] == '\"': # check for quoted arg - second_quote = args.find('\"', 1) - att_name = args[1:second_quote] - args = args[second_quote + 1:] - - args = args.partition(' ') - - # if att_name was not quoted arg - if not att_name and args[0] != ' ': - att_name = args[0] - # check for quoted val arg - if args[2] and args[2][0] == '\"': - att_val = args[2][1:args[2].find('\"', 1)] - - # if att_val was not quoted arg - if not att_val and args[2]: - att_val = args[2].partition(' ')[0] - - args = [att_name, att_val] - - # retrieve dictionary of current objects - new_dict = storage.all()[key] - - # iterate through attr names and values - for i, att_name in enumerate(args): - # block only runs on even iterations - if (i % 2 == 0): - att_val = args[i + 1] # following item is value - if not att_name: # check for att_name - print("** attribute name missing **") - return - if not att_val: # check for att_value - print("** value missing **") - return - # type cast as necessary - if att_name in HBNBCommand.types: - att_val = HBNBCommand.types[att_name](att_val) - - # update dictionary with name, value pair - new_dict.__dict__.update({att_name: att_val}) - - new_dict.save() # save updates to file - - def help_update(self): - """ Help information for the update class """ - print("Updates an object with new information") - print("Usage: update \n") - -if __name__ == "__main__": - HBNBCommand().cmdloop() +#!/usr/bin/python3 +"""Defines the HBNB console.""" +import cmd +from shlex import split +from models import storage +from datetime import datetime +from models.base_model import BaseModel +from models.user import User +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.place import Place +from models.review import Review + + +class HBNBCommand(cmd.Cmd): + """Defines the HolbertonBnB command interpreter.""" + + prompt = "(hbnb) " + __classes = { + "BaseModel", + "User", + "State", + "City", + "Amenity", + "Place", + "Review" + } + + def emptyline(self): + """Ignore empty spaces.""" + pass + + def do_quit(self, line): + """Quit command to exit the program.""" + return True + + def do_EOF(self, line): + """EOF signal to exit the program.""" + print("") + return True + + def do_create(self, line): + """Usage: create = = ... + Create a new class instance with given keys/values and print its id. + """ + try: + if not line: + raise SyntaxError() + my_list = line.split(" ") + + kwargs = {} + for i in range(1, len(my_list)): + key, value = tuple(my_list[i].split("=")) + if value[0] == '"': + value = value.strip('"').replace("_", " ") + else: + try: + value = eval(value) + except (SyntaxError, NameError): + continue + kwargs[key] = value + + if kwargs == {}: + obj = eval(my_list[0])() + else: + obj = eval(my_list[0])(**kwargs) + storage.new(obj) + print(obj.id) + obj.save() + + except SyntaxError: + print("** class name missing **") + except NameError: + print("** class doesn't exist **") + + def do_show(self, line): + """Prints the string representation of an instance + Exceptions: + SyntaxError: when there is no args given + NameError: when there is no object taht has the name + IndexError: when there is no id given + KeyError: when there is no valid id given + """ + try: + if not line: + raise SyntaxError() + my_list = line.split(" ") + if my_list[0] not in self.__classes: + raise NameError() + if len(my_list) < 2: + raise IndexError() + objects = storage.all() + key = my_list[0] + '.' + my_list[1] + if key in objects: + print(objects[key]) + else: + raise KeyError() + except SyntaxError: + print("** class name missing **") + except NameError: + print("** class doesn't exist **") + except IndexError: + print("** instance id missing **") + except KeyError: + print("** no instance found **") + + def do_destroy(self, line): + """Deletes an instance based on the class name and id + Exceptions: + SyntaxError: when there is no args given + NameError: when there is no object taht has the name + IndexError: when there is no id given + KeyError: when there is no valid id given + """ + try: + if not line: + raise SyntaxError() + my_list = line.split(" ") + if my_list[0] not in self.__classes: + raise NameError() + if len(my_list) < 2: + raise IndexError() + objects = storage.all() + key = my_list[0] + '.' + my_list[1] + if key in objects: + del objects[key] + storage.save() + else: + raise KeyError() + except SyntaxError: + print("** class name missing **") + except NameError: + print("** class doesn't exist **") + except IndexError: + print("** instance id missing **") + except KeyError: + print("** no instance found **") + + def do_all(self, line): + """Usage: all or all or .all() + Display string representations of all instances of a given class. + If no class is specified, displays all instantiated objects.""" + if not line: + o = storage.all() + print([o[k].__str__() for k in o]) + return + try: + args = line.split(" ") + if args[0] not in self.__classes: + raise NameError() + + o = storage.all(eval(args[0])) + print([o[k].__str__() for k in o]) + + except NameError: + print("** class doesn't exist **") + + def do_update(self, line): + """Updates an instanceby adding or updating attribute + Exceptions: + SyntaxError: when there is no args given + NameError: when there is no object taht has the name + IndexError: when there is no id given + KeyError: when there is no valid id given + AttributeError: when there is no attribute given + ValueError: when there is no value given + """ + try: + if not line: + raise SyntaxError() + my_list = split(line, " ") + if my_list[0] not in self.__classes: + raise NameError() + if len(my_list) < 2: + raise IndexError() + objects = storage.all() + key = my_list[0] + '.' + my_list[1] + if key not in objects: + raise KeyError() + if len(my_list) < 3: + raise AttributeError() + if len(my_list) < 4: + raise ValueError() + v = objects[key] + try: + v.__dict__[my_list[2]] = eval(my_list[3]) + except Exception: + v.__dict__[my_list[2]] = my_list[3] + v.save() + except SyntaxError: + print("** class name missing **") + except NameError: + print("** class doesn't exist **") + except IndexError: + print("** instance id missing **") + except KeyError: + print("** no instance found **") + except AttributeError: + print("** attribute name missing **") + except ValueError: + print("** value missing **") + + def count(self, line): + """count the number of instances of a class + """ + counter = 0 + try: + my_list = split(line, " ") + if my_list[0] not in self.__classes: + raise NameError() + objects = storage.all() + for key in objects: + name = key.split('.') + if name[0] == my_list[0]: + counter += 1 + print(counter) + except NameError: + print("** class doesn't exist **") + + def strip_clean(self, args): + """strips the argument and return a string of command + Args: + args: input list of args + Return: + returns string of argumetns + """ + new_list = [] + new_list.append(args[0]) + try: + my_dict = eval( + args[1][args[1].find('{'):args[1].find('}') + 1]) + except Exception: + my_dict = None + if isinstance(my_dict, dict): + new_str = args[1][args[1].find('(') + 1:args[1].find(')')] + new_list.append(((new_str.split(", "))[0]).strip('"')) + new_list.append(my_dict) + return new_list + new_str = args[1][args[1].find('(') + 1:args[1].find(')')] + new_list.append(" ".join(new_str.split(", "))) + return " ".join(i for i in new_list) + + def default(self, line): + """retrieve all instances of a class and + retrieve the number of instances + """ + my_list = line.split('.') + if len(my_list) >= 2: + if my_list[1] == "all()": + self.do_all(my_list[0]) + elif my_list[1] == "count()": + self.count(my_list[0]) + elif my_list[1][:4] == "show": + self.do_show(self.strip_clean(my_list)) + elif my_list[1][:7] == "destroy": + self.do_destroy(self.strip_clean(my_list)) + elif my_list[1][:6] == "update": + args = self.strip_clean(my_list) + if isinstance(args, list): + obj = storage.all() + key = args[0] + ' ' + args[1] + for k, v in args[2].items(): + self.do_update(key + ' "{}" "{}"'.format(k, v)) + else: + self.do_update(args) + else: + cmd.Cmd.default(self, line) + + +if __name__ == '__main__': + HBNBCommand().cmdloop() \ No newline at end of file From 1c0f0090690b387e656a88ada7699639dad4cb1c Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Wed, 22 Jan 2025 12:33:46 +0200 Subject: [PATCH 05/43] sql --- AUTHORS | 1 + setup_mysql_dev.sql | 6 ++++++ setup_mysql_test.sql | 6 ++++++ 3 files changed, 13 insertions(+) create mode 100644 setup_mysql_dev.sql create mode 100644 setup_mysql_test.sql diff --git a/AUTHORS b/AUTHORS index 5ebca7498776..eca56a3eeb6f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,3 +4,4 @@ Ezra Nobrega Justin Majetich Manzi David Isingizwe Keza Milka + diff --git a/setup_mysql_dev.sql b/setup_mysql_dev.sql new file mode 100644 index 000000000000..6633c40eaa3e --- /dev/null +++ b/setup_mysql_dev.sql @@ -0,0 +1,6 @@ +-- This file prepares MySQL server for the project +CREATE DATABASE IF NOT EXISTS hbnb_dev_db; +CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost' IDENTIFIED BY 'hbnb_dev_pwd'; +GRANT ALL PRIVILEGES ON hbnb_dev_db.* TO 'hbnb_dev'@'localhost'; +GRANT SELECT ON performance_schema.* TO 'hbnb_dev'@'localhost'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/setup_mysql_test.sql b/setup_mysql_test.sql new file mode 100644 index 000000000000..c9c3caa62665 --- /dev/null +++ b/setup_mysql_test.sql @@ -0,0 +1,6 @@ +-- a Mysql script to prepare +-- MySQL server for the project +CREATE DATABASE IF NOT EXISTS hbnb_test_db; +CREATE USER IF NOT EXISTS "hbnb_test"@"localhost" IDENTIFIED BY "hbnb_test_pwd"; +GRANT ALL PRIVILEGES ON hbnb_test_db.* TO "hbnb_test"@"localhost"; +GRANT SELECT ON performance_schema.* TO "hbnb_test"@"localhost"; \ No newline at end of file From 2ddf7efb67598c412df49b8d6de755cb651c3d81 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Wed, 22 Jan 2025 12:44:41 +0200 Subject: [PATCH 06/43] milka --- setup_mysql_dev.sql | 6 ++++++ setup_mysql_test.sql | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 setup_mysql_dev.sql create mode 100644 setup_mysql_test.sql diff --git a/setup_mysql_dev.sql b/setup_mysql_dev.sql new file mode 100644 index 000000000000..6633c40eaa3e --- /dev/null +++ b/setup_mysql_dev.sql @@ -0,0 +1,6 @@ +-- This file prepares MySQL server for the project +CREATE DATABASE IF NOT EXISTS hbnb_dev_db; +CREATE USER IF NOT EXISTS 'hbnb_dev'@'localhost' IDENTIFIED BY 'hbnb_dev_pwd'; +GRANT ALL PRIVILEGES ON hbnb_dev_db.* TO 'hbnb_dev'@'localhost'; +GRANT SELECT ON performance_schema.* TO 'hbnb_dev'@'localhost'; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/setup_mysql_test.sql b/setup_mysql_test.sql new file mode 100644 index 000000000000..c9c3caa62665 --- /dev/null +++ b/setup_mysql_test.sql @@ -0,0 +1,6 @@ +-- a Mysql script to prepare +-- MySQL server for the project +CREATE DATABASE IF NOT EXISTS hbnb_test_db; +CREATE USER IF NOT EXISTS "hbnb_test"@"localhost" IDENTIFIED BY "hbnb_test_pwd"; +GRANT ALL PRIVILEGES ON hbnb_test_db.* TO "hbnb_test"@"localhost"; +GRANT SELECT ON performance_schema.* TO "hbnb_test"@"localhost"; \ No newline at end of file From 9db76c93bf0408d06af048bee940fbddaf0c274b Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 13:02:28 +0200 Subject: [PATCH 07/43] Console file updated --- console.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/console.py b/console.py index 14404c83e445..8726884cb2ba 100755 --- a/console.py +++ b/console.py @@ -269,4 +269,5 @@ def default(self, line): if __name__ == '__main__': - HBNBCommand().cmdloop() \ No newline at end of file + HBNBCommand().cmdloop() + \ No newline at end of file From 3d89dd12c0d483b084317cdd7a864715196326e3 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 13:15:20 +0200 Subject: [PATCH 08/43] Console file updated --- console.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/console.py b/console.py index 8726884cb2ba..dc52202b572b 100755 --- a/console.py +++ b/console.py @@ -40,14 +40,14 @@ def do_EOF(self, line): print("") return True - def do_create(self, line): + def do_create(self, arg): """Usage: create = = ... Create a new class instance with given keys/values and print its id. """ try: - if not line: + if not arg: raise SyntaxError() - my_list = line.split(" ") + my_list = arg.split(" ") kwargs = {} for i in range(1, len(my_list)): @@ -61,6 +61,8 @@ def do_create(self, line): continue kwargs[key] = value + kwargs['updated_at'] = datetime.now() + if kwargs == {}: obj = eval(my_list[0])() else: @@ -270,4 +272,3 @@ def default(self, line): if __name__ == '__main__': HBNBCommand().cmdloop() - \ No newline at end of file From d003874795ff806f4c83162a2e31d149ca6672d6 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 13:59:39 +0200 Subject: [PATCH 09/43] Console file updated --- console.py | 540 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 310 insertions(+), 230 deletions(-) diff --git a/console.py b/console.py index dc52202b572b..8a4369fbbc51 100755 --- a/console.py +++ b/console.py @@ -1,274 +1,354 @@ #!/usr/bin/python3 -"""Defines the HBNB console.""" +""" Console Module """ import cmd -from shlex import split -from models import storage -from datetime import datetime +import sys +import models from models.base_model import BaseModel from models.user import User +from models.place import Place from models.state import State from models.city import City from models.amenity import Amenity -from models.place import Place from models.review import Review +from models.__init__ import storage class HBNBCommand(cmd.Cmd): - """Defines the HolbertonBnB command interpreter.""" - - prompt = "(hbnb) " - __classes = { - "BaseModel", - "User", - "State", - "City", - "Amenity", - "Place", - "Review" - } + """ Contains the functionality for the HBNB console""" - def emptyline(self): - """Ignore empty spaces.""" - pass + # determines prompt for interactive/non-interactive modes + prompt = '(hbnb) ' if sys.__stdin__.isatty() else '' + + classes = { + 'BaseModel': BaseModel, 'User': User, 'Place': Place, + 'State': State, 'City': City, 'Amenity': Amenity, + 'Review': Review + } + dot_cmds = ['all', 'count', 'show', 'destroy', 'update'] + types = { + 'number_rooms': int, 'number_bathrooms': int, + 'max_guest': int, 'price_by_night': int, + 'latitude': float, 'longitude': float + } - def do_quit(self, line): - """Quit command to exit the program.""" - return True + def preloop(self): + """Prints if isatty is false""" + if not sys.__stdin__.isatty(): + print('(hbnb)') - def do_EOF(self, line): - """EOF signal to exit the program.""" - print("") - return True + def precmd(self, line): + """Reformat command line for advanced command syntax. - def do_create(self, arg): - """Usage: create = = ... - Create a new class instance with given keys/values and print its id. + Usage: .([ [<*args> or <**kwargs>]]) + (Brackets denote optional fields in usage example.) """ - try: - if not arg: - raise SyntaxError() - my_list = arg.split(" ") - - kwargs = {} - for i in range(1, len(my_list)): - key, value = tuple(my_list[i].split("=")) - if value[0] == '"': - value = value.strip('"').replace("_", " ") - else: - try: - value = eval(value) - except (SyntaxError, NameError): - continue - kwargs[key] = value - - kwargs['updated_at'] = datetime.now() - - if kwargs == {}: - obj = eval(my_list[0])() - else: - obj = eval(my_list[0])(**kwargs) - storage.new(obj) - print(obj.id) - obj.save() + _cmd = _cls = _id = _args = '' # initialize line elements + + # scan for general formating - i.e '.', '(', ')' + if not ('.' in line and '(' in line and ')' in line): + return line + + try: # parse line left to right + pline = line[:] # parsed line + + # isolate + _cls = pline[:pline.find('.')] + + # isolate and validate + _cmd = pline[pline.find('.') + 1:pline.find('(')] + if _cmd not in HBNBCommand.dot_cmds: + raise Exception + + # if parantheses contain arguments, parse them + pline = pline[pline.find('(') + 1:pline.find(')')] + if pline: + # partition args: (, [], [<*args>]) + pline = pline.partition(', ') # pline convert to tuple + + # isolate _id, stripping quotes + _id = pline[0].replace('\"', '') + # possible bug here: + # empty quotes register as empty _id when replaced + + # if arguments exist beyond _id + pline = pline[2].strip() # pline is now str + if pline: + # check for *args or **kwargs + if pline[0] == '{' and pline[-1] == '}'\ + and type(eval(pline)) == dict: + _args = pline + else: + _args = pline.replace(',', '') + # _args = _args.replace('\"', '') + line = ' '.join([_cmd, _cls, _id, _args]) + + except Exception as mess: + pass + finally: + return line + + def postcmd(self, stop, line): + """Prints if isatty is false""" + if not sys.__stdin__.isatty(): + print('(hbnb) ', end='') + return stop + + def do_quit(self, command): + """ Method to exit the HBNB console""" + exit() + + def help_quit(self): + """ Prints the help documentation for quit """ + print("Exits the program with formatting\n") + + def do_EOF(self, arg): + """ Handles EOF to exit program """ + print() + exit() + + def help_EOF(self): + """ Prints the help documentation for EOF """ + print("Exits the program without formatting\n") - except SyntaxError: + def emptyline(self): + """ Overrides the emptyline method of CMD """ + pass + + def do_create(self, args): + """ Create an object of any class""" + if len(args) < 1: print("** class name missing **") - except NameError: - print("** class doesn't exist **") + return + # convert the args to a list + args = args.split() - def do_show(self, line): - """Prints the string representation of an instance - Exceptions: - SyntaxError: when there is no args given - NameError: when there is no object taht has the name - IndexError: when there is no id given - KeyError: when there is no valid id given - """ - try: - if not line: - raise SyntaxError() - my_list = line.split(" ") - if my_list[0] not in self.__classes: - raise NameError() - if len(my_list) < 2: - raise IndexError() - objects = storage.all() - key = my_list[0] + '.' + my_list[1] - if key in objects: - print(objects[key]) + # the 1st element of the list is the class name + class_name = args[0] + print(class_name) + if class_name not in self.classes: + print("** class doesn't exist **") + return + new_instance = self.classes[class_name]() + for params in args[1:]: + if "=" not in params: + continue + key, value = params.split('=') + value = value.replace('_', ' ') + if value.startswith('"') and value.endswith('"'): + value = value[1:-1].replace('\\"', '"') + elif '.' in value: + try: + value = float(value) + except ValueError: + continue else: - raise KeyError() - except SyntaxError: + try: + value = int(value) + except ValueError: + continue + + if value is not None and value != "" and hasattr( + new_instance, key): + setattr(new_instance, key, value) + + print(new_instance.id) + new_instance.save() + + def help_create(self): + """ Help information for the create method """ + print("Creates a class of any type") + print("[Usage]: create \n") + + def do_show(self, args): + """ Method to show an individual object """ + new = args.partition(" ") + c_name = new[0] + c_id = new[2] + + # guard against trailing args + if c_id and ' ' in c_id: + c_id = c_id.partition(' ')[0] + + if not c_name: print("** class name missing **") - except NameError: + return + + if c_name not in HBNBCommand.classes: print("** class doesn't exist **") - except IndexError: + return + + if not c_id: print("** instance id missing **") + return + + key = c_name + "." + c_id + try: + print(storage._FileStorage__objects[key]) except KeyError: print("** no instance found **") - def do_destroy(self, line): - """Deletes an instance based on the class name and id - Exceptions: - SyntaxError: when there is no args given - NameError: when there is no object taht has the name - IndexError: when there is no id given - KeyError: when there is no valid id given - """ - try: - if not line: - raise SyntaxError() - my_list = line.split(" ") - if my_list[0] not in self.__classes: - raise NameError() - if len(my_list) < 2: - raise IndexError() - objects = storage.all() - key = my_list[0] + '.' + my_list[1] - if key in objects: - del objects[key] - storage.save() - else: - raise KeyError() - except SyntaxError: + def help_show(self): + """ Help information for the show command """ + print("Shows an individual instance of a class") + print("[Usage]: show \n") + + def do_destroy(self, args): + """ Destroys a specified object """ + new = args.partition(" ") + c_name = new[0] + c_id = new[2] + if c_id and ' ' in c_id: + c_id = c_id.partition(' ')[0] + + if not c_name: print("** class name missing **") - except NameError: + return + + if c_name not in HBNBCommand.classes: print("** class doesn't exist **") - except IndexError: + return + + if not c_id: print("** instance id missing **") + return + + key = c_name + "." + c_id + + try: + del (storage.all()[key]) + storage.save() except KeyError: print("** no instance found **") - def do_all(self, line): - """Usage: all or all or .all() - Display string representations of all instances of a given class. - If no class is specified, displays all instantiated objects.""" - if not line: - o = storage.all() - print([o[k].__str__() for k in o]) - return - try: - args = line.split(" ") - if args[0] not in self.__classes: - raise NameError() + def help_destroy(self): + """ Help information for the destroy command """ + print("Destroys an individual instance of a class") + print("[Usage]: destroy \n") - o = storage.all(eval(args[0])) - print([o[k].__str__() for k in o]) + def do_all(self, args): + """ Shows all objects, or all objects of a class""" + print_list = [] - except NameError: - print("** class doesn't exist **") + if args: + args = args.split(' ')[0] # remove possible trailing args + if args not in HBNBCommand.classes: + print("** class doesn't exist **") + return + for k, v in storage.all().items(): + if k.split('.')[0] == args: + print_list.append(str(v)) + else: + for k, v in storage.all().items(): + print_list.append(str(v)) - def do_update(self, line): - """Updates an instanceby adding or updating attribute - Exceptions: - SyntaxError: when there is no args given - NameError: when there is no object taht has the name - IndexError: when there is no id given - KeyError: when there is no valid id given - AttributeError: when there is no attribute given - ValueError: when there is no value given - """ - try: - if not line: - raise SyntaxError() - my_list = split(line, " ") - if my_list[0] not in self.__classes: - raise NameError() - if len(my_list) < 2: - raise IndexError() - objects = storage.all() - key = my_list[0] + '.' + my_list[1] - if key not in objects: - raise KeyError() - if len(my_list) < 3: - raise AttributeError() - if len(my_list) < 4: - raise ValueError() - v = objects[key] - try: - v.__dict__[my_list[2]] = eval(my_list[3]) - except Exception: - v.__dict__[my_list[2]] = my_list[3] - v.save() - except SyntaxError: + print(print_list) + + def help_all(self): + """ Help information for the all command """ + print("Shows all objects, or all of a class") + print("[Usage]: all \n") + + def do_count(self, args): + """Count current number of class instances""" + count = 0 + for k, v in storage._FileStorage__objects.items(): + if args == k.split('.')[0]: + count += 1 + print(count) + + def help_count(self): + """ """ + print("Usage: count ") + + def do_update(self, args): + """ Updates a certain object with new info """ + c_name = c_id = att_name = att_val = kwargs = '' + + # isolate cls from id/args, ex: (, delim, ) + args = args.partition(" ") + if args[0]: + c_name = args[0] + else: # class name not present print("** class name missing **") - except NameError: + return + if c_name not in HBNBCommand.classes: # class name invalid print("** class doesn't exist **") - except IndexError: + return + + # isolate id from args + args = args[2].partition(" ") + if args[0]: + c_id = args[0] + else: # id not present print("** instance id missing **") - except KeyError: + return + + # generate key from class and id + key = c_name + "." + c_id + + # determine if key is present + if key not in storage.all(): print("** no instance found **") - except AttributeError: - print("** attribute name missing **") - except ValueError: - print("** value missing **") + return - def count(self, line): - """count the number of instances of a class - """ - counter = 0 - try: - my_list = split(line, " ") - if my_list[0] not in self.__classes: - raise NameError() - objects = storage.all() - for key in objects: - name = key.split('.') - if name[0] == my_list[0]: - counter += 1 - print(counter) - except NameError: - print("** class doesn't exist **") + # first determine if kwargs or args + if '{' in args[2] and '}' in args[2] and type(eval(args[2])) is dict: + kwargs = eval(args[2]) + args = [] # reformat kwargs into list, ex: [, , ...] + for k, v in kwargs.items(): + args.append(k) + args.append(v) + else: # isolate args + args = args[2] + if args and args[0] == '\"': # check for quoted arg + second_quote = args.find('\"', 1) + att_name = args[1:second_quote] + args = args[second_quote + 1:] - def strip_clean(self, args): - """strips the argument and return a string of command - Args: - args: input list of args - Return: - returns string of argumetns - """ - new_list = [] - new_list.append(args[0]) - try: - my_dict = eval( - args[1][args[1].find('{'):args[1].find('}') + 1]) - except Exception: - my_dict = None - if isinstance(my_dict, dict): - new_str = args[1][args[1].find('(') + 1:args[1].find(')')] - new_list.append(((new_str.split(", "))[0]).strip('"')) - new_list.append(my_dict) - return new_list - new_str = args[1][args[1].find('(') + 1:args[1].find(')')] - new_list.append(" ".join(new_str.split(", "))) - return " ".join(i for i in new_list) - - def default(self, line): - """retrieve all instances of a class and - retrieve the number of instances - """ - my_list = line.split('.') - if len(my_list) >= 2: - if my_list[1] == "all()": - self.do_all(my_list[0]) - elif my_list[1] == "count()": - self.count(my_list[0]) - elif my_list[1][:4] == "show": - self.do_show(self.strip_clean(my_list)) - elif my_list[1][:7] == "destroy": - self.do_destroy(self.strip_clean(my_list)) - elif my_list[1][:6] == "update": - args = self.strip_clean(my_list) - if isinstance(args, list): - obj = storage.all() - key = args[0] + ' ' + args[1] - for k, v in args[2].items(): - self.do_update(key + ' "{}" "{}"'.format(k, v)) - else: - self.do_update(args) - else: - cmd.Cmd.default(self, line) + args = args.partition(' ') + + # if att_name was not quoted arg + if not att_name and args[0] != ' ': + att_name = args[0] + # check for quoted val arg + if args[2] and args[2][0] == '\"': + att_val = args[2][1:args[2].find('\"', 1)] + + # if att_val was not quoted arg + if not att_val and args[2]: + att_val = args[2].partition(' ')[0] + + args = [att_name, att_val] + + # retrieve dictionary of current objects + new_dict = storage.all()[key] + + # iterate through attr names and values + for i, att_name in enumerate(args): + # block only runs on even iterations + if (i % 2 == 0): + att_val = args[i + 1] # following item is value + if not att_name: # check for att_name + print("** attribute name missing **") + return + if not att_val: # check for att_value + print("** value missing **") + return + # type cast as necessary + if att_name in HBNBCommand.types: + att_val = HBNBCommand.types[att_name](att_val) + + # update dictionary with name, value pair + new_dict.__dict__.update({att_name: att_val}) + + new_dict.save() # save updates to file + + def help_update(self): + """ Help information for the update class """ + print("Updates an object with new information") + print("Usage: update \n") -if __name__ == '__main__': +if __name__ == "__main__": HBNBCommand().cmdloop() + \ No newline at end of file From e3fd7021b604725209625377d2e8b6d0f2c761a4 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 15:29:26 +0200 Subject: [PATCH 10/43] FileStorageUpdated --- models/engine/file_storage.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index 6f5d7f8d4680..e76e5bc1c96b 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -48,3 +48,14 @@ def reload(self): self.all()[key] = classes[val['__class__']](**val) except FileNotFoundError: pass + + def delete(self, obj=None): + """Delete obj from __objects if it's inside""" + if obj is not None: + key = obj.__class__.__name__ + '.' + obj.id + if key in self.__objects: + del self.__objects[key] + self.save() + + else: + pass From 8d21aba90538f6a45916eed67a3e787b2ece3fb3 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Wed, 22 Jan 2025 15:40:19 +0200 Subject: [PATCH 11/43] push --- console.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/console.py b/console.py index 8a4369fbbc51..d8ea66ae166e 100755 --- a/console.py +++ b/console.py @@ -348,7 +348,5 @@ def help_update(self): print("Updates an object with new information") print("Usage: update \n") - if __name__ == "__main__": - HBNBCommand().cmdloop() - \ No newline at end of file + HBNBCommand().cmdloop() \ No newline at end of file From 129c6b686f9e64cbb7dacf40c7382b0bd07507b5 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 15:41:13 +0200 Subject: [PATCH 12/43] FileStorageUpdated --- models/engine/file_storage.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index e76e5bc1c96b..4ed6c412d031 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -8,10 +8,16 @@ class FileStorage: __file_path = 'file.json' __objects = {} - def all(self): + def all(self, cls=None): """Returns a dictionary of models currently in storage""" - return FileStorage.__objects - + if cls is None: + return FileStorage.__objects + else: + new_dict = {} + for key, value in FileStorage.__objects.items(): + if cls == value.__class__ or cls == value.__class__.__name__: + new_dict[key] = value + return new_dict def new(self, obj): """Adds new object to storage dictionary""" self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) From 6589a0c0ed5b56919f50d3c6d61546719f1415c2 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Wed, 22 Jan 2025 15:53:47 +0200 Subject: [PATCH 13/43] push --- console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console.py b/console.py index d8ea66ae166e..b0aaf251ad83 100755 --- a/console.py +++ b/console.py @@ -348,5 +348,5 @@ def help_update(self): print("Updates an object with new information") print("Usage: update \n") -if __name__ == "__main__": +if __name__ == "__main__": HBNBCommand().cmdloop() \ No newline at end of file From 860a9cbe366b46c8b6327d3292f7ef643ae86d44 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 16:17:49 +0200 Subject: [PATCH 14/43] Console file updated --- console.py | 1 - 1 file changed, 1 deletion(-) diff --git a/console.py b/console.py index 8a4369fbbc51..7de314a80a8b 100755 --- a/console.py +++ b/console.py @@ -351,4 +351,3 @@ def help_update(self): if __name__ == "__main__": HBNBCommand().cmdloop() - \ No newline at end of file From cc08aa09c30ab9a927a06faf6242cb32e5a3fd0d Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 16:22:33 +0200 Subject: [PATCH 15/43] FileStorageUpdated --- models/engine/file_storage.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index 4ed6c412d031..68b437d83670 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -18,6 +18,7 @@ def all(self, cls=None): if cls == value.__class__ or cls == value.__class__.__name__: new_dict[key] = value return new_dict + def new(self, obj): """Adds new object to storage dictionary""" self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) @@ -51,7 +52,7 @@ def reload(self): with open(FileStorage.__file_path, 'r') as f: temp = json.load(f) for key, val in temp.items(): - self.all()[key] = classes[val['__class__']](**val) + self.all()[key] = classes[val['__class__']](**val) except FileNotFoundError: pass From b894e3906c47d1b79caf6e0389761679082bf284 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Wed, 22 Jan 2025 16:24:14 +0200 Subject: [PATCH 16/43] FileStorageUpdated --- models/engine/file_storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index 68b437d83670..b56870811dc4 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -18,7 +18,7 @@ def all(self, cls=None): if cls == value.__class__ or cls == value.__class__.__name__: new_dict[key] = value return new_dict - + def new(self, obj): """Adds new object to storage dictionary""" self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) From 573f71f4c4a54d1ad579d39c3ca1c8fbb27e319a Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Wed, 22 Jan 2025 18:10:11 +0200 Subject: [PATCH 17/43] push --- console.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console.py b/console.py index b0aaf251ad83..920f572c01e0 100755 --- a/console.py +++ b/console.py @@ -349,4 +349,4 @@ def help_update(self): print("Usage: update \n") if __name__ == "__main__": - HBNBCommand().cmdloop() \ No newline at end of file + HBNBCommand().cmdloop() From 6c9cd68571433462b8c17db1bdc16b09fb19ad7d Mon Sep 17 00:00:00 2001 From: milkakeza Date: Thu, 23 Jan 2025 14:29:28 +0200 Subject: [PATCH 18/43] BaseModelUpdated --- models/base_model.py | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/models/base_model.py b/models/base_model.py index 4856e9de421f..a0c1e57e101a 100644 --- a/models/base_model.py +++ b/models/base_model.py @@ -4,8 +4,13 @@ from datetime import datetime +Base = declare_base() + class BaseModel: """A base class for all hbnb models""" + id = Column(String(60), nullable=False, primary_key=True) + created_at = Column(DateTime, nullable=False, default=datetime.utcnow()) + updated_at = Column(DateTime, nullable=False, default=datetime.utcnow()) def __init__(self, *args, **kwargs): """Instatntiates a new model""" if not kwargs: @@ -13,14 +18,23 @@ def __init__(self, *args, **kwargs): self.id = str(uuid.uuid4()) self.created_at = datetime.now() self.updated_at = datetime.now() - storage.new(self) - else: - kwargs['updated_at'] = datetime.strptime(kwargs['updated_at'], - '%Y-%m-%dT%H:%M:%S.%f') - kwargs['created_at'] = datetime.strptime(kwargs['created_at'], - '%Y-%m-%dT%H:%M:%S.%f') + + if kwargs: + if "id" not in kwargs: + kwargs["id"] = str(uuid.uuid4()) + if "created_at" not in kwargs: + kwargs["created_at"] = datetime.utcnow().isoformat() + if"updated_at" not in kwargs: + kwargs["updated_at"] = datetime.utcnow().isoformat() + for key, value in kwargs.items(): + if key == "created_at" or key == "updated_at": + value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") + if key != "__class__": + setattr(self, key, value) + + if '__class__' in kwargs: del kwargs['__class__'] - self.__dict__.update(kwargs) + self.__dict__.update(kwargs) def __str__(self): """Returns a string representation of the instance""" @@ -31,14 +45,24 @@ def save(self): """Updates updated_at with current time when instance is changed""" from models import storage self.updated_at = datetime.now() + storage.new(self) storage.save() def to_dict(self): """Convert instance into dict format""" dictionary = {} dictionary.update(self.__dict__) + for key in self.__dict__.keys(): + if key == "_sa_instance_state": + del (dictionary[key]) dictionary.update({'__class__': (str(type(self)).split('.')[-1]).split('\'')[0]}) dictionary['created_at'] = self.created_at.isoformat() dictionary['updated_at'] = self.updated_at.isoformat() return dictionary + + def delete(self): + """Deletes the current instance from storage""" + from models import storage + storage.delete(self) + storage.save() From b983997609e2adeb918692ba616064c7a6c47495 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Thu, 23 Jan 2025 14:30:55 +0200 Subject: [PATCH 19/43] CityFileUpdated --- models/city.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/models/city.py b/models/city.py index b9b4fe221502..41ed4b3f1c40 100644 --- a/models/city.py +++ b/models/city.py @@ -1,9 +1,13 @@ #!/usr/bin/python3 """ City Module for HBNB project """ from models.base_model import BaseModel +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship -class City(BaseModel): +class City(BaseModel, Base): """ The city class, contains state ID and name """ - state_id = "" - name = "" + __tablename__ = 'cities' + + name = Column(String(128), nullable=False) + state_id = Column(String(60), nullable=Fallse, ForeignKey="states.id") From bf635797a63631a0632510c9b4766e96e613b249 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Thu, 23 Jan 2025 14:31:43 +0200 Subject: [PATCH 20/43] StateFileUpdated --- models/state.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/models/state.py b/models/state.py index 583f041f07e4..03836a664c22 100644 --- a/models/state.py +++ b/models/state.py @@ -1,8 +1,26 @@ #!/usr/bin/python3 """ State Module for HBNB project """ from models.base_model import BaseModel +from models.city import City +import os +import models +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship -class State(BaseModel): +class State(BaseModel, Base): """ State class """ - name = "" + __tablename__ = 'states' + name = Column(String(128), nukllable=False) + + if os.getenv("HBNB_TYPE_STORAGE") == "db": + cities = relationship("City", backref="state", cascade="all, delete-orphan") + + else: + @property + def cities(self): + """returns the list of City instances with state_id equals to the + current State.id + """ + return [city for city in list(models.storage.all(City).values()) + if city.state_id == self.id] \ No newline at end of file From 9ebf1e6ac1d202ab768e664e1f8555dc2ec4e3c2 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Thu, 23 Jan 2025 14:32:25 +0200 Subject: [PATCH 21/43] InitFileUpdated --- models/__init__.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/models/__init__.py b/models/__init__.py index d3765c2bc603..5cea926767d0 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,7 +1,14 @@ #!/usr/bin/python3 """This module instantiates an object of class FileStorage""" -from models.engine.file_storage import FileStorage +from os import getenv -storage = FileStorage() -storage.reload() +if getenv('HBNB_TYPE_STORAGE') == 'db': + from models.engine.db_storage import DBStorage + + storage = DBStorage() + storage.reload() +else: + from models.engine.file_storage import FileStorage + storage = FileStorage() + storage.reload() From 427262e0f1421f6a19777db7f79cedf7a96265e9 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Thu, 23 Jan 2025 14:33:00 +0200 Subject: [PATCH 22/43] DataBaseStorage --- models/engine/db_storage.py | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 models/engine/db_storage.py diff --git a/models/engine/db_storage.py b/models/engine/db_storage.py new file mode 100644 index 000000000000..10a533cca1e7 --- /dev/null +++ b/models/engine/db_storage.py @@ -0,0 +1,75 @@ +#!/usr/bin/python3 +"""This module defines a class to manage database storage for hbnb clone""" + +from os import getenv +from models.base_model import Base +from models.base_model import BaseModel +from models.user import User +from models.place import Place +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.review import Review +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + + +class DBStorage: + """This class manages storage for hbnb clone""" + __engine = None + __session = None + + def __init__(self): + """Initializes a new DBStorage instance""" + self.__engine = create_engine( + 'mysql+mysqldb://{}:{}@localhost:3306/{}'.format( + getenv('HBNB_MYSQL_USER'), + getenv('HBNB_MYSQL_PWD'), + getenv('HBNB_MYSQL_HOST'), + getenv('HBNB_MYSQL_DB'), + pool_pre_ping=True + ) + ) + + if os.getenv('HBNB_ENV') == 'test': + Base.metadata.drop_all(self._engine) + + def all(self, cls=None): + """Returns a dictionary of all objects""" + classes = [User, State, City, Place, Amenity, Review] + new_dict = {} + if cls is None: + for c in classes: + for obj in self._session.query(c).all(): + key = obj.__class__.__name__ + '.' + obj.id + new_dict[key] = obj + else: + for obj in self._session.query(cls).all(): + key = obj.__class__.__name__ + '.' + obj.id + new_dict[key] = obj + return new_dict + + def new(self, obj): + """Adds a new object to the database""" + self._session.add(obj) + + def save(self): + """Saves all changes to the database""" + self._session.commit() + + def delete(self, obj=None): + """Deletes an object from the database""" + if obj is not None: + self._session.delete(obj) + + def reload(self): + """Reloads all tables""" + Base.metadata.create_all(self._engine) + session_factory = sessionmaker(bind=self._engine, + expire_on_commit=False) + Session = scoped_session(session_factory) + self._session = Session() + + def close(self): + """Close the session""" + self._session.close() From d1511a19c03ce0e0909d0bbd5dd44e149a907956 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Thu, 23 Jan 2025 14:46:17 +0200 Subject: [PATCH 23/43] UserFileUpdated --- models/user.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/models/user.py b/models/user.py index 4b54a6d24120..5c6d36edfb21 100644 --- a/models/user.py +++ b/models/user.py @@ -1,11 +1,17 @@ #!/usr/bin/python3 """This module defines a class User""" from models.base_model import BaseModel +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship -class User(BaseModel): +class User(BaseModel, Base): """This class defines a user by various attributes""" - email = '' - password = '' - first_name = '' - last_name = '' + __tablename__ = 'users' + email = Column(String(128), nullable=False) + password = Column(String(128), nullable=False) + first_name = Column(String(128), nullable=True) + last_name = Column(String(128), nullable=True) + places = relationship("Place", backref="user", cascade="all, delete") + reviews = relationship("Review", backref="user", cascade="all, delete") + \ No newline at end of file From 50824f9e687db201a0430af502f07a90e63b573e Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Fri, 24 Jan 2025 00:51:56 +0200 Subject: [PATCH 24/43] push --- console.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/console.py b/console.py index 7de314a80a8b..861e1fd1fce9 100755 --- a/console.py +++ b/console.py @@ -183,7 +183,7 @@ def do_show(self, args): key = c_name + "." + c_id try: - print(storage._FileStorage__objects[key]) + print(storage.all()[key]) except KeyError: print("** no instance found **") @@ -251,7 +251,7 @@ def help_all(self): def do_count(self, args): """Count current number of class instances""" count = 0 - for k, v in storage._FileStorage__objects.items(): + for k, v in storage.all().items(): if args == k.split('.')[0]: count += 1 print(count) @@ -348,6 +348,6 @@ def help_update(self): print("Updates an object with new information") print("Usage: update \n") - if __name__ == "__main__": HBNBCommand().cmdloop() + From 20a404587215ef85126c853dac6f9ca7fa09d92d Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Fri, 24 Jan 2025 00:58:52 +0200 Subject: [PATCH 25/43] push --- models/__init__.py | 1 - models/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 456 bytes models/__pycache__/amenity.cpython-310.pyc | Bin 0 -> 777 bytes models/__pycache__/base_model.cpython-310.pyc | Bin 0 -> 2631 bytes models/__pycache__/city.cpython-310.pyc | Bin 0 -> 788 bytes models/__pycache__/place.cpython-310.pyc | Bin 0 -> 2682 bytes models/__pycache__/review.cpython-310.pyc | Bin 0 -> 725 bytes models/__pycache__/state.cpython-310.pyc | Bin 0 -> 1271 bytes models/__pycache__/user.cpython-310.pyc | Bin 0 -> 853 bytes models/amenity.py | 14 +++- models/base_model.py | 42 ++++++---- models/city.py | 7 +- .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 144 bytes .../__pycache__/file_storage.cpython-310.pyc | Bin 0 -> 2479 bytes models/engine/db_storage.py | 38 ++++----- models/engine/file_storage.py | 29 ++++--- models/place.py | 77 +++++++++++++++--- models/review.py | 15 ++-- models/state.py | 24 +++--- models/user.py | 13 ++- modelss/__init__.py | 14 ++++ .../__pycache__/__init__.cpython-312.pyc | Bin .../__pycache__/amenity.cpython-312.pyc | Bin .../__pycache__/base_model.cpython-312.pyc | Bin .../__pycache__/city.cpython-312.pyc | Bin .../__pycache__/place.cpython-312.pyc | Bin .../__pycache__/review.cpython-312.pyc | Bin .../__pycache__/state.cpython-312.pyc | Bin .../__pycache__/user.cpython-312.pyc | Bin modelss/amenity.py | 7 ++ modelss/base_model.py | 68 ++++++++++++++++ modelss/city.py | 13 +++ modelss/engine/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin .../__pycache__/file_storage.cpython-312.pyc | Bin modelss/engine/db_storage.py | 75 +++++++++++++++++ modelss/engine/file_storage.py | 68 ++++++++++++++++ modelss/place.py | 18 ++++ modelss/review.py | 10 +++ modelss/state.py | 26 ++++++ modelss/user.py | 17 ++++ 41 files changed, 482 insertions(+), 94 deletions(-) create mode 100644 models/__pycache__/__init__.cpython-310.pyc create mode 100644 models/__pycache__/amenity.cpython-310.pyc create mode 100644 models/__pycache__/base_model.cpython-310.pyc create mode 100644 models/__pycache__/city.cpython-310.pyc create mode 100644 models/__pycache__/place.cpython-310.pyc create mode 100644 models/__pycache__/review.cpython-310.pyc create mode 100644 models/__pycache__/state.cpython-310.pyc create mode 100644 models/__pycache__/user.cpython-310.pyc create mode 100644 models/engine/__pycache__/__init__.cpython-310.pyc create mode 100644 models/engine/__pycache__/file_storage.cpython-310.pyc create mode 100644 modelss/__init__.py rename {models => modelss}/__pycache__/__init__.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/amenity.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/base_model.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/city.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/place.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/review.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/state.cpython-312.pyc (100%) rename {models => modelss}/__pycache__/user.cpython-312.pyc (100%) create mode 100644 modelss/amenity.py create mode 100644 modelss/base_model.py create mode 100644 modelss/city.py create mode 100644 modelss/engine/__init__.py rename {models => modelss}/engine/__pycache__/__init__.cpython-312.pyc (100%) rename {models => modelss}/engine/__pycache__/file_storage.cpython-312.pyc (100%) create mode 100644 modelss/engine/db_storage.py create mode 100644 modelss/engine/file_storage.py create mode 100644 modelss/place.py create mode 100644 modelss/review.py create mode 100644 modelss/state.py create mode 100644 modelss/user.py diff --git a/models/__init__.py b/models/__init__.py index 5cea926767d0..d443e0fa7827 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -2,7 +2,6 @@ """This module instantiates an object of class FileStorage""" from os import getenv - if getenv('HBNB_TYPE_STORAGE') == 'db': from models.engine.db_storage import DBStorage diff --git a/models/__pycache__/__init__.cpython-310.pyc b/models/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a6054c7960868e0ac80b054d258aa8ed557aab1 GIT binary patch literal 456 zcmZ8eJx{|h5VhTW719AFgoKo}5;PJE3qmxaz*G?J09mXwc8kHWQJhwSg`xig!N_0o z%EVt_;zBD_IO*Q$-Q7E%ZQW|EA+Q(m%rcD7M@?3Z067LX*8mKqh+#$~E=Wo+;)FHk zm^t^P+=09+8-c%XPkWedU&eC@`i)>WLz>0VcqiArcLwc>QPA1}tllnNy(N;?ma aHaJ{7%Mtt!GMfMn4sl3A?16{G1NIHx)_p?& literal 0 HcmV?d00001 diff --git a/models/__pycache__/amenity.cpython-310.pyc b/models/__pycache__/amenity.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39e7ee7e32163054d9e6853104c438e5c8b7ca3e GIT binary patch literal 777 zcmYjP&2H2%5VjrXcYoLlR0%H4b%ofKI3v_uRLX^=Vtc_CD;v9Qz=^j`w$kUz=9~u zFnm2lN{@LZWfVJ{D!&X^P=+jQV_!vO%wmj=kqAWi6^T%KlHO332(m=u==vaCHd!On zw_0qJOwY7Q-^>^DbZzuUnK$VzG)0RsvGF{sCHy6orOpK?c%{{*tZcAsOi`VWvF#hF zvZl~geNn7)m%1wyf?a< zAB^4W@+T{}UAL1|hB(r5WKv(MOyw7{-0mzeyhkV6lqBI8|-*2zR)bOk4!n>l^A>sr~%yuRP{`$0G8hux4f;~OS@ z89ZS!*cIKT6f3L~4zJx=OUtNV$U&wesaDfml~EGiOG*{>vZO4d)j~%}mXVFh$|%jF zVxXh7d-**W6uEkigR$EkUWGC-%A|b-c}^|sRZNR@oXWpZWP^TQ`71`J`TZ)q z3Hv*+@6ig=kB`n(lyV)FVsMsqh2&jFxyqAb7p_Ye#e3>@edq$|s&L$xz`>_ZxA}@@ zMg}r`!n!TlkWI9+az?h$w&kpBqdg{%$vL!h@;HJrUp21d#J9-bVRY?vv9R9P0eOBI zXT0+@`8UYZje)Ade2`_yy-Zaz>pJZxdOLoowmU-8O;-VeoD4G48?y@^uON;0c5VfP(Sn#pT+CW#U?F<)!s) z+Aqyh>^G0uB_Y)nE#Br$ye<#<+(DTWAv6MS_;2X!OY=^Pi$6o*!_xg{IDf#4rTvAE zz?fo0Fup;%T|{M=0bqCeE+2!x6Qr&M2FZcsF0dUgy|FWb#RC_`n>b*fKV1GvnSsvf z$`MLrib$(`4#U@fTRSzfPSBxeSnw*n`j}MlM72I0D%izIUU@ zHd-_OeTJ&DRCTDLv~x)PPD7s}1;M9s!PU|N zO@Bnna|fpHkVMh$I5otYv^8Li?}C1x29Jij3QS>>#1)K{G`ps3$bC@J7pJ)YUt6?6 z)@cat%{g)l#Kr>%o^^EXwdjIzwy$Jl;MqE%h=?Z{rnoyM1Qh_A}W zCliZk;{Hp1>Cd729>r3q1rLUEhY+ggQ7%Tx%9FlAifqP|$nakRxfRD7gCyG<0V8G6 zi(~E5K9q54CKKi?#`W7I9b{?!A$6CiA~0)0vpvt$8SO0)-*tehg;G-92${=I@OiwU z2v3Jz7_{2fqBEnvAnP}&vLA<&7Oi}i3;XT29XWscAz$t!d literal 0 HcmV?d00001 diff --git a/models/__pycache__/city.cpython-310.pyc b/models/__pycache__/city.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..091011db7b931e8ce912504a70b6301613eb47f8 GIT binary patch literal 788 zcmZ8g!EVz)5Z$#M+i?<9P*n*IXpclHiNv|8AVsBsS|OFwURE3Lv@xu`>8^v6o{++o z-$3G*_R6Urz=adDPDLw5+SSaw@yvT;+l)p9LHlvKQNJl6zd~@|dKkRK5$}2Wo(7hCT^muJ_r;1+X&cDz$WOpOvO*Wz{(5TG;}7`71Q zLk_tRp|KFY5Tfq(ivCcDtCiHZNG60bC8kG0v|+$DZxbA2!*XmI2Id_bQ7NB<0-J?o zx(qDbPhua3!f^e0HnqmIQ>jp%LUZy{~15HgC@q-9pkR^9oen- aBs9tow);86Z=SgD3nX-h?$ROMi~j(?_WqEY&lnCj|IIEY1$>82EMsG=;*_o6X$`?ffU#63vPW+Ku^O?7KbE(PISbxSqk zPcFfiS*=j>e#CdK!>`6zMoB2A!5!@4rjt0PjdXqfbrA7cvy>x29}Ve1i;oTE3R>E8YcFXlOIin77hKaCs|)hl$nZ~ylMhevl}C(s?wInfI8AKxHCVm^`2;_S z{Z8@IN0z_7U|EsBiZlEbzW%^CWUxHL&+xN_ye`)F&+^y!tI!$d*7><@gIe#rt`-3^ z>w24B!GxzWFIVBz({{;>TmhQ1+AvZj;@Y{oxqWr>^K0PP%~C{=P~v)z$u8NslUzt5 z=E+Y`Bf~O`9SJ6ko>>@Zhl|~C5-Z)MzzlZ2y>%_v-udSC=8bFGfbgeqDE z?df~yl%d$Z`LLp_N9S3-)Q^~Bvt80U3w;Q`RJz;Gg^NL87*0It8}DS1uauA$`w z!hK`k_{G>~caZRp8B$rcF{;goQ})Rs`yMlG+%fx_{P@xD8CJItnw?HBh9x4x^ zrb6)S;eg(J$^XyWfw67KH^|93bB%=!DB|a82}l7=fl3dbTtSl*uCv!mG)h~_%a;%% z-zW1AsJlQNVOr+V21y^HJEo%c??V42<6~HTidMuPk&4l&83e zRka;Z_hRx|7Ori2`RxswI-bRXeDYQ^bmPs1TB1k)dvIlpq<6>8h0Efo`Ug zWB?Q7XOipATpNUHuNYQyZ9pj{BSGVxll;P1(aSuMaAYMT7CtcYgo);tES29=VjkP zMz-g_CTn80jj*sOFqr+UZJDgj%vzmUb!6@nNvriv$1^2xp7AtYdmOJ^ftfnsp!mq@L9)<=guERP7((Yp}oo literal 0 HcmV?d00001 diff --git a/models/__pycache__/review.cpython-310.pyc b/models/__pycache__/review.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75a8829ca378481434c8a3682b1fe81d67937529 GIT binary patch literal 725 zcmYjPJ#Q2-5ViOFmK*{RUG0KqBXK8DM-d!SKte=_bZ)H8dPo*|*B5&?aMw^AEq{TY zUxehADu02B@i~OES7*KAIB=`Ql54h&$^uFl)NS~k?A)gQ-~nmCcKc@IjQo^Q}zLFTKLR5Ek_0Hqc&`~ z0`_Kkwqz@#KS49FTbx9y$W4~Dg?Czla*21V*k!M@8oS<=r`kY!*}sLg%gzVW_Lq&X z+CTTq-y;fyQ)C}W%3~Sv1X9Rkyrq!KWJ_f#v+pr4_R#zuo$S!!E{=F9C#a=#S&*_h z`lqQ;wY6-}%nrzonV_`oQDj#St?rr2188rLk<(_fQgs7%-pbR8x}qPIsxK65iqV4c za7z+G&Z-Bl5TdU;5WTdLBrnaHl3KlaQaxXrQmcX75#O*H>L|E4|r+lM*xC`#P-I8 z=5UA$>pK-(;R7j_bz{ScQB|`)#5Pr26sD4mo>vR7{Rfpf-YZ>*tK&bGPr=JkhJh(z zIP)0Ed>-(Sd8e59EOO09@QGg(#+i+bzd9fBxIkhxz3BlV|rIJ+y>PRRjlZ z(B4{ID}?x-0()-wU8xrHqJa!V)1rK-_{>ISq055t62qO#;dCDs6dLJUAl{%Eb_G3) z4LZQ*#CR9@+`m9S19&KgxB8tv<7TNEP0gHBQE5ZvjJhP!ssSKP$u<3>GIQFZ$}5)8 zD}x^{3jud!d%avL#T(NlVN|gZ{R|yhqx;gK`xeALIzcazSNH@Uptpbz(oIhApX88C z&&5O(2O|U#qXZ}atk$q0e8u%>N5~SW?SgW7VHnu3i)SNkq$>8g z^`J^!*}@}upKEm;BDSzP?FN`O?1FynUUXTw<*(9->y1&ju{Z47IM17+=6P$8>19P>z^#oo5q$ zC<;-|d3}5Z+TfFSBvsu4vm5I;uBdGu)i*B89VZ;3|AT7doi0DSuHW@02#0kOr!Zrf H*S&uMDjY*T literal 0 HcmV?d00001 diff --git a/models/__pycache__/user.cpython-310.pyc b/models/__pycache__/user.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..377242e82c551a5c170132ee393b674eb7e1805f GIT binary patch literal 853 zcmYjPO^?$s5VaHMquF)^E5QwvBR#N{I3ol_T28DGyIg#++<3|coTRmruDTbH%60z& zcm9&Eoc1qpVw}LXj$+N5@r>V_aWk1@1lP~g4a0U^?D%?@UJk#5dCkLM7HsI-hyrX<{U}tcoQZ-VUI>M|m zqVYYNs0pe(cFZfene|!+X?v+1hVsQW-$+w79g1&J&7y0;y2!`u-FKvWc8P-1y3<-N zG`P5{%XJ4+YW&b#^g+u49P{U0j6H(ZHz--i;;VtBOA2WVsW9&&Y)ZI3M^32_wX8r0 zmkBWp0PV35>rU!_kwgg96zHA^(fW%AzhQW(@$GaGRI=1AUE#d08>3vdERAjZ(r$!P z9844Y!|}?~v@S6{3;T}S=EV%zfwnWR?sT;^ z2_8@Jw9D5EFz0UhIaj8-2%pJwI}hTX#<`E-GA#>)h4@O2Xt`e0_)TI%8os_lWM kg`kf_a(sDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vQzbHSyL_aa7 zRM#=H$SKb$J~<~pFEzf*NIy3}B{ip5KQ%8sGcQ#?K0Y%qvm`!Vub}c4hYe7!G$+*# MWLPm1kYHf|06WSbw*UYD literal 0 HcmV?d00001 diff --git a/models/engine/__pycache__/file_storage.cpython-310.pyc b/models/engine/__pycache__/file_storage.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fff5f9235319ba6f2e4f6dfac54ca99e354b7b9 GIT binary patch literal 2479 zcma)8OOM<{5bkdG*q-OU@+2XcAVMr)M}z|i0%A8Ikq`_h144{ImUp@*@!-d#?b&5V zwiGEjzy;1o9A+ghT=+pg!ig(K5D8W7+085jiLqQRSGT*rs`{#Wl6Jd6@b}Hv;%A$X zU-iq9FhG9??(_l(K?X!n!9qHqH;FI=e?SDk&jw7eK5=Wat&i^nsS_n)8cIjVQ4q`2 z@ttAlr>T=APUOe_ZRv~x7*4Z9>6b(~cXr|(n3crxH`s>shA5YRM=-8~RgwV(C`{0S zA=rQiWKa_w!A0!>9hkxt)&nxIge~guv_(TS;aP_nEzyP<4PgM-m9lvQVDu{#v)489 z3TTBgJwlj_DuCdZ3{xkFo%i}5_MB0oB0rne(VNY2n#8>!Tf$reox^<%?(`~%oC-Q6 z%F4)?_DMhrhT5DRkn7}&_UEiH3ZB!kksG^2oy&R7a^otw+sQGuZ1(CcnN3xU@f5)@ z3zFDZ`wn1Rz#2}Kl5rO9Bfv#)doEXqsXXZ|IqP}J&R7n!w5$c0jMCEfyx5PV=ef0# zr!pLs#xP7v4ug}@_)_kd#;za!L{t;j`s1~(N|LPWhtrq00<|4)dpdL8?v-u@r7Ppx zkohhK##4$S$AXDY90l_-yyRp~4#=G5 zI)H+nC4!xX5RVO%0X?7;2nvDYv*)*jNS#>jIhET;#6$8uj$~Q)zz^W5=aqC51J{Oa zN^?39ekMyROFW!hvOu^@nK)*^dO9SPXlWbla|)Cc5npDk$)+}1Nowr2uECI^41CqCXq~B7Y^9e|06YBjYB(HUtJk)jiZZD^=vT~B0-2dt@ zsW@+sxSiR>_Y)uZ{)D8CR1)d5DkPyx%lfvT$`7!s!3+N+l?tApwJ zWc%>6wjvoH?T)@10ye#O*;#xCO$`BSEMlUzvr0XTwjbs{&ca=(%+ty_MKfYVKr^vKoJ@Wd$sc$NYTR#Vr z(w9KASPRI1c$tPt88!c6H4eqlfTD0Hdvxhxi-Y~qY<;;js)deqP%KUCN!M`oZ4ml6 zqUr+lOgM%X-4l8!_MFTZb2x;~<1=S(VYh|OgN4x7cU?=@n7#-LU6-NEpp8H`bTq|| z&KD;bIYIWzz3=hROamc%Y6U)UP0a^|?N6PCU5#!{0tfw8dV zn_$&l!d{#sEy^F7{CFs;sV?ogO}$~+@Q`!x2L&2^%k%C|{jfUxO3U*^GW5KP3%Zvf z0n`Z;2uy9F=%RRxNNd>pwHJ6Wr0A1PIK`{M?554_dgqKD2j8yXTx441_7her?W+~U Px3N%DT$95wxo-Ror8GSQ literal 0 HcmV?d00001 diff --git a/models/engine/db_storage.py b/models/engine/db_storage.py index 10a533cca1e7..7fa280570e33 100644 --- a/models/engine/db_storage.py +++ b/models/engine/db_storage.py @@ -1,36 +1,30 @@ #!/usr/bin/python3 -"""This module defines a class to manage database storage for hbnb clone""" - -from os import getenv -from models.base_model import Base -from models.base_model import BaseModel +"""New engine DBStorage""" +import os +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, scoped_session +from models.base_model import BaseModel, Base from models.user import User -from models.place import Place from models.state import State from models.city import City +from models.place import Place from models.amenity import Amenity from models.review import Review -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker class DBStorage: - """This class manages storage for hbnb clone""" - __engine = None - __session = None + """The new database storage class""" + _engine = None + _session = None def __init__(self): - """Initializes a new DBStorage instance""" - self.__engine = create_engine( - 'mysql+mysqldb://{}:{}@localhost:3306/{}'.format( - getenv('HBNB_MYSQL_USER'), - getenv('HBNB_MYSQL_PWD'), - getenv('HBNB_MYSQL_HOST'), - getenv('HBNB_MYSQL_DB'), - pool_pre_ping=True - ) - ) - + """Initialize the DBStorage class""" + self._engine = create_engine('mysql+mysqldb://{}:{}@{}:3306/{}' + .format(os.getenv('HBNB_MYSQL_USER'), + os.getenv('HBNB_MYSQL_PWD'), + os.getenv('HBNB_MYSQL_HOST'), + os.getenv('HBNB_MYSQL_DB')), + pool_pre_ping=True) if os.getenv('HBNB_ENV') == 'test': Base.metadata.drop_all(self._engine) diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index b56870811dc4..6a4f94a0618c 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -13,11 +13,11 @@ def all(self, cls=None): if cls is None: return FileStorage.__objects else: - new_dict = {} - for key, value in FileStorage.__objects.items(): - if cls == value.__class__ or cls == value.__class__.__name__: - new_dict[key] = value - return new_dict + temp = {} + for key, val in FileStorage.__objects.items(): + if cls.__name__ in key: + temp[key] = val + return temp def new(self, obj): """Adds new object to storage dictionary""" @@ -43,10 +43,10 @@ def reload(self): from models.review import Review classes = { - 'BaseModel': BaseModel, 'User': User, 'Place': Place, - 'State': State, 'City': City, 'Amenity': Amenity, - 'Review': Review - } + 'BaseModel': BaseModel, 'User': User, 'Place': Place, + 'State': State, 'City': City, 'Amenity': Amenity, + 'Review': Review + } try: temp = {} with open(FileStorage.__file_path, 'r') as f: @@ -57,12 +57,15 @@ def reload(self): pass def delete(self, obj=None): - """Delete obj from __objects if it's inside""" + """Deletes obj from __objects if it’s inside""" if obj is not None: key = obj.__class__.__name__ + '.' + obj.id - if key in self.__objects: - del self.__objects[key] + if key in FileStorage.__objects: + del FileStorage.__objects[key] self.save() - else: pass + + def close(self): + """Calls reload() method""" + self.reload() diff --git a/models/place.py b/models/place.py index 5221e8210d17..91f7f4e16698 100644 --- a/models/place.py +++ b/models/place.py @@ -1,18 +1,71 @@ #!/usr/bin/python3 """ Place Module for HBNB project """ -from models.base_model import BaseModel +import os +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String, Integer, Float, ForeignKey, Table +from sqlalchemy.orm import relationship +from models.review import Review +from models.amenity import Amenity +import models -class Place(BaseModel): +place_amenity = Table('place_amenity', Base.metadata, + Column('place_id', String(60), + ForeignKey('places.id'), + primary_key=True, nullable=False), + Column('amenity_id', String(60), + ForeignKey('amenities.id'), + primary_key=True, nullable=False)) + + +class Place(BaseModel, Base): """ A place to stay """ - city_id = "" - user_id = "" - name = "" - description = "" - number_rooms = 0 - number_bathrooms = 0 - max_guest = 0 - price_by_night = 0 - latitude = 0.0 - longitude = 0.0 + __tablename__ = 'places' + + city_id = Column(String(60), ForeignKey("cities.id", ondelete="CASCADE"), + nullable=False) + user_id = Column(String(60), ForeignKey("users.id", ondelete="CASCADE"), + nullable=False) + name = Column(String(128), nullable=False) + description = Column(String(1024), nullable=True) + number_rooms = Column(Integer, nullable=False, default=0) + number_bathrooms = Column(Integer, nullable=False, default=0) + max_guest = Column(Integer, nullable=False, default=0) + price_by_night = Column(Integer, nullable=False, default=0) + latitude = Column(Float, nullable=True) + longitude = Column(Float, nullable=True) amenity_ids = [] + + if os.getenv("HBNB_TYPE_STORAGE") == "db": + reviews = relationship("Review", backref="place") + amenities = relationship("Amenity", secondary="place_amenity", + viewonly=False, + back_populates="place_amenities") + + if os.getenv("HBNB_TYPE_STORAGE") != "db": + @property + def reviews(self): + """Returns the list of Review instances with place_id equals + to the current Place.id.""" + + reviews = list(models.storage.all(Review).values()) + + return list( + filter(lambda review: (review.place_id == self.id), reviews)) + + @property + def amenities(self): + """Returns the list of Amenity instances based on + the attribute amenity_ids that contains all Amenity.id.""" + + amenities = list(models.storage.all(Amenity).values()) + + return list( + filter(lambda amenity: (amenity.place_id in self.amenity_ids), + amenities)) + + @amenities.setter + def amenities(self, value=None): + """Adds ids in amenity_ids .""" + if type(value) == type(Amenity): + self.amenity_ids.append(value.id) diff --git a/models/review.py b/models/review.py index c487d90d34f0..f1a7632015d6 100644 --- a/models/review.py +++ b/models/review.py @@ -1,10 +1,13 @@ #!/usr/bin/python3 """ Review module for the HBNB project """ -from models.base_model import BaseModel +from models.base_model import BaseModel, Base +from sqlalchemy import Column, ForeignKey, String -class Review(BaseModel): - """ Review classto store review information """ - place_id = "" - user_id = "" - text = "" +class Review(BaseModel, Base): + """ Review class to store review information """ + __tablename__ = 'reviews' + + place_id = Column(String(60), ForeignKey("places.id"), nullable=False) + user_id = Column(String(60), ForeignKey("users.id"), nullable=False) + text = Column(String(1024), nullable=False) diff --git a/models/state.py b/models/state.py index 03836a664c22..f473fcbaef43 100644 --- a/models/state.py +++ b/models/state.py @@ -1,26 +1,28 @@ #!/usr/bin/python3 """ State Module for HBNB project """ -from models.base_model import BaseModel + +from models.base_model import BaseModel, Base +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship from models.city import City -import os import models -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.orm import relationship +import os class State(BaseModel, Base): """ State class """ __tablename__ = 'states' - name = Column(String(128), nukllable=False) + + name = Column(String(128), nullable=False) if os.getenv("HBNB_TYPE_STORAGE") == "db": - cities = relationship("City", backref="state", cascade="all, delete-orphan") + cities = relationship('City', backref='state', + cascade='all, delete-orphan') else: @property def cities(self): - """returns the list of City instances with state_id equals to the - current State.id - """ - return [city for city in list(models.storage.all(City).values()) - if city.state_id == self.id] \ No newline at end of file + """ Returns the list of City instances with state_id + equals to the current State.id. """ + return [city for city in models.storage.all(City).values() + if city.state_id == self.id] diff --git a/models/user.py b/models/user.py index 5c6d36edfb21..c7b8aa12ddca 100644 --- a/models/user.py +++ b/models/user.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 """This module defines a class User""" -from models.base_model import BaseModel +from models.base_model import BaseModel, Base from sqlalchemy import Column, String from sqlalchemy.orm import relationship @@ -8,10 +8,9 @@ class User(BaseModel, Base): """This class defines a user by various attributes""" __tablename__ = 'users' - email = Column(String(128), nullable=False) + email = Column(String(128), nullable=False, unique=True) password = Column(String(128), nullable=False) - first_name = Column(String(128), nullable=True) - last_name = Column(String(128), nullable=True) - places = relationship("Place", backref="user", cascade="all, delete") - reviews = relationship("Review", backref="user", cascade="all, delete") - \ No newline at end of file + first_name = Column(String(128)) + last_name = Column(String(128)) + places = relationship("Place", backref="user", cascade="delete") + reviews = relationship("Review", backref="user", cascade="delete") diff --git a/modelss/__init__.py b/modelss/__init__.py new file mode 100644 index 000000000000..5cea926767d0 --- /dev/null +++ b/modelss/__init__.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +"""This module instantiates an object of class FileStorage""" +from os import getenv + + +if getenv('HBNB_TYPE_STORAGE') == 'db': + from models.engine.db_storage import DBStorage + + storage = DBStorage() + storage.reload() +else: + from models.engine.file_storage import FileStorage + storage = FileStorage() + storage.reload() diff --git a/models/__pycache__/__init__.cpython-312.pyc b/modelss/__pycache__/__init__.cpython-312.pyc similarity index 100% rename from models/__pycache__/__init__.cpython-312.pyc rename to modelss/__pycache__/__init__.cpython-312.pyc diff --git a/models/__pycache__/amenity.cpython-312.pyc b/modelss/__pycache__/amenity.cpython-312.pyc similarity index 100% rename from models/__pycache__/amenity.cpython-312.pyc rename to modelss/__pycache__/amenity.cpython-312.pyc diff --git a/models/__pycache__/base_model.cpython-312.pyc b/modelss/__pycache__/base_model.cpython-312.pyc similarity index 100% rename from models/__pycache__/base_model.cpython-312.pyc rename to modelss/__pycache__/base_model.cpython-312.pyc diff --git a/models/__pycache__/city.cpython-312.pyc b/modelss/__pycache__/city.cpython-312.pyc similarity index 100% rename from models/__pycache__/city.cpython-312.pyc rename to modelss/__pycache__/city.cpython-312.pyc diff --git a/models/__pycache__/place.cpython-312.pyc b/modelss/__pycache__/place.cpython-312.pyc similarity index 100% rename from models/__pycache__/place.cpython-312.pyc rename to modelss/__pycache__/place.cpython-312.pyc diff --git a/models/__pycache__/review.cpython-312.pyc b/modelss/__pycache__/review.cpython-312.pyc similarity index 100% rename from models/__pycache__/review.cpython-312.pyc rename to modelss/__pycache__/review.cpython-312.pyc diff --git a/models/__pycache__/state.cpython-312.pyc b/modelss/__pycache__/state.cpython-312.pyc similarity index 100% rename from models/__pycache__/state.cpython-312.pyc rename to modelss/__pycache__/state.cpython-312.pyc diff --git a/models/__pycache__/user.cpython-312.pyc b/modelss/__pycache__/user.cpython-312.pyc similarity index 100% rename from models/__pycache__/user.cpython-312.pyc rename to modelss/__pycache__/user.cpython-312.pyc diff --git a/modelss/amenity.py b/modelss/amenity.py new file mode 100644 index 000000000000..a181095e4170 --- /dev/null +++ b/modelss/amenity.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 +""" State Module for HBNB project """ +from models.base_model import BaseModel + + +class Amenity(BaseModel): + name = "" diff --git a/modelss/base_model.py b/modelss/base_model.py new file mode 100644 index 000000000000..a0c1e57e101a --- /dev/null +++ b/modelss/base_model.py @@ -0,0 +1,68 @@ +#!/usr/bin/python3 +"""This module defines a base class for all models in our hbnb clone""" +import uuid +from datetime import datetime + + +Base = declare_base() + +class BaseModel: + """A base class for all hbnb models""" + id = Column(String(60), nullable=False, primary_key=True) + created_at = Column(DateTime, nullable=False, default=datetime.utcnow()) + updated_at = Column(DateTime, nullable=False, default=datetime.utcnow()) + def __init__(self, *args, **kwargs): + """Instatntiates a new model""" + if not kwargs: + from models import storage + self.id = str(uuid.uuid4()) + self.created_at = datetime.now() + self.updated_at = datetime.now() + + if kwargs: + if "id" not in kwargs: + kwargs["id"] = str(uuid.uuid4()) + if "created_at" not in kwargs: + kwargs["created_at"] = datetime.utcnow().isoformat() + if"updated_at" not in kwargs: + kwargs["updated_at"] = datetime.utcnow().isoformat() + for key, value in kwargs.items(): + if key == "created_at" or key == "updated_at": + value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") + if key != "__class__": + setattr(self, key, value) + + if '__class__' in kwargs: + del kwargs['__class__'] + self.__dict__.update(kwargs) + + def __str__(self): + """Returns a string representation of the instance""" + cls = (str(type(self)).split('.')[-1]).split('\'')[0] + return '[{}] ({}) {}'.format(cls, self.id, self.__dict__) + + def save(self): + """Updates updated_at with current time when instance is changed""" + from models import storage + self.updated_at = datetime.now() + storage.new(self) + storage.save() + + def to_dict(self): + """Convert instance into dict format""" + dictionary = {} + dictionary.update(self.__dict__) + for key in self.__dict__.keys(): + if key == "_sa_instance_state": + del (dictionary[key]) + dictionary.update({'__class__': + (str(type(self)).split('.')[-1]).split('\'')[0]}) + dictionary['created_at'] = self.created_at.isoformat() + dictionary['updated_at'] = self.updated_at.isoformat() + return dictionary + + def delete(self): + """Deletes the current instance from storage""" + from models import storage + storage.delete(self) + storage.save() diff --git a/modelss/city.py b/modelss/city.py new file mode 100644 index 000000000000..41ed4b3f1c40 --- /dev/null +++ b/modelss/city.py @@ -0,0 +1,13 @@ +#!/usr/bin/python3 +""" City Module for HBNB project """ +from models.base_model import BaseModel +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship + + +class City(BaseModel, Base): + """ The city class, contains state ID and name """ + __tablename__ = 'cities' + + name = Column(String(128), nullable=False) + state_id = Column(String(60), nullable=Fallse, ForeignKey="states.id") diff --git a/modelss/engine/__init__.py b/modelss/engine/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/models/engine/__pycache__/__init__.cpython-312.pyc b/modelss/engine/__pycache__/__init__.cpython-312.pyc similarity index 100% rename from models/engine/__pycache__/__init__.cpython-312.pyc rename to modelss/engine/__pycache__/__init__.cpython-312.pyc diff --git a/models/engine/__pycache__/file_storage.cpython-312.pyc b/modelss/engine/__pycache__/file_storage.cpython-312.pyc similarity index 100% rename from models/engine/__pycache__/file_storage.cpython-312.pyc rename to modelss/engine/__pycache__/file_storage.cpython-312.pyc diff --git a/modelss/engine/db_storage.py b/modelss/engine/db_storage.py new file mode 100644 index 000000000000..399e5896fbf9 --- /dev/null +++ b/modelss/engine/db_storage.py @@ -0,0 +1,75 @@ +#!/usr/bin/python3 +"""This module defines a class to manage database storage for hbnb clone""" + +from os import getenv +from models.base_model import Base +from models.base_model import BaseModel +from models.user import User +from models.place import Place +from models.state import State +from models.city import City +from models.amenity import Amenity +from models.review import Review +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker + + +class DBStorage: + """This class manages storage for hbnb clone""" + __engine = None + __session = None + + def __init__(self): + """Initializes a new DBStorage instance""" + self.__engine = create_engine( + 'mysql+mysqldb://{}:{}@localhost:3306/{}'.format( + getenv('HBNB_MYSQL_USER'), + getenv('HBNB_MYSQL_PWD'), + getenv('HBNB_MYSQL_HOST'), + getenv('HBNB_MYSQL_DB'), + pool_pre_ping=True + ) + ) + + if os.getenv('HBNB_ENV') == 'test': + Base.metadata.drop_all(self._engine) + + def all(self, cls=None): + """Returns a dictionary of all objects""" + classes = [User, State, City, Place, Amenity, Review] + new_dict = {} + if cls is None: + for c in classes: + for obj in self._session.query(c).all(): + key = obj.__class__.__name__ + '.' + obj.id + new_dict[key] = obj + else: + for obj in self._session.query(cls).all(): + key = obj.__class__.__name__ + '.' + obj.id + new_dict[key] = obj + return new_dict + + def new(self, obj): + """Adds a new object to the database""" + self._session.add(obj) + + def save(self): + """Saves all changes to the database""" + self._session.commit() + + def delete(self, obj=None): + """Deletes an object from the database""" + if obj is not None: + self._session.delete(obj) + + def reload(self): + """Reloads all tables""" + Base.metadata.create_all(self._engine) + session_factory = sessionmaker(bind=self._engine, + expire_on_commit=False) + Session = scoped_session(session_factory) + self._session = Session() + + def close(self): + """Close the session""" + self._session.close() diff --git a/modelss/engine/file_storage.py b/modelss/engine/file_storage.py new file mode 100644 index 000000000000..b56870811dc4 --- /dev/null +++ b/modelss/engine/file_storage.py @@ -0,0 +1,68 @@ +#!/usr/bin/python3 +"""This module defines a class to manage file storage for hbnb clone""" +import json + + +class FileStorage: + """This class manages storage of hbnb models in JSON format""" + __file_path = 'file.json' + __objects = {} + + def all(self, cls=None): + """Returns a dictionary of models currently in storage""" + if cls is None: + return FileStorage.__objects + else: + new_dict = {} + for key, value in FileStorage.__objects.items(): + if cls == value.__class__ or cls == value.__class__.__name__: + new_dict[key] = value + return new_dict + + def new(self, obj): + """Adds new object to storage dictionary""" + self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) + + def save(self): + """Saves storage dictionary to file""" + with open(FileStorage.__file_path, 'w') as f: + temp = {} + temp.update(FileStorage.__objects) + for key, val in temp.items(): + temp[key] = val.to_dict() + json.dump(temp, f) + + def reload(self): + """Loads storage dictionary from file""" + from models.base_model import BaseModel + from models.user import User + from models.place import Place + from models.state import State + from models.city import City + from models.amenity import Amenity + from models.review import Review + + classes = { + 'BaseModel': BaseModel, 'User': User, 'Place': Place, + 'State': State, 'City': City, 'Amenity': Amenity, + 'Review': Review + } + try: + temp = {} + with open(FileStorage.__file_path, 'r') as f: + temp = json.load(f) + for key, val in temp.items(): + self.all()[key] = classes[val['__class__']](**val) + except FileNotFoundError: + pass + + def delete(self, obj=None): + """Delete obj from __objects if it's inside""" + if obj is not None: + key = obj.__class__.__name__ + '.' + obj.id + if key in self.__objects: + del self.__objects[key] + self.save() + + else: + pass diff --git a/modelss/place.py b/modelss/place.py new file mode 100644 index 000000000000..5221e8210d17 --- /dev/null +++ b/modelss/place.py @@ -0,0 +1,18 @@ +#!/usr/bin/python3 +""" Place Module for HBNB project """ +from models.base_model import BaseModel + + +class Place(BaseModel): + """ A place to stay """ + city_id = "" + user_id = "" + name = "" + description = "" + number_rooms = 0 + number_bathrooms = 0 + max_guest = 0 + price_by_night = 0 + latitude = 0.0 + longitude = 0.0 + amenity_ids = [] diff --git a/modelss/review.py b/modelss/review.py new file mode 100644 index 000000000000..c487d90d34f0 --- /dev/null +++ b/modelss/review.py @@ -0,0 +1,10 @@ +#!/usr/bin/python3 +""" Review module for the HBNB project """ +from models.base_model import BaseModel + + +class Review(BaseModel): + """ Review classto store review information """ + place_id = "" + user_id = "" + text = "" diff --git a/modelss/state.py b/modelss/state.py new file mode 100644 index 000000000000..03836a664c22 --- /dev/null +++ b/modelss/state.py @@ -0,0 +1,26 @@ +#!/usr/bin/python3 +""" State Module for HBNB project """ +from models.base_model import BaseModel +from models.city import City +import os +import models +from sqlalchemy import Column, String, ForeignKey +from sqlalchemy.orm import relationship + + +class State(BaseModel, Base): + """ State class """ + __tablename__ = 'states' + name = Column(String(128), nukllable=False) + + if os.getenv("HBNB_TYPE_STORAGE") == "db": + cities = relationship("City", backref="state", cascade="all, delete-orphan") + + else: + @property + def cities(self): + """returns the list of City instances with state_id equals to the + current State.id + """ + return [city for city in list(models.storage.all(City).values()) + if city.state_id == self.id] \ No newline at end of file diff --git a/modelss/user.py b/modelss/user.py new file mode 100644 index 000000000000..5c6d36edfb21 --- /dev/null +++ b/modelss/user.py @@ -0,0 +1,17 @@ +#!/usr/bin/python3 +"""This module defines a class User""" +from models.base_model import BaseModel +from sqlalchemy import Column, String +from sqlalchemy.orm import relationship + + +class User(BaseModel, Base): + """This class defines a user by various attributes""" + __tablename__ = 'users' + email = Column(String(128), nullable=False) + password = Column(String(128), nullable=False) + first_name = Column(String(128), nullable=True) + last_name = Column(String(128), nullable=True) + places = relationship("Place", backref="user", cascade="all, delete") + reviews = relationship("Review", backref="user", cascade="all, delete") + \ No newline at end of file From 97239c8f24927af51014ff13630673b7e28778f0 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Fri, 24 Jan 2025 01:11:52 +0200 Subject: [PATCH 26/43] new onw --- alu-AirBnB_clone_v2 | 1 + models/__init__.py | 6 +- models/__pycache__/__init__.cpython-310.pyc | Bin 456 -> 0 bytes models/__pycache__/amenity.cpython-310.pyc | Bin 777 -> 0 bytes models/__pycache__/base_model.cpython-310.pyc | Bin 2631 -> 0 bytes models/__pycache__/city.cpython-310.pyc | Bin 788 -> 0 bytes models/__pycache__/place.cpython-310.pyc | Bin 2682 -> 0 bytes models/__pycache__/review.cpython-310.pyc | Bin 725 -> 0 bytes models/__pycache__/state.cpython-310.pyc | Bin 1271 -> 0 bytes models/__pycache__/user.cpython-310.pyc | Bin 853 -> 0 bytes models/base_model.py | 109 +++++++++--------- models/city.py | 5 +- .../__pycache__/__init__.cpython-310.pyc | Bin 144 -> 0 bytes .../__pycache__/file_storage.cpython-310.pyc | Bin 2479 -> 0 bytes models/engine/db_storage.py | 104 +++++++++-------- models/engine/file_storage.py | 98 ++++++++-------- models/place.py | 2 +- models/state.py | 15 ++- models/user.py | 29 +++-- 19 files changed, 203 insertions(+), 166 deletions(-) create mode 160000 alu-AirBnB_clone_v2 delete mode 100644 models/__pycache__/__init__.cpython-310.pyc delete mode 100644 models/__pycache__/amenity.cpython-310.pyc delete mode 100644 models/__pycache__/base_model.cpython-310.pyc delete mode 100644 models/__pycache__/city.cpython-310.pyc delete mode 100644 models/__pycache__/place.cpython-310.pyc delete mode 100644 models/__pycache__/review.cpython-310.pyc delete mode 100644 models/__pycache__/state.cpython-310.pyc delete mode 100644 models/__pycache__/user.cpython-310.pyc delete mode 100644 models/engine/__pycache__/__init__.cpython-310.pyc delete mode 100644 models/engine/__pycache__/file_storage.cpython-310.pyc diff --git a/alu-AirBnB_clone_v2 b/alu-AirBnB_clone_v2 new file mode 160000 index 000000000000..a234f70a5e9a --- /dev/null +++ b/alu-AirBnB_clone_v2 @@ -0,0 +1 @@ +Subproject commit a234f70a5e9a3b484b86be605c1f498e1d702bc6 diff --git a/models/__init__.py b/models/__init__.py index d443e0fa7827..2508312ffe32 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,13 +1,15 @@ #!/usr/bin/python3 """This module instantiates an object of class FileStorage""" -from os import getenv +import os -if getenv('HBNB_TYPE_STORAGE') == 'db': +if os.getenv("HBNB_TYPE_STORAGE") == "db": from models.engine.db_storage import DBStorage storage = DBStorage() storage.reload() else: + from models.engine.file_storage import FileStorage + storage = FileStorage() storage.reload() diff --git a/models/__pycache__/__init__.cpython-310.pyc b/models/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 4a6054c7960868e0ac80b054d258aa8ed557aab1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 456 zcmZ8eJx{|h5VhTW719AFgoKo}5;PJE3qmxaz*G?J09mXwc8kHWQJhwSg`xig!N_0o z%EVt_;zBD_IO*Q$-Q7E%ZQW|EA+Q(m%rcD7M@?3Z067LX*8mKqh+#$~E=Wo+;)FHk zm^t^P+=09+8-c%XPkWedU&eC@`i)>WLz>0VcqiArcLwc>QPA1}tllnNy(N;?ma aHaJ{7%Mtt!GMfMn4sl3A?16{G1NIHx)_p?& diff --git a/models/__pycache__/amenity.cpython-310.pyc b/models/__pycache__/amenity.cpython-310.pyc deleted file mode 100644 index 39e7ee7e32163054d9e6853104c438e5c8b7ca3e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 777 zcmYjP&2H2%5VjrXcYoLlR0%H4b%ofKI3v_uRLX^=Vtc_CD;v9Qz=^j`w$kUz=9~u zFnm2lN{@LZWfVJ{D!&X^P=+jQV_!vO%wmj=kqAWi6^T%KlHO332(m=u==vaCHd!On zw_0qJOwY7Q-^>^DbZzuUnK$VzG)0RsvGF{sCHy6orOpK?c%{{*tZcAsOi`VWvF#hF zvZl~geNn7)m%1wyf?a< zAB^4W@+T{}UAL1|hB(r5WKv(MOyw7{-0mzeyhkV6lqBI8|-*2zR)bOk4!n>l^A>sr~%yuRP{`$0G8hux4f;~OS@ z89ZS!*cIKT6f3L~4zJx=OUtNV$U&wesaDfml~EGiOG*{>vZO4d)j~%}mXVFh$|%jF zVxXh7d-**W6uEkigR$EkUWGC-%A|b-c}^|sRZNR@oXWpZWP^TQ`71`J`TZ)q z3Hv*+@6ig=kB`n(lyV)FVsMsqh2&jFxyqAb7p_Ye#e3>@edq$|s&L$xz`>_ZxA}@@ zMg}r`!n!TlkWI9+az?h$w&kpBqdg{%$vL!h@;HJrUp21d#J9-bVRY?vv9R9P0eOBI zXT0+@`8UYZje)Ade2`_yy-Zaz>pJZxdOLoowmU-8O;-VeoD4G48?y@^uON;0c5VfP(Sn#pT+CW#U?F<)!s) z+Aqyh>^G0uB_Y)nE#Br$ye<#<+(DTWAv6MS_;2X!OY=^Pi$6o*!_xg{IDf#4rTvAE zz?fo0Fup;%T|{M=0bqCeE+2!x6Qr&M2FZcsF0dUgy|FWb#RC_`n>b*fKV1GvnSsvf z$`MLrib$(`4#U@fTRSzfPSBxeSnw*n`j}MlM72I0D%izIUU@ zHd-_OeTJ&DRCTDLv~x)PPD7s}1;M9s!PU|N zO@Bnna|fpHkVMh$I5otYv^8Li?}C1x29Jij3QS>>#1)K{G`ps3$bC@J7pJ)YUt6?6 z)@cat%{g)l#Kr>%o^^EXwdjIzwy$Jl;MqE%h=?Z{rnoyM1Qh_A}W zCliZk;{Hp1>Cd729>r3q1rLUEhY+ggQ7%Tx%9FlAifqP|$nakRxfRD7gCyG<0V8G6 zi(~E5K9q54CKKi?#`W7I9b{?!A$6CiA~0)0vpvt$8SO0)-*tehg;G-92${=I@OiwU z2v3Jz7_{2fqBEnvAnP}&vLA<&7Oi}i3;XT29XWscAz$t!d diff --git a/models/__pycache__/city.cpython-310.pyc b/models/__pycache__/city.cpython-310.pyc deleted file mode 100644 index 091011db7b931e8ce912504a70b6301613eb47f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 788 zcmZ8g!EVz)5Z$#M+i?<9P*n*IXpclHiNv|8AVsBsS|OFwURE3Lv@xu`>8^v6o{++o z-$3G*_R6Urz=adDPDLw5+SSaw@yvT;+l)p9LHlvKQNJl6zd~@|dKkRK5$}2Wo(7hCT^muJ_r;1+X&cDz$WOpOvO*Wz{(5TG;}7`71Q zLk_tRp|KFY5Tfq(ivCcDtCiHZNG60bC8kG0v|+$DZxbA2!*XmI2Id_bQ7NB<0-J?o zx(qDbPhua3!f^e0HnqmIQ>jp%LUZy{~15HgC@q-9pkR^9oen- aBs9tow);86Z=SgD3nX-h?$ROMi~j(?_WqEY&lnCj|IIEY1$>82EMsG=;*_o6X$`?ffU#63vPW+Ku^O?7KbE(PISbxSqk zPcFfiS*=j>e#CdK!>`6zMoB2A!5!@4rjt0PjdXqfbrA7cvy>x29}Ve1i;oTE3R>E8YcFXlOIin77hKaCs|)hl$nZ~ylMhevl}C(s?wInfI8AKxHCVm^`2;_S z{Z8@IN0z_7U|EsBiZlEbzW%^CWUxHL&+xN_ye`)F&+^y!tI!$d*7><@gIe#rt`-3^ z>w24B!GxzWFIVBz({{;>TmhQ1+AvZj;@Y{oxqWr>^K0PP%~C{=P~v)z$u8NslUzt5 z=E+Y`Bf~O`9SJ6ko>>@Zhl|~C5-Z)MzzlZ2y>%_v-udSC=8bFGfbgeqDE z?df~yl%d$Z`LLp_N9S3-)Q^~Bvt80U3w;Q`RJz;Gg^NL87*0It8}DS1uauA$`w z!hK`k_{G>~caZRp8B$rcF{;goQ})Rs`yMlG+%fx_{P@xD8CJItnw?HBh9x4x^ zrb6)S;eg(J$^XyWfw67KH^|93bB%=!DB|a82}l7=fl3dbTtSl*uCv!mG)h~_%a;%% z-zW1AsJlQNVOr+V21y^HJEo%c??V42<6~HTidMuPk&4l&83e zRka;Z_hRx|7Ori2`RxswI-bRXeDYQ^bmPs1TB1k)dvIlpq<6>8h0Efo`Ug zWB?Q7XOipATpNUHuNYQyZ9pj{BSGVxll;P1(aSuMaAYMT7CtcYgo);tES29=VjkP zMz-g_CTn80jj*sOFqr+UZJDgj%vzmUb!6@nNvriv$1^2xp7AtYdmOJ^ftfnsp!mq@L9)<=guERP7((Yp}oo diff --git a/models/__pycache__/review.cpython-310.pyc b/models/__pycache__/review.cpython-310.pyc deleted file mode 100644 index 75a8829ca378481434c8a3682b1fe81d67937529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 725 zcmYjPJ#Q2-5ViOFmK*{RUG0KqBXK8DM-d!SKte=_bZ)H8dPo*|*B5&?aMw^AEq{TY zUxehADu02B@i~OES7*KAIB=`Ql54h&$^uFl)NS~k?A)gQ-~nmCcKc@IjQo^Q}zLFTKLR5Ek_0Hqc&`~ z0`_Kkwqz@#KS49FTbx9y$W4~Dg?Czla*21V*k!M@8oS<=r`kY!*}sLg%gzVW_Lq&X z+CTTq-y;fyQ)C}W%3~Sv1X9Rkyrq!KWJ_f#v+pr4_R#zuo$S!!E{=F9C#a=#S&*_h z`lqQ;wY6-}%nrzonV_`oQDj#St?rr2188rLk<(_fQgs7%-pbR8x}qPIsxK65iqV4c za7z+G&Z-Bl5TdU;5WTdLBrnaHl3KlaQaxXrQmcX75#O*H>L|E4|r+lM*xC`#P-I8 z=5UA$>pK-(;R7j_bz{ScQB|`)#5Pr26sD4mo>vR7{Rfpf-YZ>*tK&bGPr=JkhJh(z zIP)0Ed>-(Sd8e59EOO09@QGg(#+i+bzd9fBxIkhxz3BlV|rIJ+y>PRRjlZ z(B4{ID}?x-0()-wU8xrHqJa!V)1rK-_{>ISq055t62qO#;dCDs6dLJUAl{%Eb_G3) z4LZQ*#CR9@+`m9S19&KgxB8tv<7TNEP0gHBQE5ZvjJhP!ssSKP$u<3>GIQFZ$}5)8 zD}x^{3jud!d%avL#T(NlVN|gZ{R|yhqx;gK`xeALIzcazSNH@Uptpbz(oIhApX88C z&&5O(2O|U#qXZ}atk$q0e8u%>N5~SW?SgW7VHnu3i)SNkq$>8g z^`J^!*}@}upKEm;BDSzP?FN`O?1FynUUXTw<*(9->y1&ju{Z47IM17+=6P$8>19P>z^#oo5q$ zC<;-|d3}5Z+TfFSBvsu4vm5I;uBdGu)i*B89VZ;3|AT7doi0DSuHW@02#0kOr!Zrf H*S&uMDjY*T diff --git a/models/__pycache__/user.cpython-310.pyc b/models/__pycache__/user.cpython-310.pyc deleted file mode 100644 index 377242e82c551a5c170132ee393b674eb7e1805f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 853 zcmYjPO^?$s5VaHMquF)^E5QwvBR#N{I3ol_T28DGyIg#++<3|coTRmruDTbH%60z& zcm9&Eoc1qpVw}LXj$+N5@r>V_aWk1@1lP~g4a0U^?D%?@UJk#5dCkLM7HsI-hyrX<{U}tcoQZ-VUI>M|m zqVYYNs0pe(cFZfene|!+X?v+1hVsQW-$+w79g1&J&7y0;y2!`u-FKvWc8P-1y3<-N zG`P5{%XJ4+YW&b#^g+u49P{U0j6H(ZHz--i;;VtBOA2WVsW9&&Y)ZI3M^32_wX8r0 zmkBWp0PV35>rU!_kwgg96zHA^(fW%AzhQW(@$GaGRI=1AUE#d08>3vdERAjZ(r$!P z9844Y!|}?~v@S6{3;T}S=EV%zfwnWR?sT;^ z2_8@Jw9D5EFz0UhIaj8-2%pJwI}hTX#<`E-GA#>)h4@O2Xt`e0_)TI%8os_lWM kg`kf_a(sDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vQzbHSyL_aa7 zRM#=H$SKb$J~<~pFEzf*NIy3}B{ip5KQ%8sGcQ#?K0Y%qvm`!Vub}c4hYe7!G$+*# MWLPm1kYHf|06WSbw*UYD diff --git a/models/engine/__pycache__/file_storage.cpython-310.pyc b/models/engine/__pycache__/file_storage.cpython-310.pyc deleted file mode 100644 index 3fff5f9235319ba6f2e4f6dfac54ca99e354b7b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2479 zcma)8OOM<{5bkdG*q-OU@+2XcAVMr)M}z|i0%A8Ikq`_h144{ImUp@*@!-d#?b&5V zwiGEjzy;1o9A+ghT=+pg!ig(K5D8W7+085jiLqQRSGT*rs`{#Wl6Jd6@b}Hv;%A$X zU-iq9FhG9??(_l(K?X!n!9qHqH;FI=e?SDk&jw7eK5=Wat&i^nsS_n)8cIjVQ4q`2 z@ttAlr>T=APUOe_ZRv~x7*4Z9>6b(~cXr|(n3crxH`s>shA5YRM=-8~RgwV(C`{0S zA=rQiWKa_w!A0!>9hkxt)&nxIge~guv_(TS;aP_nEzyP<4PgM-m9lvQVDu{#v)489 z3TTBgJwlj_DuCdZ3{xkFo%i}5_MB0oB0rne(VNY2n#8>!Tf$reox^<%?(`~%oC-Q6 z%F4)?_DMhrhT5DRkn7}&_UEiH3ZB!kksG^2oy&R7a^otw+sQGuZ1(CcnN3xU@f5)@ z3zFDZ`wn1Rz#2}Kl5rO9Bfv#)doEXqsXXZ|IqP}J&R7n!w5$c0jMCEfyx5PV=ef0# zr!pLs#xP7v4ug}@_)_kd#;za!L{t;j`s1~(N|LPWhtrq00<|4)dpdL8?v-u@r7Ppx zkohhK##4$S$AXDY90l_-yyRp~4#=G5 zI)H+nC4!xX5RVO%0X?7;2nvDYv*)*jNS#>jIhET;#6$8uj$~Q)zz^W5=aqC51J{Oa zN^?39ekMyROFW!hvOu^@nK)*^dO9SPXlWbla|)Cc5npDk$)+}1Nowr2uECI^41CqCXq~B7Y^9e|06YBjYB(HUtJk)jiZZD^=vT~B0-2dt@ zsW@+sxSiR>_Y)uZ{)D8CR1)d5DkPyx%lfvT$`7!s!3+N+l?tApwJ zWc%>6wjvoH?T)@10ye#O*;#xCO$`BSEMlUzvr0XTwjbs{&ca=(%+ty_MKfYVKr^vKoJ@Wd$sc$NYTR#Vr z(w9KASPRI1c$tPt88!c6H4eqlfTD0Hdvxhxi-Y~qY<;;js)deqP%KUCN!M`oZ4ml6 zqUr+lOgM%X-4l8!_MFTZb2x;~<1=S(VYh|OgN4x7cU?=@n7#-LU6-NEpp8H`bTq|| z&KD;bIYIWzz3=hROamc%Y6U)UP0a^|?N6PCU5#!{0tfw8dV zn_$&l!d{#sEy^F7{CFs;sV?ogO}$~+@Q`!x2L&2^%k%C|{jfUxO3U*^GW5KP3%Zvf z0n`Z;2uy9F=%RRxNNd>pwHJ6Wr0A1PIK`{M?554_dgqKD2j8yXTx441_7her?W+~U Px3N%DT$95wxo-Ror8GSQ diff --git a/models/engine/db_storage.py b/models/engine/db_storage.py index 7fa280570e33..87e22a5aad29 100644 --- a/models/engine/db_storage.py +++ b/models/engine/db_storage.py @@ -1,69 +1,83 @@ #!/usr/bin/python3 -"""New engine DBStorage""" -import os -from sqlalchemy import create_engine +""" new class for sqlAlchemy """ +from os import getenv from sqlalchemy.orm import sessionmaker, scoped_session -from models.base_model import BaseModel, Base -from models.user import User +from sqlalchemy import (create_engine) +from models.base_model import Base from models.state import State from models.city import City +from models.user import User from models.place import Place -from models.amenity import Amenity from models.review import Review +from models.amenity import Amenity class DBStorage: - """The new database storage class""" - _engine = None - _session = None + """ create tables in environmental""" + __engine = None + __session = None def __init__(self): - """Initialize the DBStorage class""" - self._engine = create_engine('mysql+mysqldb://{}:{}@{}:3306/{}' - .format(os.getenv('HBNB_MYSQL_USER'), - os.getenv('HBNB_MYSQL_PWD'), - os.getenv('HBNB_MYSQL_HOST'), - os.getenv('HBNB_MYSQL_DB')), - pool_pre_ping=True) - if os.getenv('HBNB_ENV') == 'test': - Base.metadata.drop_all(self._engine) + user = getenv("HBNB_MYSQL_USER") + passwd = getenv("HBNB_MYSQL_PWD") + db = getenv("HBNB_MYSQL_DB") + host = getenv("HBNB_MYSQL_HOST") + env = getenv("HBNB_ENV") + + self.__engine = create_engine('mysql+mysqldb://{}:{}@{}/{}' + .format(user, passwd, host, db), + pool_pre_ping=True) + + if env == "test": + Base.metadata.drop_all(self.__engine) def all(self, cls=None): - """Returns a dictionary of all objects""" - classes = [User, State, City, Place, Amenity, Review] - new_dict = {} - if cls is None: - for c in classes: - for obj in self._session.query(c).all(): - key = obj.__class__.__name__ + '.' + obj.id - new_dict[key] = obj + """returns a dictionary + Return: + returns a dictionary of __object + """ + dic = {} + if cls: + if isinstance(cls, str): + cls = eval(cls) + query = self.__session.query(cls) + for elem in query: + key = "{}.{}".format(type(elem).__name__, elem.id) + dic[key] = elem else: - for obj in self._session.query(cls).all(): - key = obj.__class__.__name__ + '.' + obj.id - new_dict[key] = obj - return new_dict + lista = [State, City, User, Place, Review, Amenity] + for clase in lista: + query = self.__session.query(clase) + for elem in query: + key = "{}.{}".format(type(elem).__name__, elem.id) + dic[key] = elem + return (dic) def new(self, obj): - """Adds a new object to the database""" - self._session.add(obj) + """add a new element in the table + """ + self.__session.add(obj) def save(self): - """Saves all changes to the database""" - self._session.commit() + """save changes + """ + self.__session.commit() def delete(self, obj=None): - """Deletes an object from the database""" - if obj is not None: - self._session.delete(obj) + """delete an element in the table + """ + if obj: + self.session.delete(obj) def reload(self): - """Reloads all tables""" - Base.metadata.create_all(self._engine) - session_factory = sessionmaker(bind=self._engine, - expire_on_commit=False) - Session = scoped_session(session_factory) - self._session = Session() + """configuration + """ + Base.metadata.create_all(self.__engine) + sec = sessionmaker(bind=self.__engine, expire_on_commit=False) + Session = scoped_session(sec) + self.__session = Session() def close(self): - """Close the session""" - self._session.close() + """ calls remove() + """ + self.__session.close() diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index 6a4f94a0618c..25f5e066e336 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -1,71 +1,73 @@ #!/usr/bin/python3 -"""This module defines a class to manage file storage for hbnb clone""" +"""This is the file storage class for AirBnB""" import json +import shlex class FileStorage: - """This class manages storage of hbnb models in JSON format""" - __file_path = 'file.json' + """This class serializes instances to a JSON file and + deserializes JSON file to instances + Attributes: + __file_path: path to the JSON file + __objects: objects will be stored + """ + __file_path = "file.json" __objects = {} def all(self, cls=None): - """Returns a dictionary of models currently in storage""" - if cls is None: - return FileStorage.__objects + """returns a dictionary + Return: + returns a dictionary of __object + """ + dic = {} + if cls: + dictionary = self.__objects + for key in dictionary: + partition = key.replace('.', ' ') + partition = shlex.split(partition) + if (partition[0] == cls.__name__): + dic[key] = self.__objects[key] + return (dic) else: - temp = {} - for key, val in FileStorage.__objects.items(): - if cls.__name__ in key: - temp[key] = val - return temp + return self.__objects def new(self, obj): - """Adds new object to storage dictionary""" - self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) + """sets __object to given obj + Args: + obj: given object + """ + if obj: + key = "{}.{}".format(type(obj).__name__, obj.id) + self.__objects[key] = obj def save(self): - """Saves storage dictionary to file""" - with open(FileStorage.__file_path, 'w') as f: - temp = {} - temp.update(FileStorage.__objects) - for key, val in temp.items(): - temp[key] = val.to_dict() - json.dump(temp, f) + """serialize the file path to JSON file path + """ + my_dict = {} + for key, value in self.__objects.items(): + my_dict[key] = value.to_dict() + with open(self.__file_path, 'w', encoding="UTF-8") as f: + json.dump(my_dict, f) def reload(self): - """Loads storage dictionary from file""" - from models.base_model import BaseModel - from models.user import User - from models.place import Place - from models.state import State - from models.city import City - from models.amenity import Amenity - from models.review import Review - - classes = { - 'BaseModel': BaseModel, 'User': User, 'Place': Place, - 'State': State, 'City': City, 'Amenity': Amenity, - 'Review': Review - } + """serialize the file path to JSON file path + """ try: - temp = {} - with open(FileStorage.__file_path, 'r') as f: - temp = json.load(f) - for key, val in temp.items(): - self.all()[key] = classes[val['__class__']](**val) + with open(self.__file_path, 'r', encoding="UTF-8") as f: + for key, value in (json.load(f)).items(): + value = eval(value["__class__"])(**value) + self.__objects[key] = value except FileNotFoundError: pass def delete(self, obj=None): - """Deletes obj from __objects if it’s inside""" - if obj is not None: - key = obj.__class__.__name__ + '.' + obj.id - if key in FileStorage.__objects: - del FileStorage.__objects[key] - self.save() - else: - pass + """ delete an existing element + """ + if obj: + key = "{}.{}".format(type(obj).__name__, obj.id) + del self.__objects[key] def close(self): - """Calls reload() method""" + """ calls reload() + """ self.reload() diff --git a/models/place.py b/models/place.py index 91f7f4e16698..59e6b32561f7 100644 --- a/models/place.py +++ b/models/place.py @@ -67,5 +67,5 @@ def amenities(self): @amenities.setter def amenities(self, value=None): """Adds ids in amenity_ids .""" - if type(value) == type(Amenity): + if isinstance(value, type(Amenity)): self.amenity_ids.append(value.id) diff --git a/models/state.py b/models/state.py index f473fcbaef43..f04a6357ae2a 100644 --- a/models/state.py +++ b/models/state.py @@ -1,24 +1,23 @@ #!/usr/bin/python3 """ State Module for HBNB project """ - +import models from models.base_model import BaseModel, Base +import os from sqlalchemy import Column, String from sqlalchemy.orm import relationship from models.city import City -import models -import os class State(BaseModel, Base): """ State class """ - __tablename__ = 'states' - name = Column(String(128), nullable=False) + __tablename__ = "states" - if os.getenv("HBNB_TYPE_STORAGE") == "db": - cities = relationship('City', backref='state', - cascade='all, delete-orphan') + name = Column(String(128), nullable=False) + if os.getenv('HBNB_TYPE_STORAGE') == 'db': + cities = relationship('City', backref="state", + cascade="all, delete, delete-orphan") else: @property def cities(self): diff --git a/models/user.py b/models/user.py index c7b8aa12ddca..7a42db10d2ba 100644 --- a/models/user.py +++ b/models/user.py @@ -1,16 +1,29 @@ #!/usr/bin/python3 -"""This module defines a class User""" +"""User class""" from models.base_model import BaseModel, Base -from sqlalchemy import Column, String +from sqlalchemy import String, Column from sqlalchemy.orm import relationship class User(BaseModel, Base): - """This class defines a user by various attributes""" + """This is the class for user + Attributes: + email: email address + password: password for you login + first_name: first name + last_name: last name + """ __tablename__ = 'users' - email = Column(String(128), nullable=False, unique=True) + + email = Column(String(128), nullable=False) password = Column(String(128), nullable=False) - first_name = Column(String(128)) - last_name = Column(String(128)) - places = relationship("Place", backref="user", cascade="delete") - reviews = relationship("Review", backref="user", cascade="delete") + first_name = Column(String(128), nullable=True) + last_name = Column(String(128), nullable=True) + places = relationship( + 'Place', + backref='user', + cascade='all, delete-orphan') + reviews = relationship( + 'Review', + backref='user', + cascade='all, delete-orphan') From cf270f52468eb916191ce02c25bd0f6a5f978257 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Fri, 24 Jan 2025 01:14:49 +0200 Subject: [PATCH 27/43] number two --- modelss/__init__.py | 14 ---- modelss/__pycache__/__init__.cpython-312.pyc | Bin 369 -> 0 bytes modelss/__pycache__/amenity.cpython-312.pyc | Bin 441 -> 0 bytes .../__pycache__/base_model.cpython-312.pyc | Bin 2906 -> 0 bytes modelss/__pycache__/city.cpython-312.pyc | Bin 511 -> 0 bytes modelss/__pycache__/place.cpython-312.pyc | Bin 697 -> 0 bytes modelss/__pycache__/review.cpython-312.pyc | Bin 536 -> 0 bytes modelss/__pycache__/state.cpython-312.pyc | Bin 464 -> 0 bytes modelss/__pycache__/user.cpython-312.pyc | Bin 558 -> 0 bytes modelss/amenity.py | 7 -- modelss/base_model.py | 68 ---------------- modelss/city.py | 13 --- modelss/engine/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 156 -> 0 bytes .../__pycache__/file_storage.cpython-312.pyc | Bin 2977 -> 0 bytes modelss/engine/db_storage.py | 75 ------------------ modelss/engine/file_storage.py | 68 ---------------- modelss/place.py | 18 ----- modelss/review.py | 10 --- modelss/state.py | 26 ------ modelss/user.py | 17 ---- 21 files changed, 316 deletions(-) delete mode 100644 modelss/__init__.py delete mode 100644 modelss/__pycache__/__init__.cpython-312.pyc delete mode 100644 modelss/__pycache__/amenity.cpython-312.pyc delete mode 100644 modelss/__pycache__/base_model.cpython-312.pyc delete mode 100644 modelss/__pycache__/city.cpython-312.pyc delete mode 100644 modelss/__pycache__/place.cpython-312.pyc delete mode 100644 modelss/__pycache__/review.cpython-312.pyc delete mode 100644 modelss/__pycache__/state.cpython-312.pyc delete mode 100644 modelss/__pycache__/user.cpython-312.pyc delete mode 100644 modelss/amenity.py delete mode 100644 modelss/base_model.py delete mode 100644 modelss/city.py delete mode 100644 modelss/engine/__init__.py delete mode 100644 modelss/engine/__pycache__/__init__.cpython-312.pyc delete mode 100644 modelss/engine/__pycache__/file_storage.cpython-312.pyc delete mode 100644 modelss/engine/db_storage.py delete mode 100644 modelss/engine/file_storage.py delete mode 100644 modelss/place.py delete mode 100644 modelss/review.py delete mode 100644 modelss/state.py delete mode 100644 modelss/user.py diff --git a/modelss/__init__.py b/modelss/__init__.py deleted file mode 100644 index 5cea926767d0..000000000000 --- a/modelss/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/python3 -"""This module instantiates an object of class FileStorage""" -from os import getenv - - -if getenv('HBNB_TYPE_STORAGE') == 'db': - from models.engine.db_storage import DBStorage - - storage = DBStorage() - storage.reload() -else: - from models.engine.file_storage import FileStorage - storage = FileStorage() - storage.reload() diff --git a/modelss/__pycache__/__init__.cpython-312.pyc b/modelss/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 6c3b0f3c61159e58895d9a62ef16e461d788c8e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 369 zcmX@j%ge<81a~U?)3*WX#~=<2FhLogoq&w#3@Hpz3@MB$OgW6XOi@gX3``8EOskevp8WI5j0Gmk)e`VlcmZ$BqOs}AvZszG$&OdGq1QLF|Q;uu_U!vAu&%OKPf9U zxkMp9O(8iavA9^lEi)%IxFo+QF+KGq$V5%XTii%uewwVe*yH0<@{{A^Z%F~oOwB3Q zOU+Bq%uCfv18R*ghUhI~2I{@V4&~iqD@x7DPfS_K@EK(0FB500n9$yEjS>%-G6rY@vpO+e6W)uT4Iwn3oGcU6wK3=b&@)w5<#1D2w+(1JZfw))>NPJ*s kWMq8EV0)Lr=p!2gw^+As1N#jI_IAETzN-uZMWFBj0J!O79smFU diff --git a/modelss/__pycache__/amenity.cpython-312.pyc b/modelss/__pycache__/amenity.cpython-312.pyc deleted file mode 100644 index 463e2597353dc0b6e0e2afbefd78de4794324096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 441 zcmXv~Jxjzu5S`uJmv5#gesjn{}x2rMzX%E=}aUQ@gXs#A2?%fr4yT-;JhhFY*$+iDO!EQ;cCBbJ7WtuItY|Y9mJ^Y88N11R zInUIze}<_Rp6wp)dFP2xiI*XIzRb4!L*+yc3uGJ#cDv)DjF5?kO?pmmlq>y=5*kR7 zCc+rrI_CY6>Mk;RnI>aA4siZzCDFUU3-wk)D*dBMr=wZfXCj-m_N%oIls;HrpR6JL X7=(~d*!Y0W-v%Me55qq|S2q3wc;{^# diff --git a/modelss/__pycache__/base_model.cpython-312.pyc b/modelss/__pycache__/base_model.cpython-312.pyc deleted file mode 100644 index b55dec37878e7cc590fa0fddc0c9eb48e6a6bae4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2906 zcma)8O-vg{6rTODSsceEf20_ZZej?S29j2!QYj>XL`fq8m71hdU84yC8&n0qg=Xk>Rwq(n^*xm8f95|{S9vDa%7SLsNec{B6g z%=4S?dvAZ$*MN08=5J{S#$* z)(tt8rtF2x%Y#bTteWCTNJ4TXcU&onE2XouL~$*5I(mtKBe|nv2^QsZt^aFL>ztDn68jw4 z9kayoha=N96{ps_I*yd(RiObUs_48quJpjlYwbL**m=+n?7h7tOA>E5cerDs(Ul!3 z%U60EkunYE4bzHQhNS~k5NC!qRRk7ASl;LC8q-SA*qCPf(vyfMRf$=dy)B<~v`log zsFzwk=x!P8Zn@amGHUzcR4ZxNwTi;fswhK|fbA{9f@1h>!L+C?rqjA=d$8}ad0nLf z+cHv96uCt)?6v^j*b=BuB8qKEQB*x{DT?ha`VtXs(bSTowiu&hrtSTF3P*N}iKvsI zZM}QCd-$@cQFAyA{ctRq?&#BLztIm40$Y@;?+h2c8%B;POzxbV#@lp5hubo{%gFC^ z*3dokTj*xVv*5lb{=@6_4R@NC+ZWrHj;z(U&Yih=ZvDXF<>X>=$$-g++a?A7p80_r z1GmM;{-)>QxANhxT)1oX;|CXV$Ilmz4{Qot^B^~O_Et~MFTZa8XD z9&<9OTecUH?L^F?b+AMCLKopFGTRp7Nz+7%$TG#hXV)kSI00zcRf!h1g!|?N=w`|D z;O=j_Zi`=cfB8i|*qjSC-@UjNjNChv3wGoKUAaKl>ZP?n_k*`{f!;Zx5NvXk?lu3= zdcSqG>!;oyd)I<}kEA||^xpQo=nZ?`5fGsAVAa7K%T?ys1k|gSTSb0E*07f45<48( z9UV=`bwWhU^j>Bu!Ia(9AW!MmxExPY3a=m|ZRM$P%_zTt48<)z9y7)?mAwH)NDM*j z{V+1-vP?jC;glr-(TrWyN?|WjyCUrLFz96hZpcyj0IZo9o>}sTbZ9+vX!*$Ek)_T# z@n*0f1?T-Y{9grL4Ig5Vh3_mYQ#v3Pf>7oN?3Nnf6+L*VIcVodbt{#tR_Lnmtz2;2 z3)FJjE*6kPH679MKxM^3FLM+;s>-EAxdgg5IS-uWR4*$qq*_6Jjb#n9E5#~FC09#J&0ucMLpMvF?%O}-D@eQZQbSH^xZS+mvDop8)aI_d zzutJ@j&=9UQfBF7zVTSD@!0B~wZ`MCBe}-+@}X0?(5Z)e*Ft9>Ude^d|0!^d1KeMP ztG&QI4Yz)O^1GAya8EAWvlc!v=Yv!)$%X$|4mLcJ8W>)OA`+G*BQ~Ky5%eiotl%>d zWWSj(bMV U{YG{?Ax(dKTe#2$fsR@J3tpmDrT_o{ diff --git a/modelss/__pycache__/city.cpython-312.pyc b/modelss/__pycache__/city.cpython-312.pyc deleted file mode 100644 index 8cdf2aca54276da804a688138c7befcc9119052d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 511 zcmXw0F-ycS6i(V+Jx{CLq?2S2q@p4Yf+B+TKpnhEmr@9|iF%T2&!i{RNx{L*@qUB& zQ~U#WMF(+m6HXT=U)sAszW2T4z3;ueygE(|!FtP{E(TyfwKHCo5g9H6=^=)E#4s}i zZX3RVk%0~nGanGMxbb3^vA&sAT>Ex`?6=a494D+RI5|%wIrN$y>B!`YM=ANz!7k1x zy-;xo;vy>3OT;5*I1i+UIPx*nHW>CzX80EDN@luNZs{VoE9B&olStQ#M5xpXiIO-C zTd^W44O32z8YGMviNiK0IcmCgUZqrfl;$-`+eMSWrzySehGKLxK`BcjIIb2dw8e5u zUp=FtZtrh>e>*r;T&kc87=)s`y4R9k?9oUhF{d{h0Vs2!0^QnLCzE=d1=v8;EWiUA zSeyOX`rToF%DHdInQ=tZwWR)+yk2Uooxz}Vr(8%q=~BzltjN(~f7PAxDZ8=`t{$SA Z1Nb&E#vf?$9WDLXCZ2iR`bA)h#DC2kgERmD diff --git a/modelss/__pycache__/place.cpython-312.pyc b/modelss/__pycache__/place.cpython-312.pyc deleted file mode 100644 index dfb850751915af5458493538819357822fed5684..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 697 zcmXw1OK;RL5Vn)-`_bL)_8~Zs3qp%TB{-sj)CH-n3M(#LqLr*{Y|>PDEOvrOPpQ-c zH;(-ch@ZlRW3b?WIB`Q-xb(z0-dg&`-`F#r&mMp2_1Xx=_xz)Off4$poSRWwlhu77 zSBN49QA~{xM}}iyWS~Pt%}YcrW_&hvtYhZ2N&Wne{VH@lX1`2m7Bc%y!tJB!Y-%rg za>l&W{;i@XShl9FU=YMYPv>h3LaMRahv^D28W06 zMecjzXH2BBzvO|($Ra0k;Gd?l8M12pFN(x1_@%W zgv{MAdvFl&X*?w!Br@{u(H!o=LNTviU~ido)!NF`fruwyF3~sZcG({khuU;{#q)AB zE>6nLaq*(u+5Kvb%fYZXF1NOeS-CMPj>^F%xTEpK3E#OnZ#J>G`cZPIOYSY8!|Ewn y$kiXwmA4hEa(01TH}~~hKjpW;RoxeA^N)!!{)z7XK==OEyLjuv@jnDpmG~dT#KSEB diff --git a/modelss/__pycache__/review.cpython-312.pyc b/modelss/__pycache__/review.cpython-312.pyc deleted file mode 100644 index 2079022a1cadbaa2bbde018c0d847222c414337d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 536 zcmXw0y-wpm5Z<*NC;TLk6A}%@7AGMiK>-~?NcfPTAq5fzmZg>P4q&vg!`cBt6(ox5 zD0zm{J<7d6u%JLxbVz}Q>SnXaNHg=z&d$uYv;XS#X@c_HdpP?*|E7b9RK{Sqg5Z$| z5)eU!C289VEJ`f0M}&P(gag)J+uRN8Ud3~7f3ickO5mEcGtrg6PBX=db71>^%V!;x zT|iv0cU|Jqa>|c#ILHLZ*fcSgj)UP6f=2=*pvb@yG_ZvgIH(m=w`Y4!>6&r3-ehhp zqdYG%hN^%mLncX)M>{H#EM+BWdDXJUc^b8W^KzPV!xix?=a=0`jx$xxMHb_6ts|ot zcp}PbHwUGGQ@~B}hYU5<@AY4s;SnbCP^ZI4c2{>2<)=Q6WtIZJS`Tpq$UHQB);c|< zS3EKV@?X|6Xjn4k+*G)Aa=Hmv-h-DZz9T!5A3$zz8!0=^DO4 zz<^_5<_MU@jc2o{_06>6R)=fO`5+u{=PYK4;LcSnofEI)Iei)5@@U|E>uQ%|i(aTW z7I6_3{6dq`nXV!j0|%eraDx%wWQK30rfX%De8SK!Cq*Ju%E_SPRWpRXIO9v(})gx!yhr7Xr;!*_(>L3)!*1?VRdLE5L+~f3qC%}GO zs6gra+Wl1OC*`V&KO|?sfeCERvu{;ZSLCB; zfiBu9=}D@xyg(X*fyz3?KxhNIabzOK`e{!vX6lSN%7~{JJ1$cB=9yrO=UsdbMK8^y ziH@+5(_C>=-_MjDR2j@9w&&mtj4l6{?;9&^OHH>ei*_oDuj`p=^;@hf^S)pwKiXJP zNatTVDwUmiWoiiYJemvm8!V5eJ`FcVGmYWasL>q$8qLm~Z>!n&*xfi#c8#XtvMqIR zsI%84wr-A4tT6N8?sU}|S#Pw%1Pd*{!9v1$=;&Uw|&CBKgfJgQ572pS! ACjbBd diff --git a/modelss/amenity.py b/modelss/amenity.py deleted file mode 100644 index a181095e4170..000000000000 --- a/modelss/amenity.py +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/python3 -""" State Module for HBNB project """ -from models.base_model import BaseModel - - -class Amenity(BaseModel): - name = "" diff --git a/modelss/base_model.py b/modelss/base_model.py deleted file mode 100644 index a0c1e57e101a..000000000000 --- a/modelss/base_model.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/python3 -"""This module defines a base class for all models in our hbnb clone""" -import uuid -from datetime import datetime - - -Base = declare_base() - -class BaseModel: - """A base class for all hbnb models""" - id = Column(String(60), nullable=False, primary_key=True) - created_at = Column(DateTime, nullable=False, default=datetime.utcnow()) - updated_at = Column(DateTime, nullable=False, default=datetime.utcnow()) - def __init__(self, *args, **kwargs): - """Instatntiates a new model""" - if not kwargs: - from models import storage - self.id = str(uuid.uuid4()) - self.created_at = datetime.now() - self.updated_at = datetime.now() - - if kwargs: - if "id" not in kwargs: - kwargs["id"] = str(uuid.uuid4()) - if "created_at" not in kwargs: - kwargs["created_at"] = datetime.utcnow().isoformat() - if"updated_at" not in kwargs: - kwargs["updated_at"] = datetime.utcnow().isoformat() - for key, value in kwargs.items(): - if key == "created_at" or key == "updated_at": - value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f") - if key != "__class__": - setattr(self, key, value) - - if '__class__' in kwargs: - del kwargs['__class__'] - self.__dict__.update(kwargs) - - def __str__(self): - """Returns a string representation of the instance""" - cls = (str(type(self)).split('.')[-1]).split('\'')[0] - return '[{}] ({}) {}'.format(cls, self.id, self.__dict__) - - def save(self): - """Updates updated_at with current time when instance is changed""" - from models import storage - self.updated_at = datetime.now() - storage.new(self) - storage.save() - - def to_dict(self): - """Convert instance into dict format""" - dictionary = {} - dictionary.update(self.__dict__) - for key in self.__dict__.keys(): - if key == "_sa_instance_state": - del (dictionary[key]) - dictionary.update({'__class__': - (str(type(self)).split('.')[-1]).split('\'')[0]}) - dictionary['created_at'] = self.created_at.isoformat() - dictionary['updated_at'] = self.updated_at.isoformat() - return dictionary - - def delete(self): - """Deletes the current instance from storage""" - from models import storage - storage.delete(self) - storage.save() diff --git a/modelss/city.py b/modelss/city.py deleted file mode 100644 index 41ed4b3f1c40..000000000000 --- a/modelss/city.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/python3 -""" City Module for HBNB project """ -from models.base_model import BaseModel -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.orm import relationship - - -class City(BaseModel, Base): - """ The city class, contains state ID and name """ - __tablename__ = 'cities' - - name = Column(String(128), nullable=False) - state_id = Column(String(60), nullable=Fallse, ForeignKey="states.id") diff --git a/modelss/engine/__init__.py b/modelss/engine/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/modelss/engine/__pycache__/__init__.cpython-312.pyc b/modelss/engine/__pycache__/__init__.cpython-312.pyc deleted file mode 100644 index 2b267e757d82cfd1b0d17c027f6f2499dcfac319..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmX@j%ge<81a~U?(?RrO5P=Rpvj9b=GgLBYGWxA#C}INgK7-W!vUawL2`x@7Dvl`y zk}-)nrMixpMNWB6@yR*)d8zSbMlrehDXBTdF{yd!nR%%(@$s2?nI-Y@dIgogIBbA& br8%i~MXW%x7=gGL#Q4a}$jDg43}gWS{8T3E diff --git a/modelss/engine/__pycache__/file_storage.cpython-312.pyc b/modelss/engine/__pycache__/file_storage.cpython-312.pyc deleted file mode 100644 index e4d3265600f97ef975d03e4447859fa2d6b1db31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2977 zcma)8U2Ggz6~1?Vc4qb`_BzD*aek)uChfS`r7;#2DIl*++t{f=H3-Er8f|uFlikej zxOc`jyV{lf(1%1I;y@)QxKfHhs!?A2gu)Xc@WxA5E%J6qBoO6+H^)Y@WL`Mu&W``e z19x}NJ@@aNbIxCjLd%nx~ zz-9W4Yn5xT%dOb|LV1(Z z72m0%1#K@G0>gL&$IN|~F-`Yc$@Bnz1X_Aw)BHGqbH}aJCwVImfAW?9(&|6A6&*9RadPKJPfS-jQi` zWIk3iTQEcN`|pZ|a*x~sW|`DUX}`a4JG6&kM@qQ!P^;6Dd}s=W(Fu#5gpnoGfWl6I z?co-#6zRjZUP`K>A=S>0SeB<(>;*k^8v-%{;a(sD%>*|AUQKg{4o(^p(?EU@o13+A zz8xsOYvSfWC|VE{1=mE7=b;C5ovC~RlpORQOmx7C_f;T^~toAf}h98N|o=cDNzc2i*(Cis|od5XL_+QishIx7bcX)5^Eo z{oPoUFcOEFMWd7*CJkC74WTZS@D_*KJ}G#mLv7Eqa2kPes70|FBR@Pr$P8H25F1im zDy0r>gkiL|F4V=>Vf>R*67kVlyp=j5Zm)-(ySJc#1pGv|f>;ZE5ZVMOLe&(t1FiFfznVl0-)9WGoYO}|7^sS z^oZN*t#||sfP38Ui&jdRh}-My@d(xpt*(_`+*^sb2&w>UIL~37Xe0$vSL;bDfn|x8 zrc{yClfR}vrBM2e=%HRUpw9gdh!>b!<{)QSBH+=`vN_Lw8(%woLGa0dUjD9=%iG9I`B3q2Wwhv5 zp;t!Ab|qwE@7VK2d%;kc4x-o#NP3Z=hZ#DTokwy3NI)4wBu)N?7~MfSe0m12fohZU zTttv)&*PKD<3o7=^Xp@kBX zZX{5tAblP19y^X>UiZ_OlasFhhC5fWzRj4+j1$P2uoT3YjV9E(_7{V24$pdj08&I-7Z}NJqbPOWBAkTAJ62r|Dzw-(2q=Xm$^*dY`0+Hi(#-plk0wJ>Iiiy<7b- z{qy>g)Y3B_#eW(9RT9cadV=14Yiab}(N_QH>WgcAYd4!0v(5g|X8-u(Jdk_R1NFYT z68~`M7ah+<+`cWN$Zan8Ij8^mw@Nx+0AX7Cvt%b!9xc7&;lH`xp3V-FKXi?xvWECX zS7GqPkh2$+CxasL7dai)MydEmLV->i@jx}r3WU})gSd$Rg1?%;Cr$I+xt!BpQB2cv z^QIXF7Hc$*ChI~D3kDlP@)8n!S-I;&C?Fp2fR_RC9{Ehlwz|$NPP96^7B6o~f_#2c z733>)Q&r@1TV369IuwA%43T{eIu4{z*g*w5>g%Ds-(;`BK76q~#2`3?(!Y~8|4I_u Nu`ko~CIQ05{uf|Eo2UQ) diff --git a/modelss/engine/db_storage.py b/modelss/engine/db_storage.py deleted file mode 100644 index 399e5896fbf9..000000000000 --- a/modelss/engine/db_storage.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/python3 -"""This module defines a class to manage database storage for hbnb clone""" - -from os import getenv -from models.base_model import Base -from models.base_model import BaseModel -from models.user import User -from models.place import Place -from models.state import State -from models.city import City -from models.amenity import Amenity -from models.review import Review -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker - - -class DBStorage: - """This class manages storage for hbnb clone""" - __engine = None - __session = None - - def __init__(self): - """Initializes a new DBStorage instance""" - self.__engine = create_engine( - 'mysql+mysqldb://{}:{}@localhost:3306/{}'.format( - getenv('HBNB_MYSQL_USER'), - getenv('HBNB_MYSQL_PWD'), - getenv('HBNB_MYSQL_HOST'), - getenv('HBNB_MYSQL_DB'), - pool_pre_ping=True - ) - ) - - if os.getenv('HBNB_ENV') == 'test': - Base.metadata.drop_all(self._engine) - - def all(self, cls=None): - """Returns a dictionary of all objects""" - classes = [User, State, City, Place, Amenity, Review] - new_dict = {} - if cls is None: - for c in classes: - for obj in self._session.query(c).all(): - key = obj.__class__.__name__ + '.' + obj.id - new_dict[key] = obj - else: - for obj in self._session.query(cls).all(): - key = obj.__class__.__name__ + '.' + obj.id - new_dict[key] = obj - return new_dict - - def new(self, obj): - """Adds a new object to the database""" - self._session.add(obj) - - def save(self): - """Saves all changes to the database""" - self._session.commit() - - def delete(self, obj=None): - """Deletes an object from the database""" - if obj is not None: - self._session.delete(obj) - - def reload(self): - """Reloads all tables""" - Base.metadata.create_all(self._engine) - session_factory = sessionmaker(bind=self._engine, - expire_on_commit=False) - Session = scoped_session(session_factory) - self._session = Session() - - def close(self): - """Close the session""" - self._session.close() diff --git a/modelss/engine/file_storage.py b/modelss/engine/file_storage.py deleted file mode 100644 index b56870811dc4..000000000000 --- a/modelss/engine/file_storage.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/python3 -"""This module defines a class to manage file storage for hbnb clone""" -import json - - -class FileStorage: - """This class manages storage of hbnb models in JSON format""" - __file_path = 'file.json' - __objects = {} - - def all(self, cls=None): - """Returns a dictionary of models currently in storage""" - if cls is None: - return FileStorage.__objects - else: - new_dict = {} - for key, value in FileStorage.__objects.items(): - if cls == value.__class__ or cls == value.__class__.__name__: - new_dict[key] = value - return new_dict - - def new(self, obj): - """Adds new object to storage dictionary""" - self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) - - def save(self): - """Saves storage dictionary to file""" - with open(FileStorage.__file_path, 'w') as f: - temp = {} - temp.update(FileStorage.__objects) - for key, val in temp.items(): - temp[key] = val.to_dict() - json.dump(temp, f) - - def reload(self): - """Loads storage dictionary from file""" - from models.base_model import BaseModel - from models.user import User - from models.place import Place - from models.state import State - from models.city import City - from models.amenity import Amenity - from models.review import Review - - classes = { - 'BaseModel': BaseModel, 'User': User, 'Place': Place, - 'State': State, 'City': City, 'Amenity': Amenity, - 'Review': Review - } - try: - temp = {} - with open(FileStorage.__file_path, 'r') as f: - temp = json.load(f) - for key, val in temp.items(): - self.all()[key] = classes[val['__class__']](**val) - except FileNotFoundError: - pass - - def delete(self, obj=None): - """Delete obj from __objects if it's inside""" - if obj is not None: - key = obj.__class__.__name__ + '.' + obj.id - if key in self.__objects: - del self.__objects[key] - self.save() - - else: - pass diff --git a/modelss/place.py b/modelss/place.py deleted file mode 100644 index 5221e8210d17..000000000000 --- a/modelss/place.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/python3 -""" Place Module for HBNB project """ -from models.base_model import BaseModel - - -class Place(BaseModel): - """ A place to stay """ - city_id = "" - user_id = "" - name = "" - description = "" - number_rooms = 0 - number_bathrooms = 0 - max_guest = 0 - price_by_night = 0 - latitude = 0.0 - longitude = 0.0 - amenity_ids = [] diff --git a/modelss/review.py b/modelss/review.py deleted file mode 100644 index c487d90d34f0..000000000000 --- a/modelss/review.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/python3 -""" Review module for the HBNB project """ -from models.base_model import BaseModel - - -class Review(BaseModel): - """ Review classto store review information """ - place_id = "" - user_id = "" - text = "" diff --git a/modelss/state.py b/modelss/state.py deleted file mode 100644 index 03836a664c22..000000000000 --- a/modelss/state.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python3 -""" State Module for HBNB project """ -from models.base_model import BaseModel -from models.city import City -import os -import models -from sqlalchemy import Column, String, ForeignKey -from sqlalchemy.orm import relationship - - -class State(BaseModel, Base): - """ State class """ - __tablename__ = 'states' - name = Column(String(128), nukllable=False) - - if os.getenv("HBNB_TYPE_STORAGE") == "db": - cities = relationship("City", backref="state", cascade="all, delete-orphan") - - else: - @property - def cities(self): - """returns the list of City instances with state_id equals to the - current State.id - """ - return [city for city in list(models.storage.all(City).values()) - if city.state_id == self.id] \ No newline at end of file diff --git a/modelss/user.py b/modelss/user.py deleted file mode 100644 index 5c6d36edfb21..000000000000 --- a/modelss/user.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/python3 -"""This module defines a class User""" -from models.base_model import BaseModel -from sqlalchemy import Column, String -from sqlalchemy.orm import relationship - - -class User(BaseModel, Base): - """This class defines a user by various attributes""" - __tablename__ = 'users' - email = Column(String(128), nullable=False) - password = Column(String(128), nullable=False) - first_name = Column(String(128), nullable=True) - last_name = Column(String(128), nullable=True) - places = relationship("Place", backref="user", cascade="all, delete") - reviews = relationship("Review", backref="user", cascade="all, delete") - \ No newline at end of file From 7b9cd246258d42a435d53748847f9ddf1c691866 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Fri, 24 Jan 2025 20:06:50 +0200 Subject: [PATCH 28/43] TestConsoleFile --- tests/test_console.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/test_console.py diff --git a/tests/test_console.py b/tests/test_console.py new file mode 100644 index 000000000000..764f11c488f4 --- /dev/null +++ b/tests/test_console.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +""" +Contains the class TestConsoleDocs +""" + +import console +import pep8 +import unittest +HBNBCommand = console.HBNBCommand + + +class TestConsoleDocs(unittest.TestCase): + """Class for testing documentation of the console""" + + def test_pep8_conformance_console(self): + """Test that console.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['console.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_pep8_conformance_test_console(self): + """Test that tests/test_console.py conforms to PEP8.""" + pep8s = pep8.StyleGuide(quiet=True) + result = pep8s.check_files(['tests/test_console.py']) + self.assertEqual(result.total_errors, 0, + "Found code style errors (and warnings).") + + def test_console_module_docstring(self): + """Test for the console.py module docstring""" + self.assertIsNot(console.__doc__, None, + "console.py needs a docstring") + self.assertTrue(len(console.__doc__) >= 1, + "console.py needs a docstring") + + def test_HBNBCommand_class_docstring(self): + """Test for the HBNBCommand class docstring""" + self.assertIsNot(HBNBCommand.__doc__, None, + "HBNBCommand class needs a docstring") + self.assertTrue(len(HBNBCommand.__doc__) >= 1, + "HBNBCommand class needs a docstring") \ No newline at end of file From 68cd37f0162caf770fa2db4107b06fb38134a707 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Fri, 24 Jan 2025 20:08:55 +0200 Subject: [PATCH 29/43] TestFilleStorage --- .../test_engine/test_file_storage.py | 223 +++++++++--------- 1 file changed, 114 insertions(+), 109 deletions(-) diff --git a/tests/test_models/test_engine/test_file_storage.py b/tests/test_models/test_engine/test_file_storage.py index e1de7198b697..c80a064c9a89 100755 --- a/tests/test_models/test_engine/test_file_storage.py +++ b/tests/test_models/test_engine/test_file_storage.py @@ -1,109 +1,114 @@ -#!/usr/bin/python3 -""" Module for testing file storage""" -import unittest -from models.base_model import BaseModel -from models import storage -import os - - -class test_fileStorage(unittest.TestCase): - """ Class to test the file storage method """ - - def setUp(self): - """ Set up test environment """ - del_list = [] - for key in storage._FileStorage__objects.keys(): - del_list.append(key) - for key in del_list: - del storage._FileStorage__objects[key] - - def tearDown(self): - """ Remove storage file at end of tests """ - try: - os.remove('file.json') - except: - pass - - def test_obj_list_empty(self): - """ __objects is initially empty """ - self.assertEqual(len(storage.all()), 0) - - def test_new(self): - """ New object is correctly added to __objects """ - new = BaseModel() - for obj in storage.all().values(): - temp = obj - self.assertTrue(temp is obj) - - def test_all(self): - """ __objects is properly returned """ - new = BaseModel() - temp = storage.all() - self.assertIsInstance(temp, dict) - - def test_base_model_instantiation(self): - """ File is not created on BaseModel save """ - new = BaseModel() - self.assertFalse(os.path.exists('file.json')) - - def test_empty(self): - """ Data is saved to file """ - new = BaseModel() - thing = new.to_dict() - new.save() - new2 = BaseModel(**thing) - self.assertNotEqual(os.path.getsize('file.json'), 0) - - def test_save(self): - """ FileStorage save method """ - new = BaseModel() - storage.save() - self.assertTrue(os.path.exists('file.json')) - - def test_reload(self): - """ Storage file is successfully loaded to __objects """ - new = BaseModel() - storage.save() - storage.reload() - for obj in storage.all().values(): - loaded = obj - self.assertEqual(new.to_dict()['id'], loaded.to_dict()['id']) - - def test_reload_empty(self): - """ Load from an empty file """ - with open('file.json', 'w') as f: - pass - with self.assertRaises(ValueError): - storage.reload() - - def test_reload_from_nonexistent(self): - """ Nothing happens if file does not exist """ - self.assertEqual(storage.reload(), None) - - def test_base_model_save(self): - """ BaseModel save method calls storage save """ - new = BaseModel() - new.save() - self.assertTrue(os.path.exists('file.json')) - - def test_type_path(self): - """ Confirm __file_path is string """ - self.assertEqual(type(storage._FileStorage__file_path), str) - - def test_type_objects(self): - """ Confirm __objects is a dict """ - self.assertEqual(type(storage.all()), dict) - - def test_key_format(self): - """ Key is properly formatted """ - new = BaseModel() - _id = new.to_dict()['id'] - for key in storage.all().keys(): - temp = key - self.assertEqual(temp, 'BaseModel' + '.' + _id) - - def test_storage_var_created(self): - """ FileStorage object storage created """ - from models.engine.file_storage import FileStorage - print(type(storage)) - self.assertEqual(type(storage), FileStorage) +#!/usr/bin/python3 +""" Module for testing file storage""" +import unittest + +import models +from models.base_model import BaseModel +import os + + +@unittest.skipIf(os.getenv('HBNB_TYPE_STORAGE') == 'db', "skip if not db") +class TestFileStorage(unittest.TestCase): + """ Class to test the file storage method """ + + def setUp(self): + """ Set up test environment """ + self.storage = models.storage + del_list = [] + for key in self.storage._FileStorage__objects.keys(): + del_list.append(key) + for key in del_list: + del self.storage._FileStorage__objects[key] + + def tearDown(self): + """ Remove storage file at end of tests """ + try: + os.remove('file.json') + except: + pass + + del self.storage + + def test_obj_list_empty(self): + """ __objects is initially empty """ + self.assertEqual(len(self.storage.all()), 0) + + def test_new(self): + """ New object is correctly added to __objects """ + new = BaseModel() + for obj in self.storage.all().values(): + temp = obj + self.assertTrue(temp is obj) + + def test_all(self): + """ __objects is properly returned """ + new = BaseModel() + temp = self.storage.all() + self.assertIsInstance(temp, dict) + + def test_base_model_instantiation(self): + """ File is not created on BaseModel save """ + new = BaseModel() + self.assertFalse(os.path.exists('file.json')) + + def test_empty(self): + """ Data is saved to file """ + new = BaseModel() + thing = new.to_dict() + new.save() + new2 = BaseModel(**thing) + self.assertNotEqual(os.path.getsize('file.json'), 0) + + def test_save(self): + """ FileStorage save method """ + new = BaseModel() + self.storage.save() + self.assertTrue(os.path.exists('file.json')) + + def test_reload(self): + """ Storage file is successfully loaded to __objects """ + new = BaseModel() + self.storage.save() + self.storage.reload() + for obj in self.storage.all().values(): + loaded = obj + self.assertEqual(new.to_dict()['id'], loaded.to_dict()['id']) + + def test_reload_empty(self): + """ Load from an empty file """ + with open('file.json', 'w') as f: + pass + with self.assertRaises(ValueError): + self.storage.reload() + + def test_reload_from_nonexistent(self): + """ Nothing happens if file does not exist """ + self.assertEqual(self.storage.reload(), None) + + def test_base_model_save(self): + """ BaseModel save method calls storage save """ + new = BaseModel() + new.save() + self.assertTrue(os.path.exists('file.json')) + + def test_type_path(self): + """ Confirm __file_path is string """ + self.assertEqual(type(self.storage._FileStorage__file_path), str) + + def test_type_objects(self): + """ Confirm __objects is a dict """ + self.assertEqual(type(self.storage.all()), dict) + + def test_key_format(self): + """ Key is properly formatted """ + new = BaseModel() + _id = new.to_dict()['id'] + for key in self.storage.all().keys(): + temp = key + self.assertEqual(temp, 'BaseModel' + '.' + _id) + + def test_storage_var_created(self): + """ FileStorage object storage created """ + from models.engine.file_storage import FileStorage + print(type(self.storage)) + self.assertEqual(type(self.storage), FileStorage) From c270b91749b22db430730b1690bfae76bfc7d3c1 Mon Sep 17 00:00:00 2001 From: milkakeza Date: Fri, 24 Jan 2025 20:09:53 +0200 Subject: [PATCH 30/43] TestDB --- .../test_engine/test_db_storage.py | 103 ++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 tests/test_models/test_engine/test_db_storage.py diff --git a/tests/test_models/test_engine/test_db_storage.py b/tests/test_models/test_engine/test_db_storage.py new file mode 100644 index 000000000000..63ed1db3cfc0 --- /dev/null +++ b/tests/test_models/test_engine/test_db_storage.py @@ -0,0 +1,103 @@ +#!/usr/bin/python3 +import unittest +import models +from models.user import User +from models.review import Review +from models.amenity import Amenity +from models.state import State +from models.place import Place +from models.city import City +import os + + +# skip these test if the storage is not db +@unittest.skipIf(os.getenv('HBNB_TYPE_STORAGE') != 'db', "skip if not fs") +class TestDBStorage(unittest.TestCase): + """DB Storage test""" + + def setUp(self): + """ Set up test environment """ + self.storage = models.storage + + def tearDown(self): + """ Remove storage file at end of tests """ + del self.storage + + def test_user(self): + """ Tests user """ + user = User(name="Chyna", email="chyna@gmail.com", password="Chyna12345") + user.save() + self.assertFalse(user.id in self.storage.all()) + self.assertEqual(user.name, "Chyna") + + def test_city(self): + """ test city """ + state = State(name="California") + state.save() + city = City(name="Batch") + city.state_id = state.id + city.save() + self.assertFalse(city.id in self.storage.all()) + self.assertEqual(city.name, "Batch") + + def test_state(self): + """ test state""" + state = State(name="California") + state.save() + self.assertFalse(state.id in self.storage.all()) + self.assertEqual(state.name, "California") + + def test_place(self): + """Test place""" + state = State(name="California") + state.save() + + city = City(name="Batch") + city.state_id = state.id + city.save() + + user = User(name="Chyna", email="chyna@gmail.com", password="Chyna12345") + user.save() + + place = Place(name="Palace", number_rooms=4) + place.city_id = city.id + place.user_id = user.id + place.save() + + self.assertFalse(place.id in self.storage.all()) + self.assertEqual(place.number_rooms, 4) + self.assertEqual(place.name, "Palace") + + def test_amenity(self): + """ test amenity """ + amenity = Amenity(name="Startlink") + amenity.save() + self.assertFalse(amenity.id in self.storage.all()) + self.assertTrue(amenity.name, "Startlink") + + def test_review(self): + """ test review """ + state = State(name="California") + state.save() + + city = City(name="Batch") + city.state_id = state.id + city.save() + + user = User(name="Chyna", email="chyna@gmail.com", password="Chyna12345") + user.save() + + place = Place(name="Palace", number_rooms=4) + place.city_id = city.id + place.user_id = user.id + place.save() + + review = Review(text="no comment", place_id=place.id, user_id=user.id) + review.save() + + self.assertFalse(review.id in self.storage.all()) + self.assertEqual(review.text, "no comment") + + +if __name__ == '__main__': + unittest.main() From 9498b0a8e44f6bbec001867c3137b71a06c3cfbd Mon Sep 17 00:00:00 2001 From: milkakeza Date: Fri, 24 Jan 2025 20:19:21 +0200 Subject: [PATCH 31/43] FileStorage --- models/engine/file_storage.py | 144 +++++++++++++++++----------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/models/engine/file_storage.py b/models/engine/file_storage.py index 25f5e066e336..eca2dcf3b267 100644 --- a/models/engine/file_storage.py +++ b/models/engine/file_storage.py @@ -1,73 +1,71 @@ -#!/usr/bin/python3 -"""This is the file storage class for AirBnB""" -import json -import shlex - - -class FileStorage: - """This class serializes instances to a JSON file and - deserializes JSON file to instances - Attributes: - __file_path: path to the JSON file - __objects: objects will be stored - """ - __file_path = "file.json" - __objects = {} - - def all(self, cls=None): - """returns a dictionary - Return: - returns a dictionary of __object - """ - dic = {} - if cls: - dictionary = self.__objects - for key in dictionary: - partition = key.replace('.', ' ') - partition = shlex.split(partition) - if (partition[0] == cls.__name__): - dic[key] = self.__objects[key] - return (dic) - else: - return self.__objects - - def new(self, obj): - """sets __object to given obj - Args: - obj: given object - """ - if obj: - key = "{}.{}".format(type(obj).__name__, obj.id) - self.__objects[key] = obj - - def save(self): - """serialize the file path to JSON file path - """ - my_dict = {} - for key, value in self.__objects.items(): - my_dict[key] = value.to_dict() - with open(self.__file_path, 'w', encoding="UTF-8") as f: - json.dump(my_dict, f) - - def reload(self): - """serialize the file path to JSON file path - """ - try: - with open(self.__file_path, 'r', encoding="UTF-8") as f: - for key, value in (json.load(f)).items(): - value = eval(value["__class__"])(**value) - self.__objects[key] = value - except FileNotFoundError: - pass - - def delete(self, obj=None): - """ delete an existing element - """ - if obj: - key = "{}.{}".format(type(obj).__name__, obj.id) - del self.__objects[key] - - def close(self): - """ calls reload() - """ - self.reload() +#!/usr/bin/python3 +"""This module defines a class to manage file storage for hbnb clone""" +import json + + +class FileStorage: + """This class manages storage of hbnb models in JSON format""" + __file_path = 'file.json' + __objects = {} + + def all(self, cls=None): + """Returns a dictionary of models currently in storage""" + if cls is None: + return FileStorage.__objects + else: + temp = {} + for key, val in FileStorage.__objects.items(): + if cls.__name__ in key: + temp[key] = val + return temp + + def new(self, obj): + """Adds new object to storage dictionary""" + self.all().update({obj.to_dict()['__class__'] + '.' + obj.id: obj}) + + def save(self): + """Saves storage dictionary to file""" + with open(FileStorage.__file_path, 'w') as f: + temp = {} + temp.update(FileStorage.__objects) + for key, val in temp.items(): + temp[key] = val.to_dict() + json.dump(temp, f) + + def reload(self): + """Loads storage dictionary from file""" + from models.base_model import BaseModel + from models.user import User + from models.place import Place + from models.state import State + from models.city import City + from models.amenity import Amenity + from models.review import Review + + classes = { + 'BaseModel': BaseModel, 'User': User, 'Place': Place, + 'State': State, 'City': City, 'Amenity': Amenity, + 'Review': Review + } + try: + temp = {} + with open(FileStorage.__file_path, 'r') as f: + temp = json.load(f) + for key, val in temp.items(): + self.all()[key] = classes[val['__class__']](**val) + except FileNotFoundError: + pass + + def delete(self, obj=None): + """Deletes obj from __objects if s inside""" + if obj is not None: + key = obj.__class__.__name__ + '.' + obj.id + if key in FileStorage.__objects: + del FileStorage.__objects[key] + self.save() + else: + pass + + def close(self): + """Calls reload() method""" + self.reload() From 5c69b7fb47d46e802e13dc55be36727ab5962a4d Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Sat, 25 Jan 2025 20:31:34 +0200 Subject: [PATCH 32/43] pull one --- models/user.py | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/models/user.py b/models/user.py index 7a42db10d2ba..495c3fa86eca 100644 --- a/models/user.py +++ b/models/user.py @@ -1,29 +1,16 @@ #!/usr/bin/python3 -"""User class""" +"""This module defines a class User""" from models.base_model import BaseModel, Base -from sqlalchemy import String, Column +from sqlalchemy import Column, String from sqlalchemy.orm import relationship class User(BaseModel, Base): - """This is the class for user - Attributes: - email: email address - password: password for you login - first_name: first name - last_name: last name - """ - __tablename__ = 'users' - + """This class defines a user by various attributes""" + __tablename__ = "users" email = Column(String(128), nullable=False) password = Column(String(128), nullable=False) - first_name = Column(String(128), nullable=True) - last_name = Column(String(128), nullable=True) - places = relationship( - 'Place', - backref='user', - cascade='all, delete-orphan') - reviews = relationship( - 'Review', - backref='user', - cascade='all, delete-orphan') + first_name = Column(String(128)) + last_name = Column(String(128)) + places = relationship('Place', backref='user', cascade='delete') + reviews = relationship('Review', backref='user', cascade='delete') \ No newline at end of file From fb228e2feda9d3c755f833829ffe498e76f44487 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Sat, 25 Jan 2025 20:52:35 +0200 Subject: [PATCH 33/43] new changes --- models/review.py | 1 - models/user.py | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/models/review.py b/models/review.py index f1a7632015d6..8fd47bbf8dc2 100644 --- a/models/review.py +++ b/models/review.py @@ -7,7 +7,6 @@ class Review(BaseModel, Base): """ Review class to store review information """ __tablename__ = 'reviews' - place_id = Column(String(60), ForeignKey("places.id"), nullable=False) user_id = Column(String(60), ForeignKey("users.id"), nullable=False) text = Column(String(1024), nullable=False) diff --git a/models/user.py b/models/user.py index 495c3fa86eca..11bbcedb3793 100644 --- a/models/user.py +++ b/models/user.py @@ -1,16 +1,18 @@ #!/usr/bin/python3 """This module defines a class User""" -from models.base_model import BaseModel, Base from sqlalchemy import Column, String from sqlalchemy.orm import relationship +from models.base_model import BaseModel, Base class User(BaseModel, Base): - """This class defines a user by various attributes""" - __tablename__ = "users" + """ + This class defines a user by various attributes + """ + __tablename__ = 'users' email = Column(String(128), nullable=False) password = Column(String(128), nullable=False) - first_name = Column(String(128)) - last_name = Column(String(128)) - places = relationship('Place', backref='user', cascade='delete') - reviews = relationship('Review', backref='user', cascade='delete') \ No newline at end of file + first_name = Column(String(128), nullable=False) + last_name = Column(String(128), nullable=False) + places = relationship('Place', backref='user', cascade='all, delete-orphan') + reviews = relationship('Review', backref='user', cascade='all, delete-orphan') From 0ef662de5db46188c267d025a9ae2900c7a23eb7 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Sat, 25 Jan 2025 21:01:01 +0200 Subject: [PATCH 34/43] new changes 1 --- models/user.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/models/user.py b/models/user.py index 11bbcedb3793..4d398c7b6a0d 100644 --- a/models/user.py +++ b/models/user.py @@ -12,7 +12,7 @@ class User(BaseModel, Base): __tablename__ = 'users' email = Column(String(128), nullable=False) password = Column(String(128), nullable=False) - first_name = Column(String(128), nullable=False) - last_name = Column(String(128), nullable=False) + first_name = Column(String(128), nullable=True) + last_name = Column(String(128), nullable=True) places = relationship('Place', backref='user', cascade='all, delete-orphan') - reviews = relationship('Review', backref='user', cascade='all, delete-orphan') + reviews = relationship('Review', backref='user', cascade='all, delete-orphan') \ No newline at end of file From 784d7d32a1ed501dfd2a41878113bd5ec91264dd Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Sat, 25 Jan 2025 21:03:55 +0200 Subject: [PATCH 35/43] new changes 1 --- models/amenity.py | 12 ++--- models/place.py | 114 +++++++++++++++++++++++++++------------------- 2 files changed, 72 insertions(+), 54 deletions(-) diff --git a/models/amenity.py b/models/amenity.py index db9369e1ffd0..88817f551ab7 100644 --- a/models/amenity.py +++ b/models/amenity.py @@ -1,15 +1,15 @@ #!/usr/bin/python3 """ State Module for HBNB project """ -import os - from models.base_model import BaseModel, Base from sqlalchemy import Column, String from sqlalchemy.orm import relationship +from models.place import association_table class Amenity(BaseModel, Base): - """Amenities of a place""" - __tablename__ = 'amenities' + """Amenity model of hbnb project""" + __tablename__ = "amenities" name = Column(String(128), nullable=False) - if os.getenv('HBNB_TYPE_STORAGE') == 'db': - place_amenities = relationship('Place', secondary="place_amenity") + place_amenities = relationship( + "Place", + secondary=association_table,) \ No newline at end of file diff --git a/models/place.py b/models/place.py index 59e6b32561f7..bf22b592c092 100644 --- a/models/place.py +++ b/models/place.py @@ -1,71 +1,89 @@ #!/usr/bin/python3 """ Place Module for HBNB project """ -import os - from models.base_model import BaseModel, Base -from sqlalchemy import Column, String, Integer, Float, ForeignKey, Table -from sqlalchemy.orm import relationship -from models.review import Review -from models.amenity import Amenity import models +from os import getenv + + +from sqlalchemy import ( + Column, + String, + ForeignKey, + Integer, + Float, + Table +) -place_amenity = Table('place_amenity', Base.metadata, - Column('place_id', String(60), - ForeignKey('places.id'), - primary_key=True, nullable=False), - Column('amenity_id', String(60), - ForeignKey('amenities.id'), - primary_key=True, nullable=False)) +from sqlalchemy.orm import relationship + +metadata = Base.metadata + +association_table = Table( + "place_amenity", + metadata, + Column( + "place_id", + String(60), + ForeignKey("places.id"), + primary_key=True, + nullable=False + ), + Column( + "amenity_id", + String(60), + ForeignKey("amenities.id"), + primary_key=True, + nullable=False + )) class Place(BaseModel, Base): - """ A place to stay """ - __tablename__ = 'places' - city_id = Column(String(60), ForeignKey("cities.id", ondelete="CASCADE"), - nullable=False) - user_id = Column(String(60), ForeignKey("users.id", ondelete="CASCADE"), - nullable=False) + """ A place to stay """ + __tablename__ = "places" + city_id = Column(String(60), ForeignKey("cities.id"), nullable=False) + user_id = Column(String(60), ForeignKey("users.id"), nullable=False) name = Column(String(128), nullable=False) - description = Column(String(1024), nullable=True) + description = Column(String(1024)) number_rooms = Column(Integer, nullable=False, default=0) number_bathrooms = Column(Integer, nullable=False, default=0) max_guest = Column(Integer, nullable=False, default=0) price_by_night = Column(Integer, nullable=False, default=0) - latitude = Column(Float, nullable=True) - longitude = Column(Float, nullable=True) - amenity_ids = [] + latitude = Column(Float) + longitude = Column(Float) - if os.getenv("HBNB_TYPE_STORAGE") == "db": - reviews = relationship("Review", backref="place") - amenities = relationship("Amenity", secondary="place_amenity", - viewonly=False, - back_populates="place_amenities") + reviews = relationship("Review", backref="place", cascade="delete") + amenities = relationship( + "Amenity", + secondary=association_table, + viewonly=False + ) + amenity_ids = [] - if os.getenv("HBNB_TYPE_STORAGE") != "db": + if getenv("HBNB_TYPE_STORAGE", None) != "db": @property def reviews(self): - """Returns the list of Review instances with place_id equals - to the current Place.id.""" - - reviews = list(models.storage.all(Review).values()) - - return list( - filter(lambda review: (review.place_id == self.id), reviews)) + """Getter method for reviews attribute for FileStorage""" + from models.review import Review + review_list = [] + for review in list(models.storage.all(Review).values()): + if review.place_id == self.id: + review_list.append(review) + return review @property def amenities(self): - """Returns the list of Amenity instances based on - the attribute amenity_ids that contains all Amenity.id.""" - - amenities = list(models.storage.all(Amenity).values()) - - return list( - filter(lambda amenity: (amenity.place_id in self.amenity_ids), - amenities)) + """Getter method for amenities attribute for FileStorage""" + from models.amenity import Amenity + amenity_list = [] + for amenity in list(models.storage.all(Amenity).values()): + if amenity.id in self.amenity_ids: + amenity_list.append(amenity) + return amenity_list @amenities.setter - def amenities(self, value=None): - """Adds ids in amenity_ids .""" - if isinstance(value, type(Amenity)): - self.amenity_ids.append(value.id) + def amenities(self, value): + """Setter method for amenities property for FileStorage""" + from models.amenity import Amenity + if type(value) is Amenity: + self.amenity_ids.append(value.id) \ No newline at end of file From 11f96000e008870ce970e776b9c376467a09ab9c Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Sat, 25 Jan 2025 21:16:33 +0200 Subject: [PATCH 36/43] lol --- models/user.py | 1 - 1 file changed, 1 deletion(-) diff --git a/models/user.py b/models/user.py index 4d398c7b6a0d..2bb16870856a 100644 --- a/models/user.py +++ b/models/user.py @@ -4,7 +4,6 @@ from sqlalchemy.orm import relationship from models.base_model import BaseModel, Base - class User(BaseModel, Base): """ This class defines a user by various attributes From 49f9f65be313f8d00534c11b0213c11cad9d4343 Mon Sep 17 00:00:00 2001 From: DLOADIN Date: Sat, 25 Jan 2025 11:17:02 -0800 Subject: [PATCH 37/43] sasa --- models/__init__.py | 0 models/amenity.py | 0 models/base_model.py | 0 models/city.py | 0 models/place.py | 0 models/review.py | 0 models/state.py | 0 models/user.py | 0 8 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 models/__init__.py mode change 100644 => 100755 models/amenity.py mode change 100644 => 100755 models/base_model.py mode change 100644 => 100755 models/city.py mode change 100644 => 100755 models/place.py mode change 100644 => 100755 models/review.py mode change 100644 => 100755 models/state.py mode change 100644 => 100755 models/user.py diff --git a/models/__init__.py b/models/__init__.py old mode 100644 new mode 100755 diff --git a/models/amenity.py b/models/amenity.py old mode 100644 new mode 100755 diff --git a/models/base_model.py b/models/base_model.py old mode 100644 new mode 100755 diff --git a/models/city.py b/models/city.py old mode 100644 new mode 100755 diff --git a/models/place.py b/models/place.py old mode 100644 new mode 100755 diff --git a/models/review.py b/models/review.py old mode 100644 new mode 100755 diff --git a/models/state.py b/models/state.py old mode 100644 new mode 100755 diff --git a/models/user.py b/models/user.py old mode 100644 new mode 100755 From d11360934f30bdbf0129589d9ba1c85ed6d416ee Mon Sep 17 00:00:00 2001 From: Lemanzi David <166613293+DLOADIN@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:23:47 +0200 Subject: [PATCH 38/43] Create 0-setup_web_static.sh --- 0-setup_web_static.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 0-setup_web_static.sh diff --git a/0-setup_web_static.sh b/0-setup_web_static.sh new file mode 100644 index 000000000000..75b212057c0a --- /dev/null +++ b/0-setup_web_static.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# script that sets up web servers for the deployment of web_static +sudo apt-get update +sudo apt-get -y install nginx +sudo ufw allow 'Nginx HTTP' + +sudo mkdir -p /data/ +sudo mkdir -p /data/web_static/ +sudo mkdir -p /data/web_static/releases/ +sudo mkdir -p /data/web_static/shared/ +sudo mkdir -p /data/web_static/releases/test/ +sudo touch /data/web_static/releases/test/index.html +sudo echo " + + + + Holberton School + +" | sudo tee /data/web_static/releases/test/index.html + +sudo ln -s -f /data/web_static/releases/test/ /data/web_static/current + +sudo chown -R ubuntu:ubuntu /data/ + +sudo sed -i '/listen 80 default_server/a location /hbnb_static { alias /data/web_static/current/;}' /etc/nginx/sites-enabled/default + +sudo service nginx restart From f8cd9c7203b87b82fd683e1c2628827e3a042214 Mon Sep 17 00:00:00 2001 From: Lemanzi David <166613293+DLOADIN@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:24:16 +0200 Subject: [PATCH 39/43] Create 1-pack_web_static.py --- 1-pack_web_static.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 1-pack_web_static.py diff --git a/1-pack_web_static.py b/1-pack_web_static.py new file mode 100644 index 000000000000..7ee74b83abfb --- /dev/null +++ b/1-pack_web_static.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +""" +Fabric script to genereate tgz archive +execute: fab -f 1-pack_web_static.py do_pack +""" + +from datetime import datetime +from fabric.api import * + + +def do_pack(): + """ + making an archive on web_static folder + """ + + time = datetime.now() + archive = 'web_static_' + time.strftime("%Y%m%d%H%M%S") + '.' + 'tgz' + local('mkdir -p versions') + create = local('tar -cvzf versions/{} web_static'.format(archive)) + if create is not None: + return archive + else: + return None From d3786dd282a553c9db6550a4b28947de05e7f42f Mon Sep 17 00:00:00 2001 From: Lemanzi David <166613293+DLOADIN@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:24:43 +0200 Subject: [PATCH 40/43] Create 2-do_deploy_web_static.py --- 2-do_deploy_web_static.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 2-do_deploy_web_static.py diff --git a/2-do_deploy_web_static.py b/2-do_deploy_web_static.py new file mode 100644 index 000000000000..e8f2f9dc7062 --- /dev/null +++ b/2-do_deploy_web_static.py @@ -0,0 +1,30 @@ +#!/usr/bin/python3 +""" +Fabric script based on the file 1-pack_web_static.py that distributes an +archive to the web servers +""" + +from fabric.api import put, run, env +from os.path import exists +env.hosts = ['54.89.109.87', '100.25.190.21'] + + +def do_deploy(archive_path): + """distributes an archive to the web servers""" + if exists(archive_path) is False: + return False + try: + file_n = archive_path.split("/")[-1] + no_ext = file_n.split(".")[0] + path = "/data/web_static/releases/" + put(archive_path, '/tmp/') + run('mkdir -p {}{}/'.format(path, no_ext)) + run('tar -xzf /tmp/{} -C {}{}/'.format(file_n, path, no_ext)) + run('rm /tmp/{}'.format(file_n)) + run('mv {0}{1}/web_static/* {0}{1}/'.format(path, no_ext)) + run('rm -rf {}{}/web_static'.format(path, no_ext)) + run('rm -rf /data/web_static/current') + run('ln -s {}{}/ /data/web_static/current'.format(path, no_ext)) + return True + except: + return False From e93dc79ef8bf341b5938059f58d580c1e98412f3 Mon Sep 17 00:00:00 2001 From: Lemanzi David <166613293+DLOADIN@users.noreply.github.com> Date: Fri, 7 Feb 2025 16:25:22 +0200 Subject: [PATCH 41/43] Create 3-deploy_web_static.py --- 3-deploy_web_static.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 3-deploy_web_static.py diff --git a/3-deploy_web_static.py b/3-deploy_web_static.py new file mode 100644 index 000000000000..dcf3c19264e2 --- /dev/null +++ b/3-deploy_web_static.py @@ -0,0 +1,54 @@ +#!/usr/bin/python3 +""" +Fabric script based on the file 2-do_deploy_web_static.py that creates and +distributes an archive to the web servers + +execute: fab -f 3-deploy_web_static.py deploy -i ~/.ssh/id_rsa -u ubuntu +""" + +from fabric.api import env, local, put, run +from datetime import datetime +from os.path import exists, isdir +env.hosts = ['54.160.77.90', '10.25.190.21'] + + +def do_pack(): + """generates a tgz archive""" + try: + date = datetime.now().strftime("%Y%m%d%H%M%S") + if isdir("versions") is False: + local("mkdir versions") + file_name = "versions/web_static_{}.tgz".format(date) + local("tar -cvzf {} web_static".format(file_name)) + return file_name + except: + return None + + +def do_deploy(archive_path): + """distributes an archive to the web servers""" + if exists(archive_path) is False: + return False + try: + file_n = archive_path.split("/")[-1] + no_ext = file_n.split(".")[0] + path = "/data/web_static/releases/" + put(archive_path, '/tmp/') + run('mkdir -p {}{}/'.format(path, no_ext)) + run('tar -xzf /tmp/{} -C {}{}/'.format(file_n, path, no_ext)) + run('rm /tmp/{}'.format(file_n)) + run('mv {0}{1}/web_static/* {0}{1}/'.format(path, no_ext)) + run('rm -rf {}{}/web_static'.format(path, no_ext)) + run('rm -rf /data/web_static/current') + run('ln -s {}{}/ /data/web_static/current'.format(path, no_ext)) + return True + except: + return False + + +def deploy(): + """creates and distributes an archive to the web servers""" + archive_path = do_pack() + if archive_path is None: + return False + return do_deploy(archive_path) From 0a823b1fa595dbd846afe96ff28aebfcd3260f72 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 7 Feb 2025 18:19:31 +0200 Subject: [PATCH 42/43] bash --- 0-setup_web_static.sh | 2 +- 1-pack_web_static.py | 0 2-do_deploy_web_static.py | 0 3-deploy_web_static.py | 0 AUTHORS | 0 README.md | 0 setup_mysql_dev.sql | 0 setup_mysql_test.sql | 0 8 files changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 0-setup_web_static.sh mode change 100644 => 100755 1-pack_web_static.py mode change 100644 => 100755 2-do_deploy_web_static.py mode change 100644 => 100755 3-deploy_web_static.py mode change 100644 => 100755 AUTHORS mode change 100644 => 100755 README.md mode change 100644 => 100755 setup_mysql_dev.sql mode change 100644 => 100755 setup_mysql_test.sql diff --git a/0-setup_web_static.sh b/0-setup_web_static.sh old mode 100644 new mode 100755 index 75b212057c0a..206e5c82bdb9 --- a/0-setup_web_static.sh +++ b/0-setup_web_static.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# script that sets up web servers for the deployment of web_static +# script that sets up web servers for the deployment of web_statics sudo apt-get update sudo apt-get -y install nginx sudo ufw allow 'Nginx HTTP' diff --git a/1-pack_web_static.py b/1-pack_web_static.py old mode 100644 new mode 100755 diff --git a/2-do_deploy_web_static.py b/2-do_deploy_web_static.py old mode 100644 new mode 100755 diff --git a/3-deploy_web_static.py b/3-deploy_web_static.py old mode 100644 new mode 100755 diff --git a/AUTHORS b/AUTHORS old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 diff --git a/setup_mysql_dev.sql b/setup_mysql_dev.sql old mode 100644 new mode 100755 diff --git a/setup_mysql_test.sql b/setup_mysql_test.sql old mode 100644 new mode 100755 From 0a637e303aa08c94fa9038a9d39a7ecc3a953c9a Mon Sep 17 00:00:00 2001 From: root Date: Sat, 15 Feb 2025 23:26:21 +0200 Subject: [PATCH 43/43] new --- web_flask/0-hello_route.py | 18 ++ web_flask/1-hbnb_route.py | 24 ++ web_flask/10-hbnb_filters.py | 0 web_flask/2-c_route.py | 28 +++ web_flask/3-python_route.py | 35 +++ web_flask/4-number_route.py | 41 ++++ web_flask/5-number_template.py | 47 ++++ web_flask/6-number_odd_or_even.py | 53 +++++ web_flask/7-states_list.py | 27 +++ web_flask/8-cities_by_states.py | 27 +++ web_flask/9-states.py | 45 ++++ web_flask/README.md | 5 + web_flask/__init__.py | 0 web_flask/static/images/icon.ico | Bin 0 -> 1150 bytes web_flask/static/images/icon_bath.png | Bin 0 -> 704 bytes web_flask/static/images/icon_bed.png | Bin 0 -> 447 bytes web_flask/static/images/icon_group.png | Bin 0 -> 1051 bytes web_flask/static/images/icon_pets.png | Bin 0 -> 970 bytes web_flask/static/images/icon_tv.png | Bin 0 -> 961 bytes web_flask/static/images/icon_wifi.png | Bin 0 -> 1006 bytes web_flask/static/images/logo.png | Bin 0 -> 9876 bytes web_flask/static/styles/100-places.css | 209 ++++++++++++++++++ web_flask/static/styles/101-places.css | 209 ++++++++++++++++++ web_flask/static/styles/102-common.css | 13 ++ web_flask/static/styles/102-filters.css | 101 +++++++++ web_flask/static/styles/102-footer.css | 10 + web_flask/static/styles/102-header.css | 18 ++ web_flask/static/styles/102-places.css | 209 ++++++++++++++++++ web_flask/static/styles/103-common.css | 13 ++ web_flask/static/styles/103-filters.css | 101 +++++++++ web_flask/static/styles/103-footer.css | 10 + web_flask/static/styles/103-header.css | 18 ++ web_flask/static/styles/103-places.css | 209 ++++++++++++++++++ web_flask/static/styles/2-common.css | 4 + web_flask/static/styles/2-footer.css | 9 + web_flask/static/styles/2-header.css | 5 + web_flask/static/styles/3-common.css | 8 + web_flask/static/styles/3-footer.css | 10 + web_flask/static/styles/3-header.css | 18 ++ web_flask/static/styles/4-common.css | 13 ++ web_flask/static/styles/4-filters.css | 27 +++ web_flask/static/styles/5-filters.css | 61 +++++ web_flask/static/styles/6-filters.css | 101 +++++++++ web_flask/static/styles/7-places.css | 32 +++ web_flask/static/styles/8-places.css | 126 +++++++++++ web_flask/templates/10-hbnb_filters.html | 58 +++++ web_flask/templates/5-number.html | 11 + web_flask/templates/6-number_odd_or_even.html | 14 ++ web_flask/templates/7-states_list.html | 14 ++ web_flask/templates/8-cities_by_states.html | 20 ++ web_flask/templates/9-states.html | 26 +++ 51 files changed, 2027 insertions(+) create mode 100755 web_flask/0-hello_route.py create mode 100755 web_flask/1-hbnb_route.py create mode 100755 web_flask/10-hbnb_filters.py create mode 100755 web_flask/2-c_route.py create mode 100755 web_flask/3-python_route.py create mode 100755 web_flask/4-number_route.py create mode 100755 web_flask/5-number_template.py create mode 100755 web_flask/6-number_odd_or_even.py create mode 100755 web_flask/7-states_list.py create mode 100755 web_flask/8-cities_by_states.py create mode 100755 web_flask/9-states.py create mode 100644 web_flask/README.md create mode 100644 web_flask/__init__.py create mode 100644 web_flask/static/images/icon.ico create mode 100644 web_flask/static/images/icon_bath.png create mode 100644 web_flask/static/images/icon_bed.png create mode 100644 web_flask/static/images/icon_group.png create mode 100644 web_flask/static/images/icon_pets.png create mode 100644 web_flask/static/images/icon_tv.png create mode 100644 web_flask/static/images/icon_wifi.png create mode 100644 web_flask/static/images/logo.png create mode 100644 web_flask/static/styles/100-places.css create mode 100644 web_flask/static/styles/101-places.css create mode 100644 web_flask/static/styles/102-common.css create mode 100644 web_flask/static/styles/102-filters.css create mode 100644 web_flask/static/styles/102-footer.css create mode 100644 web_flask/static/styles/102-header.css create mode 100644 web_flask/static/styles/102-places.css create mode 100644 web_flask/static/styles/103-common.css create mode 100644 web_flask/static/styles/103-filters.css create mode 100644 web_flask/static/styles/103-footer.css create mode 100644 web_flask/static/styles/103-header.css create mode 100644 web_flask/static/styles/103-places.css create mode 100644 web_flask/static/styles/2-common.css create mode 100644 web_flask/static/styles/2-footer.css create mode 100644 web_flask/static/styles/2-header.css create mode 100644 web_flask/static/styles/3-common.css create mode 100644 web_flask/static/styles/3-footer.css create mode 100644 web_flask/static/styles/3-header.css create mode 100644 web_flask/static/styles/4-common.css create mode 100644 web_flask/static/styles/4-filters.css create mode 100644 web_flask/static/styles/5-filters.css create mode 100644 web_flask/static/styles/6-filters.css create mode 100644 web_flask/static/styles/7-places.css create mode 100644 web_flask/static/styles/8-places.css create mode 100644 web_flask/templates/10-hbnb_filters.html create mode 100644 web_flask/templates/5-number.html create mode 100644 web_flask/templates/6-number_odd_or_even.html create mode 100644 web_flask/templates/7-states_list.html create mode 100644 web_flask/templates/8-cities_by_states.html create mode 100644 web_flask/templates/9-states.html diff --git a/web_flask/0-hello_route.py b/web_flask/0-hello_route.py new file mode 100755 index 000000000000..e6cc0bcfb493 --- /dev/null +++ b/web_flask/0-hello_route.py @@ -0,0 +1,18 @@ +#!/usr/bin/python3 +"""Starts a Flask web application""" + + +from flask import Flask + + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello(): + """Returns a string at the root route""" + return 'Hello HBNB!' + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/1-hbnb_route.py b/web_flask/1-hbnb_route.py new file mode 100755 index 000000000000..6a83b367e451 --- /dev/null +++ b/web_flask/1-hbnb_route.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 +"""Starts a Flask web application""" + + +from flask import Flask + + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello(): + """Returns a string at the root route""" + return 'Hello HBNB!' + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """Returns a string at the root route""" + return 'HBNB' + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/10-hbnb_filters.py b/web_flask/10-hbnb_filters.py new file mode 100755 index 000000000000..e69de29bb2d1 diff --git a/web_flask/2-c_route.py b/web_flask/2-c_route.py new file mode 100755 index 000000000000..be91b62efd3a --- /dev/null +++ b/web_flask/2-c_route.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 + +"""Script that starts a Flask web application""" +from flask import Flask + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello_hbnb(): + """Comment""" + return "Hello HBNB!" + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """Comment""" + return "HBNB" + + +@app.route('/c/', strict_slashes=False) +def text_var(text): + """Comment""" + return "C {}".format(text.replace("_", " ")) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/3-python_route.py b/web_flask/3-python_route.py new file mode 100755 index 000000000000..db64f2eb40d0 --- /dev/null +++ b/web_flask/3-python_route.py @@ -0,0 +1,35 @@ +#!/usr/bin/python3 + +"""Script that starts a Flask web application""" +from flask import Flask + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello_hbnb(): + """Comment""" + return "Hello HBNB!" + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """Comment""" + return "HBNB" + + +@app.route('/c/', strict_slashes=False) +def text_route(text): + """Comment""" + return "C {}".format(text.replace("_", " ")) + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def text_route_python(text="is cool"): + """Comment""" + return "Python {}".format(text.replace("_", " ")) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/4-number_route.py b/web_flask/4-number_route.py new file mode 100755 index 000000000000..d2388366b1eb --- /dev/null +++ b/web_flask/4-number_route.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 + +"""Script that starts a Flask web application""" +from flask import Flask + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello_hbnb(): + """Comment""" + return "Hello HBNB!" + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """Comment""" + return "HBNB" + + +@app.route('/c/', strict_slashes=False) +def text_route(text): + """Comment""" + return "C {}".format(text.replace("_", " ")) + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def text_route_python(text="is cool"): + """Comment""" + return "Python {}".format(text.replace("_", " ")) + + +@app.route('/number/', strict_slashes=False) +def num_route(n): + """Comment""" + return "{} is a number".format(n) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/5-number_template.py b/web_flask/5-number_template.py new file mode 100755 index 000000000000..d2147a72d098 --- /dev/null +++ b/web_flask/5-number_template.py @@ -0,0 +1,47 @@ +#!/usr/bin/python3 + +"""Script that starts a Flask web application""" +from flask import Flask, render_template + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello_hbnb(): + """Comment""" + return "Hello HBNB!" + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """Comment""" + return "HBNB" + + +@app.route('/c/', strict_slashes=False) +def text_route(text): + """Comment""" + return "C {}".format(text.replace("_", " ")) + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def text_route_python(text="is cool"): + """Comment""" + return "Python {}".format(text.replace("_", " ")) + + +@app.route('/number/', strict_slashes=False) +def num_route(n): + """Comment""" + return "{} is a number".format(n) + + +@app.route('/number_template/', strict_slashes=False) +def num_route_template(n): + """Comment""" + return render_template('5-number.html', n=n) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/6-number_odd_or_even.py b/web_flask/6-number_odd_or_even.py new file mode 100755 index 000000000000..3996383b99cc --- /dev/null +++ b/web_flask/6-number_odd_or_even.py @@ -0,0 +1,53 @@ +#!/usr/bin/python3 + +"""Script that starts a Flask web application""" +from flask import Flask, render_template + +app = Flask(__name__) + + +@app.route('/', strict_slashes=False) +def hello_hbnb(): + """Comment""" + return "Hello HBNB!" + + +@app.route('/hbnb', strict_slashes=False) +def hbnb(): + """Comment""" + return "HBNB" + + +@app.route('/c/', strict_slashes=False) +def text_route(text): + """Comment""" + return "C {}".format(text.replace("_", " ")) + + +@app.route('/python', strict_slashes=False) +@app.route('/python/', strict_slashes=False) +def text_route_python(text="is cool"): + """Comment""" + return "Python {}".format(text.replace("_", " ")) + + +@app.route('/number/', strict_slashes=False) +def num_route(n): + """Comment""" + return "{} is a number".format(n) + + +@app.route('/number_template/', strict_slashes=False) +def num_route_template(n): + """Comment""" + return render_template('5-number.html', n=n) + + +@app.route('/number_odd_or_even/', strict_slashes=False) +def num_route_odd_or_even(n): + """Comment""" + return render_template('6-number_odd_or_even.html', n=n) + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/web_flask/7-states_list.py b/web_flask/7-states_list.py new file mode 100755 index 000000000000..e057c112547c --- /dev/null +++ b/web_flask/7-states_list.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 + +"""Starts a Flask web application""" + +from models import storage +from models.state import State +from flask import Flask +from flask import render_template + +app = Flask(__name__) + + +@app.route('/states_list', strict_slashes=False) +def states(): + """Comment""" + return render_template('7-states_list.html', + states=storage.all('State').values()) + + +@app.teardown_appcontext +def teardown(self): + """Remove the current SQLAlchemy Session""" + storage.close() + + +if __name__ == '__main__': + app.run(host='0.0.0.0') diff --git a/web_flask/8-cities_by_states.py b/web_flask/8-cities_by_states.py new file mode 100755 index 000000000000..c0a8df03258a --- /dev/null +++ b/web_flask/8-cities_by_states.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 + +"""Starts a Flask web application""" + +from models import storage +from models.state import State +from flask import Flask +from flask import render_template + +app = Flask(__name__) + + +@app.route('/cities_by_states', strict_slashes=False) +def cities_route(): + """Comment""" + return render_template('8-cities_by_states.html', + states=storage.all('State').values()) + + +@app.teardown_appcontext +def teardown(self): + """Removes the current SQLAlchemy Session""" + storage.close() + + +if __name__ == '__main__': + app.run(host='0.0.0.0') diff --git a/web_flask/9-states.py b/web_flask/9-states.py new file mode 100755 index 000000000000..4945809f0587 --- /dev/null +++ b/web_flask/9-states.py @@ -0,0 +1,45 @@ +#!/usr/bin/python3 + +"""Starts a Flask web application""" + +from models import storage +from models.state import State +from flask import Flask +from flask import render_template + +app = Flask(__name__) + + +@app.route('/states', strict_slashes=False) +def state_list(): + """Comment""" + states = storage.all('State').values() + return render_template( + "9-states.html", + states=states, + condition="states_list") + + +@app.route('/states/', strict_slashes=False) +def states_by_id(id): + """Comment""" + all_states = storage.all('State') + key = "State.{}".format(id) + try: + state = all_states[key] + return render_template( + '9-states.html', + state=state, + condition="state_id") + except: + return render_template('9-states.html', condition="not_found") + + +@app.teardown_appcontext +def teardown(self): + """Removes the current SQLAlchemy Session""" + storage.close() + + +if __name__ == '__main__': + app.run(host='0.0.0.0') diff --git a/web_flask/README.md b/web_flask/README.md new file mode 100644 index 000000000000..1d74d099f279 --- /dev/null +++ b/web_flask/README.md @@ -0,0 +1,5 @@ +# AirBnB clone - Web framework +![AirBnB clone - Web framework](https://s3.amazonaws.com/intranet-projects-files/concepts/74/hbnb_step3.png) + +## Description +This is the third step towards building our first full web application: the AirBnB clone. This is the first part of the web framework. It is a simple HTML static page that is served from the route /airbnb-onepage/ on your web server. diff --git a/web_flask/__init__.py b/web_flask/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/web_flask/static/images/icon.ico b/web_flask/static/images/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7a4b2a9b3568d98290c0510fa649db9fc0e29715 GIT binary patch literal 1150 zcmZ`&O-vI}5FT1$A@b9U1dWPO5-VbW14;R@we5DhyWRf(gOyTBTZ({11f)@##-gOL zL?ulla8Nne5G8~I2QS8xBp$r!$!OwLHt87h7cmZaohmVS8A=VuNPsX(Fnv$CKK50cG%k50=ZlcJv}{OFc^wHv)K&M zXcW9&@1ImvRaMZ{)den>s~Y{R)oSHD9#5@WtptvvAP@*tU`{2P#b&b|QLELE%jF=O z%|d^Ff03)Vx3^xS(WH?li*Xsfp3hn>e4E**JgwL3@1w32#2>LNyM)@B6beO=KN5++ z#>R#SW2TXJDi(`XjE-KDm`!>uqxUaU?9dv|a|5`lCnhGu7K_D6@*%GTH4@F_el;A& zt@?bvZh{R49MHkM15fA!uXBG{vG_jK*m|)|@8cki-H zRruJb$bWCu?YxZN{d$b1sd?nKk(nTOKDfrm$6y@+LXcbrahz!nfL%8iA4txRFF zp=)oGGYqO3hF%JXhopUdeUM6}4ju=Bp*AvSZ8WWUc6BU$qEWRoeX=wE=7J$VprzFF zR;$I?+lIu}-I(<5=3?ZWE4n+6A}AGoaMb+GX#RKB>#)F3#QlnS(p& z1NMf@L<>b}a}K+yF@9@Us!}N*VBM`U+1dYc@8?M*5+tS!?=gryTElugp=o;N=1iJq literal 0 HcmV?d00001 diff --git a/web_flask/static/images/icon_bath.png b/web_flask/static/images/icon_bath.png new file mode 100644 index 0000000000000000000000000000000000000000..7a9bfed9d8d9f02a29a50847808f6bb0eb61c246 GIT binary patch literal 704 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|^t4*@+_k(E=`(ls_UvvG9s4+snii-}K4PRS{+sH|>kZta*d zb^5Hi%T}!2uxZzxeMgUB_uttD3|2-1PZ!4!kK=EzMEf6d z5MX_<`NFNF>}b(ImcWUtRxDUiq0Myf64zg@7xpEqNdy0}VK@7U`tS21i8(3ekx#7LRz)t6QhuZvYoqq(ZPJWeo{wbL zESc!_=-iIXBXixXdh-l+?sMFJ(Npp3leugCmHBqA^*EAv+fU7J_sqjOf%_PaZ8|Of UVsdFeFj^QqUHx3vIVCg!0N#=_Pyhe` literal 0 HcmV?d00001 diff --git a/web_flask/static/images/icon_bed.png b/web_flask/static/images/icon_bed.png new file mode 100644 index 0000000000000000000000000000000000000000..2a63284877067dcb61b769fd59e8ee373587b0be GIT binary patch literal 447 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx|^t$pJngu0XnMkb%!ndUAozGAIf1 z3ua(sX64}I;^CE*Q#3F%wXpN{i-=9nD6gz;XziFdWA5TjTelxSb?*G-JNG_+|M~mx zviF&$K)tIyT^vI^j=#O^&UeT_#Pwo+)q9mM_a;x+{r{?=!!(C77B>!oQ*-yt>6GnW zvb0u7U+vo+51u1=EDhnF`&QiX_{);$Z#jXF;fza^;C9#FjyJu$eswQfV=yaSXUXd8 zOV{`w(o3GyDaWjxm?#vV?{2*?Yr?E~e^`u+I&Q^G-!Q>}@0sHBZ48dCLMLt(OVPgg&ebxsLQ E03-gv2mk;8 literal 0 HcmV?d00001 diff --git a/web_flask/static/images/icon_group.png b/web_flask/static/images/icon_group.png new file mode 100644 index 0000000000000000000000000000000000000000..3e012ab4d5cdc2146782461b475b2a81ce0fea4d GIT binary patch literal 1051 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx~p(FqQ=Pgt!8^Wut(;A)xa1&vRh7 zSC<6&1v4-*F|)9;v2$>8ar5x<@e2qF35$q|iAze!$jZqpD66S!Xld)}=^Gdt8Jn70 zTG`s!J370#x_Nqe`}q0=hQ-7sr)1|86ql4%RM$6jboNi2I(^3MxeFF8TeW)arY+ld z?%K2Oz~Q6EPnA zgW||zoJzi$)5NBGZPtle#HKS|ONG3(HoLZl9GLX^x%AAL)@KUZ+vTc0{VsSi z|7-5$4L5oF7urh2ac+5eFFjb7YkJ+RdkcL#rzu5sa_K66=m>b_)UA@+{lO#H>wv(! zKGwt?PPf%;9!;rgkiMT8v73YEVpvoAipxQ+*R6D08{BU5?0I*&$T((Mh|u|rRhb!| z=lE8x*>H4C#d+ti#sLx)(RZV*`io0Cl{SazpONRXdQn&qR2=$s=a78nheKN1tRgd#}OF1pXGJj3wWR$qG zJasw0!xKYYO^YwQa#}23?syqCK4vvLo2~S{GEriAwuwpFgGu|Qp7rZ^&2D1D=_J3; z+)l#jl{)Y1sC={E2_fx=7<{+ZSg{DoMlXFiyMceBvwY+aiN*6{8Mpd>DP{C>{588Z zXx6`N3#KHp2h2)ij}53i#g`N?Go5{Jz|3TJ^#w)K|4A{fc)|NCs^ON!-w=}@5qGMv?l9JQXGqZDY3kr)%YC1Y+&0Vl~>8jOhH*MLzYtOy|2M-@Te&W=* zi`VZxdh+bW%hzu|e*XE__WZeNz$o44>Eak7A^G-TX0%WsL)*jjWe1lY>Iuql+_uPNGk@3)Fq ze%5+#l|TGkcNLdvCEq;!VS4J78lLrP$@8XEx*jvUr}d5R@jNAc&zXTsJXgg3{>5o3 zI#V&#XQSMMjo;2P*>=S$FAd+Q_h9z7wT!V{b5-81?%_QU-p!wL;>S6`N=eoSJyD+= z92f3&?30SQ8Lcm%wfd>xLhjeq^6Uj4>Q^omyb!rzO>>xWiNKw|s}KL{W#7^B?!}6^ zhHvy%?mZo`cE#S%9GjaJ5iFZHH+)EWoVa<#H?fUU0oBhp&JM5^-qB+w^3!(a+*R6_ uBo3cFJ@wSohju;t9(wJZ^4X&7LcQ)iZPlv@J5qsZh{4m<&t;ucLK6TAF|D5f literal 0 HcmV?d00001 diff --git a/web_flask/static/images/icon_tv.png b/web_flask/static/images/icon_tv.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf25087ed593f0d39ef29bd37f773efd609e00d GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx~p(Fa`(sgt!8^Wut(qA;7V=<~}f3 z3rd3gf*BZ@m|57^IXJnvd3gB+g+(Q$q-A8~>XTO-P}F> z!Xski5|dNXGxCc|N-HYsTH89id;0pP&zLoP>9Q58*RJ2NW$Vsedk!2tdi=zxiQPrUck-3}4Q%Xewj#x9m;ko(HPL zo5^rv+GJ6NyXV7M1g1`|Wtjd>fbq!F2TTqxPAE6X++oOk8)zHW$*Hm>#ec3lkHOXy z_5&+>gsxADWoX|tZOSy4E1j{o%HBA}{|Lk$mQ7W|#h0DdTa%Ymff7<}a&l3wOM}^(VReU^Dk;<FVdQ&MBb@05Wj3;Q#;t literal 0 HcmV?d00001 diff --git a/web_flask/static/images/icon_wifi.png b/web_flask/static/images/icon_wifi.png new file mode 100644 index 0000000000000000000000000000000000000000..abbb643c9c1fbba020c2aadac1447d2db66ea094 GIT binary patch literal 1006 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=3?wxlRx~p(Fct>*gt!8^Wut(OA>h36>q%gs zSCs_$1v4-*F|)9;v2$>8ar5x<2?z=ai-<}{Nz2H}D<~?fsH$md>FDYk8X23JTUgrK z**iMBxO)5e1_Xu0#Kt8ir=+Fl-L>{ z_8mBU^!SNW*Kggq_u$c!XD?sB|M>aq_n*K2p7pu;0+<9gdAc};NJzdtm>DgU$k2B2 zx2%Hc86A-mN|V3wOb^>^vdKt1CwSA9_5@r zyRdOz@ms+|9(VsQQ?198g>g4j+!;y-L!SFVfWjpXQ9T^&!=!e-_&f0{hy2W z+VVuCbDjS5r}COCtJLzRQb*GL`ffYqRD{-jtB^Sn8WMUeJuGM`_l~G*Vc#Y+9_d=5 zS`$^DxluN0z37u{<0Jc5%sF`8MB3s@@Vry2Crbal{`u%8o2MohayI(bxUNe&wm~m) zLbk5!0#8f3Ef2dSWIl=)oe|FP3jNMdT$SZ{>HSRazz1Ec>;zYARoN}RW5hs=<{szD!E|y zV9!~-4-6+yn!99PTa0=^PEMH?_mZk;j`WbeMT%SMD&>T3ZMx>lxiZi+(Hil;_TS%j)VBq`m~49gG7~TjF?hQAxvXayIZ)EefGD{{c-o5 zXU&p+s@|%uu3pvEwW5?2rO}WHkO2Syn#?B&Rme3S@)tyehn#EPg54pP42 znV=^>1i;=LWK8C1Z|C63?b8+*t^N{`fM*)%MVrIdwDk1f6S&%0o z3M&xEiJyhV!@~pU!2xu1v1DQ61`?uxX!<{0uy^_otb^;n%>*$Ri>I*@3mcI2ZVY`B#(^zqpIJG04$H-OGL=~%^Hhgx z-hKdk=Hq_DxzPE&KbY_Bz>Yh+C8oXQ^UWE(6CRJ#+5j4nhcnEO{#v&)o=2-eESI0t z-H8qxLEQG?A$^sU!AstNAnSQ{0sGy{954JRDJ>o5+C9E4nmznlQ=|Nz`7@Qz{aI>aVxn$VY``+5V zzP`J2Woj!#82GHBRr>AUZnMGH7Z-^Z6Is^PQ@H})ZwG7|N2iOW8`~Hd7#eEPNd&d| zK?fHxoi#NWFJ~{0*L%AoDethb$kSO27oOIu^abeY=t>t1YLYA}AWD8xSO0P+yt;?4 z2R(U;104r{dw-uE8ylNAK0Yq8ySEqD^Hs{#WNGB)=EfAD%yi}zf_aOU2jw9sRczn5@YJS^}VL{)jcei380?YaR&b0gnB@b+rOH}J`9}56D z9XRMs6M-b-2)L5%SDS8wj}KM4{Qb&rN6XZ{qnFf)KyT{7l~$>%%Vy%pVmp!^Zd9bh zK0KnmR@1AwEN`SS>;Cx#q4Y{hO47pDpT}*PQ%4qb$h~odNAF|Tf@Ql!ULWrXK>+U^ zUtPHzt~4GWKi{9Tm^=&@G^l82#75cBiLp8vC3c;FJ9L97C|Ne#7WM13s`U7B$zK)? z171HvY?0sMwDmDpA9K|bQ8C!_%>Tr3ijKZ3oWbJL-Cp}d?N!D2^nXL<&> zl<}CXVbO&WHlh6mA#}%$9<{N|I*rA!supd)UR71qCIX$9!L^$R3bRjM^st{IRdS#x z!H%kpAq5rz&Wk#Xr;>>dm?Z4?^b@h;nno-mB_)O5Vmw1S6I3Br7*o`4;xeY8{~Ng? z8EbuyrrUT|Z4s%YbE(bEHh;a{qnUDb^9|W5bs3~08Cjm(4tj4GzCt}vBo1pXY!+b*Ti+zuP9|5m6=+Suby!MT}zFuhPu~4WbEHNpG?RBO^F6p2hZTv?cxT~NepNKkg z=9`(_Xz-Ef8N1U$wV@$x)0R!2tP;QXjTHg``dfMe0oM^1X+S^}xA&*)nU6^m$NeiU zW$J!+TbyIH>zCWu6i=JKNPplrSn8DZhw&t%)~F?r2yLv?TTX#cDFA0jWQc`1KwO>eozIApLPUY9#s2UG8BO|_ZdB$B8*YQd9Ckoc+iCCOP- znO6nlF}^K_gnqK)31{Lf2_dzB=-9Z7ygX+ve=a>U0S`_9X(dC9hTZahzl-3H6dQ zG(zq#^A%chHa0f7PX_5ZI4IYul}aVF2jPgQ(wj!LU&_&B+X>4KW=di*!IV2SKz69* zUnIO%*@ewJ<-Fjv2En+^U@WFpO&yOWgpTx}C*7KAcP)+XJ5P)^7r{ihtDOW98@nT9 zE6&x$h1L}ydQM7YY8ouaW7|hXMP)Ap0mDBoSUW*DG$K55&XKGs5mS7Ru-;vFCIN(7 zgNYl)CBia(GmmgR`n%Kja~-?MPBu?EY75jf;f5Xl2OZfEQ68a}StSv!-`z5`IR#lj zWb5BaRvD{tmApYjq*~lVpEj?A8b8~P;g!kzI62i=U>b0~L;K{e88y9%dnsGWGxXEA zP*(0!u;!1?G9Nz%yBkkd5{bLL7B`St70@>Z2D_fxlwt9rR@=6JYS!DkI6cSeIT3yH ze>E6-P7?&Ru$^r&n3iSm*_T*9XOTQb(y>v2UMht79f~JsEuD^76YIlXx4dH}(Zg-P;#5}I{sz+f8Uvqa!5b)5)o z#TDYDk@ClkfWtgQf|V=Hb@RCH!a|$2mU8;DyL0dxiGUnfsKBsGB)rkaJZT(ceKl)P zYi6Mg8|C%p_RFw%Sh$l*G(JP5iD|k5KW~Vo&OIBl)`EDIP{+=+54~!|l$P|8a7Vi?s0ry&Prb$7P50wvi}o+VGa+OR1EI!|_2vvcrwFy+biSa9X{vcgq81i$*-!-M`|bP8Nt!9gM`69gSB^OMDvFm4 zmJE9!;(6{p=Vc)haEc?!hbG{R=c#}8v@ZryF|z-xu2^MXNJFbaYCTz6X|x5a`}^*e zs#J5^EsTF%Z4>(mXt|pGkRngoDKzw}$gOSh0nhX{j=-QXb0Ut>An&Q__9m)l;X2cK z8;^|tO*GEgu4F*j>yodnMRPl7F&*;`UQ$|%LNNb+UdvG7dwU?({>?c!AZIjaZjOh5 zlZGbTt`x}}Pm7bbcHRT*$7At)cZz*t8QFk4`GPk1++39?-$BEf&O~MyFgk zXse-)pg1xgIJqc{ynjVcn8$(~;7fbEkWBO#I?(?p;xi(+B+VZp;Zfx@RNka6eg6iA1{J-b6qr!jDh& z%w(*fxg5ep*8dt-=IfWj4!@{{jvdQj$6qB(5HAYKA-xOwn9hiOJqvSkEhH+Xe7jL& z+=pI5&Puxv$bpGOl&(WhB~c#lMH%c6blDw7+8IiC3kMs=BZ9HUkNY7n8X(1WA~|4^ z)M#zASUTa(LdZs}9ykf}=6<^3c6nUg^#@i58Aail2<4e7@V({KZ{A+xU+(e0=M_cQZ0|h5Zi+mmTg=oqR-7@3KnlgQDoj}=z%T$V`I+U9GngFpMWuc%W z3i`C$XF6DuH6rGbNO0FLIa;QNrZqd#4gDX*!nbj{;@c2!54yYWuLWSgkCHo+*PzG8 z-TFW7rB_3<+C%lS{cLU`E0)^4IbJ*`)#M0cYfzBJr_M|X)G*yf=cUte*&1qZP{fRi z!|lLgWZCxxJvM-u7vaKUfGt74llwE*nSLLi>o7lEWvVSc`~58H1X6wd>NrI*gD9*k z7vbYo66l{FRx4OnUr!pw?b#%gLi5OJ=N6VC8ZgzBL#7qVPMe%E(6-uOEl$H5=p9T( zM+%ME`_Lc6ZlbBFS^PI+=#$+zqVqnjlC@1=33q^De0Udl9`+W3NC6#fEzm}UcStQ zXYSKoaYvX{UubKk68xTCEpc1>-dK8qRDf!a;Os-*m^OctI&bLFz)!>e7|A!^I3=1R5A(K?P|%UC@|p zbWBxTv7o5gjrZt{r=Czsn_Yg-A6@3Kl*Puz2Jdy45m+T?wQeux9|4b`gR{u0&!)d* zQ_nvTwvm}P@v=osELG3Cdq=len{pyvH!8qUI(G)dRm(F z6)LOF+zqLp(EBP?%b@HIhD^Jrw=ss$h6o@!3$Mk15H2OptlLE7y?149yRgSNGd(4p zrOhyqV@S4884I{xsTNsygg*qqBdEf(RN_rWPL6$FGu`cD!C&#nv-@PlF`M|yJxUl@ z)$LBtBc{dTR6@=(^zOGYrr)eZusIOzXz}gOW={x9qKnMBQI5KDW#-9d&UBL_yA8ku zY^%#f_v4gbnvv5A-08<7bid|0lw%F>GBphNRdoD{Gq83K2YckuV91?yViayCY8cZ0e|HBrnj(jU%M!*fH7++dwm|I19 zNv=c4c@rIDf=e-fam-RI?U=nWv|qnFD=A;7k01pZc2-cNxCr8jO4XpnEk=^T=O z^^-iyWj8v4{ppuORcMcC1uAxF@SQoT9?d`{I|Z~6Q1X=e z3%t>3%d7$+Be7zVALVkHA9&ZuINIEndSmi~oT#!cZTn@Rr>3*`^S-xOh#(Pl#Y`yGOFj^+aK z%UaK~Is7$ZfG5pyj*qbNs;bHG5)ML6!p6f&Z27KV{s0hlSC1=QMp1q0{D=DU-z^;& z2JLiy2sGQZoK*67H;ymO3$`TnzCZg>g2ijFFhqxQa!vkpo6~`D;!5{kjxarFr{!|s z!fqmqtA2?U0SeR!6U{8_`%t5Pg!az3{u2s&AdBeU4)fEX3N2{EpIaAKduVJ?xcC=T zkbije^6bK~E|uM#-&>01jeRXUKW!A(Y2YW7!oU&-!~@^r?|N|Uu$ko-D&$;a<_ED; zwY@_o=AI$Z`QdCERlwe&X=|c3sH(~~=pl4~Qe(6Z#_{GoTT*x%)sU6)g1Cjcj{&1r z)f|4rc;BBDsLZM>d3PgNjzeV1?1wIXEf~xrr5xVEpb*rc*8NNDi59@Op!3T{Vlz$T z%`Eob%8(dhsJQoh?*w7%{IuSP0?mwn=bXM1ZE4OM>sA@fDGeQr5{W6_doUVAUt;(rTg}*3pQGGNwBb7;k3&xUAh~HR#+)n&7Z!6Li~OeuC>!3%r`_V2 zrc|-<$K*ny*kk(mKn%)K9`+1ho9X<07KIdaH0nUxaA*VR>DYN;zCR$(04ZQ2!G{?L zBTXHs&8GQyEy2!sJX10zoe?S+t;DSwjQCxcMv{OVSLh}#%?;I-EYFlQ(|Y5lZwnez z(e*`J4;6n+vM_@|dFP)iwi~;&i9E(%k56n&cvHy~^fxGpdL1f)6YpzRl-y~Z-Cz>2>zhKYlnW4HL#Oq)rm|aA@kGyjDRmIO^%bCqe5ggfiU?!HH!B$BZ#{_O z%Ls^5T3DL?D(i||abo1MJM;?=S~$?}V`#LeOi7eD8!hdKsFFJ5WTGN#Dq@>@0r&v)(Xj~Ge%`>L|*e_1Rdcggj-?nD- zh~L0Wo*H z@MLZ(hU8q=ThD%jBMYSJ{Fb)8c7cfeoAuo^7#^17N9(U8?&n|MmGUvd(TUqe%m=p$ zB0q6{GskQ#!bQ&$0nWu$Se# zs#(V3`tU)6&sKzn$@JD9s>1x#3J65}U)B*B;0u-1h)7FREK?!t%qM!#gq+c}ora;k zrHc(LI)P&pOT;oMNUm?QJO{0Bk!YB@jU}&*1^Dxio~KuswihXjgznR(GMgiqv*BoV z07dAmBcO;1!^ZA&`-#@K>OTvjctpOBQlA`5@8bB#N%;)aX_kH6iA3iGKCA&rrV364 zEqH4gC@aRAF?T^4X2iFMQEECd6)gKBLH3FZtki3%3QdGDaR(}vK*`@7_Z#haCu^}l zsOzuC;I4oXNZMUhBw~vtwjS}^w%sW5T0qL;;qs!CX6`6cZPRZ0_6~#}f;1 z4=vdlG3$dspuH3&VXvJscn8-D<;+*8p466mvThS`A^thtL9puAZ!m#Aq7UBA<4)OW zySuyBiG;Sbo1L&~7@~%h%9bDOd~yVitazmDX_KfO-4iRMHoM6>qknrADF`iW`C7@Y zUI(%W#z?*G7bln(w8~S&X|t`Z?Q*cEYM20lSKOLkZYyJLJG5S4t}40dFRpLii5Cyc zUILUKPH>?jDk@907fATXE3T0TLY7qo_5||J_X-(b==;ISfl}31ij&=%3Ekx|JBpQk z6Gf+PH}W?j0=dg+VM-2H!}PQUr)jPtQLf>1AY5&8-2Ld-AMDd>Gb+G{z^(HA=Lg;R zKQ1b3m=Ey?qljdU=V9mX#fFG~-;YQg{c7vT)AQHLr7kk4J?}b&p*-8k!EDe|h859I zWfW1>SgqgjVvq?%Lh=|lV<@T0gPtSN7N=EupFTQL_s$yc1Nj6Nmlq{fg7t#DugMMr zvgMQ&K}PN&3(26R;JqDz{!Hyq8cMD=?vu{ANl?W$2F6#*{ow?>E2@eanl17|RSi`t zT&sNJ$|p7$glH~`k4W_)&kR9o>j}_K$(e||N1Y#DH)P`_>?!K(8wILK#`fN18B0^# z zi0}T0D~7O}@L0X`3Pv)RPH}_2ZUE=!qvloQ?k+KPX$s@PXzG|r@A0>dJd+*?&BN+y z&L=xzr$JO&Eu=D>KzjsM*d>odr7MmB{z(S~;&KYKii2K#hw3@RoY2rvH&$5>fEj^i z8|2^H%FM!pMEseLaW(}DW1ou6HW%F4>>=PnhM z&)Lu5_-JT|QQ+v7Q`}m{h-ECldHsfAX6!g8(_t-X-IkkcAUu<*3S7QL}O9GcV6!K@ZgeQ_F8K?G?+3lhvc*W zH2m)ClKEJg^+_$HRGW0rCj_ej$=~az7jIvL?}N+RGt|T)%l6#x}?n7h^wgxWk}s$!loc7caoRiwp7TgH(-Q`Ob33ybmILXlbWxz)h#UqAm5( zq>pZI8Sk07m9?)0AltyNV|hY88!+{r6$k@4Jm@0?l|CcM)G$szjGk|%jCyEW-ue<7 zX*LrdALvldTi1s|{?;8;Ol-FMqm+h*hAgKal=o`o(t$#$nVFCHDTbVRPky*{aHz|G z%A4&hF5AiOT%l4DxsLrj9~yLG{u^9qWok?WRD4z{ZtgoZf@Cn{)%u_YP<{^@HUrT0 zUv4J9{`^D-QW$M>JLbk>#mNFpC2Z-_R|R0&jI>4EQV3ioF73au^zb!pJ zHCmR*2heE5FR`#Ygeiv{mkJ<4uO4(@8r+>1qT5usfH%(BvBMm(^zv7?87n3PHDU~O zbOWg7R>aS=`GK9-T^u{WH>yoK$_mS}O@H)W$%$a{X3BnhxCN_jX^{eI7eLl4;*aJe zxKe?GGl#S&b+^@g)`t&OjBrLPFh*2G9ZteiaZ@f(gCS1YgaCqU@0)qFtN_F5)_|xr z{WB}|J>c0ke0+OL&<@aHvn7U*_w4HJ$4fN;1^|a9@@e^3ZS3Fg#AGBDC8|Ce1^*w{ C(Z%)v literal 0 HcmV?d00001 diff --git a/web_flask/static/styles/100-places.css b/web_flask/static/styles/100-places.css new file mode 100644 index 000000000000..14accab9bbd6 --- /dev/null +++ b/web_flask/static/styles/100-places.css @@ -0,0 +1,209 @@ +.places { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin: 45px auto; + text-align: center; +} + +article { + display: flex; + width: 390px; + flex: none; + flex-wrap: wrap; + flex-direction: row; + align-content: flex-start; + + padding-top: 10px; + padding-right: 20px; + padding-left: 20px; + padding-bottom: 40px; + margin: 20px; + + border: 1px solid #FF5A5F; + border-radius: 4px; +} + +.headline { + display: flex; + flex-direction: row; + position: relative; + + height: 80px; + width: 100%; +} + +.price_by_night { + display: flex; + justify-content: center; + align-self: flex-end; + + position: absolute; + right: 0; + + line-height: 60px; + color: #FF5A5F; + font-size: 30px; + padding: 5px; + border: 4px solid #FF5A5F; + border-radius: 100%; + float: right; + min-width: 60px; + height: 60px; +} + +.information { + display: block; + height: 80px; + width: 100%; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + + padding-top: 5px; + padding-bottom: 12px; + margin-top: 10px; + margin-bottom: 20px; +} + +.max_guest, .number_rooms, .number_bathrooms { + display: inline-block; + width: 100px; + text-align: center; + margin: 0px auto; +} + +.user { + margin-top: 5px; + margin-bottom: 5px; +} + +.description { + text-align: left; +} + +h1 { + display: block; + text-align: left; + width: 95%; + display: block; + margin-top: 0px; + margin-left: 20px; + margin-bottom: 5px; + font-size: 30px; +} + +article .amenities { + display: flex; + flex-wrap: wrap; + width: 100%; + margin-top: 40px; +} + +.article_subtitle { + font-size: 16px; + text-align: left; + width: 100%; + border-bottom: 1px solid #DDDDDD; + padding: 0px; + margin: 0px; + padding-bottom: 10px; +} + +.article_title { + font-size: 30px; + margin: 10px auto; + padding: 0px; +} + +article ul { + text-align: left; + margin-top: 20px; + margin-bottom: 0px; + padding-bottom: 0px; +} + +article li { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-content: flex-start; + margin-bottom: 10px; +} + +.reviews { + margin-top: 40px; + width: 100%; +} + +.review_item { + margin-bottom: 10px; +} + +.review_text { + margin: 0px; +} + +article h3 { + font-size: 14px; + padding: 0px; + margin: 0px; + margin-bottom: 5px; + +} + +.guest_icon { + display: inline-block; + background-image: url("../images/icon_group.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bed_icon { + display: inline-block; + background-image: url("../images/icon_bed.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bath_icon { + display: inline-block; + background-image: url("../images/icon_bath.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.tv_icon { + display: inline-block; + background-image: url("../images/icon_tv.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.wifi_icon { + display: inline-block; + background-image: url("../images/icon_wifi.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.pet_icon { + display: inline-block; + background-image: url("../images/icon_pets.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} diff --git a/web_flask/static/styles/101-places.css b/web_flask/static/styles/101-places.css new file mode 100644 index 000000000000..14accab9bbd6 --- /dev/null +++ b/web_flask/static/styles/101-places.css @@ -0,0 +1,209 @@ +.places { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin: 45px auto; + text-align: center; +} + +article { + display: flex; + width: 390px; + flex: none; + flex-wrap: wrap; + flex-direction: row; + align-content: flex-start; + + padding-top: 10px; + padding-right: 20px; + padding-left: 20px; + padding-bottom: 40px; + margin: 20px; + + border: 1px solid #FF5A5F; + border-radius: 4px; +} + +.headline { + display: flex; + flex-direction: row; + position: relative; + + height: 80px; + width: 100%; +} + +.price_by_night { + display: flex; + justify-content: center; + align-self: flex-end; + + position: absolute; + right: 0; + + line-height: 60px; + color: #FF5A5F; + font-size: 30px; + padding: 5px; + border: 4px solid #FF5A5F; + border-radius: 100%; + float: right; + min-width: 60px; + height: 60px; +} + +.information { + display: block; + height: 80px; + width: 100%; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + + padding-top: 5px; + padding-bottom: 12px; + margin-top: 10px; + margin-bottom: 20px; +} + +.max_guest, .number_rooms, .number_bathrooms { + display: inline-block; + width: 100px; + text-align: center; + margin: 0px auto; +} + +.user { + margin-top: 5px; + margin-bottom: 5px; +} + +.description { + text-align: left; +} + +h1 { + display: block; + text-align: left; + width: 95%; + display: block; + margin-top: 0px; + margin-left: 20px; + margin-bottom: 5px; + font-size: 30px; +} + +article .amenities { + display: flex; + flex-wrap: wrap; + width: 100%; + margin-top: 40px; +} + +.article_subtitle { + font-size: 16px; + text-align: left; + width: 100%; + border-bottom: 1px solid #DDDDDD; + padding: 0px; + margin: 0px; + padding-bottom: 10px; +} + +.article_title { + font-size: 30px; + margin: 10px auto; + padding: 0px; +} + +article ul { + text-align: left; + margin-top: 20px; + margin-bottom: 0px; + padding-bottom: 0px; +} + +article li { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-content: flex-start; + margin-bottom: 10px; +} + +.reviews { + margin-top: 40px; + width: 100%; +} + +.review_item { + margin-bottom: 10px; +} + +.review_text { + margin: 0px; +} + +article h3 { + font-size: 14px; + padding: 0px; + margin: 0px; + margin-bottom: 5px; + +} + +.guest_icon { + display: inline-block; + background-image: url("../images/icon_group.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bed_icon { + display: inline-block; + background-image: url("../images/icon_bed.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bath_icon { + display: inline-block; + background-image: url("../images/icon_bath.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.tv_icon { + display: inline-block; + background-image: url("../images/icon_tv.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.wifi_icon { + display: inline-block; + background-image: url("../images/icon_wifi.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.pet_icon { + display: inline-block; + background-image: url("../images/icon_pets.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} diff --git a/web_flask/static/styles/102-common.css b/web_flask/static/styles/102-common.css new file mode 100644 index 000000000000..cd9f953ee6ae --- /dev/null +++ b/web_flask/static/styles/102-common.css @@ -0,0 +1,13 @@ +body { + margin:0px; + padding:0px; + + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.container { + max-width: 1000px; + margin: 30px auto; +} diff --git a/web_flask/static/styles/102-filters.css b/web_flask/static/styles/102-filters.css new file mode 100644 index 000000000000..10f686218bfe --- /dev/null +++ b/web_flask/static/styles/102-filters.css @@ -0,0 +1,101 @@ +.filters { + display: block; + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations { + display: inline; + vertical-align: middle; + float: left; + height: 100%; + width: 25%; + + line-height: 20px; + border-right: 1px solid #DDDDDD; +} + +.filter_amenities { + display: inline; + vertical-align: middle; + height: 100%; + float: left; + width: 25%; + + line-height: 20px; +} + +.popover { + list-style-type: none; + display: none; + background-color: #FAFAFA; + width: 100%; + + margin-left: -1px; + margin-top: 8px; + padding: 25px 0px; + + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations:hover .popover { + display: inline-block; +} + +.filter_amenities:hover .popover { + display: inline-block; +} + +ul { + list-style-type: none; + padding: 0px; + padding-bottom: 20px; +} + +li { +} + +h2 { + font-size: 16px; + padding-left: 30px; + margin: 0px; +} + +h3 { + font-weight: 600; + margin-top: 12px; + margin-bottom: 5px; + padding-left: 45px; +} + +h4 { + font-size: 14px; + font-weight: 400; + margin-top: 5px; + margin-bottom: 5px; + padding-left: 45px; +} + +button { + color: #FFFFFF; + font-size: 18px; + + height: 48px; + width: 20%; + background-color: #FF5A5F; + border-style: none; + border-radius: 4px; + + float: right; + margin-top: 11px; + margin-bottom: 11px; + margin-right: 30px; +} + +button:hover { + opacity: 90%; +} diff --git a/web_flask/static/styles/102-footer.css b/web_flask/static/styles/102-footer.css new file mode 100644 index 000000000000..11c938cd5021 --- /dev/null +++ b/web_flask/static/styles/102-footer.css @@ -0,0 +1,10 @@ +footer { + position: fixed; + bottom: 0; + background-color: white; + height: 60px; + width: 100%; + text-align: center; + line-height: 30px; + border-top: 1px solid #CCCCCC; +} diff --git a/web_flask/static/styles/102-header.css b/web_flask/static/styles/102-header.css new file mode 100644 index 000000000000..6684b08ded6f --- /dev/null +++ b/web_flask/static/styles/102-header.css @@ -0,0 +1,18 @@ +header { + background-color: white; + height: 70px; + width: 100%; + + border-bottom: 1px solid #CCCCCC; +} + +#header_logo { + height: 100%; + width: 142px; + + background-image: url("../images/logo.png"); + background-repeat: no-repeat; + background-position: center; + + margin-left: 20px; +} diff --git a/web_flask/static/styles/102-places.css b/web_flask/static/styles/102-places.css new file mode 100644 index 000000000000..14accab9bbd6 --- /dev/null +++ b/web_flask/static/styles/102-places.css @@ -0,0 +1,209 @@ +.places { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin: 45px auto; + text-align: center; +} + +article { + display: flex; + width: 390px; + flex: none; + flex-wrap: wrap; + flex-direction: row; + align-content: flex-start; + + padding-top: 10px; + padding-right: 20px; + padding-left: 20px; + padding-bottom: 40px; + margin: 20px; + + border: 1px solid #FF5A5F; + border-radius: 4px; +} + +.headline { + display: flex; + flex-direction: row; + position: relative; + + height: 80px; + width: 100%; +} + +.price_by_night { + display: flex; + justify-content: center; + align-self: flex-end; + + position: absolute; + right: 0; + + line-height: 60px; + color: #FF5A5F; + font-size: 30px; + padding: 5px; + border: 4px solid #FF5A5F; + border-radius: 100%; + float: right; + min-width: 60px; + height: 60px; +} + +.information { + display: block; + height: 80px; + width: 100%; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + + padding-top: 5px; + padding-bottom: 12px; + margin-top: 10px; + margin-bottom: 20px; +} + +.max_guest, .number_rooms, .number_bathrooms { + display: inline-block; + width: 100px; + text-align: center; + margin: 0px auto; +} + +.user { + margin-top: 5px; + margin-bottom: 5px; +} + +.description { + text-align: left; +} + +h1 { + display: block; + text-align: left; + width: 95%; + display: block; + margin-top: 0px; + margin-left: 20px; + margin-bottom: 5px; + font-size: 30px; +} + +article .amenities { + display: flex; + flex-wrap: wrap; + width: 100%; + margin-top: 40px; +} + +.article_subtitle { + font-size: 16px; + text-align: left; + width: 100%; + border-bottom: 1px solid #DDDDDD; + padding: 0px; + margin: 0px; + padding-bottom: 10px; +} + +.article_title { + font-size: 30px; + margin: 10px auto; + padding: 0px; +} + +article ul { + text-align: left; + margin-top: 20px; + margin-bottom: 0px; + padding-bottom: 0px; +} + +article li { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-content: flex-start; + margin-bottom: 10px; +} + +.reviews { + margin-top: 40px; + width: 100%; +} + +.review_item { + margin-bottom: 10px; +} + +.review_text { + margin: 0px; +} + +article h3 { + font-size: 14px; + padding: 0px; + margin: 0px; + margin-bottom: 5px; + +} + +.guest_icon { + display: inline-block; + background-image: url("../images/icon_group.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bed_icon { + display: inline-block; + background-image: url("../images/icon_bed.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bath_icon { + display: inline-block; + background-image: url("../images/icon_bath.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.tv_icon { + display: inline-block; + background-image: url("../images/icon_tv.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.wifi_icon { + display: inline-block; + background-image: url("../images/icon_wifi.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.pet_icon { + display: inline-block; + background-image: url("../images/icon_pets.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} diff --git a/web_flask/static/styles/103-common.css b/web_flask/static/styles/103-common.css new file mode 100644 index 000000000000..cd9f953ee6ae --- /dev/null +++ b/web_flask/static/styles/103-common.css @@ -0,0 +1,13 @@ +body { + margin:0px; + padding:0px; + + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.container { + max-width: 1000px; + margin: 30px auto; +} diff --git a/web_flask/static/styles/103-filters.css b/web_flask/static/styles/103-filters.css new file mode 100644 index 000000000000..10f686218bfe --- /dev/null +++ b/web_flask/static/styles/103-filters.css @@ -0,0 +1,101 @@ +.filters { + display: block; + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations { + display: inline; + vertical-align: middle; + float: left; + height: 100%; + width: 25%; + + line-height: 20px; + border-right: 1px solid #DDDDDD; +} + +.filter_amenities { + display: inline; + vertical-align: middle; + height: 100%; + float: left; + width: 25%; + + line-height: 20px; +} + +.popover { + list-style-type: none; + display: none; + background-color: #FAFAFA; + width: 100%; + + margin-left: -1px; + margin-top: 8px; + padding: 25px 0px; + + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations:hover .popover { + display: inline-block; +} + +.filter_amenities:hover .popover { + display: inline-block; +} + +ul { + list-style-type: none; + padding: 0px; + padding-bottom: 20px; +} + +li { +} + +h2 { + font-size: 16px; + padding-left: 30px; + margin: 0px; +} + +h3 { + font-weight: 600; + margin-top: 12px; + margin-bottom: 5px; + padding-left: 45px; +} + +h4 { + font-size: 14px; + font-weight: 400; + margin-top: 5px; + margin-bottom: 5px; + padding-left: 45px; +} + +button { + color: #FFFFFF; + font-size: 18px; + + height: 48px; + width: 20%; + background-color: #FF5A5F; + border-style: none; + border-radius: 4px; + + float: right; + margin-top: 11px; + margin-bottom: 11px; + margin-right: 30px; +} + +button:hover { + opacity: 90%; +} diff --git a/web_flask/static/styles/103-footer.css b/web_flask/static/styles/103-footer.css new file mode 100644 index 000000000000..11c938cd5021 --- /dev/null +++ b/web_flask/static/styles/103-footer.css @@ -0,0 +1,10 @@ +footer { + position: fixed; + bottom: 0; + background-color: white; + height: 60px; + width: 100%; + text-align: center; + line-height: 30px; + border-top: 1px solid #CCCCCC; +} diff --git a/web_flask/static/styles/103-header.css b/web_flask/static/styles/103-header.css new file mode 100644 index 000000000000..6684b08ded6f --- /dev/null +++ b/web_flask/static/styles/103-header.css @@ -0,0 +1,18 @@ +header { + background-color: white; + height: 70px; + width: 100%; + + border-bottom: 1px solid #CCCCCC; +} + +#header_logo { + height: 100%; + width: 142px; + + background-image: url("../images/logo.png"); + background-repeat: no-repeat; + background-position: center; + + margin-left: 20px; +} diff --git a/web_flask/static/styles/103-places.css b/web_flask/static/styles/103-places.css new file mode 100644 index 000000000000..14accab9bbd6 --- /dev/null +++ b/web_flask/static/styles/103-places.css @@ -0,0 +1,209 @@ +.places { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin: 45px auto; + text-align: center; +} + +article { + display: flex; + width: 390px; + flex: none; + flex-wrap: wrap; + flex-direction: row; + align-content: flex-start; + + padding-top: 10px; + padding-right: 20px; + padding-left: 20px; + padding-bottom: 40px; + margin: 20px; + + border: 1px solid #FF5A5F; + border-radius: 4px; +} + +.headline { + display: flex; + flex-direction: row; + position: relative; + + height: 80px; + width: 100%; +} + +.price_by_night { + display: flex; + justify-content: center; + align-self: flex-end; + + position: absolute; + right: 0; + + line-height: 60px; + color: #FF5A5F; + font-size: 30px; + padding: 5px; + border: 4px solid #FF5A5F; + border-radius: 100%; + float: right; + min-width: 60px; + height: 60px; +} + +.information { + display: block; + height: 80px; + width: 100%; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + + padding-top: 5px; + padding-bottom: 12px; + margin-top: 10px; + margin-bottom: 20px; +} + +.max_guest, .number_rooms, .number_bathrooms { + display: inline-block; + width: 100px; + text-align: center; + margin: 0px auto; +} + +.user { + margin-top: 5px; + margin-bottom: 5px; +} + +.description { + text-align: left; +} + +h1 { + display: block; + text-align: left; + width: 95%; + display: block; + margin-top: 0px; + margin-left: 20px; + margin-bottom: 5px; + font-size: 30px; +} + +article .amenities { + display: flex; + flex-wrap: wrap; + width: 100%; + margin-top: 40px; +} + +.article_subtitle { + font-size: 16px; + text-align: left; + width: 100%; + border-bottom: 1px solid #DDDDDD; + padding: 0px; + margin: 0px; + padding-bottom: 10px; +} + +.article_title { + font-size: 30px; + margin: 10px auto; + padding: 0px; +} + +article ul { + text-align: left; + margin-top: 20px; + margin-bottom: 0px; + padding-bottom: 0px; +} + +article li { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-content: flex-start; + margin-bottom: 10px; +} + +.reviews { + margin-top: 40px; + width: 100%; +} + +.review_item { + margin-bottom: 10px; +} + +.review_text { + margin: 0px; +} + +article h3 { + font-size: 14px; + padding: 0px; + margin: 0px; + margin-bottom: 5px; + +} + +.guest_icon { + display: inline-block; + background-image: url("../images/icon_group.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bed_icon { + display: inline-block; + background-image: url("../images/icon_bed.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bath_icon { + display: inline-block; + background-image: url("../images/icon_bath.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.tv_icon { + display: inline-block; + background-image: url("../images/icon_tv.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.wifi_icon { + display: inline-block; + background-image: url("../images/icon_wifi.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} + +.pet_icon { + display: inline-block; + background-image: url("../images/icon_pets.png"); + background-size: cover; + width: 20px; + height: 20px; + + margin-right: 10px; +} diff --git a/web_flask/static/styles/2-common.css b/web_flask/static/styles/2-common.css new file mode 100644 index 000000000000..ad75df807b36 --- /dev/null +++ b/web_flask/static/styles/2-common.css @@ -0,0 +1,4 @@ +body { + margin:0px; + padding:0px; +} diff --git a/web_flask/static/styles/2-footer.css b/web_flask/static/styles/2-footer.css new file mode 100644 index 000000000000..cc90e425f269 --- /dev/null +++ b/web_flask/static/styles/2-footer.css @@ -0,0 +1,9 @@ +footer { + position: fixed; + bottom: 0; + background-color: #00FF00; + height: 60px; + width: 100%; + text-align: center; + line-height: 30px; +} diff --git a/web_flask/static/styles/2-header.css b/web_flask/static/styles/2-header.css new file mode 100644 index 000000000000..6fa40ea7a838 --- /dev/null +++ b/web_flask/static/styles/2-header.css @@ -0,0 +1,5 @@ +header { + background-color:#FF0000; + height:70px; + width:100%; +} diff --git a/web_flask/static/styles/3-common.css b/web_flask/static/styles/3-common.css new file mode 100644 index 000000000000..b9bb6f05bb9a --- /dev/null +++ b/web_flask/static/styles/3-common.css @@ -0,0 +1,8 @@ +body { + margin:0px; + padding:0px; + + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} diff --git a/web_flask/static/styles/3-footer.css b/web_flask/static/styles/3-footer.css new file mode 100644 index 000000000000..11c938cd5021 --- /dev/null +++ b/web_flask/static/styles/3-footer.css @@ -0,0 +1,10 @@ +footer { + position: fixed; + bottom: 0; + background-color: white; + height: 60px; + width: 100%; + text-align: center; + line-height: 30px; + border-top: 1px solid #CCCCCC; +} diff --git a/web_flask/static/styles/3-header.css b/web_flask/static/styles/3-header.css new file mode 100644 index 000000000000..6684b08ded6f --- /dev/null +++ b/web_flask/static/styles/3-header.css @@ -0,0 +1,18 @@ +header { + background-color: white; + height: 70px; + width: 100%; + + border-bottom: 1px solid #CCCCCC; +} + +#header_logo { + height: 100%; + width: 142px; + + background-image: url("../images/logo.png"); + background-repeat: no-repeat; + background-position: center; + + margin-left: 20px; +} diff --git a/web_flask/static/styles/4-common.css b/web_flask/static/styles/4-common.css new file mode 100644 index 000000000000..cd9f953ee6ae --- /dev/null +++ b/web_flask/static/styles/4-common.css @@ -0,0 +1,13 @@ +body { + margin:0px; + padding:0px; + + color: #484848; + font-size: 14px; + font-family: Circular,"Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.container { + max-width: 1000px; + margin: 30px auto; +} diff --git a/web_flask/static/styles/4-filters.css b/web_flask/static/styles/4-filters.css new file mode 100644 index 000000000000..72fbe1a33d53 --- /dev/null +++ b/web_flask/static/styles/4-filters.css @@ -0,0 +1,27 @@ +.filters { + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +button { + color: #FFFFFF; + font-size: 18px; + + height: 48px; + width: 20%; + background-color: #FF5A5F; + border-style: none; + border-radius: 4px; + + float: right; + margin-top: 11px; + margin-bottom: 11px; + margin-right: 30px; +} + +button:hover { + opacity: 90%; +} diff --git a/web_flask/static/styles/5-filters.css b/web_flask/static/styles/5-filters.css new file mode 100644 index 000000000000..d6d37eaee357 --- /dev/null +++ b/web_flask/static/styles/5-filters.css @@ -0,0 +1,61 @@ +.filters { + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations { + display: inline-block; + vertical-align: middle; + + height: 100%; + width: 25%; + + margin-left: 45px; + border-right: 1px solid #DDDDDD; +} + +.amenities { + display: inline-block; + vertical-align: middle; + + height: 100%; + width: 25%; + + margin-left: 45px; +} + +h3 { + font-weight: 600; + margin-top: 12px; + margin-bottom: 5px; +} + +h4 { + font-size: 14px; + font-weight: 400; + margin-top: 5px; + margin-bottom: 12px; +} + +button { + color: #FFFFFF; + font-size: 18px; + + height: 48px; + width: 20%; + background-color: #FF5A5F; + border-style: none; + border-radius: 4px; + + float: right; + margin-top: 11px; + margin-bottom: 11px; + margin-right: 30px; +} + +button:hover { + opacity: 90%; +} diff --git a/web_flask/static/styles/6-filters.css b/web_flask/static/styles/6-filters.css new file mode 100644 index 000000000000..10f686218bfe --- /dev/null +++ b/web_flask/static/styles/6-filters.css @@ -0,0 +1,101 @@ +.filters { + display: block; + background-color: white; + height: 70px; + width: 100%; + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations { + display: inline; + vertical-align: middle; + float: left; + height: 100%; + width: 25%; + + line-height: 20px; + border-right: 1px solid #DDDDDD; +} + +.filter_amenities { + display: inline; + vertical-align: middle; + height: 100%; + float: left; + width: 25%; + + line-height: 20px; +} + +.popover { + list-style-type: none; + display: none; + background-color: #FAFAFA; + width: 100%; + + margin-left: -1px; + margin-top: 8px; + padding: 25px 0px; + + border: 1px solid #DDDDDD; + border-radius: 4px; +} + +.locations:hover .popover { + display: inline-block; +} + +.filter_amenities:hover .popover { + display: inline-block; +} + +ul { + list-style-type: none; + padding: 0px; + padding-bottom: 20px; +} + +li { +} + +h2 { + font-size: 16px; + padding-left: 30px; + margin: 0px; +} + +h3 { + font-weight: 600; + margin-top: 12px; + margin-bottom: 5px; + padding-left: 45px; +} + +h4 { + font-size: 14px; + font-weight: 400; + margin-top: 5px; + margin-bottom: 5px; + padding-left: 45px; +} + +button { + color: #FFFFFF; + font-size: 18px; + + height: 48px; + width: 20%; + background-color: #FF5A5F; + border-style: none; + border-radius: 4px; + + float: right; + margin-top: 11px; + margin-bottom: 11px; + margin-right: 30px; +} + +button:hover { + opacity: 90%; +} diff --git a/web_flask/static/styles/7-places.css b/web_flask/static/styles/7-places.css new file mode 100644 index 000000000000..22489f4a7b52 --- /dev/null +++ b/web_flask/static/styles/7-places.css @@ -0,0 +1,32 @@ +.places { + display: block; + margin: 45px auto; + text-align: center; +} + +article { + display: inline-block; + width: 390px; + padding: 20px; + margin: 20px; + border: 1px solid #FF5A5F; + border-radius: 4px; + text-align: center; +} + +h1 { + float: left; + text-align: left; + width: 95%; + display: block; + margin-top: 0px; + margin-left: 20px; + margin-bottom: 5px; + font-size: 30px; +} + +article h2 { + font-size: 30px; + padding: 0px; + margin: auto; +} diff --git a/web_flask/static/styles/8-places.css b/web_flask/static/styles/8-places.css new file mode 100644 index 000000000000..ef5ab6b6f3bb --- /dev/null +++ b/web_flask/static/styles/8-places.css @@ -0,0 +1,126 @@ +.places { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin: 45px auto; + text-align: center; +} + +article { + display: flex; + width: 390px; + flex: none; + flex-wrap: wrap; + flex-direction: row; + align-content: flex-start; + + padding-top: 10px; + padding-right: 20px; + padding-left: 20px; + padding-bottom: 20px; + margin: 20px; + + border: 1px solid #FF5A5F; + border-radius: 4px; +} + +.headline { + display: flex; + flex-direction: row; + position: relative; + + height: 80px; + width: 100%; +} + +.price_by_night { + display: flex; + justify-content: center; + align-self: flex-end; + + position: absolute; + right: 0; + + line-height: 60px; + color: #FF5A5F; + font-size: 30px; + padding: 5px; + border: 4px solid #FF5A5F; + border-radius: 100%; + float: right; + min-width: 60px; + height: 60px; +} + +.information { + display: block; + height: 80px; + width: 100%; + border-top: 1px solid #DDDDDD; + border-bottom: 1px solid #DDDDDD; + + padding-top: 5px; + padding-bottom: 12px; + margin-top: 10px; + margin-bottom: 20px; +} + +.max_guest, .number_rooms, .number_bathrooms { + display: inline-block; + width: 100px; + text-align: center; + margin: 0px auto; +} + +.user { + margin-top: 5px; + margin-bottom: 5px; +} + +.description { + text-align: left; +} + +h1 { + display: block; + text-align: left; + width: 95%; + display: block; + margin-top: 0px; + margin-left: 20px; + margin-bottom: 5px; + font-size: 30px; +} + +article h2 { + font-size: 30px; + margin: 10px auto; + padding: 0px; +} + +.guest_icon { + display: inline-block; + background-image: url("../images/icon_group.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bed_icon { + display: inline-block; + background-image: url("../images/icon_bed.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} + +.bath_icon { + display: inline-block; + background-image: url("../images/icon_bath.png"); + background-repeat: no-repeat; + background-position: center; + width: 50px; + height: 50px; +} diff --git a/web_flask/templates/10-hbnb_filters.html b/web_flask/templates/10-hbnb_filters.html new file mode 100644 index 000000000000..e0c924becec8 --- /dev/null +++ b/web_flask/templates/10-hbnb_filters.html @@ -0,0 +1,58 @@ + + + + AirBnB clone + + + + + + + + + + +
+ +
+
+
+ +
+

States

+

 

+
    + {% for state in states|sort(attribute='name') %} +
  • +

    {{ state.name }}

    + {% for city in state.cities|sort(attribute='name') %} +
      +
    • {{ city.name }}
    • +
    + {% endfor %} +
  • + {% endfor %} +
+
+
+

Amenities

+

 

+
    + {% for amenity in amenities|sort(attribute='name') %} +
  • {{ amenity.name }}
  • + {% endfor %} +
+
+ +
+
+
+

Holberton School

+
+ + diff --git a/web_flask/templates/5-number.html b/web_flask/templates/5-number.html new file mode 100644 index 000000000000..a6e76df9d166 --- /dev/null +++ b/web_flask/templates/5-number.html @@ -0,0 +1,11 @@ + + + + HBNB + + + {% if n %} +

Number: {{ n }}

+ {% endif %} + + diff --git a/web_flask/templates/6-number_odd_or_even.html b/web_flask/templates/6-number_odd_or_even.html new file mode 100644 index 000000000000..db28bea53bb3 --- /dev/null +++ b/web_flask/templates/6-number_odd_or_even.html @@ -0,0 +1,14 @@ + + + + + Odd | Even + + +{% if n is divisibleby(2) %} +

Number: {{ n }} is even

+{% else %} +

Number: {{ n }} is odd

+{% endif %} + + diff --git a/web_flask/templates/7-states_list.html b/web_flask/templates/7-states_list.html new file mode 100644 index 000000000000..9e5e569f42e8 --- /dev/null +++ b/web_flask/templates/7-states_list.html @@ -0,0 +1,14 @@ + + + + HBNB + + +

States

+
    + {% for state in states|sort(attribute="name") %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+ + diff --git a/web_flask/templates/8-cities_by_states.html b/web_flask/templates/8-cities_by_states.html new file mode 100644 index 000000000000..8622ebcc86b8 --- /dev/null +++ b/web_flask/templates/8-cities_by_states.html @@ -0,0 +1,20 @@ + + + + HBNB + + +

States

+
    + {% for state in states|sort(attribute="name") %} +
  • {{ state.id }}: {{ state.name }} +
      + {% for city in state.cities|sort(attribute="name") %} +
    • {{ city.id }}: {{ city.name }}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+ + diff --git a/web_flask/templates/9-states.html b/web_flask/templates/9-states.html new file mode 100644 index 000000000000..32af79cf808d --- /dev/null +++ b/web_flask/templates/9-states.html @@ -0,0 +1,26 @@ + + + + HBNB + + +{% if condition=='states_list' %} +

States

+
    + {% for state in states|sort(attribute="name") %} +
  • {{ state.id }}: {{ state.name }}
  • + {% endfor %} +
+{% elif condition=='state_id' %} +

State: {{ state.name }}

+

Cities:

+
    + {% for city in state.cities|sort(attribute="name") %} +
  • {{ city.id }}: {{ city.name }}
  • + {% endfor %} +
+{% elif condition=='not_found' %} +

Not found!

+{% endif %} + +