From 40677b57194a892204d7bc8da8e85d37df279672 Mon Sep 17 00:00:00 2001 From: Muhammad Faizan Fareed Date: Sun, 5 Jul 2020 13:08:21 +0500 Subject: [PATCH] release v1.0.0 --- .gitignore | 5 + LICENSE | 21 + covid19nearyou/__init__.py | 0 .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 153 bytes .../__pycache__/admin.cpython-36.pyc | Bin 0 -> 622 bytes .../__pycache__/apps.cpython-36.pyc | Bin 0 -> 1222 bytes .../context_processors.cpython-36.pyc | Bin 0 -> 367 bytes .../__pycache__/forms.cpython-36.pyc | Bin 0 -> 2494 bytes .../__pycache__/models.cpython-36.pyc | Bin 0 -> 10781 bytes .../__pycache__/receivers.cpython-36.pyc | Bin 0 -> 3963 bytes .../__pycache__/redis_keys.cpython-36.pyc | Bin 0 -> 401 bytes .../__pycache__/signals.cpython-36.pyc | Bin 0 -> 344 bytes .../__pycache__/urls.cpython-36.pyc | Bin 0 -> 796 bytes .../__pycache__/views.cpython-36.pyc | Bin 0 -> 13394 bytes covid19nearyou/admin.py | 17 + covid19nearyou/apps.py | 26 + covid19nearyou/context_processors.py | 10 + covid19nearyou/covid19_settings_variables.py | 72 ++ covid19nearyou/forms.py | 71 ++ covid19nearyou/migrations/0001_initial.py | 100 ++ covid19nearyou/migrations/__init__.py | 0 .../__pycache__/0001_initial.cpython-36.pyc | Bin 0 -> 2506 bytes .../__pycache__/__init__.cpython-36.pyc | Bin 0 -> 164 bytes covid19nearyou/models.py | 341 +++++++ covid19nearyou/receivers.py | 214 +++++ covid19nearyou/redis_keys.py | 12 + covid19nearyou/signals.py | 6 + .../pages/add_data_into_redis.html | 223 +++++ .../pages/add_delete_points.html | 95 ++ .../covid19nearyou/pages/dashboard.html | 118 +++ .../templates/covid19nearyou/pages/help.html | 82 ++ .../templates/covid19nearyou/pages/index.html | 177 ++++ .../covid19nearyou/pages/settings.html | 198 ++++ .../advices/advice_links_template.html | 32 + .../advices/all_advices_template.html | 25 + .../advices/green_zone_advices_template.html | 24 + .../advices/red_zone_advices_template.html | 24 + .../advices/who_advices_template.html | 72 ++ .../advices/yellow_zone_advices_template.html | 23 + .../advices/zero_zone_advices_template.html | 25 + .../templates/covid19_near_you_template.html | 22 + .../dashboard/data_missing_template.html | 10 + .../dashboard/data_updated_at_template.html | 9 + .../dashboard/geospatial_data_template.html | 19 + ...nearest_confirmed_case_point_template.html | 15 + .../nearest_quarantine_template.html | 24 + .../templates/points_in_radius_template.html | 112 +++ .../templates/points_template.html | 22 + .../country_and_who_web_links_template.html | 19 + covid19nearyou/tests.py | 3 + covid19nearyou/urls.py | 16 + covid19nearyou/views.py | 905 ++++++++++++++++++ requirements.txt | 12 + static/css/admin.css | 140 +++ static/css/map.css | 133 +++ static/js/base.js | 3 + static/js/map.js | 307 ++++++ templates/404.html | 13 + templates/500.html | 13 + templates/admin/base_site.html | 35 + templates/base.html | 137 +++ templates/error_base.html | 38 + templates/semanticui_jq_cdn.html | 6 + 63 files changed, 4026 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 covid19nearyou/__init__.py create mode 100644 covid19nearyou/__pycache__/__init__.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/admin.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/apps.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/context_processors.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/forms.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/models.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/receivers.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/redis_keys.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/signals.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/urls.cpython-36.pyc create mode 100644 covid19nearyou/__pycache__/views.cpython-36.pyc create mode 100644 covid19nearyou/admin.py create mode 100644 covid19nearyou/apps.py create mode 100644 covid19nearyou/context_processors.py create mode 100644 covid19nearyou/covid19_settings_variables.py create mode 100644 covid19nearyou/forms.py create mode 100644 covid19nearyou/migrations/0001_initial.py create mode 100644 covid19nearyou/migrations/__init__.py create mode 100644 covid19nearyou/migrations/__pycache__/0001_initial.cpython-36.pyc create mode 100644 covid19nearyou/migrations/__pycache__/__init__.cpython-36.pyc create mode 100644 covid19nearyou/models.py create mode 100644 covid19nearyou/receivers.py create mode 100644 covid19nearyou/redis_keys.py create mode 100644 covid19nearyou/signals.py create mode 100644 covid19nearyou/templates/covid19nearyou/pages/add_data_into_redis.html create mode 100644 covid19nearyou/templates/covid19nearyou/pages/add_delete_points.html create mode 100644 covid19nearyou/templates/covid19nearyou/pages/dashboard.html create mode 100644 covid19nearyou/templates/covid19nearyou/pages/help.html create mode 100644 covid19nearyou/templates/covid19nearyou/pages/index.html create mode 100644 covid19nearyou/templates/covid19nearyou/pages/settings.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/advice_links_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/all_advices_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/green_zone_advices_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/red_zone_advices_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/who_advices_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/yellow_zone_advices_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/advices/zero_zone_advices_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/covid19_near_you_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/dashboard/data_missing_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/dashboard/data_updated_at_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/dashboard/geospatial_data_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/locations/nearest_quarantine_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/points_in_radius_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/points_template.html create mode 100644 covid19nearyou/templates/covid19nearyou/templates/weblinks/country_and_who_web_links_template.html create mode 100644 covid19nearyou/tests.py create mode 100644 covid19nearyou/urls.py create mode 100644 covid19nearyou/views.py create mode 100644 requirements.txt create mode 100644 static/css/admin.css create mode 100644 static/css/map.css create mode 100644 static/js/base.js create mode 100644 static/js/map.js create mode 100644 templates/404.html create mode 100644 templates/500.html create mode 100644 templates/admin/base_site.html create mode 100644 templates/base.html create mode 100644 templates/error_base.html create mode 100644 templates/semanticui_jq_cdn.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fff4895 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.env +manage.py +env/ +covid19/ +media/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0243191 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2020] [Muhammad Faizan Fareed] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/covid19nearyou/__init__.py b/covid19nearyou/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/covid19nearyou/__pycache__/__init__.cpython-36.pyc b/covid19nearyou/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69784f0c471ffdca02d6164e8f80e10fecc2488b GIT binary patch literal 153 zcmXr!<>fkm^k*Cc5IhDEFu(|8H~?`m3y?@*2xib^^jpbL1QJFNzufe5Q&Tb%_0tkF zs}l3l5{pt(Q}hFh^0QKtOZ43{OFT-G6!eqx%Q908En#$CYGP4keyM(Zd}dx|NqoFs WLFFwDo80`A(wtN~komn&_s=>CoX2#4%p4olJ2ev#+y&$yZ8jX zdg2v4*=0kr=(g#!-#0(~GILU`mb>rt`HK?rO;Rgo-sk27zA=n2>XR8AQA(J_a=!IM zka{^Uj|D7#SaglHu#`gESWclGtfWvC?G&ovZj4y|k+cg-^CM|fT>v)YVri7ch#uXw z>m!?aAf~e8N)akPR+e$<;!HC11Dy|eh`OY3%7YM@a5Y2Lg8*-&3n7<6w=(IA z_%mG_MhZm81@=(HH5z}2B+MS54CbaB_-enD&>=?hH2c&{9HSxK^&Y3@HY?>P>9UASJFc_bOt=U xipGadp9}CESH5y~++E)SK`mtDK-{{{e4$IHW)hK)XYtGe+n5S1Gw&!au0WrI?YS%$)qz*hT%0Bep|+2^3N<8vma&(Vy?j00RQ&zKqCv_&p}ayQAwC3 zDYK;|?K{F8>A+QPzS|k!hI0QPP(shf(?xx@HCT9)g?B)gWw9!r4xDrwgrq%K8XDsl(LVV8oV8*lL(v+Fa4wRe&`QbHM?D^? zLDo7Av$N?{t@S=kMATZMdU!9yjbuWX_-BE|eL zk?I>ahIXMBwxh5LzZKC`aT%tQNX#~Jv;*0@NCB>@XF1e?qtP4G{oI!$kz9|>I5e`w z_LiQ(ILUN))ifXBB5q@RcT-&Bp0KU;kO68I#|*~Yxd~$Ky<2SQA?{R)ldVwmv$spz F&R=??8m|BV literal 0 HcmV?d00001 diff --git a/covid19nearyou/__pycache__/context_processors.cpython-36.pyc b/covid19nearyou/__pycache__/context_processors.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d59d3d915bf9eb1a6a68d6d88e216efb17c7d2d GIT binary patch literal 367 zcmYjNu};G<5Vf6F4bV!k!N!`U5n@6@2#EovsuEiVB9psRjv71I4p0OeKf`~(Pk4lh zUtr=K0pg_h&c1tRKl^Yp*&M#TUcEEMJ_vsyXmv_(yF|c%uUNwuoHG!RJhO#>!6nOv zpVVa;52-`%m0r4%#|lL}AmWVRwuwBeIq*H=C;rH3Sj<9N+*#SS2$`@^Ooake>5C#0 zVPx^9L+3-PwDVGz_`>XnRA2MFK~OTUq;OIAN zly+@8+G>yYzG$r}(K%z?v|WdtAO8il<6Yh*(f5Fei7~eulxJBIwxE`JX{IErddGdI XclD1_Qit@oG0?5>B>sqtuN#YR->O?y literal 0 HcmV?d00001 diff --git a/covid19nearyou/__pycache__/forms.cpython-36.pyc b/covid19nearyou/__pycache__/forms.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94f7dffc571394238c4f8597c258381d47c2ca7d GIT binary patch literal 2494 zcmcguTW=dh6yCdc*N)?aHl$4>%$=oR(-sgQ1ZkQ}BP9+BE`ohvwcQyf>#ld**)cR$ zc_F;!hwzu?0SWQczrYjcjJfT=*G4 zZ@|bI08xmVC~bvkL{HS7=4&d_Mxyr&-;lJKm_5rcN!m*6p5r^Jva661v42sBO|`Cj zru${!IK%~x3!DmY7JySG72s6HoGMxPTJfqcR5;jEh5GIbAdoUU8SCXhEPfLvF$sB` zrQ3{U3|N(8$~k?;gCrcD!rabb9;e57gqw?>1;hr7ybVAVUnPpKQN3#rmEhMTIx%9E znCB|7&UN3CveHCmUyzkX7xC?p`MxtUTU_4=PdVh;hfNBYTK~T&V zm@~fKaHU>YUe5-+o^|RhOpmE>VU~3y4OcRvj8M-JZk)$y&cigKq7o%EOeqNtV<)_+>QCe!Q*-}%6^E+ollEzN<(&< z4Vp6X8vRpIm6k)2jY7Nvit`G9qSdsjc1<?AAMWwZF#P+gCGriGzf$n1ig$55~M3Z@N^I+BZ;(5xI37C zJ26d&aN1CEdue~bSq;rwN4SMhN0^!{DYTo}01Ggrt+rNCYdCbfCMB2Jj}FT=a4GIC z+7I+UXg<*Ypfr7*=ul>cSl*>s-iIs;lbtxBm_PG1VWlY?CnI@t{ zpG66@zj@9Q1{&}g?9Q=XZKxOaJ`gR>xT0OM=c!74UT#e7!JS|2s|6<5O3PSHRzpfY2S`b)vyzJecM| zl=b=vg_wwSSb!ZL&6*>wU6qNYr-Lin#NuR8KZ{eIi`sO}m~(ToWO8(Inpm5zo)JQ2 zO>e`R;1>1)!X1RW2=@>^MED5dV}RM*SvrDVoL_W1yN#>gLy)yK1zBa7C7Uq*d)_o) z_m`+a=8ev9-trcOCDS$+7U{zCm5qAB%4pJvGDaJa(6o>7$VU&%>R347agsMUct6Jn zAxjzle<2&4C{GlmolzGxFtKD$5Y7QsikxFMOH=0ETG*eD8rK*2wC7a-Y%uVrRjlRP H%cZ{ntuJ(I literal 0 HcmV?d00001 diff --git a/covid19nearyou/__pycache__/models.cpython-36.pyc b/covid19nearyou/__pycache__/models.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9abc5bf6dfd97ba1d225eb236e394290eefe1d15 GIT binary patch literal 10781 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 literal 0 HcmV?d00001 diff --git a/covid19nearyou/__pycache__/receivers.cpython-36.pyc b/covid19nearyou/__pycache__/receivers.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..058485ae4f1a7ac1725472e43e99f32c180a14b5 GIT binary patch literal 3963 zcmeHKTXP&o6`t<7?Ceci+v|%Q$C%(itrH|n3M!!>630@ynweQ%JE{a(QYtH*5tV{6BSYY z%o?-ydDJhUUK4dwZ=%lRMX~Uli$&2ezDve;+4#V`pjy- zCN7IBcwZClp4D3V0=u+YT$lT4mIqn*MCz(33K`2>wwU(zqN5~?zhKmn>57sf%7PR5 zEZau4c_j0oaCOook)1qBlNMJ5qxO~T$moew=*Vu7x!a*>=;z@n;rS3x_BqUu3ASXZ zO7c6D_>wi^IWQWtkv+7#Y;293q0{BU$?dL_yF=df#>~7+V}_bPw#F{AOdl70%EA*R z_$y;;((0MkYEgr&VFY4|5%rl5y@mh0@Gjt+ZoW8l$Bd!~w94Ds>l}y4k<@;aWOxPTK2*iO`kZjrFa);KPki_VfkJxc6{%e{1!Au)ey#N?z?A#%Y-Aa-1edQ9ck@ zOC07!sXmVe0;F4OJ3rf6zx`hD!aNUmwzl{8f{l+KZtZT&XI-L^^0Xf*8H9NdCBYzx zPV)#WcaM9S%=LNdaU5pH!C|V3khlF}1eQ~p>_fYK6(xDg(_SVMA(i${o`&iuQ#IPS z4U(wyRPvO}fZ87|braQpZ?5#ft8nEoj6MyM!%#^nRvxOf3r4MMM)|$L!Htzp`Xmy! z-OMm;N9OYfEeg#fJ9df7Z<{r2OhMKo;m|C7O zwSqR(V54qVOcjqJvnf3)Hzuov**Zyhk6c?yhd{Z*9+Mrzj5U zGMOu6mdIQq^E#R9FfC8rpz=4#5Qo$oWQarRTV#kng?SStef7~GRAG|ia0P2J$)%#m z8x{I4+Or!lh`jA1*1ql8H|jR9zs`+ zrD#{Obf7vif7X}!JF7zMr+3k5TRvS)#D+PhJF!?R&cl@Ax|AN!dC8zsN`_Ex{sL?- z;dEtl_W6LOo}G_Ru)K^oZvmqwQ@2r?fj|JvK)8d-Dc!y z?sYw!1h75u3ocJo)hU442PQlct%{;J>4o|FXnAUdoHjH_y^WIkK2?2zO&X1|lk};s zOu&PHX@{<|mObCUE)mKA=w-sZ3v`41v;YAB2S7L|AP#_WFah~hAvwSjGGZhFRpIBE z$7)Rd2=y6U#2LB?4QKA7FoO$>S+WdQ?iv0#CyrXqiA$X7LuL*>BN;)NF(VlL^Q_(vJ^Ukr%^c!o25ZKHaalAv#!7klsnO>ZY>Zg$KOrLu^ zn4YBRJa10sdG(N;nW`}#SHCTlyVqS-M zNIw!Ox>eWkWdDIVvPL!@N3f9#z&QZ?%jutyO|YQ_hym_v$galry7h}cjJ%;Y_gzMS zPAv7Cp*Jd>^^g3aJ1h--VgKG9m2)t9Qg@y^qY5$YhCLU#d$9m=0vGyCD{U&fC+L2!X=2{J<&Ddi|21+kz|8C$z1a@s|* zqH=BHN^Uv2Zkz$~4Z>RcMKwuv74bfjLD9KfRA@*^yQYFyIzWEZX}}{Y?ULCevrpzMGt@`qJA3b`58(R~p0C3Qh>u|e&Czeii{!e< zt$gx(#q_!~nO`@ivrfOPD%7t&Q*eRV=gUy&gig- zz(j?O&Kmw3*j|9rfNJtB|HoL|AeQfw>X_`RforhFkX^w7FnT+UZ#3R+mYelv-Cy}H DTnElt literal 0 HcmV?d00001 diff --git a/covid19nearyou/__pycache__/redis_keys.cpython-36.pyc b/covid19nearyou/__pycache__/redis_keys.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..528aca5f89189e5413a37d01d74453f5d410d1a0 GIT binary patch literal 401 zcmXr!<>ivz@F7l$k%8ec0}=r8861GPSOQ3-Fhnt=Fh((^Fhwz?Fh?<`utc$>um&?| zvPJPa`-geD7+MDSd-{b0NAbHx1O&x9`nkkI1gdy)@{|mQw%L(bY5y=QDuIqei2Y- laeQ`aWwBmCe1XjVKl(Tz7@XxHHLZ$nD16jd1=4e~6X;XIm?~ z>jW#;JJiO3_ulZBk9Sm-yVtMlyAQ_LTf}c=u{)1&$B~dB@7RnJZsq>*eWly)Apq>#%6=!QbMRjf&M=qeuedTSmPD&5S%Hm=IU z7~42%Ca7EwUM@nuHA3;{OjVvXQ+T)^?Nl9k}oo zJO%HuS5AEdI5F!u1zY}hzn%GZza7t+?|1W`zrUQ+9p{(x-_xV{bNbTn1mJ)hJBd4W zT|2MEwWL0+C*IT}UI#C3B+Y5lb+8T%Y%W{Sgx0q@u{N?E=LpQa1ul zp9H|u#kJxZLesgM7pEK`$W$;BF$NOX0hbWqW+gNRDhAqqr;b%ro{)y-WCFlGDRw~; zc7drEw;aYqnMS)p%$I zu;g;Cj;S=67T3B)RX4qAG1qabsj(dGS!h{k+Jr{=FLc)~*hbTR3%-Scg&~3Ik(_Rn zp_b_nM<3dNg+DLC1VQj{#zn#9jB7*)KWMeYC<`w|_By|Q99CxcqxDRdLu=`HwKeUh XiGn=FXSPk!5kcQQaQoiC{rCO_0(|ac literal 0 HcmV?d00001 diff --git a/covid19nearyou/__pycache__/views.cpython-36.pyc b/covid19nearyou/__pycache__/views.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7adad306398e0f28d563a3fb1dbadb221ee3c8c6 GIT binary patch literal 13394 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 settings.REGION_BOUNDRY_MAX_LATITUDE : + raise forms.ValidationError( + _(' Latitude out of range'),code='outofrange' + + ) + + + + return Latitude + + def clean_longitude(self): + + if isinstance(self.cleaned_data['longitude'],(float)): + + Longitude = float(self.cleaned_data['longitude']) + + + + if Longitude < settings.REGION_BOUNDRY_MIN_LONGITUDE or Longitude >= settings.REGION_BOUNDRY_MAX_LONGITUDE : + raise forms.ValidationError( + _('Longitude out of range'),code='outofrange', + + ) + + + + return Longitude + +class GeospatialFileForm(forms.ModelForm): + + class Meta: + model = GeospatialFile + exclude = ('created_at','is_finshed','finshed_at',) + + +class LocationBatchManagerForm(forms.ModelForm): + + + class Meta: + model = RedisBatchManager + exclude = ( 'created_at','is_finshed','is_quarantine_batches_completed','is_location_batches_completed','location_batches','qurantine_batches','location_points','qurantine_points','location_completed_batches','qurantine_completed_batches',) + + + diff --git a/covid19nearyou/migrations/0001_initial.py b/covid19nearyou/migrations/0001_initial.py new file mode 100644 index 0000000..073934b --- /dev/null +++ b/covid19nearyou/migrations/0001_initial.py @@ -0,0 +1,100 @@ +# Generated by Django 3.0.7 on 2020-06-29 10:58 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ConfirmedCaseLocation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150, unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('expire_at', models.DateTimeField()), + ('is_visible', models.BooleanField(default=True)), + ('latitude', models.DecimalField(decimal_places=6, max_digits=8)), + ('longitude', models.DecimalField(decimal_places=6, max_digits=8)), + ], + ), + migrations.CreateModel( + name='GeospatialFile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('is_finshed', models.BooleanField(default=False)), + ('finshed_at', models.DateTimeField(null=True)), + ], + ), + migrations.CreateModel( + name='QurantineCenter', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=150, unique=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('is_visible', models.BooleanField(default=True)), + ('latitude', models.DecimalField(decimal_places=6, max_digits=8)), + ('longitude', models.DecimalField(decimal_places=6, max_digits=8)), + ], + ), + migrations.CreateModel( + name='RedisBatchManager', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('is_finshed', models.BooleanField(default=False)), + ('is_quarantine_batches_completed', models.BooleanField(default=False)), + ('is_location_batches_completed', models.BooleanField(default=False)), + ('location_points', models.PositiveIntegerField(blank=True, default=0)), + ('qurantine_points', models.PositiveIntegerField(blank=True, default=0)), + ('location_batches', models.PositiveIntegerField(blank=True, default=0)), + ('qurantine_batches', models.PositiveIntegerField(blank=True, default=0)), + ('location_completed_batches', models.PositiveIntegerField(blank=True, default=0)), + ('qurantine_completed_batches', models.PositiveIntegerField(blank=True, default=0)), + ], + ), + migrations.CreateModel( + name='QuarantineCenterBatch', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('is_completed', models.BooleanField(default=False)), + ('batch_no', models.PositiveIntegerField()), + ('range_start', models.PositiveIntegerField()), + ('range_end', models.PositiveIntegerField()), + ('batch_manager', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='covid19nearyou.RedisBatchManager')), + ], + ), + migrations.CreateModel( + name='ConfirmedCaseLocationBatch', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('is_completed', models.BooleanField(default=False)), + ('batch_no', models.PositiveIntegerField()), + ('range_start', models.PositiveIntegerField()), + ('range_end', models.PositiveIntegerField()), + ('batch_manager', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='covid19nearyou.RedisBatchManager')), + ], + ), + migrations.CreateModel( + name='AddToFileNewAndExpireOldCovid19Location', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_file_created', models.BooleanField(default=False)), + ('is_points_removed', models.BooleanField(default=False)), + ('is_finshed', models.BooleanField(default=False)), + ('url', models.URLField(null=True)), + ('geospatialfile', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='covid19nearyou.GeospatialFile')), + ], + ), + ] diff --git a/covid19nearyou/migrations/__init__.py b/covid19nearyou/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/covid19nearyou/migrations/__pycache__/0001_initial.cpython-36.pyc b/covid19nearyou/migrations/__pycache__/0001_initial.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73ccddbdd3faa4b049f0cf7927bb3fbe90cd75fa GIT binary patch literal 2506 zcmcguNpssa6ecNJ3nkfdV!KV!EL~G|k({Q>bf(j(Bgamr+2dSvC9!{9^V@p-t31~trcE!9B}$Bb^0E4`=!X~`>-%BQ;(LQGOkh=FP|>Z@_|3{ zXa#9CYN)jX4{?AvKvX|)5jAqu%+R7iuN@{^$h$_yqoB9!K@U@2mg8?@w`e9lOKUwQY1|_5Q3_eO|1-z||rw zja%c&czJw=en~qfg6Jqy-T&R<`l%MLp{GYteKm*XyX`vi&d$1xevN45ScKo?5tdC( zqe_33ev32uovz)T4d;$t?MX3WY67%JVz?uR+0bf_(Jk%W-fa82LDEEqLj@!Os_Rq5 zCPcjqpTbLBi$O8M**@sT9;ktgArxc++BeU`Uvb8>cL8}3au89ntIMfi&r;Aqt}i4> z+s#b~`8*_)>L8s`W6ScYnR(>t8oZb?1xVHbi^Dw@vjGR(UZF4|DNl5jqxVTl;joOR z53APxB84IP%)==sLx}O+g#J(#u_V?tE(I=dOWRWol-K1E15RVTxD7I%qCUd67)OuM zrD|69*yeuP#?w~Af4LA`t=Gb5cZ zgbHtF4(JO<;%_on9~J@Gz_W;T10yMfbu}{+3aRTDd<0>f5S8ef1t6$yT8W9x)c%#B z+++0G_X4ojWZHQnm)KV|DMCD0Fmc*Tq&|OYCtGi>Zcw@-O&#yS^9@07W}S4O)1EbR zXV&*iS(P~y{l1I@o5xVWMDAgcN~z*{F)G?)glhLMo^W`+d+xQ@bT!OoBMfyAhIk~V zXeHE*&~yYh^Ma_t1T!6{8x*FP77#-QvGPn|>%D9Q@0!C@;i2j1+6GSMmT6aA>+KR{ zm(5Kao*gy;3mZ42?~b~U-e!-#pLFp}!$@~T*gg>> zq5x?3fs$hwCf#k8+)4*mx_K&R|9KB|k3K27>+9>+!aP@<=}Tq4St@wPuklg!e9!lN z*Yj4~mb-{ofOpGXD_NSMtmJFUKgl%`t>QYqFF;*^d+C^_Hz{U!=25$>Yc_u!I>?G> p>vpancI>B7XO>xY%Vf$#bCff?dVn-t{lWIlkEZ;w5o@{C(mxV};7kAj literal 0 HcmV?d00001 diff --git a/covid19nearyou/migrations/__pycache__/__init__.cpython-36.pyc b/covid19nearyou/migrations/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..016338ce006db60071b16f4f15a3d136a25734c7 GIT binary patch literal 164 zcmXr!<>fkm^k*Cc5IhDEFu(|8H~?`m3y?@*2xib^^jpbL1QJFNzXJ7hQ&Tb%_0tkF zs}l3l5{pt(Q}hFh^0QKtOZ43{OFT-G6!eqx%Q908En#$CYGP4keyM(LW_nR#NoIat hv3`7fW?p7Ve7s&k self.expire_at : + + return True + else: + return False + + + +class ConfirmedCaseLocationAdmin(admin.ModelAdmin): + + list_display = ('name', 'latitude','longitude' ,'is_visible', 'created_at', 'expire_at','updated_at',) + list_filter = ('is_visible',) + exclude =('expire_at',) + + search_fields = ('name',) + + + def delete_queryset(self, request, queryset): + + con = get_redis_connection("default") + pipeline = con.pipeline() + + for instance in queryset: + + pipeline.execute_command('DEL',instance.get_redis_key()) + pipeline.execute_command('ZREM',REDIS_KEYS.GEOSPATIAL_DATA_KEY,instance.get_redis_key()) + pipeline.execute_command('ZREM',REDIS_KEYS.COVID19_GEOSPATIAL_POINTS_EXPIRE_DATA_KEY,instance.get_redis_key()) + + result = pipeline.execute() + + + TotalDeletedObjects = queryset.delete() + + def message_user(self, *args): + pass + + def has_change_permission(self, request, obj=None): + return False + + def save_model(self, request, obj, form, change): + + + if not change and form.has_changed(): + + currentdate = datetime.date.today() + obj.expire_at = currentdate + timedelta(days=settings.COVID19_INCUBATION_PERIOD_FOR_EXPIRE_POINT) + + super(ConfirmedCaseLocationAdmin, self).save_model(request, obj, form, change) + signals.location_done.send(self.__class__,instance=obj,change=change,changedfeilds=form.changed_data) + + elif change and form.has_changed(): + + + messages.add_message(request, messages.error, 'Location does not exist anymore.') + return + + elif change and not form.has_changed() : + + messages.add_message(request, messages.info, 'Post not created or not updated only saved') + + + + + + + diff --git a/covid19nearyou/receivers.py b/covid19nearyou/receivers.py new file mode 100644 index 0000000..91dec02 --- /dev/null +++ b/covid19nearyou/receivers.py @@ -0,0 +1,214 @@ +from django.db.models.signals import post_save , post_delete +from django.dispatch import Signal +from . import redis_keys as REDIS_KEYS +import time +import datetime +from django_redis import get_redis_connection +from django.dispatch import Signal, receiver +from . models import * +from . signals import * +from django.db.models import F + + + +@receiver(location_done) +def Confirmed_Case_Location_Reciever(sender,**kwargs): + if kwargs['change']: # updated + pass + + else: + + # created + instance = kwargs['instance'] + + + con = get_redis_connection("default") + pipeline = con.pipeline() + + + + #GEOSPATIAL INSERTION + pipeline.execute_command('GEOADD',REDIS_KEYS.GEOSPATIAL_DATA_KEY,float(instance.longitude),float(instance.latitude),instance.get_redis_key()) + #EXPIRE AND DATA INSERTION + pipeline.execute_command('zadd',REDIS_KEYS.COVID19_GEOSPATIAL_POINTS_EXPIRE_DATA_KEY,'nx','ch',instance.get_expire_at_in_unixtime() ,instance.get_redis_key()) + + #COVID19 GEOSPATIAL HASH + pipeline.hmset(instance.get_redis_key(),instance.get_hash_for_redis()) + + #COVID19 GEOSPATIAL HASH SETTING EXPIRE DATE + pipeline.expireat(name=instance.get_redis_key(),when=instance.get_expire_at_in_unixtime()) + + result = pipeline.execute() + print(result) + + +@receiver(quarantine_done) +def Quarantine_Center_Receiver(sender,**kwargs): + if kwargs['change']: + # updated + + instance = kwargs['instance'] + + con = get_redis_connection("default") + pipeline = con.pipeline() + + + if instance.is_visible: + + #GEOSPATIAL INSERTION + pipeline.execute_command('GEOADD',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY,float(instance.longitude),float(instance.latitude),instance.get_redis_key()) + + #COVID19 GEOSPATIAL HASH + pipeline.hmset(instance.get_redis_key(),instance.get_hash_for_redis()) + + else: + pipeline.execute_command('ZREM', REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY,instance.get_redis_key()) + + pipeline.execute_command('DEL',instance.get_redis_key()) + + result = pipeline.execute() + + else: + + # created + instance = kwargs['instance'] + + + con = get_redis_connection("default") + pipeline = con.pipeline() + + #GEOSPATIAL INSERTION + pipeline.execute_command('GEOADD',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY,float(instance.longitude),float(instance.latitude),instance.get_redis_key()) + + #COVID19 GEOSPATIAL HASH + pipeline.hmset(instance.get_redis_key(),instance.get_hash_for_redis()) + + result = pipeline.execute() + + +@receiver(post_save, sender=GeospatialFile) +def Geospatial_File_Reciever(**kwargs): + + instance = kwargs['instance'] + + if instance.is_finshed == False and instance.sourcetype == 1: + AddToFileNewAndExpireOldCovid19Location.objects.create(geospatialfile=instance) + + +@receiver(post_save, sender=AddToFileNewAndExpireOldCovid19Location) +def Add_To_File_New_And_Expire_Old_Covid19_Location_Reciever(**kwargs): + + instance = kwargs['instance'] + + if instance.is_finshed == True: + + fileobj = GeospatialFile.objects.get(id=instance.geospatialfile.id) + fileobj.is_finshed = True + fileobj.finshed_at = datetime.datetime.now() + fileobj.save() + + +@receiver(post_save, sender=RedisBatchManager) +def Redis_Batch_Manager_Reciever(**kwargs): + + instance = kwargs['instance'] + + if kwargs['created'] == True: + + if instance.location_batches > 0: + Create_Confirmed_Case_Batch_Ranges(instance.location_points,instance.location_batches,instance) + if instance.qurantine_batches > 0: + Create_Quarantine_Center_Batch_Ranges(instance.qurantine_points,instance.qurantine_batches,instance) + + +def Create_Confirmed_Case_Batch_Ranges(totalpoints,step,instance): + + + BtachObjectsList = [] + listofBtach = [] + index = 0 + + if totalpoints > 1: + for i in range(0,totalpoints,round(totalpoints/step)): + + if i+(round((totalpoints/step)) ) < totalpoints: + + start = i + end = i+round((totalpoints/step)) + batch = { + 'batch':index, + 'start':start, + 'end':end + } + btachObject = ConfirmedCaseLocationBatch(batch_manager=instance,batch_no=index,range_start=start,range_end=end) + BtachObjectsList.append(btachObject) + + listofBtach.append(batch) + else: + + start = i + end = totalpoints + batch = { + 'batch':index, + 'start':start, + 'end':end + } + listofBtach.append(batch) + btachObject = ConfirmedCaseLocationBatch(batch_manager=instance,batch_no=index,range_start=start,range_end=end) + BtachObjectsList.append(btachObject) + index = index + 1 + + + ConfirmedCaseLocationBatch.objects.bulk_create(BtachObjectsList,step) + elif totalpoints == 1: + + ConfirmedCaseLocationBatch.objects.create(batch_manager=instance,batch_no=1,range_start=0,range_end=1) + + + return None + + +def Create_Quarantine_Center_Batch_Ranges(totalpoints,step,instance): + + + BtachObjectsList = [] + listofBtach = [] + index = 0 + + if totalpoints > 1: + for i in range(0,totalpoints,round(totalpoints/step)): + + if i+(round((totalpoints/step)) ) < totalpoints: + + start = i + end = i+round((totalpoints/step)) + batch = { + 'batch':index, + 'start':start, + 'end':end + } + btachObject = QuarantineCenterBatch(batch_manager=instance,batch_no=index,range_start=start,range_end=end) + BtachObjectsList.append(btachObject) + + listofBtach.append(batch) + else: + + start = i + end = totalpoints + batch = { + 'batch':index, + 'start':start, + 'end':end + } + listofBtach.append(batch) + btachObject = QuarantineCenterBatch(batch_manager=instance,batch_no=index,range_start=start,range_end=end) + BtachObjectsList.append(btachObject) + index = index + 1 + QuarantineCenterBatch.objects.bulk_create(BtachObjectsList,step) + elif totalpoints == 1: + + QuarantineCenterBatch.objects.create(batch_manager=instance,batch_no=1,range_start=0,range_end=1) + + + return None + diff --git a/covid19nearyou/redis_keys.py b/covid19nearyou/redis_keys.py new file mode 100644 index 0000000..49a7fcc --- /dev/null +++ b/covid19nearyou/redis_keys.py @@ -0,0 +1,12 @@ + + +#GEOSPATIAL DATA +GEOSPATIAL_DATA_KEY = 'COVID19POINTS' +#COIVD19 GEOSPATIAL EXPIRESET +COVID19_GEOSPATIAL_POINTS_EXPIRE_DATA_KEY = 'EXPR_AND_POINTS' + + + +LOCATION_OBJECT_KEY = 'location-id:' +GEOSPATIAL_QUARANTINE_DATA_KEY = 'COVID19QUARANTINE' +QUARANTINE_OBJECT_KEY = 'quarantine-id:' \ No newline at end of file diff --git a/covid19nearyou/signals.py b/covid19nearyou/signals.py new file mode 100644 index 0000000..1a9fe13 --- /dev/null +++ b/covid19nearyou/signals.py @@ -0,0 +1,6 @@ +#Custom signals +import django.dispatch + +location_done = django.dispatch.Signal(providing_args=['sender','instance','change','changedfeilds']) + +quarantine_done = django.dispatch.Signal(providing_args=['sender','instance','change','changedfeilds']) \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/pages/add_data_into_redis.html b/covid19nearyou/templates/covid19nearyou/pages/add_data_into_redis.html new file mode 100644 index 0000000..36b7824 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/pages/add_data_into_redis.html @@ -0,0 +1,223 @@ +{% extends 'base.html' %} + +{%block title%} +Add data into Redis +{%endblock %} + +{%block pageName%} +Adding data into Redis Database + {%endblock %} + +{%block content%} + +
+ {%if message%} + +

{{message}}

+ + {%endif%} + + {%if form%} + +
+ +
+ {{location_points}} +
+ + Location Points + +
+ +
+
+ {{location_batches}} +
+ Location Batches +
+ + +
+
+ {{qurantine_points}} +
+ + Quarantine Points + +
+ +
+ +
+ {{qurantine_batches}} +
+ + Quarantine Batches + +
+ +
+ {{form.as_p}} + {% csrf_token %} + + + + + + + + +
+
+

1 batch consist of {{LOCATION_CACHE_BATCH_SIZE}} records.

+ + {%endif%} + + {%if Batch_Manager_Object %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IdCreated atStatusLocation Batch statusQuarantine Batch statusLocation PointsQuarantine Points Location BatchesQuarantine Batches Compeleted Location Batches Compeleted Quarantine Batches
{{Batch_Manager_Object.id}}{{Batch_Manager_Object.created_at}}{{Batch_Manager_Object.is_finshed}}{{Batch_Manager_Object.is_location_batches_completed}}{{Batch_Manager_Object.is_quarantine_batches_completed}}{{Batch_Manager_Object.location_points}}{{Batch_Manager_Object.qurantine_points}}{{Batch_Manager_Object.location_batches}}{{Batch_Manager_Object.qurantine_batches}}{{Batch_Manager_Object.location_completed_batches}}{{Batch_Manager_Object.qurantine_completed_batches}}
+ + + {% if Location_Batches%} + + + + + + + + + + + + + {%for batch in Location_Batches%} + + {%if batch.id == Location_batch_not_completed_Id%} + + + {% csrf_token %} + + + + + + + + + + + + + + + + {%else%} + + + + + + + + + + + {%endif%} + + {%endfor%} + +
IdBatch no CompeletedStart rangeEnd rangeProcess
{{batch.id}} {{batch.batch_no}} {{batch.is_completed}} {{batch.range_start}} {{batch.range_end}}
{{batch.id}} {{batch.batch_no}} {{batch.is_completed}} {{batch.range_start}} {{batch.range_end}}
+ + {%endif%} + + + {% if Quarantine_Batches%} + + + + + + + + + + + + + + {%for batch in Quarantine_Batches%} + + {%if batch.id == Quarantine_batch_not_completed_Id%} + + + {% csrf_token %} + + + + + + + + + + + + + + + {%else%} + + + + + + + + + + {%endif%} + + {%endfor%} + +
IdBatch no CompeletedStart rangeEnd rangeProcess
{{batch.id}} {{batch.batch_no}} {{batch.is_completed}} {{batch.range_start}} {{batch.range_end}}
{{batch.id}} {{batch.batch_no}} {{batch.is_completed}} {{batch.range_start}} {{batch.range_end}}
+ + {%endif%} + {%endif%} + {%endblock %} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/pages/add_delete_points.html b/covid19nearyou/templates/covid19nearyou/pages/add_delete_points.html new file mode 100644 index 0000000..09d3174 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/pages/add_delete_points.html @@ -0,0 +1,95 @@ +{% extends 'base.html' %} + +{%block title%} +Add new points +{%endblock %} + +{%block pageName%} +Add new and remove expired points from Geospatial file. +{%endblock %} + +{%block content%} + +
+
+ + {%if form%} + +
+ {% csrf_token %} +

Create new Geospatial file

+ {{form.as_p}} + + +
+
+

+ Geospatial file consisit of Location and Quarantine points to plot data onto Map. +

+

Redis database is used to check COVID-19 NEAR YOU. +

+ {%endif%} + + + {% if no_of_locations%} + +

Thier is no record into your database.

+

Add locations from Admin pannel or Upload location file.

+ {%endif%} + + + {% if geospatialfile %} +
+ + + {%if is_step1 %} +
+
+
Add new points
+
Add them in Geospatial file
+
+
+ +
+
+
Delete expired points
+
Delete them from Geospatial file.
+
+
+
+ +
+ {% csrf_token %} +

Delete expired points

+ + + +
+ + {%else%} + +
+
+
Add new points
+
Add them in Geospatial file
+
+
+ +
+
+
Delete expired points
+
Delete them from Geospatial file.
+
+
+
+ +
+ {% csrf_token %} + + +
+ {%endif%} + {%endif%} + +
+{%endblock %} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/pages/dashboard.html b/covid19nearyou/templates/covid19nearyou/pages/dashboard.html new file mode 100644 index 0000000..1674e4a --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/pages/dashboard.html @@ -0,0 +1,118 @@ +{% extends 'base.html' %} + +{%block title%} +Dashboard +{%endblock %} + + +{%block pageName%} +Dashboard +{%endblock %} + +{%block content%} + + + +{% if is_cache_exist %} + + +{%if geospatialfile %} + + {% include 'covid19nearyou/templates/dashboard/data_updated_at_template.html' %} + {% include 'covid19nearyou/templates/dashboard/geospatial_data_template.html' %} + + + {% if Is_need_to_update_points_into_file and is_need_to_add_data_into_cache or is_need_to_add_data_into_cache%} + + {% include 'covid19nearyou/templates/dashboard/data_missing_template.html' %} + + {%else%} + {% if Is_need_to_update_points_into_file %} + + +

Add points into Geospatial File

+


+

Data points in Geospatial file and Redis database need to be updated.

+

+ Click here to Add new (or updated ) and + delete + expired points from Redis and Geospatial File. +

+ +

Geospatial file consisit of Location and Quarantine points to plot data onto Map.

+

Redis database is used to check COVID-19 NEAR YOU.

+
+

+ OR +

+ +

If needed add more points .

+
+

+

You can add more COVID-19 cases and Quarantine center location points.

+ +

Click here to add + COVID-19 Location + points. +

+ + {%endif%} + + {%endif%} + +{%else%} + + + +

Add points into Geospatial file.

+
+

+Add points into Geospatial file. +

+ OR +

+ +

If needed add more points .

+
+

+

You can add more COVID-19 cases and Quarantine center location points.

+ +

Click here to add + COVID-19 Location + points. + +

+ +{%endif%} + + +{%else%} + + +{%if geospatialfile %} + +{% include 'covid19nearyou/templates/dashboard/data_updated_at_template.html' %} +{% include 'covid19nearyou/templates/dashboard/geospatial_data_template.html' %} + +{%endif%} + +{%if is_cache_miss %} +{% include 'covid19nearyou/templates/dashboard/data_missing_template.html' %} + +{%else%} + + +

Add points

+ +
+

+

Add COVID-19 cases and Quarantine center location points.

+ +

Click here to add + COVID-19 Location + points. + +

+{%endif%} +{%endif%} +{%endblock %} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/pages/help.html b/covid19nearyou/templates/covid19nearyou/pages/help.html new file mode 100644 index 0000000..ed8c6b2 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/pages/help.html @@ -0,0 +1,82 @@ +{% extends 'base.html' %} + +{%block title%} +How to use +{%endblock %} + +{%block pageName%} +How to use ? +{%endblock %} + +{%block content%} + +You can follow these steps to use COVID-19 NEAR YOU app. +

+ If you have any suggestions, found bugs, facing issues or start new discussion open issue on github. + Fork us on Github + . +

+

Add points (Confirmed case or Qurantine )

+

+ Goto Admin + Pannel select + ConfirmedCaseLocation or QurantineCenter model to save points.

+
    +
  • You can add data points,
  • +
  • Delete data points.
  • +
  • Can't update ConfirmedCaseLocation points. First you need to delete them then add them.
  • +
+

+ +

Create Geospatial file and delete expired points

+When new points added, then goto Dashboard and follow given instructions. +

+ + + +

+

If data missing in Redis database

+

+ When data is missing in Redis database then we need to add data into Redis database. +

+ +
    +
  • This link Add data into + Redis database will redirect to Redis database page. +
      +
        +
      • Click on Create batches button to create batches of points.
      • + +
          + +
        + +
      +

      + {%endblock %} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/pages/index.html b/covid19nearyou/templates/covid19nearyou/pages/index.html new file mode 100644 index 0000000..91d5e44 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/pages/index.html @@ -0,0 +1,177 @@ +{% load static %} + + + + {% include 'semanticui_jq_cdn.html' %} + + + + + COVID-19 NEAR YOU + + + + + + +

      + + + + + +
      + +
      +
      +
      +
      +
      + +
      +
      +
      + + Last updated at : + {{data_updated_at}} + + +
      +
      + +
      +
      +

      + We all need to work together now to protect the most vulnerable healthcare workers, people over 60 years age + and those with underlying health conditions (e.g. heart or lung dusease , diabetes, or immunocompromised) +

      +
      +
      + +
      +
      + {% include 'covid19nearyou/templates/covid19_near_you_template.html' %} +
      +
      +
      + + + + + + + \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/pages/settings.html b/covid19nearyou/templates/covid19nearyou/pages/settings.html new file mode 100644 index 0000000..d60ae2f --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/pages/settings.html @@ -0,0 +1,198 @@ +{% extends 'base.html' %} + +{%block title%} +Settings +{%endblock %} + +{%block pageName%} +Configurations +{%endblock %} + +{%block content%} + +

      Change these according to your requirements . Goto covid19/settings.py

      +

      Default settings like country name ,boundry, web link and map center points configured for Pakistan.

      + +

      COUNTRY

      +
      +
      +
      + {{COUNTRY_NAME}} +
      +
      +
      + +
      +
      + +
      +

      RADIUS RANGES

      +
      +
      +
      + {{FIRST_RANGE_CIRCLE}} {{RANGE_IN_UNITS}} +
      +
      + First Radius Range +
      +
      + +
      +
      + {{SECOND_RANGE_CIRCLE}} {{RANGE_IN_UNITS}} +
      +
      + Second Radius Range +
      +
      + +
      +
      + {{THIRD_RANGE_CIRCLE}} {{RANGE_IN_UNITS}} +
      +
      + Third Radius Range +
      +
      + +
      +
      +
      + +
      +

      QUARANTINE RADIUS RANGE

      + +
      +
      +
      + {{QUARANTINE_RADIUS_RANGE}} +
      +
      + {{QUARANTINE_RADIUS_RANGE_UNIT}} radius range +
      +
      +
      + +

      + +
      +

      MAP CENTER POINT

      +
      +
      +
      + {{MAP_CENTER_POINT_LATITUDE}} +
      +
      + Latitude +
      +
      + +
      +
      + {{MAP_CENTER_POINT_MAGNITUDE}} +
      +
      + Longitude +
      +
      +
      + +

      + +
      +

      + {{COUNTRY_NAME}} BOUNDRY

      +
      +
      +
      + {{REGION_BOUNDRY_MIN_LATITUDE}} +
      +
      + Min Latitude +
      +
      + +
      +
      + {{REGION_BOUNDRY_MAX_LATITUDE}} +
      +
      + Max Latitude +
      +
      +
      +
      + {{REGION_BOUNDRY_MIN_LONGITUDE}} +
      +
      + Min longitude +
      +
      +
      +
      + {{REGION_BOUNDRY_MAX_LONGITUDE}} +
      +
      + Max longitude +
      +
      +
      + + +

      + +
      +

      +
      INCUBATION       BATCH SIZE    FILE UPDATE TIME 
      +

      +
      +
      +
      + {{COVID19_INCUBATION_PERIOD_FOR_EXPIRE_POINT}} days +
      +
      + Region Incubation Peroid +
      +
      +
      +
      + {{LOCATION_CACHE_BATCH_SIZE}} records +
      +
      + Batch size for Redis +
      +
      + +
      +
      + {{COVID19_UPDATE_DATA_TIME}} Hours +
      +
      + FILE UPDATE TIME +
      +
      + +
      + +
      +
      +
      +

      WEB LINKS

      + + +

      + +{%endblock %} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/advice_links_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/advice_links_template.html new file mode 100644 index 0000000..1a0ccf8 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/advice_links_template.html @@ -0,0 +1,32 @@ +
      +
        +
      1. +

        + Myth + busters +

        +
      2. + +
      3. +

        + When and how to + use masks +

        +
      4. +
      5. +

        + Advice for + public +

        +
      6. + +
      7. +

        + Advocacy +

        +
      8. +
      +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/all_advices_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/all_advices_template.html new file mode 100644 index 0000000..eb5c819 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/all_advices_template.html @@ -0,0 +1,25 @@ +{% if nearest_covid19_point %} + +{% if nearest_covid19_point.red == 0 %} + + {% include 'covid19nearyou/templates/advices/red_zone_advices_template.html' %} + +{% elif nearest_covid19_point.yellow == 1 %} + + {% include 'covid19nearyou/templates/advices/yellow_zone_advices_template.html' %} + +{% elif nearest_covid19_point.green == 2 %} + + {% include 'covid19nearyou/templates/advices/green_zone_advices_template.html' %} + +{%elif nearest_covid19_point.no_points == 3%} + + + {% include 'covid19nearyou/templates/advices/zero_zone_advices_template.html' %} +{%endif%} + +{%endif%} + +{% include 'covid19nearyou/templates/advices/who_advices_template.html' %} +{% include 'covid19nearyou/templates/advices/advice_links_template.html' %} +{% include 'covid19nearyou/templates/weblinks/country_and_who_web_links_template.html' %} diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/green_zone_advices_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/green_zone_advices_template.html new file mode 100644 index 0000000..818e0ea --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/green_zone_advices_template.html @@ -0,0 +1,24 @@ +
      + +

      + + You are in Green zone +

      + +
        +
      1. +

        Stay home stay safe

        +
      2. +
      3. +

        No need to worry about COVID-19, always take appropriate precautions

        +
      4. + +
      5. +

        Green zone means nearest point is within {{nearest_covid19_point.radius_range_in_km}} {{RANGE_IN_UNITS}} radius. Their is a possibility COVID-19 carriers maybe around your region. +

      6. + +
      7. +

        Wear mask,clean your hands often, avoid crowded and infected places, don't invite relatives during pandemic, don't touch your eyes ,nose or mouth.

        +
      8. +
      +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/red_zone_advices_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/red_zone_advices_template.html new file mode 100644 index 0000000..8205966 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/red_zone_advices_template.html @@ -0,0 +1,24 @@ +
      +

      + + You are in Red zone +

      +
        + +
      1. +

        Stay home stay safe

        +
      2. + +
      3. +

        No need to worry about COVID-19, always take appropriate precautions

        +
      4. + +
      5. +

        Red zone means nearest point is within {{nearest_covid19_point.radius_range_in_km}} {{RANGE_IN_UNITS}} radius. Their is a possibility COVID-19 carriers maybe in your region.

        +
      6. + +
      7. +

        Wear mask,clean your hands often, avoid crowded and infected places, don't invite relatives during pandemic, don't touch your eyes ,nose or mouth.

        +
      8. +
      +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/who_advices_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/who_advices_template.html new file mode 100644 index 0000000..ac9910f --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/who_advices_template.html @@ -0,0 +1,72 @@ +
      + +
        + +
      1. +

        + COVID-19 may be spread by people who are not showing symptoms. + +

        +
      2. + + +
      3. +

        + If you have a fever, cough , difficulty breathing, aches and pains, nasal congestion and runny nose, seek + medical attention. + Call in advance. +

        +
      4. + + +
      5. +

        + Maintain at least 1 metre distance between yourself and others. +

        +
      6. + + +
      7. +

        + If someones not wearing mask avoid them.* +

        +
      8. + +
      9. +

        + Always make sure someone not coming from infected region to meet you.* +

        +
      10. + +
      11. +

        + + Protect yourself and your loved ones from COVID-19 . +

        +
      12. + +
      13. +

        + Cover your nose and mouth with a bent elbow or paper tissue when coughing or sneezing , dispose of the tissue immediately after use , + and perform hand hygiene. +

        +
      14. + +
      15. +

        + Don't spread rumors. +

        +
      16. + + +
      17. +

        + It is normal to feel sad, stressed, confused, scared or angry during a crisis.Talking to people you trust can help. Contact your friends and family. + +

        +
      18. + + + +
      +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/yellow_zone_advices_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/yellow_zone_advices_template.html new file mode 100644 index 0000000..a000c59 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/yellow_zone_advices_template.html @@ -0,0 +1,23 @@ +
      +

      + + You are in Yellow zone +

      +
        +
      1. +

        Stay home stay safe

        +
      2. +
      3. +

        No need to worry about COVID-19, always take appropriate precautions

        +
      4. +
      5. +

        Yellow zone means nearest point is within {{nearest_covid19_point.radius_range_in_km}} {{RANGE_IN_UNITS}}radius. Their is a possibility COVID-19 carriers maybe around your region.

        +
      6. + +
      7. +

        Wear mask,clean your hands often, avoid crowded and infected places, don't invite relatives during + pandemic, don't touch your eyes ,nose or mouth.

        +
      8. +
      +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/advices/zero_zone_advices_template.html b/covid19nearyou/templates/covid19nearyou/templates/advices/zero_zone_advices_template.html new file mode 100644 index 0000000..06f20b1 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/advices/zero_zone_advices_template.html @@ -0,0 +1,25 @@ +
      +

      + + You are in Green zone +

      + + +
        +
      1. +

        + Stay home stay safe +

        +
      2. +
      3. +

        No need to worry about COVID-19, always take appropriate precautions

        +
      4. +
      5. +

        No points around you doesn't mean you are in safe region.Their is a possibility COVID-19 carriers around your region.

        +
      6. + +
      7. +

        Wear mask,clean your hands often, avoid crowded and infected places, don't invite relatives during pandemic, don't touch your eyes ,nose or mouth.

        +
      8. +
      +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/covid19_near_you_template.html b/covid19nearyou/templates/covid19nearyou/templates/covid19_near_you_template.html new file mode 100644 index 0000000..cbb7dfe --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/covid19_near_you_template.html @@ -0,0 +1,22 @@ +
      + + {% if nearest_covid19_point or nearest_covid19_quarantine or total_covid19_points_near_you %} + +
      + {% include 'covid19nearyou/templates/points_template.html' %} +
      + +
      + {% include 'covid19nearyou/templates/advices/all_advices_template.html' %} +
      + + {%else%} + +
      + {% include 'covid19nearyou/templates/advices/all_advices_template.html' %} +
      + + {%endif %} + + +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/dashboard/data_missing_template.html b/covid19nearyou/templates/covid19nearyou/templates/dashboard/data_missing_template.html new file mode 100644 index 0000000..6845cb8 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/dashboard/data_missing_template.html @@ -0,0 +1,10 @@ + +

      Data missing in Redis

      +
      +

      +

      App is not working right now due to some points missing in Redis database.

      +

      COVID-19 nearest point and Quarantine center features based on Redis database.

      +Add data intoRedis database. + + + diff --git a/covid19nearyou/templates/covid19nearyou/templates/dashboard/data_updated_at_template.html b/covid19nearyou/templates/covid19nearyou/templates/dashboard/data_updated_at_template.html new file mode 100644 index 0000000..cc35055 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/dashboard/data_updated_at_template.html @@ -0,0 +1,9 @@ + + {% if DataUpdatedAt %} +
      +
      + File is updated +
      + {{DataUpdatedAt}} +
      + {%endif%} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/dashboard/geospatial_data_template.html b/covid19nearyou/templates/covid19nearyou/templates/dashboard/geospatial_data_template.html new file mode 100644 index 0000000..c9a8212 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/dashboard/geospatial_data_template.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + +
      IdCreated atData added atStatus
      {{geospatialfile.id}}{{geospatialfile.created_at}}{{geospatialfile.finshed_at}}{{geospatialfile.is_finshed}}
      + diff --git a/covid19nearyou/templates/covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html b/covid19nearyou/templates/covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html new file mode 100644 index 0000000..b2f5237 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html @@ -0,0 +1,15 @@ +
      +

      NEAREST POINT

      + + + {{nearest_covid19_point.address}} +

      + + {{nearest_covid19_point.radius_range_in_km}} {{RANGE_IN_UNITS}} range circle +

      + + + + {{nearest_covid19_point.distance}} {{RANGE_IN_UNITS}} distance + +
      \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/locations/nearest_quarantine_template.html b/covid19nearyou/templates/covid19nearyou/templates/locations/nearest_quarantine_template.html new file mode 100644 index 0000000..bfb75d1 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/locations/nearest_quarantine_template.html @@ -0,0 +1,24 @@ +{%if nearest_covid19_quarantine%} + +
      +

      NEAREST QUARANTINE CENTER

      + + + + {{nearest_covid19_quarantine.address}} + +

      + + {{QUARANTINE_RADIUS_RANGE}} + {{QUARANTINE_RADIUS_RANGE_UNIT}} + radius range + + +

      + + + {{nearest_covid19_quarantine.distance}} Km + distance + +
      +{%endif%} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/points_in_radius_template.html b/covid19nearyou/templates/covid19nearyou/templates/points_in_radius_template.html new file mode 100644 index 0000000..251b15e --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/points_in_radius_template.html @@ -0,0 +1,112 @@ +{%if total_covid19_points_near_you or total_covid19_points_near_you == 0 %} +
      + +

      POINTS IN RADIUS

      + +
      +
      + + {%if total_covid19_points_near_you > 1 %} + +
      + +
      + {{total_covid19_points_near_you}} +
      +
      + POINTS AROUND YOU +
      +
      + + + {%elif total_covid19_points_near_you == 1 or total_covid19_points_near_you == 0 %} + +
      + +
      + {{total_covid19_points_near_you}} +
      +
      + POINT AROUND YOU +
      +
      + + {%endif%} + +
      +
      + + {%if total_covid19_points_near_you == 0 or total_covid19_points_near_you %} + +
      + +
      + {{THIRD_RANGE_CIRCLE}} +
      +
      + {{RANGE_IN_UNITS}} range circle +
      + +
      + + {%endif%} +
      + +
      + + {%if covid19_point_list%} + + {% for point in covid19_point_list%} + + {% if point.0.radius_range_in_km == 1 %} + +
      +
      + + {{point.0.total_effected_zone}} + +
      + +
      + {{point.0.radius_range_in_km}} km +
      + +
      + {% elif point.0.radius_range_in_km == 2 %} + + +
      +
      + + {{point.0.total_effected_zone}} + +
      + +
      + {{point.0.radius_range_in_km}} km +
      + +
      + + {% elif point.0.radius_range_in_km == 3 %} + +
      +
      + + {{point.0.total_effected_zone}} + +
      + +
      + {{point.0.radius_range_in_km}} km +
      + +
      + {%endif%} + {%endfor%} + {%endif%} +
      +
      +
      + +{%endif%} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/points_template.html b/covid19nearyou/templates/covid19nearyou/templates/points_template.html new file mode 100644 index 0000000..7dd329a --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/points_template.html @@ -0,0 +1,22 @@ +{% if nearest_covid19_point %} + + {% if nearest_covid19_point.red == 0 %} + + {% include 'covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html' %} + + {% elif nearest_covid19_point.yellow == 1 %} + + {% include 'covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html' %} + + {% elif nearest_covid19_point.green == 2 %} + + {% include 'covid19nearyou/templates/locations/nearest_confirmed_case_point_template.html' %} + + + + {%endif%} + +{%endif%} + +{% include 'covid19nearyou/templates/points_in_radius_template.html' %} +{% include 'covid19nearyou/templates/locations/nearest_quarantine_template.html' %} \ No newline at end of file diff --git a/covid19nearyou/templates/covid19nearyou/templates/weblinks/country_and_who_web_links_template.html b/covid19nearyou/templates/covid19nearyou/templates/weblinks/country_and_who_web_links_template.html new file mode 100644 index 0000000..6db1855 --- /dev/null +++ b/covid19nearyou/templates/covid19nearyou/templates/weblinks/country_and_who_web_links_template.html @@ -0,0 +1,19 @@ +
      +
        +
      1. +

        + Keep up to date on the latest information from trusted sources, such as WHO or your local and national health + authorities. Why? Local and national authorities are best placed to advise on what people in your area should + be doing to protect themselves. +

        +
      2. + +
      3. + +
      4. {{MY_COUNTRY_COVID19_WEB_LINK_NAME}}
      5. +
      6. + {{WHO_WEBSITE_LINK_NAME}} +
      7. + +
      +
      \ No newline at end of file diff --git a/covid19nearyou/tests.py b/covid19nearyou/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/covid19nearyou/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/covid19nearyou/urls.py b/covid19nearyou/urls.py new file mode 100644 index 0000000..9ebed4d --- /dev/null +++ b/covid19nearyou/urls.py @@ -0,0 +1,16 @@ +from django.contrib import admin +from django.urls import path, include +from . import views + +urlpatterns = [ + + path('', views.index, name='index_map'), + path('help/', views.help, name='help'), + path('settings-configuration/', views.settings_config, name='settings_config'), + path('covid19-dashboard/', views.dashboard, name='dashboard'), + path('add-to-file-new-and-expire-old-covid19-locations/', views.Add_To_File_New_And_Expire_Old_Covid19_Locations, name='Add_To_File_New_And_Expire_Old_Covid19_Locations'), + path('cache-empty-add-geospatial-data-into-cache/', views.Cache_Failed_Add_Geospatial_Data_Into_Cache, name='Cache_Failed_Add_Geospatial_Data_Into_Cache'), + path('ajax-request/', views.AJAX_find_covid19_near_you, name='AJAX_find_covid19_near_you'), + + + ] \ No newline at end of file diff --git a/covid19nearyou/views.py b/covid19nearyou/views.py new file mode 100644 index 0000000..90417c1 --- /dev/null +++ b/covid19nearyou/views.py @@ -0,0 +1,905 @@ +from django.shortcuts import render, redirect +from django_redis import get_redis_connection +from covid19.settings import STATIC_URL +from geojson import Point, Feature, FeatureCollection, dump +from .forms import * +from .redis_keys import * +from .models import * +import datetime +from datetime import timedelta +import time +import shutil +from django.conf import settings +from django.db.models import Prefetch +from django.http import HttpResponse +from django.http import JsonResponse +from django.template.loader import render_to_string +from . import context_processors +from . import redis_keys as REDIS_KEYS +import os +from django.contrib.sites.shortcuts import get_current_site +from django.utils import timezone +from django.contrib.humanize.templatetags import humanize +from django.contrib.auth.decorators import login_required + +#Settings view +@login_required(login_url='/admin/') +def settings_config(request): + return render(request,'covid19nearyou/pages/settings.html',) + +#Help view +@login_required(login_url='/admin/') +def help(request): + return render(request,'covid19nearyou/pages/help.html',) + + + +""" +Index() view. + +1 : Render Map, location form and with some advices +2 : Get user location and pass to FindCovid19NearYou function and then pass response to template and render back to user + +""" + +#Map Index page +def index(request): + context = {} + + geospatialFile_obj = GeospatialFile.objects.filter(is_finshed=True).order_by('-created_at').first() + + if geospatialFile_obj: + context['data_updated_at'] = geospatialFile_obj.finshed_at + + if request.method == 'POST': + + form = LatitudeLongitudeForm(request.POST) + + if form.is_valid(): + + latitude = form.cleaned_data['latitude'] + longitude = form.cleaned_data['longitude'] + + newcontext = FindCovid19NearYou(latitude,longitude) + context = newcontext + context['form']=form + + else: + context['form']= form + + else: + context['form'] = LatitudeLongitudeForm() + + return render(request,'covid19nearyou/pages/index.html',context) + + +""" +dashboard() view + +This view is guery to Redis database to make sure if any point (data) missing or not + +if data is missing : + 1- Get recent geospatial file object from MySQL db for store information in context like + - Store object + - Last updated at time + 2- And also get those points from MySQL db which are not expired if points greater than 0 that's mean cache is missing + and then set is_cache_miss = True. + +if data not missing : + 1- Set is_cache_exist = True + 2- Get recent geospatial file object from MySQL db for store information in context like + - Store object + - Last updated at time + - Set Is_need_to_update_points_into_file = geospatialFile_obj.isNeedTo_Update_Points_Into_File() + - Set is_need_to_add_data_into_cache = is_need_to_add_data_into_cache(pipeline) + +""" + +#dashboard view +@login_required(login_url='/admin/') +def dashboard(request): + context={} + + con = get_redis_connection("default") + pipeline = con.pipeline() + + pipeline.execute_command('EXISTS',REDIS_KEYS.GEOSPATIAL_DATA_KEY) + pipeline.execute_command('EXISTS',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY) + + result = pipeline.execute() + today = datetime.date.today() + + if result[0] == 0 : # Cache Miss + context['is_cache_exist'] = False # Not exist + geospatialFile_obj = GeospatialFile.objects.filter(is_finshed=True).order_by('-created_at').first() + + if geospatialFile_obj: + context['geospatialfile'] = geospatialFile_obj + context['DataUpdatedAt'] = geospatialFile_obj.getDataUpdatedAt() + + location_points = ConfirmedCaseLocation.objects.filter(expire_at__gt=today).count() # No of Locations points in Db for cache + quarantine_points = QurantineCenter.objects.all().count() # No of QurantineCenter points in Db for cache + + if (location_points > 0 and quarantine_points > 0) or location_points > 0: + context['is_cache_miss'] = True + + elif quarantine_points > 0 and result[1] == 0: + context['is_cache_miss'] = True + + else:# Cache Exist + context['is_cache_exist'] = True # exist + + geospatialFile_obj = GeospatialFile.objects.filter(is_finshed=True).order_by('-created_at').first() + + if geospatialFile_obj: + context['geospatialfile']=geospatialFile_obj + context['DataUpdatedAt'] = geospatialFile_obj.getDataUpdatedAt() + context['Is_need_to_update_points_into_file'] = geospatialFile_obj.isNeedTo_Update_Points_Into_File() + context['is_need_to_add_data_into_cache'] = is_need_to_add_data_into_cache(pipeline) + + return render(request,'covid19nearyou/pages/dashboard.html',context) + +""" +This method is used for is_need_to_add_data_into_cache(). + +1- Get current date +2 - Count no of points in Redis which are not expired +3 - Also Count no of points which are not expired in MySQl db. + +After that comparing points if points are not equal in Redis and MySQL db that's mean some points are missing in +Redis and return True else False. +""" + + +def is_need_to_add_data_into_cache(pipeline): + today = datetime.date.today() + today_for_redis = time.mktime(today.timetuple()) + + pipeline.execute_command('ZCOUNT',REDIS_KEYS.COVID19_GEOSPATIAL_POINTS_EXPIRE_DATA_KEY,today_for_redis,'+inf') + pipeline.execute_command('ZCOUNT',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY,'-inf','+inf') + + Location_Points_In_Redis,Quarantine_Points_In_Redis, = pipeline.execute() + + location_points_In_MYSQL = ConfirmedCaseLocation.objects.filter(expire_at__gte=today).count() # No of Locations points in Db for cache + quarantine_points_In_MYSQL = QurantineCenter.objects.filter(is_visible=True).count() + + + if Location_Points_In_Redis == location_points_In_MYSQL and Quarantine_Points_In_Redis == quarantine_points_In_MYSQL: + return False + else: + #Add data into Cahce + pipeline.execute_command('DEL',REDIS_KEYS.GEOSPATIAL_DATA_KEY) + pipeline.execute() + return True + + +# ------- Add data into Geospatial file and remov expired points ------------# + +""" +These 4 function + +1 - Add_To_File_New_And_Expire_Old_Covid19_Locations() +2 - AddPointsToGeojsonFile() +3 - RemoveCovid19ExpirePointsFromCache() +4 - get_features() + +are used for add data into Geospatial File and Remove expired points from Redis and Geojosn file. + +""" + +# Function : 1 +@login_required +def Add_To_File_New_And_Expire_Old_Covid19_Locations(request): + context={} + + if request.method == 'POST': + + if 'step1' in request.POST: + + #here to call function which update the coordinate file + filepath = AddPointsToGeojsonFile(request) + Filecreated = AddToFileNewAndExpireOldCovid19Location.objects.get(id=request.POST['id']) + if Filecreated: + Filecreated.is_file_created = True + Filecreated.url = filepath + Filecreated.save() + + elif 'step2' in request.POST: + + RemoveCovid19ExpirePointsFromCache() + Filecreated = AddToFileNewAndExpireOldCovid19Location.objects.get(id=request.POST['id']) + print(Filecreated) + if Filecreated: + Filecreated.is_points_removed = True + Filecreated.is_finshed = True + Filecreated.save() + + return redirect('dashboard') + + elif 'creategeospatialfile' in request.POST: + + form = GeospatialFileForm(request.POST) + if form.is_valid(): + + form.instance.sourcetype = 1 + + form.save() + + + return redirect('Add_To_File_New_And_Expire_Old_Covid19_Locations') + else: + + geospatialfile = GeospatialFile.objects.filter(is_finshed=False).select_related('addtofilenewandexpireoldcovid19location').first() + + if geospatialfile: + + context['geospatialfile'] = geospatialfile + + if hasattr(geospatialfile, 'addtofilenewandexpireoldcovid19location'): + + + if geospatialfile.addtofilenewandexpireoldcovid19location.is_file_created == False: + context['is_step1'] = False + else: + context['is_step1'] = True + + context['singlepoint'] = geospatialfile.addtofilenewandexpireoldcovid19location + + + return render(request,'covid19nearyou/pages/add_delete_points.html',context) + + else: + + + geospatialFile_obj = GeospatialFile.objects.filter(is_finshed=True).order_by('-created_at').first() + + + if geospatialFile_obj: + + if geospatialFile_obj.isNeedTo_Update_Points_Into_File(): + + context['form'] = GeospatialFileForm() + + else: + return redirect('dashboard') + else: + + + context['form'] = GeospatialFileForm() + + return render(request,'covid19nearyou/pages/add_delete_points.html',context) + + +# Function : 2 +# Add new points into Geospatial file +def AddPointsToGeojsonFile(request): + + today = datetime.date.today() + today = time.mktime(today.timetuple()) + + + con = get_redis_connection("default",) + pipeline = con.pipeline() + + + features= [] + + pipeline.execute_command('ZRANGEBYSCORE',REDIS_KEYS.COVID19_GEOSPATIAL_POINTS_EXPIRE_DATA_KEY,today,'+inf') + pipeline.execute_command('ZRANGEBYSCORE',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY,'-inf','+inf') + + NewPoints,Quarantine_Points, = pipeline.execute() + + for keys in NewPoints: + pipeline.execute_command('hgetall',keys.decode()) + + LcoationHashKeys = pipeline.execute() + + locationFeatures = get_features(LcoationHashKeys,False) + + for keys in Quarantine_Points: + pipeline.execute_command('hgetall',keys.decode()) + + QuarantineHashKeys = pipeline.execute() + QurantineFeatures = get_features(QuarantineHashKeys,True) + + + features = locationFeatures + QurantineFeatures + feature_collection = FeatureCollection(features) + + + today = datetime.date.today() + + filename = today.strftime('%d-%m-%y') + filepath = os.path.join(settings.MEDIA_ROOT+'location/', filename+'.json') + + + with open(filepath, 'w') as f: + dump(feature_collection, f) + + + mapfilepath = os.path.join(settings.MEDIA_ROOT+'location/data/', 'data.json') + shutil.copy(filepath, mapfilepath) + + full_url = ''.join(['http://', get_current_site(request).domain, '/media/location/data/'+filename+'.json']) + + return full_url + +# Function : 3 +# Remove expired points from Redis +def RemoveCovid19ExpirePointsFromCache(): + + con = get_redis_connection("default",) + pipeline = con.pipeline() + + today = datetime.date.today() + today = time.mktime(today.timetuple()) + + + pipeline.execute_command('ZRANGEBYSCORE','EXPR_AND_POINTS','-inf',today) + + ExpirePoints, = pipeline.execute() + + + for key in ExpirePoints: + pipeline.execute_command('zrem','COVID19POINTS',key.decode()) + + for key in ExpirePoints: + pipeline.execute_command('zrem','EXPR_AND_POINTS',key.decode()) + + + deletedpointsstatus = pipeline.execute() + +# Function : 4 +# Create features for Geospatial file (Geojson file) +def get_features(hashes,is_quarantine): + + + features= [] + + for zone in hashes: + + if zone: + + if is_quarantine: + + point = Point((float(zone[b'longitude'].decode()),float(zone[b'latitude'].decode()))) + + features.append(Feature(geometry=point, properties={ + "name": zone[b'name'].decode(), + "created_at": zone[b'created_at'].decode(), + "updated_at" : zone[b'updated_at'].decode(), + + "is_quarantine":1, + } + )) + else: + point = Point((float(zone[b'longitude'].decode()),float(zone[b'latitude'].decode()))) + + features.append(Feature(geometry=point, properties={ + "name": zone[b'name'].decode(), + "created_at": zone[b'created_at'].decode(), + "updated_at" : zone[b'updated_at'].decode(), + "expire_at" : zone[b'expire_at'].decode(), + "is_quarantine":0, + } + )) + return features + + + + + +# ------- Add data into Redis Database. ------------# + + +""" +Add data into Redis Database. +These methods add data into Redis. + +1 - Cache_Failed_Add_Geospatial_Data_Into_Cache() view +2 - Add_Location_Batch_Into_Cache() +3 - Add_Quarantine_Batch_Into_Cache() +4 - getNoOfBatches() + +""" + + + +# Function : 1 +# Main view for Add data into Redis +@login_required(login_url='/admin/') +def Cache_Failed_Add_Geospatial_Data_Into_Cache(request): + + context={} + + if request.method == 'POST': + + + if 'createbtach' in request.POST: + form = LocationBatchManagerForm(request.POST) + + if form.is_valid(): + + form = form.save(commit=False) + + + form.qurantine_points = int(request.POST['qurantine_points']) + + form.qurantine_batches = int(request.POST['qurantine_batches']) + + form.location_points = int(request.POST['location_points']) + + form.location_batches = int(request.POST['location_batches']) + + if form.qurantine_points == 0: + form.is_quarantine_batches_completed = True + + + if form.location_points == 0: + form.is_location_batches_completed = True + + form.save() + + return redirect('Cache_Failed_Add_Geospatial_Data_Into_Cache') + + elif 'process_location_batch' in request.POST: + + batchId= request.POST['Location_batch_not_completed_Id'] + + if batchId: + try: + batch = ConfirmedCaseLocationBatch.objects.get(id=batchId,is_completed=False) + result = Add_Location_Batch_Into_Cache(batch) + if result: + batch.is_completed = True + batch.save() + + Batch_Manager_Object = RedisBatchManager.objects.get(id=batch.batch_manager.id) + + Batch_Manager_Object.location_completed_batches = Batch_Manager_Object.location_completed_batches + 1 + + if Batch_Manager_Object.location_completed_batches == Batch_Manager_Object.location_batches: + if Batch_Manager_Object.qurantine_completed_batches == Batch_Manager_Object.qurantine_batches: + Batch_Manager_Object.is_finshed = True + + Batch_Manager_Object.is_location_batches_completed = True + Batch_Manager_Object.save() + return redirect('dashboard') + else: + + Batch_Manager_Object.save() + + return redirect('Cache_Failed_Add_Geospatial_Data_Into_Cache') + + except ConfirmedCaseLocationBatch.DoesNotExist: + batch = None + + else: + pass # error + + elif 'process_quarantine_batch' in request.POST: + batchId= request.POST['Quarantine_batch_not_completed_Id'] + + if batchId: + try: + batch = QuarantineCenterBatch.objects.get(id=batchId,is_completed=False) + result = Add_Quarantine_Batch_Into_Cache(batch) + if result: + batch.is_completed = True + batch.save() + + Batch_Manager_Object = RedisBatchManager.objects.get(id=batch.batch_manager.id) + + Batch_Manager_Object.qurantine_completed_batches = Batch_Manager_Object.qurantine_completed_batches + 1 + + if Batch_Manager_Object.qurantine_completed_batches == Batch_Manager_Object.qurantine_batches: + if Batch_Manager_Object.qurantine_completed_batches == Batch_Manager_Object.qurantine_batches: + Batch_Manager_Object.is_finshed = True + + Batch_Manager_Object.is_quarantine_batches_completed = True + Batch_Manager_Object.save() + return redirect('dashboard') + else: + + Batch_Manager_Object.save() + + return redirect('Cache_Failed_Add_Geospatial_Data_Into_Cache') + + except QuarantineCenterBatch.DoesNotExist: + batch = None + + else: + pass # errror + + return redirect('Cache_Failed_Add_Geospatial_Data_Into_Cache') + else: + con = get_redis_connection("default",) + pipeline = con.pipeline() + pipeline.execute_command('EXISTS',REDIS_KEYS.GEOSPATIAL_DATA_KEY) + pipeline.execute_command('EXISTS',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY) + result = pipeline.execute() + + + + + if result[0] == 0 : # Cache Miss + + + today = datetime.date.today() + + location_points = ConfirmedCaseLocation.objects.filter(expire_at__gt=today).count() # No of Locations points in Db for cache + quarantine_points = QurantineCenter.objects.all().count() # No of QurantineCenter points in Db for cache + + if location_points > 0 or quarantine_points > 0: # Locations or QurantineCenter Points greater 0 + + Batch_Manager_Object = RedisBatchManager.objects.filter(is_finshed=False).first() + + if Batch_Manager_Object: + + context['Batch_Manager_Object']= Batch_Manager_Object + + Location_Batches = ConfirmedCaseLocationBatch.objects.filter(batch_manager=Batch_Manager_Object) + Quarantine_Batches = QuarantineCenterBatch.objects.filter(batch_manager=Batch_Manager_Object) + + if Location_Batches: + context['Location_Batches'] = Location_Batches + context['Location_batch_not_completed_Id'] = Batch_Manager_Object.get_Id_of_which_batch_is_not_completed(Location_Batches) + + if Quarantine_Batches: + context['Quarantine_Batches'] = Quarantine_Batches + context['Quarantine_batch_not_completed_Id'] = Batch_Manager_Object.get_Id_of_which_batch_is_not_completed(Quarantine_Batches) + + + else: + + intial_data = {'location_batches':getNoOfBatches(location_points),'location_points':location_points,'qurantine_batches':getNoOfBatches(quarantine_points),'qurantine_points':quarantine_points} + form = LocationBatchManagerForm(intial_data) + + context['form']=form + + context['location_points'] = location_points + + context['location_batches'] = getNoOfBatches(location_points) + + context['qurantine_points'] = quarantine_points + + context['qurantine_batches'] = getNoOfBatches(quarantine_points) + + else: + context['message']= 'Add points and then create first geospatil file thanks' + else: # No Cache Miss + + Batch_Manager_Object = RedisBatchManager.objects.filter(is_finshed=False).first() #If cache in processing then comes here + + if Batch_Manager_Object: + context['Batch_Manager_Object']= Batch_Manager_Object + + Location_Batches = ConfirmedCaseLocationBatch.objects.filter(batch_manager=Batch_Manager_Object) + Quarantine_Batches = QuarantineCenterBatch.objects.filter(batch_manager=Batch_Manager_Object) + + if Location_Batches: + context['Location_Batches'] = Location_Batches + context['Location_batch_not_completed_Id'] = Batch_Manager_Object.get_Id_of_which_batch_is_not_completed(Location_Batches) + + if Quarantine_Batches: + context['Quarantine_Batches'] = Quarantine_Batches + context['Quarantine_batch_not_completed_Id'] = Batch_Manager_Object.get_Id_of_which_batch_is_not_completed(Quarantine_Batches) + + + else: + print('Cache is not empty sad : Thier is no need to update Cache.') + context['message']='Thier is no need to update Cache.' + + + + + + return render(request,'covid19nearyou/pages/add_data_into_redis.html.html',context) + +# Function : 2 +# Add Confirmed Case location batch into Redis database +def Add_Location_Batch_Into_Cache(batch): + + + today = datetime.date.today() + locationlist = ConfirmedCaseLocation.objects.filter(expire_at__gt=today).all()[batch.range_start:batch.range_end] + + con = get_redis_connection("default") + pipeline = con.pipeline() + + for instance in locationlist: + + #GEOSPATIAL INSERTION + pipeline.execute_command('GEOADD',REDIS_KEYS.GEOSPATIAL_DATA_KEY,float(instance.longitude),float(instance.latitude),instance.get_redis_key()) + #EXPIRE AND DATA INSERTION + pipeline.execute_command('zadd',REDIS_KEYS.COVID19_GEOSPATIAL_POINTS_EXPIRE_DATA_KEY,'nx','ch',instance.get_expire_at_in_unixtime() ,instance.get_redis_key()) + + #COVID19 GEOSPATIAL HASH + pipeline.hmset(instance.get_redis_key(),instance.get_hash_for_redis()) + + #COVID19 GEOSPATIAL HASH SETTING EXPIRE DATE + pipeline.expireat(name=instance.get_redis_key(),when=instance.get_expire_at_in_unixtime()) + + result = pipeline.execute() + + + return result + +# Function : 3 +# Add Quarantine batch into Redis database +def Add_Quarantine_Batch_Into_Cache(batch): + + + today = datetime.date.today() + Quarantine_Batches = QurantineCenter.objects.all()[batch.range_start:batch.range_end] + + con = get_redis_connection("default") + pipeline = con.pipeline() + + for instance in Quarantine_Batches: + + #GEOSPATIAL INSERTION + pipeline.execute_command('GEOADD',REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY,float(instance.longitude),float(instance.latitude),instance.get_redis_key()) + + #COVID19 GEOSPATIAL HASH + pipeline.hmset(instance.get_redis_key(),instance.get_hash_for_redis()) + + result = pipeline.execute() + + + return result + +# Function : 4 +# Calculate no of batches required for Redis +def getNoOfBatches(locationPoints): + + if locationPoints == 0: + return 0 + elif locationPoints <= settings.LOCATION_CACHE_BATCH_SIZE: + return 1 + else: + if locationPoints/settings.LOCATION_CACHE_BATCH_SIZE % 2 == 0 : + return round(locationPoints/settings.LOCATION_CACHE_BATCH_SIZE) + else: + return round(locationPoints/settings.LOCATION_CACHE_BATCH_SIZE) + 1 + + + +""" +This method is used for AJAX request and return back response. + +1 - AJAX_find_covid19_near_you() + +""" + + +#Handle AJAX request and send back response as a JSON +def AJAX_find_covid19_near_you(request): + data = {} + if request.is_ajax and request.method == 'POST': + + form = LatitudeLongitudeForm(request.POST) + + if form.is_valid(): + + latitude = form.cleaned_data['latitude'] + longitude = form.cleaned_data['longitude'] + + + context = FindCovid19NearYou(latitude,longitude) + context.update(context_processors.setting_constants(request)) #render_to_string not supported context_processors + templateTag = render_to_string('covid19nearyou/templates/covid19_near_you_template.html', context) + + + data = { + 'is_success':True, + 'data':templateTag, + 'current_latitude':latitude, + 'current_longitude':longitude, + } + + return JsonResponse(data,safe=False) + else: # Not Valid + + data['is_success'] = False + + if form.has_error('latitude',code='invalid'): + + latitude_error = 'Latitude must be numeric' + data['latitude_error'] = latitude_error + + else: + + latitude_error = 'Latitude out of range' + data['latitude_error'] = latitude_error + + if form.has_error('longitude',code='invalid'): + longitude_error = 'Longitude must be numeric' + + data['longitude_error'] = longitude_error + else: + + longitude_error = 'Longitude out of range' + data['longitude_error'] = longitude_error + + return JsonResponse(data,safe=False) + +""" +This method is actually finds the COVID19 related stuff. + +1 - FindCovid19NearYou() + +""" + +#Find COVID-19 Nearest Points +def FindCovid19NearYou(latitude,longitude): + + con = get_redis_connection("default",) + pipeline = con.pipeline() + context = {} + + context['current_latitude']=latitude + context['current_longitude']=longitude + + + pipeline.georadius(name=REDIS_KEYS.GEOSPATIAL_DATA_KEY, longitude=longitude, + latitude=latitude, radius=settings.FIRST_RANGE_CIRCLE, unit=settings.RANGE_IN_UNITS, withdist=True, withcoord=True, sort='ASC') + + pipeline.georadius(name=REDIS_KEYS.GEOSPATIAL_DATA_KEY, longitude=longitude, + latitude=latitude, radius=settings.SECOND_RANGE_CIRCLE, unit=settings.RANGE_IN_UNITS, withdist=True, withcoord=True, sort='ASC') + + pipeline.georadius(name=REDIS_KEYS.GEOSPATIAL_DATA_KEY, longitude=longitude, + latitude=latitude, radius=settings.THIRD_RANGE_CIRCLE, unit=settings.RANGE_IN_UNITS, withdist=True, withcoord=True, sort='ASC') + + pipeline.georadius(name=REDIS_KEYS.GEOSPATIAL_QUARANTINE_DATA_KEY, longitude=longitude, + latitude=latitude, radius=settings.QUARANTINE_RADIUS_RANGE, unit=settings.QUARANTINE_RADIUS_RANGE_UNIT, withdist=True, withcoord=True, sort='ASC') + + + covid19_point_list = pipeline.execute() + + dict_list_of_covid19_point = [] + + nearest_covid19_quarantine = {} + + index = 0 + radius_range = 'radius_range_in_' + settings.RANGE_IN_UNITS + + for covid19_point in covid19_point_list: + + if index == 3: #Quarantine + + if covid19_point: + for nearestQuarantine in covid19_point: # Quarantine consist of multiple quarantine center + address = nearestQuarantine[0].decode() + address = address.split(':') + zone = { + + 'address':address[2], + 'distance': nearestQuarantine[1], + 'longitude': nearestQuarantine[2][0], + 'latitude': nearestQuarantine[2][1], + 'lat_long':str(nearestQuarantine[2][0]) + ','+ str(nearestQuarantine[2][1]), + } + + nearest_covid19_quarantine = zone + break # if nearest quarantine found then no need to find others + + + + else: #Other 3 queries result Confirmed cases + + if covid19_point: + + listofmultiplezones = [] + + total_zone = {radius_range: index+1, 'total_effected_zone': len(covid19_point), 'is_empty': False, + } + listofmultiplezones.append(total_zone) + address = [] + for eachzone in covid19_point: + + address = eachzone[0].decode() + address = address.split(':') + + zone = { + + 'address':address[2], + + radius_range: index+1, + + 'distance': eachzone[1], + + 'longitude': eachzone[2][0], + 'latitude': eachzone[2][1], + 'lat_long':str(eachzone[2][0]) + ','+ str(eachzone[2][1]), + } + + + listofmultiplezones.append(zone) + + dict_list_of_covid19_point.append(listofmultiplezones) + + else: # empty + listofmultiplezones = [] + total_zone = {radius_range: index+1, + 'total_effected_zone': len(covid19_point), 'is_empty': True, } + listofmultiplezones.append(total_zone) + + zone = { + radius_range: index+1, + } + listofmultiplezones.append(zone) + dict_list_of_covid19_point.append(listofmultiplezones) + + + index = index + 1 + + + + + + nearest_covid19_point = {} + + + + + + if dict_list_of_covid19_point[0][0]['radius_range_in_km'] == 1 and not dict_list_of_covid19_point[0][0]['is_empty']: + + nearest_covid19_point = dict_list_of_covid19_point[0][1] + + + nearest_covid19_point['red'] = 0 #'Red zone' + + zones = { + 'is_empty':True, + + } + nearest_covid19_point['zones'] = zones + + elif dict_list_of_covid19_point[1][0]['radius_range_in_km'] == 2 and not dict_list_of_covid19_point[1][0]['is_empty']: + + + nearest_covid19_point = dict_list_of_covid19_point[1][1] + + nearest_covid19_point['yellow'] = 1 #'yellow zone' + + + elif dict_list_of_covid19_point[2][0]['radius_range_in_km'] == 3 and not dict_list_of_covid19_point[2][0]['is_empty']: + + nearest_covid19_point = dict_list_of_covid19_point[2][1] + + nearest_covid19_point['green'] = 2 #'green zone' + + else: # no points around you + + nearest_covid19_point['no_points'] = 3 + + total_covid19_points_near_you = dict_list_of_covid19_point[2][0]['total_effected_zone'] + + + context['total_covid19_points_near_you'] = total_covid19_points_near_you + context['nearest_covid19_point'] = nearest_covid19_point + context['covid19_point_list'] = dict_list_of_covid19_point + context['nearest_covid19_quarantine'] = nearest_covid19_quarantine + + + return context + + + + + + + + + + + + + + + + + + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7fc563d --- /dev/null +++ b/requirements.txt @@ -0,0 +1,12 @@ +asgiref==3.2.7 +autopep8==1.5.2 +Django==3.0.7 +django-redis==4.11.0 +geojson==2.5.0 +mysqlclient==1.4.6 +pkg-resources==0.0.0 +pycodestyle==2.5.0 +python-decouple==3.3 +pytz==2019.3 +redis==3.4.1 +sqlparse==0.3.1 diff --git a/static/css/admin.css b/static/css/admin.css new file mode 100644 index 0000000..64135af --- /dev/null +++ b/static/css/admin.css @@ -0,0 +1,140 @@ + +/* + HEADER */ + + + +#header { + width: auto; + height: auto; + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 40px; + background-color: #6980f5; + color: #fff; + overflow: hidden; + +} +.module h2, .module caption, .inline-group h2 { + background-color: #6980f5; + opacity: 0.8; + } + + +a:link, a:visited { + color:#6980f5; + opacity: 0.8; + } + + div.breadcrumbs { + background: #6980f5; + + } +#header a:focus , #header a:hover { + text-decoration: underline; +} + +#branding { + float: left; +} + +#branding h1 { + padding: 0; + margin: 0 20px 0 0; + font-weight: 300; + font-size: 24px; + color: #fff; +} + +#branding h1, #branding h1 a:link, #branding h1 a:visited { + color: #fff; +} + +#branding h2 { + padding: 0 10px; + font-size: 14px; + margin: -8px 0 8px 0; + font-weight: normal; + color: #fff; +} + +#branding a:hover { + text-decoration: none; +} + +#user-tools { + float: right; + padding: 0; + margin: 0 0 0 20px; + font-weight: 300; + font-size: 11px; + letter-spacing: 0.5px; + text-transform: uppercase; + text-align: right; + color: #fff; +} + +#user-tools a { + border-bottom: 1px solid rgba(255, 255, 255, 0.25); +} + +#user-tools a:focus, #user-tools a:hover { + text-decoration: none; + border-bottom-color: #fff; + color: #fff; +} + +/* +* BREADCRUMBS */ + +div.breadcrumbs { + background:white; + padding: 10px 40px; + border: none; + font-size: 14px; + color: #6980f5; + text-align: left; +} + +div.breadcrumbs a { + color: #6980f5; +} + +div.breadcrumbs a:focus, div.breadcrumbs a:hover { + color:#6980f5; +} + + + +/* FORM BUTTONS */ + + +.button, input[type=submit], input[type=button], .submit-row input, a.button { + background: #6980f5; + } + .button.default, input[type=submit].default, .submit-row input.default { + background:#6980f5; + } + .button:active, input[type=submit]:active, input[type=button]:active, .button:focus, input[type=submit]:focus, input[type=button]:focus, .button:hover, input[type=submit]:hover, input[type=button]:hover { + background: #6980f5; + opacity: 0.8; + } + .button.default:active, input[type=submit].default:active, .button.default:focus, input[type=submit].default:focus, .button.default:hover, input[type=submit].default:hover { + background: #6980f5; + opacity: 0.8; + } + + +.object-tools a:link, .object-tools a:visited { + display: block; + float: left; + padding: 3px 12px; + background: #6980f5; + font-weight: 400; + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.5px; + color: #fff; +} + diff --git a/static/css/map.css b/static/css/map.css new file mode 100644 index 0000000..006b309 --- /dev/null +++ b/static/css/map.css @@ -0,0 +1,133 @@ +html, +body { + margin: 0; + height: 100%; + padding: 0; + + +} + + + +.custom-card{ + border: 1px solid #e5e7e9; + padding: 20px 10px 15px 10px; + border-radius: 10px; + + margin-top: 0px; + margin-bottom: 10px; + + +} + +.point-custom-card{ + border: 1px solid #e5e7e9; + padding: 20px 20px 25px 20px; + border-radius: 5px; + + margin-top: 0px; + margin-bottom: 10px; + + +} + + + +p { + font: 1em sans-serif; + +} + +.point-title{ + color: #2d4047; +} + +.IconColor { + color: #2d4047; + +} + +.nearest-point-design{ + margin-left: 8px; + font-size: 15px; + color: #2d4047; +} + + +#brandIconColor{ + color: #6980f5; +} + + h2.ui.header { + font-size: 1.71428571rem; + +} + + +#map { + position: relative; + top: 10; + bottom: 0; + width: 100%; + + height: 40vh; + + + +} + +.ring-container { + position: relative; +} + +.circle {} + +.ringring { + border: 7px solid #ef5350; + -webkit-border-radius: 50px; + height: 0px; + width: 0px; + position: absolute; + + -webkit-animation: pulsate 1s ease-out; + -webkit-animation-iteration-count: infinite; + opacity: 0.0 +} + +.quarantineringring { + border: 7px solid #2196f3; + -webkit-border-radius: 50px; + height: 0px; + width: 0px; + position: absolute; + + -webkit-animation: pulsate 1s ease-out; + -webkit-animation-iteration-count: infinite; + opacity: 0.0 +} + + + +@-webkit-keyframes pulsate { + 0% { + -webkit-transform: scale(0.1, 0.1); + opacity: 0.0; + } + + 50% { + opacity: 1.0; + } + + 100% { + -webkit-transform: scale(1.2, 1.2); + opacity: 0.0; + } +} + +.collapsed.row.stretched { + margin: 0 1rem; +} + +.collapsed.row.stretched .column { + padding: 0; +} \ No newline at end of file diff --git a/static/js/base.js b/static/js/base.js new file mode 100644 index 0000000..07c7ea1 --- /dev/null +++ b/static/js/base.js @@ -0,0 +1,3 @@ +$(document).ready(function(){ + $('.ui.accordion').accordion(); + }); \ No newline at end of file diff --git a/static/js/map.js b/static/js/map.js new file mode 100644 index 0000000..da69673 --- /dev/null +++ b/static/js/map.js @@ -0,0 +1,307 @@ + +$(document).ready(function () { + + + + + + function LocatePostion_AndDrawRangeCircle(current_latitude, current_longitude) { + + var green = { + radius: FirstRangeCircleRadius, + fillColor: "#5c6bc0", + color: "#ffffff", + weight: 2, + opacity: 0.1, + fillOpacity: 0.4 + }; + + var yellow = { + radius: SecondRangeCircleRadius, + fillColor: "#7986cb", + color: "#ffffff", + weight: 2, + opacity: 0.0, + fillOpacity: 0.4 + }; + + var red = { + radius: ThirdRangeCircleRadius, + fillColor: "#9fa8da", + color: "#ffffff", + weight: 2, + opacity: 0.0, + fillOpacity: 0.2 + }; + + + FirstRangeCircle = L.circle([current_latitude, current_longitude], green).addTo(map); + + SecondRangeCircle = L.circle([current_latitude, current_longitude], yellow).addTo(map); + + ThirdRangeCircle = L.circle([current_latitude, current_longitude], red).addTo(map); + + + CurrentLocationMarker = L.marker([current_latitude, current_longitude]).addTo(map); + + map.flyTo([current_latitude, current_longitude], 12); + + + } + + function UnlocatePostion_AndRemoveRangeCircle() { + + if (FirstRangeCircle != undefined && SecondRangeCircle != undefined && ThirdRangeCircle != undefined) { + // console.log('Removed marker is called') + FirstRangeCircle.remove(); SecondRangeCircle.remove(); ThirdRangeCircle.remove(); + CurrentLocationMarker.remove(); + + }; + + } + + + function validate_latitudeLongitude() { + + var Latitude = $("#id_latitude").val(); + var Longitude = $("#id_longitude").val(); + + $(".latitudeerror").remove(); + $(".longitudeerror").remove(); + + is_latValid = false; + is_longValid = false; + + + if ($.isNumeric(Latitude)) { + if (Latitude < REGION_BOUNDRY_MIN_LATITUDE || Latitude >= REGION_BOUNDRY_MAX_LATITUDE) { + + + $('#id_latitude').after('
      Latitude out of range
      '); + } else { + is_latValid = true + } + + } else { + $('#id_latitude').after('
      Must be numeric
      '); + + } + + if ($.isNumeric(Longitude)) { + + if (Longitude < REGION_BOUNDRY_MIN_LONGITUDE || Longitude >= REGION_BOUNDRY_MAX_LONGITUDE) { + + + $('#id_longitude').after('
      Longitude out of range
      '); + } else { + is_longValid = true + } + + } else { + $('#id_longitude').after('
      Must be numeric
      '); + + } + + if (is_latValid && is_longValid) { + + return true; + } else { + + + return false; + } + + } + + $('#latlongform').on('submit', function (event) { + event.preventDefault(); + + if (validate_latitudeLongitude()) { + + + find_nearest_location_ajax(); + } + }); + + + function getCookie(name) { + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + // AJAX + function csrfSafeMethod(method) { + // these HTTP methods do not require CSRF protection + return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); + } + + function find_nearest_location_ajax() { + + + var csrftoken = getCookie('csrftoken'); + $.ajaxSetup({ + beforeSend: function (xhr, settings) { + if (!csrfSafeMethod(settings.type) && !this.crossDomain) { + xhr.setRequestHeader("X-CSRFToken", csrftoken); + } + } + }); + $.ajax({ + url: endpoint, + type: "POST", + + data: $("#latlongform").serialize(), // data sent with the post request + + // handle a successful response + success: function (json) { + + + if (json['is_success'] == true) { + + $('#datablock').empty(); + $('#datablock').append(json['data']); + + map.flyTo([json['current_latitude'], json['current_longitude']], 14) + + UnlocatePostion_AndRemoveRangeCircle(); + LocatePostion_AndDrawRangeCircle(json['current_latitude'], json['current_longitude']) + + } else { + + if (json['latitude_error']) { + + $('#id_latitude').after('
      ' + json['latitude_error'] + '
      '); + } + + if (json['longitude_error']) { + + $('#id_longitude').after('
      ' + json['longitude_error'] + '
      '); + } + } + + + + }, + + // handle a non-successful response + error: function (xhr, errmsg, err) { + + + if (xhr.status === 500) { + + + + $("#wentworng").remove(); + + $("#error").append("

      500 Internal server error.

      "); + + } else { + + $("#error").append("

      Oops! We have encountered an error.

      "); + + } + } + }); + }; + + + + + var datapoints_geojson = new L.geoJson(); + datapoints_geojson.addTo(map); + + + + function Fetch_PlotGeoJsonData() { + + + $.ajax({ + + dataType: "json", + + url: url, + success: function (data) { + + + function onEachFeature(feature, layer) { + + + + if (feature.properties && feature.properties.name) { + var locationtype = 'Location '; + + if (feature.properties.is_quarantine == 1) { + + locationtype = ' Quarantine ' + locationtype; + layer.bindPopup('

      ' + locationtype + ' : ' + feature.properties.name + '

      ' + + + '

      Created at : ' + feature.properties.created_at + '

      ' + ).openPopup(); + } else { + + + layer.bindPopup('

      ' + locationtype + ' : ' + feature.properties.name + '

      ' + + ).openPopup(); + } + + + + } + + } + + + var Covid19ConfirmedCaseIcon = L.divIcon({ + + className: 'circle', + html: '
      ' + + , iconSize: [22, 22] + + }); + + var Covid19QuarantineIcon = L.divIcon({ + + className: 'circle', + html: '
      ' + + , iconSize: [22, 22] + + }); + + + L.geoJson(data, { + onEachFeature: onEachFeature, pointToLayer: function (feature, latlng) { + + + switch (feature.properties.is_quarantine) { + case 1: + return L.marker(latlng, { icon: Covid19QuarantineIcon }); + case 0: + return L.marker(latlng, { icon: Covid19ConfirmedCaseIcon }); + } + } + }).addTo(map); + + + + } + + }); + + } + + + Fetch_PlotGeoJsonData(); +}); \ No newline at end of file diff --git a/templates/404.html b/templates/404.html new file mode 100644 index 0000000..aa537a4 --- /dev/null +++ b/templates/404.html @@ -0,0 +1,13 @@ +{% extends 'error_base.html' %} + +{%block title%} +404 +{%endblock %} + +{%block statusCode%} +404 +{%endblock %} + +{%block errormessage%} +Page not found +{%endblock %} \ No newline at end of file diff --git a/templates/500.html b/templates/500.html new file mode 100644 index 0000000..0ee1cf8 --- /dev/null +++ b/templates/500.html @@ -0,0 +1,13 @@ +{% extends 'error_base.html' %} + +{%block title%} +Server error +{%endblock %} + +{%block statusCode%} +500 +{%endblock %} + +{%block errormessage%} +Internal server error +{%endblock %} diff --git a/templates/admin/base_site.html b/templates/admin/base_site.html new file mode 100644 index 0000000..4d3093a --- /dev/null +++ b/templates/admin/base_site.html @@ -0,0 +1,35 @@ +{% extends "admin/base.html" %} +{% load static %} + +{% block title %}{{ title }} | {{ site_title|default:_('COVID-19 NEAR YOU ADMIN') }}{% endblock %} + + + + +{% block branding %} + + + + +

      {{ site_header|default:_('COVID-19 NEAR YOU ADMIN') }}

      + + + +{% endblock %} + + + + + + +{% block extrastyle %} + + + + +{% endblock %} + + + +{% block nav-global %}{% endblock %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html new file mode 100644 index 0000000..10864cd --- /dev/null +++ b/templates/base.html @@ -0,0 +1,137 @@ +{% load static %} + + + + + + {% include 'semanticui_jq_cdn.html' %} + + + {%block title%} + + {%endblock %} + + + + + + + +
      +

      + +

      + {%block pageName%} + + {%endblock %} +

      + + +
      + + {%block content%} + + {%endblock %} +
      + + + + + + + + \ No newline at end of file diff --git a/templates/error_base.html b/templates/error_base.html new file mode 100644 index 0000000..cba8599 --- /dev/null +++ b/templates/error_base.html @@ -0,0 +1,38 @@ + + + + {% include 'semanticui_jq_cdn.html' %} + + {%block title%} + + {%endblock %} + + + + + + + +
      +

      + + +
      + +

      + {%block statusCode%} + + {%endblock %} +

      + +

      + {%block errormessage%} + + {%endblock %}

      +
      + +
      + + + + \ No newline at end of file diff --git a/templates/semanticui_jq_cdn.html b/templates/semanticui_jq_cdn.html new file mode 100644 index 0000000..d7447df --- /dev/null +++ b/templates/semanticui_jq_cdn.html @@ -0,0 +1,6 @@ + + + + + +