From 42af039f0c55d3ca945b8458a441fb334c85ec59 Mon Sep 17 00:00:00 2001 From: Temake Date: Sat, 12 Apr 2025 17:04:01 +0100 Subject: [PATCH 1/7] Goggle Fuctinality2 --- event/__pycache__/urls.cpython-313.pyc | Bin 1396 -> 1483 bytes event/__pycache__/views.cpython-313.pyc | Bin 10928 -> 10714 bytes event/urls.py | 2 +- 3 files changed, 1 insertion(+), 1 deletion(-) diff --git a/event/__pycache__/urls.cpython-313.pyc b/event/__pycache__/urls.cpython-313.pyc index e793523b30d0e557a4dd5b9da59a0457d1f61e59..041864560b2b30c7877730c98342afd259fe4703 100644 GIT binary patch delta 328 zcmeyub(&k_GcPX}0}y=a{gv*|%)sy%#DM``DC08=(?pH+>TE$0Fc}0L%pJ^Q$sEI| z#1PCI!vrMxCLR!-EX*jb5-b3h5sYCAl0oQ!v4Z3$>o7_)3kCB`?qHN>gz!Xwykjt) zvKZV9aiAG0Fr5e*Vg|1SNS!`Mk#IVzrsQNkrVth0^!)tvoK*ds{PfH`{VE;^R~O9H zWW2?amzbM6Ig!a|@@%GMj3Sern9JB8N+xe(KF=i&w1E+bi{DP}XYt{YpP@QmXQs}I YxQi?{ldrQ(;uhrOXKLgwk_9RO07l9{wg3PC delta 240 zcmX@j{e?^8GcPX}0}$91eM%Q#W?*;>;=lk8l=1ly<3x@1tV~J_!Q2xMh|2QBumwrL z6d~wf-e5jU=E;1FGE70Tll>T_l?6ZoF^oWcf8zUKlMR?cCa+{NzUx(=tZk$&Jiqlm9cHOA zPxVu2rAmE(IjF7dL4;l`p$I;R7bz9Ahaw)eT0sxuWTkdsXa4h>?;93oHov4;zFRCN z!p4&C*YJUHix)nR$4eKeLm^6I)+xKFOC&6tvToT!Jz8$c^0JqDwajG&Dkx^flJ&`c z>etMg4ah+nWZA6PvLRWdqTEVbWr<3f*|T9eLL+jNM&%fd$#EK&6Eq(I>0Okj4RUT5r7 zd;+0q`~m^})?p4g-6R~sySk+MO4kG6S9!yL9z?Zl>}5M#;HuDxR~uJh2c9>r!EQX$ zv;zCoW9BkI25Xj2?0DAt6MFEW?KGP`_6MM-bM|h4qiAS(1PVTFslXr>90HuXf7SuU zF+%d2ayDEJ3V735*7b!j<_a~5_2;OMoP>uBjt+B|E<*Z3|4eI%tmlojPh8KrSiK9( zSaJ0_Mip|3+s_rDNcQMMqzFliT69~%NK>pn>BKvpA>{Zgn?~8Ted}}geB~_~_)1|NSo=jR_O*dq^P!a}UP`xOu0bIwj|4GA~fsh;cTHx_^z^Uc~ zW^kI1J%fHBNUu+hqyDL4Fy)|iP&A#hfgPMyK0Jh=d_^OWH j!>NP<)A%*905kY388FSW%bpu`1LTctO_kq7y delta 946 zcmZ9ITWAw$6vw}l$<%3*Nhg`4xi^zb(~QN-T1C8d(HbigSC@>U*anH3)`HmbO(~0b zc~N{2!SsMsR;b`UltrpA54Pw_wRJ_7-H3ukL}A%SAA`;0G^fFjFXy&dK97)y)o<6nrU-Q+p<2*PyID*&jx5fcj#g^ zsD)^##+=!(7NHTQ9ePu?MT^p?rcgzT(O8X1*|?UV2`x#JS}SeUQZ%Kt(Kanj)0#?E zh4@LF=&m5qd3Uchw-a5wjORdTYOfhGGd#VJ+w+Alsc|pk%`D&hg)ggdALIUSxU(_9 zNRW~J_2i-zdMHR}2UZ}$t?aj>WVwicT2$C>KD2BD2$_mC&q35Yv1kXI@E>6oRv=EH;~0^O@pjQr9U8N&Pv??yV2pk z3OSs1PlWSq&GrKv>-7?tsLl&7t{j&Ee!~-<3&|GJ6RijKbg!~})(Yu~)#O?n8xPqcAk2{8BWGLVt0sLKm~MR4+F9 zidLCPG<;_p2AD8(wEAbHN}Lln!&9mC^57%s=T`#$<=?yS{VRcZA`1j+mbdI*b1N}b zxS5*rmzy^|mbxBDUGFPg)qQ6yXS;64)XhP1$8OIEWHxBa@Z4r?1nGWm>zKkD|h0w+Dys&!S zrCjcw*f!Bwj;}3C>nc16rYgi7Zruy83ja;L#Jg?3!Z`ZUcVQBrr6aZ(wh*dI?<21! IuwA|O2^2f Date: Sun, 13 Apr 2025 13:38:33 +0100 Subject: [PATCH 2/7] Fix: error in views and urls --- db.sqlite3 | Bin 208896 -> 208896 bytes event/__pycache__/permissions.cpython-313.pyc | Bin 1330 -> 1295 bytes event/__pycache__/serializers.cpython-313.pyc | Bin 8439 -> 8439 bytes event/__pycache__/views.cpython-313.pyc | Bin 10714 -> 11114 bytes event/permissions.py | 2 +- event/serializers.py | 4 ++-- event/views.py | 21 +++++++++-------- main/__pycache__/settings.cpython-313.pyc | Bin 4888 -> 4888 bytes main/__pycache__/urls.cpython-313.pyc | Bin 1469 -> 1543 bytes main/settings.py | 1 + main/urls.py | 22 ++---------------- main/views.py | 8 +++++++ 12 files changed, 25 insertions(+), 33 deletions(-) diff --git a/db.sqlite3 b/db.sqlite3 index dd01caec5bd76badd40a4ea3fb0495b398dedb17..9bfbaf55078ba95683597e2f7aab1c458ec1d40a 100644 GIT binary patch delta 202 zcmZp8z|-)6XM!~2Zum{_Jy`_GsMlsU}6|A_xE{}Q0gH2&>N_?co4a08Vy^5-$| z=ke!lRxC*3pPqN0$&-bFfx&b7?)yw`{QOsd^2-_cmjmGk{#QV))A^?_f6t@~Qlm3{ w?|mi>9xndhKt*2}_`mXh1uA&S&&|rr$jHqERKd!%=z+q-0QT+d3d}$G0gAXmc>n+a delta 202 zcmW;Dud2de9Eb7W`$xp>)h}jGnC*ag6@p?BZ(tx^z%ZEyn#Y;JHwrRXvB-o45d?3+ zB*KPGixz_zJTK)bM;qaVffQx;d&4)ETICboXQ&&Bz4DElVFtwD>iOf0yDx4 zDb7jNpF%r5F7^DwJR=d|f&(HWbEFZtySIsm!y_|zNqsbg_A=g;9VT79&3GGMj|oS_ wc;IGM4ISTkQ#OQK(z}fRD(f3P32!`2aD`nEjM-cYR4BO~Ko2DL9NT#T9%qOXhUUli5<$^hgP2?M18zBwe} delta 217 zcmeC@+Qh~CnU|M~0SK5^y-nxa$a{*3v2F4VrbwnBj>+=OqBdYTkURodc`z`jFlaLQ zg=n%BaRbGRm_Y;&h~NMcx7Z7c^3yVNQYWV~=QA2izRs*Dbe&)MBERy2;N{T^qc8Fs zT;MR6%);WzC^6ZKMVe7+avF;^qv7O9EEcX(AX9`vgaF7W4x8Nkl+v73yCNkZml24I iK`K5lGcq#XWl;OV!o_GfA^N(g{zXy!uM9vAST6uWP%f_k diff --git a/event/__pycache__/serializers.cpython-313.pyc b/event/__pycache__/serializers.cpython-313.pyc index 507ae718ea2c23a53f75168e3d0939eb0053f2f9..b7a82d3150ce130dc3ecbbcf44066854457fdb9d 100644 GIT binary patch delta 55 zcmezF_}!8BGcPX}0}xyl`<*VZk@vVLW6|cTqNa?DLYuk8mvi#TFzQXnzAk2XQOxiQ KgUsXu3g!U!sS&OK delta 55 zcmezF_}!8BGcPX}0}wnv^F3X7Bkyrh#=^~4MNJtQ1vYbwFX!ZwX4IRIeO=7(qL|?q K2I=2h-^CQN#T!lh6Ff412}zWFMmU$srXiipKqlJ- zT|yVhZ9P$2vI8)XlG>zdNvn@$OR3+h{!*y2)MKP2=q)W^~P zYsY&23#RzmP^&(xZ8|NyHPpAGe*M_{!kHxnS4|ilL-Hu2G)R)ssY##cBT_k=ZDJoSen1taDeKHx1XKkKk~M#lVqGA7$-;{LkIu0_k>> z|2CB%N8&H^khfCXAg$)euWvdYlP&|6$w92Bpp+6%Eu+i)<4`-B=KGM28RA zoF0ZL3OY}4f#78V+7e6?gc101W7q6FjTQ;668H$jdKXEWBzSs(Gc+VPgRk`p!aLG_ z{KSsCWnb&tQFZ>?#~P z?2f_2_G0)l8>n9|5EI}UL7af-19J#Sgc^7FZX~7%HqY}vN6g-O*5~xlbB`ykc$!Z) zcJ;s-O(!z`yv=Tsb(2489;xMUlXA#j!MYeq7z$Owb*c-6ssSax;ekLw)*JXtv_C-1 zaN&EnEb%v^DeYAc4#Z=~uQnXZS6rivzn9Q%57#?FH=b?oL*_)lEEFvp@^-OOUMUsJ zn~=va-2<)o0dY5ise(j;uI{IFgJ95|3+t+xJej641s%a*rbX36sSr;sALsZd@g&>a{%3rO ztxu9OWk3)95AKi?B^9XPYFroFK1ajn5vfWB0xD!H!#_~9)RCfi0)G$pdgfWJpvmsI z7v_!2j_cy|5EY8YA13d0x6sVLcg-X>1j)Qx&3QhNx zbl~RiwSRZJKk)}Q&J{?v<6OPz61&gur8n@u@gzNr`oYX=>>=OEB&WZPQP?Bt11Ct9 zYrVT4WyfDAV*6Vu=Wm$s1{qz#(eYL-6Y5&%=6}tMDc`3luJISTQnx8DPQbGBcGX&0 zt*n`Fhcxc%R;3I9@~fA%<5@2Pl0HP*VFHyvP~$X7NrE~n^rqUM;67>{WnpS@YSw^< zG-$Ldo48jnt=IWZSA_kT|FP?|LdSrYxYj+q;BpMwBy=;NK`-Qz|?{2jBNTShE>8ge|PNNp1XsOnfkfxWBx;zBx?sUf260~)V}`(U;aK` delta 2411 zcma)7ZERCz6uxiQUAlg)-MaN--PWz^w%frNj4gbO;eZLYY>Zt5V+M6}m(tO-^W0lL zG-hCe5~IQSs)0x%iiyD=YO+LsnizkXm~8O}coP%&gTY@!7L5r;&w0xV5@Kx9=brnV zkN3RiJ@2`{9xzqcJ(tTa;m>UNGqZi(6|~%D^PR;xNv%ry5_M1)kyJ^wC+ib_@C(_I z3?zaO6tXQDf{^M|UCD+-7{Y>cCmRz@(1fy6txh&4A`nTmKue+(S_S7xMiXt&mWV+t z(GKm24(Ld9LT5q&B@u^sL<&f)l3n$NB(-M3I(~qE$r`Fx6RFlB=bK>T&kL?waCOMl zqupV_^$5<7T%gRY6I>9v5OPywr}U}~Aqh52$QU)emh~|zfh4JoA*rt&Mr5lq*Hl3O@49FfS8k(L;!8URkB-la_S%EN@tJ>{CL0o#?TgRsP=ISo~ zji<(mxjR)WqHDs<&sH@Ct5rLAFkh$X96q7tjRRTjq^cQrdimE?@AvdmRFPaAN!I;`Tlg#X)odgG%)Xut@}KR;;z?8}6|jaZ%fVJ$HzE7bwczMs z1N@33imu-|a#&FG36eh(E9q26Tm#Yc@mZ&jPdcM)8$X9Q$geqnA8H^E>PcurP~=jA zw5(~FJ#JQNv_UvT24ZO$rHJ^IYIum>bTzP@{Jv|aA__<~zQ#rsFFZv~Lj>Cib`Vf* zu#;b|iSn1-L3NZ~_YpixP(>itdYYuij%zn@1ikpz_aM9`-SD?BT75S{vFo9}rBL5u zu%F*@Z<0kOyLqJggE_Jjkwz8wf22fK<@18W_-fi-ENXCC*9@?dc9_6M@TBC9l7fKN z(-nkLa(v9=^WLQVx|c%Ti@~)&TI*qOq3GGqc9jnoHj?*2f_eh#85lvpHYhiYX%lCW z%1-GOsKPTSoxmvf)M#_%+K(!(CvH<5^iB#ac9SMa?8Zsb6oEL6Cv9$;v;->t^>zf> zobpKJ->LPNiaw1+4`NT^<*8rGz@}EJ6(MPwL6vF+d&Z*3{MFj{!Y$u|eK%96V_=p#$B`ieYx`>-0SWQ5; z$E-B6MoxojBE0-+U{lL_5~+V+1AClN_GEJwZ6b(;MD)|84 z8f<3M3x|S3Y)*9P5j0X9|EKT|+lVIB6MIP~1p&38-iYw8azALKMQi;ZzK%-wURD}u z|J5`7H`@kbl?~nG=KEL1VqB zr_zNf4bD(F>$G0TgM;kK*T$?ong#4C7qM#z0tBL2){)diQ0^0@x-@4mAZyBFL*qju zDqNx$w^2Bbxq_z8^1+ywUFKu4^)hV(HuLkbZ8c)D%9%nTgMIb|@>dpqiXFCyyP)** zt)2G*A5$RD)bwONQ|L|?K?O2xRZMnXe b?PV8tUk~>#g?pDJdiyQM_;6Q?mFD0-lRy)Q diff --git a/event/permissions.py b/event/permissions.py index 1001cc7..9cb5c7f 100644 --- a/event/permissions.py +++ b/event/permissions.py @@ -10,4 +10,4 @@ def has_permission(self, request, view): def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True - return request.user.profile==obj.creator \ No newline at end of file + return request.user==obj.creator \ No newline at end of file diff --git a/event/serializers.py b/event/serializers.py index 2a5f238..4a9b2a6 100644 --- a/event/serializers.py +++ b/event/serializers.py @@ -108,14 +108,14 @@ def get_creator_phone(self, obj): return obj.creator.profile.phone_number except ObjectDoesNotExist: return None - + + def create(self, validated_data): """Associate the event with the creator.""" validated_data["creator"] = self.context["request"].user return super().create(validated_data) - class EventDetailSerializer(EventSerializer): """Serializer for detailed event view.""" diff --git a/event/views.py b/event/views.py index d2854e2..d0eb64b 100644 --- a/event/views.py +++ b/event/views.py @@ -6,6 +6,7 @@ from rest_framework.authtoken.models import Token from rest_framework.views import APIView import requests +from .permissions import IsEventCreator from django.core.mail import send_mail from rest_framework_simplejwt.tokens import RefreshToken from django.conf import settings @@ -50,7 +51,7 @@ def post(self, request, *args, **kwargs): class EventViewSet(viewsets.ModelViewSet): serializer_class = EventSerializer - permission_classes = [permissions.IsAuthenticated] + permission_classes = [IsEventCreator] authentication_classes = [TokenAuthentication] def get_queryset(self): @@ -76,8 +77,7 @@ def attendees(self, request, pk=None): class PublicEventListView(generics.ListAPIView): serializer_class = EventSerializer queryset = Event.objects.all() - - permission_classes = [permissions.AllowAny] + permission_classes = [permissions.IsAuthenticatedOrReadOnly] class AttendeeView(generics.ListAPIView): @@ -94,14 +94,15 @@ def get_queryset(self): class EventRegistrationView(generics.GenericAPIView): serializer_class = AttendeeSerializer permission_classes = [permissions.AllowAny] + - # def get(self, request): + def get(self, request,registration_link=None): - # # Find the event by matching the registration code in the registration_link - # event = get_object_or_404(Event) - # return Response({ - # 'event': EventSerializer(event).data - # }) + # Find the event by matching the registration code in the registration_link + event = get_object_or_404(Event, registration_link=registration_link) + return Response({ + 'event': EventSerializer(event).data + }) def post(self, request, registration_link=None): @@ -144,7 +145,7 @@ def post(self, request, registration_link=None): return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - +@api_view(["POST"]) def logout(request): try: request.user.auth_token.delete() diff --git a/main/__pycache__/settings.cpython-313.pyc b/main/__pycache__/settings.cpython-313.pyc index 6332bbd88f2044b4f42d857fdb92d0e0c3c9645a..c870c6e06844f1979c0bbf5b34902942a66ba315 100644 GIT binary patch delta 29 jcmbQCHbaf~GcPX}0}yme{Z2R9$g3&HD6rXF@F61rblL~N delta 29 jcmbQCHbaf~GcPX}0}!;G`JQgDkylfYk#DoP;6p|Lew+wp diff --git a/main/__pycache__/urls.cpython-313.pyc b/main/__pycache__/urls.cpython-313.pyc index f50148bb85983b818bd27677a4e108e6b2b06c6a..be58aaa72d4eb74bfd7362adf6d2e9038183b6e6 100644 GIT binary patch delta 296 zcmdnX-Oi)_nU|M~0SInz|4#2>VPJR+;=lkWl=1n`M0H=WVD?}RZyqn+B3=cC7#1al zV9pq(Aeo7E#_C)#yusYTJeJI0Vcr;?AUT*32s%h{;wfoOKDaXe7*?Pe0;Y@*C8kUe zTA!szFkMhnXfq$6qknR)uR7;bTZ1OpP&Q-KOt z@)C1XC%j7!YDLZjb$=Z5%=V6EEBjuZUGrnTr@d=RY~zKgUmw~jt+?lrqit^ nT1~f~Xn&bS`6f_AsKaxH)kPMy$!)AU+??$EOpV+{GC+L*5JW&7 delta 263 zcmZqY*~_i|nU|M~0SMF*Kc%~}Ffcp@abSQ0%J}?fqPj0v42u#&FnbJBkkrI3<5-Ru zo*)^RLIfQok6^=Crcg#OXE2u~GuRmJ7*?QRJf@5gDN`m0t$ zTVhIXW}g0JeHJNMO~zX+d5O8HRV;}Gnfg^+sb#5oC3>YrImLdOf|KJ|CQtsx(#s_U zGzVm6aq8q=Rwa>-Yz(ZN9TF2vr&~?5nr=VQ{xXa5 Date: Tue, 22 Apr 2025 11:08:59 +0100 Subject: [PATCH 3/7] Feat: init --- .gitignore | 2 +- event/__pycache__/models.cpython-313.pyc | Bin 6291 -> 6291 bytes event/__pycache__/permissions.cpython-313.pyc | Bin 1295 -> 1295 bytes event/__pycache__/serializers.cpython-313.pyc | Bin 8439 -> 0 bytes event/__pycache__/urls.cpython-313.pyc | Bin 1483 -> 0 bytes event/__pycache__/views.cpython-313.pyc | Bin 11114 -> 0 bytes main/__init__.py | 2 +- main/__pycache__/settings.cpython-313.pyc | Bin 4888 -> 0 bytes main/__pycache__/urls.cpython-313.pyc | Bin 1543 -> 0 bytes 9 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 event/__pycache__/serializers.cpython-313.pyc delete mode 100644 event/__pycache__/urls.cpython-313.pyc delete mode 100644 event/__pycache__/views.cpython-313.pyc delete mode 100644 main/__pycache__/settings.cpython-313.pyc delete mode 100644 main/__pycache__/urls.cpython-313.pyc diff --git a/.gitignore b/.gitignore index 8dd938b..9dcf8fd 100644 --- a/.gitignore +++ b/.gitignore @@ -55,7 +55,7 @@ cover/ *.mo *.pot - +*.__pycache__/ # Flask stuff: instance/ .webassets-cache diff --git a/event/__pycache__/models.cpython-313.pyc b/event/__pycache__/models.cpython-313.pyc index c168155d14bba6c789625a1e4c511491fba6b58f..f4cc61dd868b49f5c9e787718098cdf39e09d058 100644 GIT binary patch delta 21 bcmbPiIN6ZrGcPX}0}vb*WXagb(=Gu3JqHCy delta 21 bcmbPiIN6ZrGcPX}0}ym&eoEiS(=Gu3LpBCf diff --git a/event/__pycache__/permissions.cpython-313.pyc b/event/__pycache__/permissions.cpython-313.pyc index 43599390f9285b20665f90e3fd062d91fa559ee8..56a02b1280946fdf796772f2538009b80162ae49 100644 GIT binary patch delta 21 acmeC@>gVG5%*)Hg00jA>EEyYlm{|cb{sapE delta 21 bcmeC@>gVG5%*)Hg00d9Cey4BbVP*vYJRSvW diff --git a/event/__pycache__/serializers.cpython-313.pyc b/event/__pycache__/serializers.cpython-313.pyc deleted file mode 100644 index b7a82d3150ce130dc3ecbbcf44066854457fdb9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8439 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 D>~FL( diff --git a/event/__pycache__/urls.cpython-313.pyc b/event/__pycache__/urls.cpython-313.pyc deleted file mode 100644 index 041864560b2b30c7877730c98342afd259fe4703..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1483 zcmb7DL1-IC6rGhut5sxKwPmm4D8-Jb5r)WXiUhV1rovXhmSY*M9g}9MyNM>sHk(~D zyBpJmLUKw%2-t^^^wb>FTaP{V*rOL6M5ctc4KNd;ib> zvwM)qoB?$G_2lnPGY-HT2BMWYG!9@4fTutOs?Y$-0v48II5y63tPx*^7*ac~!bW0Q z#3J`68cCegU;$JPQ(#GxTDd6k@u`ZM*cv*8>ZJr zlLE;sqMN#Bx-Hvt5q`^_g?bZr4YcE|5)s`+mg|rNKWRX^t~V&zJs^j9hleM-?!@51M_=7xW>11efh@{(J=~l<)onZP00u1R!K8=VWk4Vv_NMD_e{tA5u6}bemfe|qrF%iR2k)aJbw-z5)I37kPN!{6E??-ZL zd{#Ws3T>H3`)Y?1;b@o#Po+rHa`a1~k6=09g9CbFKrS!LX{?^3t=BIvtu8fJHa2VH zwZ(d)d9^mRSXUeC&9&0{!s^=6%q4Bn-my$uZ#x>VfDKzitRamxGPV6Rk*as>wr8Sw z%zi)i-8p~I?Oj|DgkQnLYcTy9t-%=Vc`{&9*#Yq`0nDj7hir6z$(Kddn5a!Q{4fj3#S<# z-K{@c*;{$>O#mwl=XX(0o(|;co;(xCGhKOZzqTI04I0}|jk2ocAYbm~t3kfn&Cma| z6~!iAc)j9mP@L@*YeBKrEiU}51n_gN`}Bu;uiOmE&0cvkC~tPlSNFek1L(aQNM&R9 J)A(cB@jn7%eenPQ diff --git a/event/__pycache__/views.cpython-313.pyc b/event/__pycache__/views.cpython-313.pyc deleted file mode 100644 index ffccd01e2f499ed10c8ad08a3f9fcd1f37f43393..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11114 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 OQOGT6-xVp`ynh2w`@+xw From a3743ad0ff1501ff8e137e70553c0040e3076b0f Mon Sep 17 00:00:00 2001 From: Temake Date: Tue, 22 Apr 2025 15:12:03 +0100 Subject: [PATCH 4/7] Fixture --- event/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event/views.py b/event/views.py index d0eb64b..4277c6f 100644 --- a/event/views.py +++ b/event/views.py @@ -212,4 +212,4 @@ def google(request): 'token': token.key }, status=200) - return Response({"message":"An error occured, Pleasee try again later"},status=500) + return Response({"message":"An error occured, Pleasee try again later"},status=status.HTTP_500_INTERNAL_SERVER_ERROR) From c7c864c8a8eb66735043336d424a98ccb1c4521b Mon Sep 17 00:00:00 2001 From: Temake Date: Tue, 22 Apr 2025 15:14:11 +0100 Subject: [PATCH 5/7] settings --- main/settings.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/main/settings.py b/main/settings.py index 7b9bee4..c3087e0 100644 --- a/main/settings.py +++ b/main/settings.py @@ -1,14 +1,3 @@ -""" -Django settings for main project. - -Generated by 'django-admin startproject' using Django 5.1.7. - -For more information on this file, see -https://docs.djangoproject.com/en/5.1/topics/settings/ - -For the full list of settings and their values, see -https://docs.djangoproject.com/en/5.1/ref/settings/ -""" import os from rest_framework.authentication import TokenAuthentication From 644001da5f709ef758366480ebe7662528ec9e46 Mon Sep 17 00:00:00 2001 From: Temake Date: Mon, 5 May 2025 13:05:37 +0100 Subject: [PATCH 6/7] feat: DockerFile --- .dockerignore | 34 ++++++++ Dockerfile | 14 ++++ Dockerfile.Celery | 51 ++++++++++++ README.Docker.md | 22 +++++ event/__pycache__/permissions.cpython-313.pyc | Bin 1295 -> 1295 bytes event/serializers.py | 3 +- event/tasks.py | 76 +++++++++--------- event/views.py | 63 +++++++++------ main/__init__.py | 2 +- main/__pycache__/__init__.cpython-313.pyc | Bin 258 -> 253 bytes main/settings.py | 4 +- templates/event_registration.html | 57 +++++++++++++ 12 files changed, 261 insertions(+), 65 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 Dockerfile.Celery create mode 100644 README.Docker.md create mode 100644 templates/event_registration.html diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..03a268b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.DS_Store +**/__pycache__ +**/.venv +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose.y*ml +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5a394b3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.12-slim + +ENV PYTHONDONTWRITEBYTECODE = 1 +ENV PYTHONUNBUFFERED = 1 +RUN apt-get update && apt-get install -y gcc python3-dev libpq-dev + + +WORKDIR /app +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . + + +CMD ["gunicorn", "--bind", "0.0.0:8000", "--workers", "4", "main.wsgi:application"] \ No newline at end of file diff --git a/Dockerfile.Celery b/Dockerfile.Celery new file mode 100644 index 0000000..fcb6668 --- /dev/null +++ b/Dockerfile.Celery @@ -0,0 +1,51 @@ +# # syntax=docker/dockerfile:1 + +# # Comments are provided throughout this file to help you get started. +# # If you need more help, visit the Dockerfile reference guide at +# # https://docs.docker.com/go/dockerfile-reference/ + +# # Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7 + +# ARG PYTHON_VERSION=3.13.0 +# FROM python:${PYTHON_VERSION}-slim as base + +# # Prevents Python from writing pyc files. +# ENV PYTHONDONTWRITEBYTECODE=1 + +# # Keeps Python from buffering stdout and stderr to avoid situations where +# # the application crashes without emitting any logs due to buffering. +# ENV PYTHONUNBUFFERED=1 + +# WORKDIR /app + +# # Create a non-privileged user that the app will run under. +# # See https://docs.docker.com/go/dockerfile-user-best-practices/ +# ARG UID=10001 +# RUN adduser \ +# --disabled-password \ +# --gecos "" \ +# --home "/nonexistent" \ +# --shell "/sbin/nologin" \ +# --no-create-home \ +# --uid "${UID}" \ +# appuser + +# # Download dependencies as a separate step to take advantage of Docker's caching. +# # Leverage a cache mount to /root/.cache/pip to speed up subsequent builds. +# # Leverage a bind mount to requirements.txt to avoid having to copy them into +# # into this layer. +# RUN --mount=type=cache,target=/root/.cache/pip \ +# --mount=type=bind,source=requirements.txt,target=requirements.txt \ +# python -m pip install -r requirements.txt + +# # Switch to the non-privileged user to run the application. +# USER appuser + +# # Copy the source code into the container. +# COPY . . + +# # Expose the port that the application listens on. +# EXPOSE 8000 + +# # Run the application. +# CMD gunicorn 'enbv.Lib.site-packages.asgiref.wsgi' --bind=0.0.0.0:8000 diff --git a/README.Docker.md b/README.Docker.md new file mode 100644 index 0000000..6dae561 --- /dev/null +++ b/README.Docker.md @@ -0,0 +1,22 @@ +### Building and running your application + +When you're ready, start your application by running: +`docker compose up --build`. + +Your application will be available at http://localhost:8000. + +### Deploying your application to the cloud + +First, build your image, e.g.: `docker build -t myapp .`. +If your cloud uses a different CPU architecture than your development +machine (e.g., you are on a Mac M1 and your cloud provider is amd64), +you'll want to build the image for that platform, e.g.: +`docker build --platform=linux/amd64 -t myapp .`. + +Then, push it to your registry, e.g. `docker push myregistry.com/myapp`. + +Consult Docker's [getting started](https://docs.docker.com/go/get-started-sharing/) +docs for more detail on building and pushing. + +### References +* [Docker's Python guide](https://docs.docker.com/language/python/) \ No newline at end of file diff --git a/event/__pycache__/permissions.cpython-313.pyc b/event/__pycache__/permissions.cpython-313.pyc index 56a02b1280946fdf796772f2538009b80162ae49..0f1100892a41fb9f4245e9b559de01320f7ff82f 100644 GIT binary patch delta 20 acmeC@>gVGA%*)Hg00h>H**9{tumS)t{saF2 delta 20 ZcmeC@>gVGA%*)Hg00jA>EE~C5SOG2v1EK%` diff --git a/event/serializers.py b/event/serializers.py index 4a9b2a6..6d8916e 100644 --- a/event/serializers.py +++ b/event/serializers.py @@ -144,8 +144,7 @@ def create(self, validated_data): class ReminderSerializer(serializers.ModelSerializer): - """Serializer for reminders.""" - + class Meta: model = Reminder fields = ["id", "sent_at", "message", "type"] diff --git a/event/tasks.py b/event/tasks.py index 3a1b328..dd019c0 100644 --- a/event/tasks.py +++ b/event/tasks.py @@ -7,42 +7,7 @@ from celery import shared_task from .models import Event, Reminder -@shared_task -def send_event_reminders(): - - tomorrow = timezone.now() + timedelta(days=1) - four_days = timezone.now() + timedelta(days=4) - - # Get events in the next 3 days - upcoming_events = Event.objects.filter( - date__gte=tomorrow, - date__lte=four_days - ) - - for event in upcoming_events: - days_until_event = (event.date - timezone.now()).days - - for attendee in event.attendees.all(): - - if Reminder.objects.filter( - attendee=attendee, - sent_at__date=timezone.now().date() - ).exists(): - continue - - - if days_until_event <= 1: - message = f"REMINDER: The event '{event.title}' is TOMORROW at {event.date.strftime('%H:%M')} in {event.location}." - else: - message = f"REMINDER: The event '{event.title}' is coming up in {days_until_event} days at {event.date.strftime('%H:%M')} in {event.location}." - - # Send email reminder - send_email_reminder(attendee, event, message) - - # Send WhatsApp reminder if phone number is available - if attendee.phone_number: - send_whatsapp_reminder(attendee, message) def send_email_reminder(attendee, event, message): """Send email reminder to an attendee""" @@ -79,4 +44,43 @@ def send_whatsapp_reminder(attendee, message): ) except Exception as e: - print(f"Failed to send WhatsApp reminder: {str(e)}") \ No newline at end of file + print(f"Failed to send WhatsApp reminder: {str(e)}") + + +@shared_task +def send_event_reminders(): + + + tomorrow = timezone.now() + timedelta(days=1) + four_days = timezone.now() + timedelta(days=4) + + # Get events in the next 3 days + upcoming_events = Event.objects.filter( + date__gte=tomorrow, + date__lte=four_days + ) + + for event in upcoming_events: + days_until_event = (event.date - timezone.now()).days + + for attendee in event.attendees.all(): + + if Reminder.objects.filter( + attendee=attendee, + sent_at__date=timezone.now().date() + ).exists(): + continue + + + if days_until_event <= 1: + message = f"REMINDER: The event '{event.title}' is TOMORROW at {event.date.strftime('%H:%M')} in {event.location}." + else: + message = f"REMINDER: The event '{event.title}' is coming up in {days_until_event} days at {event.date.strftime('%H:%M')} in {event.location}." + + # Send email reminder + send_email_reminder(attendee, event, message) + + # Send WhatsApp reminder if phone number is available + if attendee.phone_number: + send_whatsapp_reminder(attendee, message) + diff --git a/event/views.py b/event/views.py index 4277c6f..893e99a 100644 --- a/event/views.py +++ b/event/views.py @@ -1,6 +1,8 @@ from rest_framework import viewsets, permissions, status, generics from rest_framework.decorators import api_view, permission_classes, action from rest_framework.response import Response +from django.template.loader import render_to_string +from django.utils.html import strip_tags from django.contrib.auth.models import User from rest_framework.authentication import TokenAuthentication from rest_framework.authtoken.models import Token @@ -94,15 +96,12 @@ def get_queryset(self): class EventRegistrationView(generics.GenericAPIView): serializer_class = AttendeeSerializer permission_classes = [permissions.AllowAny] - - def get(self, request,registration_link=None): + def get(self, request, registration_link=None): # Find the event by matching the registration code in the registration_link event = get_object_or_404(Event, registration_link=registration_link) - return Response({ - 'event': EventSerializer(event).data - }) + return Response({"event": EventSerializer(event).data}) def post(self, request, registration_link=None): @@ -116,16 +115,24 @@ def post(self, request, registration_link=None): if serializer.is_valid(): serializer.save() - # Send confirmation email - message = f"Thank you for registering for {event.title}, We look forward to seeing you at the event" + context = { + "event_title": event.title, + "event_date": event.date, + "event_time": event.time, + "event_location": event.location, + "attendee_email": attendee, + } + html_message = render_to_string("emails/event_registration.html", context) + plain_message = strip_tags(html_message) try: send_mail( subject=f"You have Successfully registered for {event.title}", - message=message, + message=plain_message, from_email=settings.DEFAULT_FROM_EMAIL, recipient_list=[attendee], fail_silently=False, + html_message=html_message, ) # # Create a reminder record @@ -145,6 +152,7 @@ def post(self, request, registration_link=None): return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + @api_view(["POST"]) def logout(request): try: @@ -162,7 +170,7 @@ def logout(request): def google(request): code = request.GET.get("code") if code is None: - return Response({"message": "No code provided"}, status=400) + return Response({"message": "No code provided"}, status=400) PARAMS = { "client_id": os.environ.get("google_id") or "", @@ -172,18 +180,22 @@ def google(request): "grant_type": "authorization_code", } headers = {"Content-Type": "application/x-www-form-urlencoded"} - token_response = requests.post("https://oauth2.googleapis.com/token", data=PARAMS, headers=headers) + token_response = requests.post( + "https://oauth2.googleapis.com/token", data=PARAMS, headers=headers + ) if token_response.status_code != 200: - print(token_response.json()) - return Response({"message": "Failed to get access token", "error": token_response.json()}, status=400) + return Response( + {"message": "Failed to get access token", "error": token_response.json()}, + status=400, + ) token_data = token_response.json() access_token = token_data.get("access_token") user_info_response = requests.get( "https://www.googleapis.com/oauth2/v2/userinfo", - headers={"Authorization": f"Bearer {access_token}"} + headers={"Authorization": f"Bearer {access_token}"}, ) if user_info_response.status_code != 200: @@ -195,21 +207,24 @@ def google(request): if existing_user: token, created = Token.objects.get_or_create(user=existing_user) user_data = UserSerializer(existing_user).data - return Response({ - 'user': user_data, - 'token': token.key - }, status=200) + return Response({"user": user_data, "token": token.key}, status=200) # Creating a new user - create_user = SocialAccountSeralizer(data={"email": user_info["email"], "username": user_info["given_name"],"phone_number":user_info["phone_number"]}) + create_user = SocialAccountSeralizer( + data={ + "email": user_info["email"], + "username": user_info["given_name"], + "phone_number": user_info["phone_number"], + } + ) if create_user.is_valid(): user_instance = create_user.save() token, created = Token.objects.get_or_create(user=user_instance) - - return Response({ - 'user': create_user.data, - 'token': token.key - }, status=200) - return Response({"message":"An error occured, Pleasee try again later"},status=status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response({"user": create_user.data, "token": token.key}, status=200) + + return Response( + {"message": "An error occured, Please try again later"}, + status=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) diff --git a/main/__init__.py b/main/__init__.py index 048d597..cd04264 100644 --- a/main/__init__.py +++ b/main/__init__.py @@ -1,3 +1,3 @@ from .celery import app as celery_app -' __all__'== [celery_app] \ No newline at end of file +__all__ = ['celery_app'] diff --git a/main/__pycache__/__init__.cpython-313.pyc b/main/__pycache__/__init__.cpython-313.pyc index 3bd0e2df3710fb075052612985adf129e60de5ac..6d40c966af1204050b3b1a6707a9a7ef68d88381 100644 GIT binary patch delta 141 zcmZo-`pd}snU|M~0SMmo@Mkzr1T*O~7BQzYYqGp# z1WIZ$-eOKHD7eLyoSKtbR2dIs`)RV=VuNstn1M=)Sb)SW_W1b3oSgXhiB&0zAUi;s bi}``X2WCb_#=8uv54goU^cvZVIDldRWO^Z3 delta 146 zcmey%*u=#9nU|M~0SMC1d{1|p$SWBl1LRC)2xbUo^k(p4EMih%2xf|5(r2{tU|>*S zNN3h$dC3S=qRDuRIkBLiibEkjJ~1aJKHg80`4(GpYEEiVWf3z_!7VNbCmyJ3VnvDy jCr}Keu~-O5d|+l|WW39u`hbC}Bda6kGJ|9hJ5U$^`|Tq{ diff --git a/main/settings.py b/main/settings.py index c3087e0..bc59d80 100644 --- a/main/settings.py +++ b/main/settings.py @@ -160,7 +160,7 @@ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = os.environ.get('EMAIL_HOST') EMAIL_PORT = 587 -DEFAULT_FROM_EMAIL= "Eventrio " +DEFAULT_FROM_EMAIL= "Eventrio" EMAIL_USE_TLS = True EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER') @@ -174,7 +174,7 @@ CELERY_RESULT_SERIALIZER = 'json' CELERY_TIMEZONE = 'UTC' -# Schedule for the reminder task to run daily + CELERY_BEAT_SCHEDULE = { 'send-event-reminders': { 'task': '.tasks.send_event_reminders', diff --git a/templates/event_registration.html b/templates/event_registration.html new file mode 100644 index 0000000..d598455 --- /dev/null +++ b/templates/event_registration.html @@ -0,0 +1,57 @@ + + + + + + +
+
+

Event Registration Confirmation

+
+
+

Dear Attendee,

+

Thank you for registering for {{ event_title }}.

+

Here are the event details:

+
    +
  • Date: {{ event_date }}
  • +
  • Time: {{ event_time }}
  • +
  • Location: {{ event_location }}
  • +
+

We look forward to seeing you at the event!

+
+ +
+ + \ No newline at end of file From d4460281f832b7c8a237c419e1f123c573a39589 Mon Sep 17 00:00:00 2001 From: Temake Date: Mon, 5 May 2025 13:28:57 +0100 Subject: [PATCH 7/7] fix: Template Processors --- event/serializers.py | 2 +- main/settings.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/event/serializers.py b/event/serializers.py index 6d8916e..0d70e92 100644 --- a/event/serializers.py +++ b/event/serializers.py @@ -56,7 +56,7 @@ def validate(self, data): return data def create(self, validated_data): - """Create a new user and associate a profile.""" + email = validated_data.get("email") username = validated_data.get("username") phone_number = validated_data.pop("phone_number", None) diff --git a/main/settings.py b/main/settings.py index bc59d80..13f0803 100644 --- a/main/settings.py +++ b/main/settings.py @@ -81,7 +81,7 @@ TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [