From aba7e11ad0c020419d24799ac5cc0051e7ceb33e Mon Sep 17 00:00:00 2001
From: "fred.perso"
Date: Tue, 7 Jan 2020 01:24:32 +0100
Subject: [PATCH 1/9] update python requirements
---
requirements.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/requirements.txt b/requirements.txt
index 712d73cb..8d7dc46f 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -14,6 +14,8 @@ django-js-asset==1.2.2
django-leaflet==0.24.0
django-nested-admin==3.2.4
django-tables2==2.1.1
+djangorestframework==3.11.0
+djangorestframework-gis==0.15
et-xmlfile==1.0.1
jdcal==1.4.1
odfpy==1.4.0
--
GitLab
From 863cd0bc548b8c884c9adea02e482b4ae204bb9a Mon Sep 17 00:00:00 2001
From: lpofredc
Date: Tue, 7 Jan 2020 12:20:06 +0100
Subject: [PATCH 2/9] WIP ubuntu based geodjango image
---
Dockerfile.ubuntu | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 Dockerfile.ubuntu
diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu
new file mode 100644
index 00000000..8e1e671b
--- /dev/null
+++ b/Dockerfile.ubuntu
@@ -0,0 +1,33 @@
+FROM makinacorpus/geodjango:bionic-3.7
+
+ENV PYTHONUNBUFFERED 1
+ENV PYTHONDONTWRITEBYTECODE 1
+
+WORKDIR /usr/src/dbchiro
+
+COPY requirements.txt /usr/src/dbchiro
+
+RUN apt update -y add --no-cache \
+ --upgrade \
+ --repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
+ postgresql-client \
+ libpq \
+ nginx
+
+COPY requirements.txt /usr/src/dbchiro
+
+RUN python3 -m pip install --upgrade pip --no-cache-dir \
+ && python3 -m pip install -r requirements.txt --no-cache-dir \
+ && python3 -m pip install gunicorn --no-cache-dir
+
+COPY docker-entrypoint.sh /usr/bin/docker-entrypoint.sh
+
+COPY . /usr/src/dbchiro
+
+VOLUME ["/dbchiro"]
+
+WORKDIR /app
+
+EXPOSE 80
+
+ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]
\ No newline at end of file
--
GitLab
From 0a5631cf8120a485e3dfc275be378f8ef2829e73 Mon Sep 17 00:00:00 2001
From: fredperso
Date: Tue, 7 Jan 2020 23:00:33 +0100
Subject: [PATCH 3/9] Ubuntu based docker image
---
.docker-entrypoint-ubuntu.sh.swp | Bin 0 -> 16384 bytes
Dockerfile | 7 +-
Dockerfile.ubuntu | 19 ++-
docker-compose.yaml | 6 +-
docker-entrypoint-ubuntu.sh | 198 +++++++++++++++++++++++++++++++
5 files changed, 214 insertions(+), 16 deletions(-)
create mode 100644 .docker-entrypoint-ubuntu.sh.swp
create mode 100755 docker-entrypoint-ubuntu.sh
diff --git a/.docker-entrypoint-ubuntu.sh.swp b/.docker-entrypoint-ubuntu.sh.swp
new file mode 100644
index 0000000000000000000000000000000000000000..2b19f0ffc4ffe4df758b3f90d6a4b027a646157e
GIT binary patch
literal 16384
zcmeI3ZEPGz8OMjDP#}F%Qwbq~m|U*-h3uWnCAn<^y4OZo*$r9vCEQYjLGA|de&L5mO+p(+SI0;Mf460KT^!Uz5{v$MOm
zcTQ|RRcO!p>2_zI=b4#jW}n@8=3F29*z6oVTo@zx+(O8!_HAcsf7?aYZY9KXoPZZ!
z>vPWa#}6MGJ9x)61RvlAi-yx!V_wmyH`=D>th2giuybLl#_Yh`a2?YQv~Im?2i=0-
zzJ}H8a^``|1K0FGH)v{yZ(KewzF*wxdvkl}?pv3ysg?<39>_e9c_8yZ=7G!unFlft
zWFE*o@c-k1z}-PUjqdCSyR;I1zb*B>Gd#D$@72`x@HG3%Jdk-H^FZc-%mbMRG7n@P
z$UKmFAoD=xfy@J$2i}4n&<#S~jdp#3FZi+luh#!>+)T*p;P2om@EGvG5wH_HdlMmF
z0(0Od@T(gM`7)RXH-q2YK*%Mq3MhDG7a`Apr@?o@Q{X|+025#rco7YG2wVVlZ~{>9
z0r1AV2)P2D1W$l`Ux*wipRs@n$jH#(MSuTkCdm~L!PcHZ;@KSz?<
z%<@@J0l(N;<0jNkE{c(5znIs1gv}aOcgP{R?1Hf^4`D$O60=9LS$t+*T9L-4~@TOT!DRz8{28x04)
zF!5>Ka$2y^z+sCyh91E8x~;cZ2fs$4zS(MXClg}XRP$rUG#tBWwhHbBEuuG(bA1*B
zrrq+3@_JW}VR!~<;&rIj+@?;`Ot?ZCrcKjg>8U_TH2yv_sAkffU!0wpuT52EYxhjA
z(n&hB;h;^fxyCkz(wFiV60#SEimlv$?uwSg)>%h4tukxsT`M^5Ih|tu!t~tK?8#br
z`uNoH$)(!y#f773EUHoAJ<%+TdHhLA2T*|{wgY8-9(Af)TqU3D^Oe6zFNg|&O)=g
zIJ?>C^wsGz#E9S?w!!tLk1b9wVMcDXW}_YsP5J27hXqRUY=YueXOdB0_VE+7{Dtz-
zt-_}b+&cRZ7*mPe7)l$L`0D(3RsC)(qcA4
zgkscY>ogHq;$VtU75-E&j$u(OCA?8x-z)lFBN7{x?IeENaRVMQ4JT+>PMz9a%i;%w
zu=6f%G@6JulRdGgq{UI{VkF)lSD+;e`3+Oj^72HCnW{q;Vdx`S9G5f~6XO)Z%*9?g
zt{MsQ6Bw;7*MyOjD4&LrC_gD_cied}C4@K-$>6x89oO-IP79&&v6SeEkBCq(9K=?;
z5LjrXYNl!o(9SjlKb9oR-M%AN~_mNLmX-}O+f>E{8OG~r!GgU4Y
z9>Ry7V{{w*6(zE`3IP@PSK*M@A1jF~D1s`m
z+d)*D6cUpqmYJ$nPc1B>b)AiJ6j2iL;iQQas9q5cxCmQoZYy)BYOy=77}
zS!b`5ln%>OJCupAIPRvBlWtLG>F?gFk#<^aYv)RRYtsEvZx#J;Ao?44^%B*5%)bBO
z6Kf~bqdA>4IG`}09Mv9)MI|uOU)ZA>iuOwlP)#X9r$;Dmacm7`{aXBT+^+B_QJ^%`
zw^2XFe>jhYlo`~v^HBz{mf5?fSU2q=ep}Di|F>b?`V!W*eEn~SYtnyWjsFt(Blt1+
z5qJhX3O)-Kz};XL41*iMYsdrq1N;K~9Q+LY09*oJ2Np0v8I-_5pn-iL5B7qcUXC371oMv+(M?XmR7Fp0J@>pFkic$*s32u(WITTk9
z+Dpz9vPe9W#Ir73Nl1%D7gSXf`5H~6kUT8RVkzGYn2-OS((4v8ile0AZfUV7s;DJx
zN2|uzHm`C}3wj!$gk&P9Aet%PR+G-6$3)Vs>oGb%GdsVMc+?BA9N8;<#N{x4Vcv^B
zBBe3pEhx{>`RU9T5i(d?$xO!}4a?CDX2j`InTQkCiecifaMpM1LhF8EjoWZHf;L7|
z>x3ym%8iH=;nnqIYq>DbDat1AL+aG@VQ7N}`WkX~biIunUZGHsZQ_YlDwCLbk(vyc
z=b3@yZBUKfN5|;tXcgFdc``rjdia;QCe1aGfm2z`LdP+X4y0yBEVh@FwFxSuhogdm
zQ$Nd){=}#uAv!!VlEd;T?77T@@+_y{W|lQFU`%A{R5)c&W}0Ut(}R*wx!R}*F)=1v
z9*_YliLr?5-NfZwV6eCOm9(Q}WxZ~$SbBq1Jk~IMER2<}drPeOEBr>_=by-Sn5~)X?`;MI`
zwgzgv#^I=1D)Q3%D9`iobTX>J_CQ({c5stLT9ZnBMBNILlVc^^bv(z-bLUYmXlQ~c
z%c>lS7L+Ors#IlEaEXYUQ*Aq>?#{4f6O_myn#5cBz=01pLewgtx||+w`9Ml-R$z<6
zsqu$I!L?iR(SV0gVB*o#X%%~}CO0THmFd}#sKPD+W6S9a%F%9wdLC_NFna8S&!SY5
z5Q)PFfa<<{&R};&Rc&^#V>2*q+0(l?bxHbSd&99T9tVYEsHWNYKV-KX(0)m|^~8|k
z?laOsXiw}+Q8nJkuHvb;mA$4x15ao11|e?mx{h#~e5UeaK3QZ+wS4!~{LDg4CFyE&
z3+3gL)065EuXd*jc_o46Q`=d`BW{tdudi!7jF;4bm?#jyb|79%2=Oh(Tslq+$L5=i
z@^n9rAf*G<0nMawWE+KJbI04Yr7<)B0GaKUZlwrZv?H!!s}&6h>un`$mUxn&BQ7wNL;cs-jOTAYI?wY3ht9FW!YUf+UQK#kh
QaMbB=*myVP2Y2y*0kEbXr~m)}
literal 0
HcmV?d00001
diff --git a/Dockerfile b/Dockerfile
index 6b755551..697df63b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,7 +12,8 @@ RUN apk add --no-cache \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
postgresql-client \
libpq \
- nginx\
+ nginx \
+ binutils \
&& apk add --no-cache \
--upgrade \
--repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
@@ -20,13 +21,13 @@ RUN apk add --no-cache \
postgresql-dev \
zlib-dev jpeg-dev \
alpine-sdk \
+ poppler \
&& apk add --no-cache \
--upgrade \
- --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing \
+ --repository http://dl-cdn.alpinelinux.org/alpine/edge/community \
geos \
proj \
gdal \
- binutils \
&& ln -s /usr/lib/libproj.so.15 /usr/lib/libproj.so \
&& ln -s /usr/lib/libgdal.so.20 /usr/lib/libgdal.so \
&& ln -s /usr/lib/libgeos_c.so.1 /usr/lib/libgeos_c.so \
diff --git a/Dockerfile.ubuntu b/Dockerfile.ubuntu
index 8e1e671b..b863c145 100644
--- a/Dockerfile.ubuntu
+++ b/Dockerfile.ubuntu
@@ -7,20 +7,19 @@ WORKDIR /usr/src/dbchiro
COPY requirements.txt /usr/src/dbchiro
-RUN apt update -y add --no-cache \
- --upgrade \
- --repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
+RUN apt update -y \
+ && apt-get install -y \
postgresql-client \
- libpq \
- nginx
+ nginx \
+ python3-pip
COPY requirements.txt /usr/src/dbchiro
-RUN python3 -m pip install --upgrade pip --no-cache-dir \
- && python3 -m pip install -r requirements.txt --no-cache-dir \
- && python3 -m pip install gunicorn --no-cache-dir
+RUN python3 -m pip install --upgrade pip \
+ && python3 -m pip install -r requirements.txt \
+ && python3 -m pip install gunicorn
-COPY docker-entrypoint.sh /usr/bin/docker-entrypoint.sh
+COPY docker-entrypoint-ubuntu.sh /usr/bin/docker-entrypoint.sh
COPY . /usr/src/dbchiro
@@ -30,4 +29,4 @@ WORKDIR /app
EXPOSE 80
-ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]
\ No newline at end of file
+ENTRYPOINT ["/usr/bin/docker-entrypoint.sh"]
diff --git a/docker-compose.yaml b/docker-compose.yaml
index 031460dd..10a47013 100644
--- a/docker-compose.yaml
+++ b/docker-compose.yaml
@@ -4,7 +4,7 @@ services:
db:
image: mdillon/postgis:11-alpine
- container_name: dbchiro_db
+ container_name: dbchirodev_db
volumes:
- $POSTGRES_DATA_DIR:/var/lib/postgresql/data
environment:
@@ -14,8 +14,8 @@ services:
dbchiro:
- image: dbchiro/dbchiroweb:alpine
- container_name: dbchiro_app
+ image: dbchiro/dbchiroweb:develop
+ container_name: dbchirodev_app
volumes:
- $DBCHIRO_APP_DIR:/dbchiro
links:
diff --git a/docker-entrypoint-ubuntu.sh b/docker-entrypoint-ubuntu.sh
new file mode 100755
index 00000000..8c150769
--- /dev/null
+++ b/docker-entrypoint-ubuntu.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+
+echo ""
+echo "dbChiro init_____________________________________________"
+echo ""
+echo " * * * *"
+echo " *** ********** ***"
+echo " ***** ********** *****"
+echo " ******* ********** *******"
+echo " ********** ************ **********"
+echo " ****************************************************"
+echo " ******************************************************"
+echo "********************************************************"
+echo "********************************************************"
+echo "********************************************************"
+echo " ******************************************************"
+echo " ******** ************************ ********"
+echo " ******* * ********* * *******"
+echo " ****** ******* ******"
+echo " ***** ***** *****"
+echo " *** *** ***"
+echo " ** * **"
+echo ""
+
+
+export DBHOST=${POSTGRES_HOST:-db}
+export DBNAME=${POSTGRES_DB:-dbchiro}
+export DBUSER=${POSTGRES_USER:-dbadmin}
+export DBPWD=${POSTGRES_PASSWORD:-myDbPassword}
+export DBPORT=${POSTGRES_PORT:-5432}
+export SECRETKEY=${SECRETKEY:-$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c50)}
+export SRID=${SRID:-4326}
+export X=${DEFAULT_X:-5}
+export Y=${DEFAULT_Y:-45}
+export SETTINGS=${SETTINGS:-production}
+
+export SU_USERNAME=${SU_USERNAME:-admin}
+export SU_PWD=${SU_PWD:-admin}
+export SU_EMAIL=${SU_EMAIL:-admin@domain.tld}
+
+export EMAIL_SMTP=${EMAIL_SMTP:-smtp.domain.tld}
+export EMAIL_SSL=${EMAIL_SSL:-False}
+export EMAIL_PORT=${EMAIL_PORT:-465}
+export EMAIL_USER=${EMAIL_USER:-$SU_EMAIL}
+export EMAIL_PWD=${EMAIL_PWD:-passWord}
+export EMAIL_DEFAULT_FROM=${EMAIL_SMTP:-$EMAIL_USER}
+
+export IGN_API_KEY=${IGN_API_KEY:-yourapikey}
+
+shopt -s dotglob nullglob
+mv /usr/src/dbchiro/* /app/
+
+if [ ! -f /dbchiro/config.py ]; then
+ echo "generate new config file"
+ mv /app/dbchiro/settings/configuration/config.py.sample /dbchiro/config.py
+ sed -i "s/dbHost/${DBHOST}/g" /dbchiro/config.py
+ sed -i "s/dbName/${DBNAME}/g" /dbchiro/config.py
+ sed -i "s/dbUser/${DBUSER}/g" /dbchiro/config.py
+ sed -i "s/dbPassword/${DBPWD}/g" /dbchiro/config.py
+ sed -i "s/dbPort/${DBPORT}/g" /dbchiro/config.py
+ sed -i "s/secretKey/${SECRETKEY}/g" /dbchiro/config.py
+ sed -i "s/geoDefaultProj/${SRID}/g" /dbchiro/config.py
+ sed -i "s/geoDefaultX/${X}/g" /dbchiro/config.py
+ sed -i "s/geoDefaultY/${Y}/g" /dbchiro/config.py
+ sed -i "s/emailSmtpHost/${EMAIL_SMTP}/g" /dbchiro/config.py
+ sed -i "s/emailSsl/${EMAIL_SSL}/g" /dbchiro/config.py
+ sed -i "s/emailPort/${EMAIL_PORT}/g" /dbchiro/config.py
+ sed -i "s/emailAddress/${EMAIL_USER}/g" /dbchiro/config.py
+ sed -i "s/emailPassword/${EMAIL_PWD}/g" /dbchiro/config.py
+ sed -i "s/emailDefaultFrom/${EMAIL_DEFAULT_FROM}/g" /dbchiro/config.py
+ sed -i "s/IGN_API_KEY = 'yourapikey'/IGN_API_KEY = '${IGN_API_KEY}'/g" /dbchiro/config.py
+else
+ echo "config file already exists"
+fi
+rm -f /app/dbchiro/settings/configuration/config.py
+ln -s /dbchiro/config.py /app/dbchiro/settings/configuration/config.py
+
+
+djapps="accounts blog dicts geodata management sights"
+if [ ! -d /dbchiro/migrations ]; then
+ echo "Create symlink for migrations dirs"
+ mkdir /dbchiro/migrations
+ for a in $djapps; do
+ echo "create $a migrations symlink"
+ if [ ! -d /dbchiro/migrations/$a ]; then
+ mkdir /dbchiro/migrations/$a
+ else
+ "$a migration dir and symlink already exists"
+ fi
+ done
+else
+ echo "Migrations dir already exists"
+fi
+
+for a in $djapps; do
+ rm -rf /app/$a/migrations
+ ln -s /dbchiro/migrations/$a /app/$a/migrations
+done
+
+if [ ! -d /dbchiro/media ]; then
+ echo "Create media dir"
+ mkdir /dbchiro/media
+else
+ echo "Media dir already exusts"
+fi
+
+rm -rf /app/media
+ln -s /dbchiro/media /app/media
+
+until pg_isready -h $DBHOST -p $DBPORT
+do
+ echo "Awaiting Database container"
+ sleep 1
+done
+sleep 2
+
+cd /app
+
+chown -R www-data:www-data /app
+
+export DJANGO_SETTINGS_MODULE=dbchiro.settings.$SETTINGS
+
+echo "************ Init database ****************"
+
+python3 -m manage makemigrations accounts core blog dicts geodata management sights
+python3 -m manage migrate
+python3 -m manage collectstatic --noinput
+
+
+if [ ! -f /dbchiro/logo_site.png ]; then
+ echo "Create default site logo image"
+ cp /app/static/img/logo_site.png.sample /dbchiro/logo_site.png
+else
+ echo "Site logo already exists"
+fi
+rm -f /app/static/img/logo_site.png
+ln -s /dbchiro/logo_site.png /app/static/img/logo_site.png
+
+echo "************** Create dbChiro SU ******************"
+
+script="
+from accounts.models import Profile;
+
+username = '$SU_USERNAME';
+password = '$SU_PWD';
+email = '$SU_EMAIL';
+
+if Profile.objects.filter(username=username).count()==0:
+ superuser=Profile.objects.create_user(username, email, password);
+ superuser.is_superuser=True;
+ superuser.save();
+ print('Superuser',username,'created.');
+else:
+ print('Superuser creation skipped.')
+"
+printf "$script" | python3 manage.py shell
+
+
+echo "************** Populate with initial data ***************"
+
+export countdict=$(printf "from dicts.models import PlacePrecision; print(PlacePrecision.objects.count())" | python3 manage.py shell)
+
+if [ $countdict -eq 0 ]
+ then
+ echo "load dicts data"
+ python3 -m manage loaddata datas/dicts.json
+ rm -f datas/dicts.json
+ echo "dicts data loaded"
+ else
+ echo "dicts data already exists"
+fi
+
+export countterritory=$(printf "from geodata.models import Territory; print(Territory.objects.count())" | python3 manage.py shell)
+
+if [ $countterritory -eq 0 ]
+ then
+ echo "load geo datas, this may take a while..."
+ python3 -m manage loaddata datas/geodata.json.gz
+ rm -f datas/geodata.json.gz
+ echo "geo datas loaded"
+ else
+ echo "geo datas already exists"
+fi
+
+
+#nginx Conf
+echo "************ Configure NGINX ***************"
+rm -f /etc/nginx/conf.d/default.conf
+cp /app/dbchiro/settings/configuration/nginx_dbchiro.conf.sample /etc/nginx/conf.d/dbchiro.conf
+rm -rf /etc/nginx/sites-enabled/*
+sed -i "s/pathToApp/app/g" /etc/nginx/conf.d/dbchiro.conf
+#/etc/init.d/nginx restart
+nginx -g "daemon off;" &
+
+echo "************ Start Gunicorn ***************"
+gunicorn -b 127.0.0.1:8000 dbchiro.wsgi
+
+
--
GitLab
From 9131586cf6e55cba18921f1ebbc74b37ae32cd16 Mon Sep 17 00:00:00 2001
From: "fred.perso"
Date: Tue, 7 Jan 2020 23:06:59 +0100
Subject: [PATCH 4/9] Fix superuser creation skipped if superuser exists
---
accounts/models.py | 4 +-
accounts/tables.py | 54 ++-
accounts/urls.py | 6 +-
accounts/views.py | 20 +-
blog/urls.py | 2 +-
blog/views.py | 76 ++--
core/js.py | 2 +-
core/mixins.py | 4 +-
core/views.py | 12 +-
dbchiro/settings/helper/context_processors.py | 4 +-
dicts/admin.py | 4 +-
docker-entrypoint-ubuntu.sh | 4 +-
docker-entrypoint.sh | 6 +-
geodata/models.py | 12 +-
management/models.py | 49 +--
management/tables.py | 87 +++--
management/urls.py | 81 +++--
sights/countdetail/urls.py | 8 +-
sights/countdetail/views.py | 36 +-
sights/forms.py | 102 ++++--
sights/metaplace/urls.py | 16 +-
sights/mixins.py | 340 ++++++++++++------
sights/session/urls.py | 41 +--
sights/session/views.py | 36 +-
sights/urls.py | 12 +-
synthesis/urls.py | 4 +-
synthesis/views.py | 111 +++---
27 files changed, 664 insertions(+), 469 deletions(-)
diff --git a/accounts/models.py b/accounts/models.py
index 0b3a1465..288224e7 100755
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -82,9 +82,7 @@ class Profile(AbstractBaseUser, PermissionsMixin):
default=False, verbose_name=_("Peut éditer toutes les données")
)
catchauth = models.ManyToManyField(
- 'management.CatchAuth',
- blank=True,
- verbose_name=_("Authorisations de capture"),
+ "management.CatchAuth", blank=True, verbose_name=_("Authorisations de capture"),
)
organism = models.CharField(
max_length=255, blank=True, null=True, verbose_name=_("Organisme")
diff --git a/accounts/tables.py b/accounts/tables.py
index abb20271..17fd6c6b 100644
--- a/accounts/tables.py
+++ b/accounts/tables.py
@@ -6,7 +6,7 @@ from .models import Profile
class ProfileTable(tables.Table):
- ACTIONS = '''
+ ACTIONS = """
- '''
+ """
MODIFY_BY = """
{% if record.updated_by %}{{record.updated_by}}{% else %}{{ record.created_by }}{% endif %}
"""
- is_resp = tables.BooleanColumn(verbose_name=_('Responsable local'))
- access_all_data = tables.BooleanColumn(verbose_name=_('Peut tout lire'))
- edit_all_data = tables.BooleanColumn(verbose_name=_('Peut tout éditer'))
- mobile_phone = tables.Column(verbose_name=_('n° mobile'))
- home_phone = tables.Column(verbose_name=_('n° domicile'))
- email = tables.EmailColumn(verbose_name=_('@email'))
+ is_resp = tables.BooleanColumn(verbose_name=_("Responsable local"))
+ access_all_data = tables.BooleanColumn(verbose_name=_("Peut tout lire"))
+ edit_all_data = tables.BooleanColumn(verbose_name=_("Peut tout éditer"))
+ mobile_phone = tables.Column(verbose_name=_("n° mobile"))
+ home_phone = tables.Column(verbose_name=_("n° domicile"))
+ email = tables.EmailColumn(verbose_name=_("@email"))
actions = tables.TemplateColumn(
- ACTIONS, verbose_name="Actions", orderable=False, attrs={'th': {'style': 'width: 75px;'}})
- username = tables.LinkColumn('accounts:user_detail', args=[A('id')], accessor='username')
+ ACTIONS,
+ verbose_name="Actions",
+ orderable=False,
+ attrs={"th": {"style": "width: 75px;"}},
+ )
+ username = tables.LinkColumn(
+ "accounts:user_detail", args=[A("id")], accessor="username"
+ )
modify_by = tables.TemplateColumn(
- MODIFY_BY, verbose_name="Dernière modification", orderable=False)
+ MODIFY_BY, verbose_name="Dernière modification", orderable=False
+ )
last_login = tables.DateTimeColumn()
class Meta:
model = Profile
- template = 'table_bootstrap.html'
- attrs = {'class': 'table table-striped'}
+ template = "table_bootstrap.html"
+ attrs = {"class": "table table-striped"}
fields = (
- 'actions', 'username', 'email', 'first_name', 'last_name', 'organism', 'is_active', 'is_resp',
- 'access_all_data',
- 'edit_all_data', 'home_phone', 'mobile_phone', 'addr_city', 'last_login', 'modify_by',)
- exclude = ('id',)
+ "actions",
+ "username",
+ "email",
+ "first_name",
+ "last_name",
+ "organism",
+ "is_active",
+ "is_resp",
+ "access_all_data",
+ "edit_all_data",
+ "home_phone",
+ "mobile_phone",
+ "addr_city",
+ "last_login",
+ "modify_by",
+ )
+ exclude = ("id",)
diff --git a/accounts/urls.py b/accounts/urls.py
index 4c30a03f..4f9210a6 100644
--- a/accounts/urls.py
+++ b/accounts/urls.py
@@ -24,7 +24,11 @@ urlpatterns = [
path("/detail", UserDetail.as_view(), name="user_detail"),
path("myprofile/change_password", change_password, name="change_password"),
path("myprofile/detail", MyProfileDetail.as_view(), name="myprofile_detail"),
- path("myprofile/detail/export", MyProfileDetailExport.as_view(), name="myprofile_detail_export"),
+ path(
+ "myprofile/detail/export",
+ MyProfileDetailExport.as_view(),
+ name="myprofile_detail_export",
+ ),
path("myprofile/update", MyProfileUpdate.as_view(), name="myprofile_update"),
path("list", UserListView.as_view(), name="user_search"),
]
diff --git a/accounts/views.py b/accounts/views.py
index 890a37a4..786c70a2 100755
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -31,6 +31,7 @@ from .tables import ProfileTable
logger = logging.getLogger(__name__)
+
class UserCreate(ManageAccountAuthMixin, CreateView):
"""
User Creation View
@@ -185,9 +186,7 @@ class MyProfileUpdate(ManageMyAccountAuthMixin, UpdateView):
return super(MyProfileUpdate, self).form_valid(form)
def get_object(self):
- return get_user_model().objects.get(
- id=self.request.user.id
- ) # or request.POST
+ return get_user_model().objects.get(id=self.request.user.id) # or request.POST
def get_context_data(self, **kwargs):
context = super(MyProfileUpdate, self).get_context_data(**kwargs)
@@ -214,31 +213,30 @@ class UserDelete(ManageAccountAuthMixin, DeleteView):
class UserDetail(LoginRequiredMixin, DetailView):
model = get_user_model()
template_name = "accounts/profile.html"
-
+
+
class MyProfileDetail(LoginRequiredMixin, DetailView):
model = get_user_model()
template_name = "accounts/profile.html"
def get_object(self):
logger.info(self.request.user.id)
- return get_user_model().objects.get(
- id=self.request.user.id
- )
+ return get_user_model().objects.get(id=self.request.user.id)
+
-class MyProfileDetailExport(LoginRequiredMixin,DetailView, TemplateResponseMixin):
+class MyProfileDetailExport(LoginRequiredMixin, DetailView, TemplateResponseMixin):
model = get_user_model()
- content_type="text/plain; charset=utf-8"
+ content_type = "text/plain; charset=utf-8"
template_name = "accounts/personnal_data.txt"
def get_object(self):
logger.debug(self.request.user.id)
profile = get_user_model().objects.get(id=self.request.user.id)
dict = model_to_dict(profile)
- del dict['password']
+ del dict["password"]
return dict
-
@login_required()
def change_password(request):
"""
diff --git a/blog/urls.py b/blog/urls.py
index 68f8af61..b1218976 100755
--- a/blog/urls.py
+++ b/blog/urls.py
@@ -11,4 +11,4 @@ urlpatterns = [
path("actu/add", ActuCreate.as_view(), name="actu_create"),
path("actu//update", ActuUpdate.as_view(), name="actu_update"),
path("actu//delete", ActuDelete.as_view(), name="actu_delete"),
-]
\ No newline at end of file
+]
diff --git a/blog/views.py b/blog/views.py
index 469fb0da..2a4b2a50 100755
--- a/blog/views.py
+++ b/blog/views.py
@@ -19,10 +19,11 @@ from accounts.models import Profile
# model = Actu
#
+
class ActuCreate(BlogCreateAuthMixin, CreateView):
model = Actu
form_class = ActuForm
- template_name = 'normal_form.html'
+ template_name = "normal_form.html"
def form_valid(self, form):
form.instance.created_by = self.request.user
@@ -31,9 +32,11 @@ class ActuCreate(BlogCreateAuthMixin, CreateView):
def get_context_data(self, **kwargs):
context = super(ActuCreate, self).get_context_data(**kwargs)
- context['icon'] = 'fi-align-left'
- context['title'] = _('Ajout d\'une actualité')
- context['js'] = """
+ context["icon"] = "fi-align-left"
+ context["title"] = _("Ajout d'une actualité")
+ context[
+ "js"
+ ] = """
"""
return context
@@ -41,7 +44,7 @@ class ActuCreate(BlogCreateAuthMixin, CreateView):
class ActuUpdate(BlogModifyAuthMixin, UpdateView):
model = Actu
form_class = ActuForm
- template_name = 'normal_form.html'
+ template_name = "normal_form.html"
def form_valid(self, form):
form.instance.created_by = self.request.user
@@ -49,57 +52,64 @@ class ActuUpdate(BlogModifyAuthMixin, UpdateView):
def get_context_data(self, **kwargs):
context = super(ActuUpdate, self).get_context_data(**kwargs)
- context['icon'] = 'fi-align-left'
- context['title'] = _('Modification d\'une actualité')
- context['js'] = """
+ context["icon"] = "fi-align-left"
+ context["title"] = _("Modification d'une actualité")
+ context[
+ "js"
+ ] = """
"""
return context
class ActuDelete(BlogModifyAuthMixin, DeleteView):
model = Actu
- template_name = 'confirm_delete.html'
- success_url = reverse_lazy('blog:home')
+ template_name = "confirm_delete.html"
+ success_url = reverse_lazy("blog:home")
def get_context_data(self, **kwargs):
context = super(ActuDelete, self).get_context_data(**kwargs)
- context['icon'] = 'fi-trash'
- context['title'] = _('Suppression d\'une actualité')
- context['message_alert'] = _('Êtes-vous certain de vouloir supprimer l\'actualité')
+ context["icon"] = "fi-trash"
+ context["title"] = _("Suppression d'une actualité")
+ context["message_alert"] = _(
+ "Êtes-vous certain de vouloir supprimer l'actualité"
+ )
return context
class ActuDetail(DetailView):
model = Actu
- template_name = 'actu_detail.html'
+ template_name = "actu_detail.html"
def get_context_data(self, **kwargs):
context = super(ActuDetail, self).get_context_data(**kwargs)
- context['icon'] = 'fi-align-left'
- context['js'] = """
+ context["icon"] = "fi-align-left"
+ context[
+ "js"
+ ] = """
"""
return context
+
class ActuList(ListView):
model = Actu
- template_name = 'actu_list.html'
- ordering = '-timestamp_update'
+ template_name = "actu_list.html"
+ ordering = "-timestamp_update"
paginate_by = 3
def get_context_data(self, **kwargs):
context = super(ActuList, self).get_context_data(**kwargs)
- context['icon'] = 'fas fa-info-circle'
- context['title'] = _('Dernières actualités')
- context['sightingsicon'] = 'fi-eye'
- context['sightingscount'] = Sighting.objects.all().count()
- context['sightingstext'] = _('observations')
- context['placesicon'] = 'fi-marker'
- context['placescount'] = Place.objects.all().count()
- context['placestext'] = _('localités')
- context['sessionsicon'] = 'far fa-calendar-alt'
- context['sessionscount'] = Session.objects.all().count()
- context['sessionstext'] = _('sessions')
- context['observersicon'] = 'fi-torsos-all-female'
- context['observerscount'] = Profile.objects.all().count()
- context['observerstext'] = _('observateurs')
- return context
\ No newline at end of file
+ context["icon"] = "fas fa-info-circle"
+ context["title"] = _("Dernières actualités")
+ context["sightingsicon"] = "fi-eye"
+ context["sightingscount"] = Sighting.objects.all().count()
+ context["sightingstext"] = _("observations")
+ context["placesicon"] = "fi-marker"
+ context["placescount"] = Place.objects.all().count()
+ context["placestext"] = _("localités")
+ context["sessionsicon"] = "far fa-calendar-alt"
+ context["sessionscount"] = Session.objects.all().count()
+ context["sessionstext"] = _("sessions")
+ context["observersicon"] = "fi-torsos-all-female"
+ context["observerscount"] = Profile.objects.all().count()
+ context["observerstext"] = _("observateurs")
+ return context
diff --git a/core/js.py b/core/js.py
index 43bbbdf8..f8a8c001 100644
--- a/core/js.py
+++ b/core/js.py
@@ -46,4 +46,4 @@ TimeInput = """
format: 'HH:mm'
});
});
-"""
\ No newline at end of file
+"""
diff --git a/core/mixins.py b/core/mixins.py
index 217d9b77..def6a17a 100644
--- a/core/mixins.py
+++ b/core/mixins.py
@@ -2,7 +2,7 @@
Mixins
"""
-from django.contrib.auth.mixins import LoginRequiredMixin,UserPassesTestMixin
+from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class ManageAccountAuthMixin:
@@ -29,8 +29,6 @@ class ManageAccountAuthMixin:
return redirect("core:view_unauth")
-
-
class AdminRequiredMixin(LoginRequiredMixin, UserPassesTestMixin):
def test_func(self):
return self.request.user.is_superuser or self.request.user.is_staff
diff --git a/core/views.py b/core/views.py
index 80435c57..16aa1efa 100644
--- a/core/views.py
+++ b/core/views.py
@@ -5,15 +5,18 @@ from .mixins import AdminRequiredMixin
from .functions import version
import os
+
def db_datas():
with connection.cursor() as cursor:
- cursor.execute("SELECT pg_size_pretty( pg_database_size( current_database() ) ), version(), postgis_version()")
+ cursor.execute(
+ "SELECT pg_size_pretty( pg_database_size( current_database() ) ), version(), postgis_version()"
+ )
row = cursor.fetchone()
print(row)
data = {}
- data['database_size']= row[0]
- data['database_pg_version'] = row[1]
- data['database_postgis_version'] = row[2]
+ data["database_size"] = row[0]
+ data["database_pg_version"] = row[1]
+ data["database_postgis_version"] = row[2]
return data
@@ -49,4 +52,3 @@ class SystemInformation(AdminRequiredMixin, TemplateView):
sysinfo = {**server_info, **db_datas()}
context["sysinfo"] = sysinfo
return context
-
diff --git a/dbchiro/settings/helper/context_processors.py b/dbchiro/settings/helper/context_processors.py
index abb276d6..ac125454 100755
--- a/dbchiro/settings/helper/context_processors.py
+++ b/dbchiro/settings/helper/context_processors.py
@@ -5,6 +5,6 @@ from core.functions import version
def site_info(request):
"""Return SITE NAME to frontend"""
return {
- 'SITE_NAME': settings.SITE_NAME,
- 'VERSION' : version(),
+ "SITE_NAME": settings.SITE_NAME,
+ "VERSION": version(),
}
diff --git a/dicts/admin.py b/dicts/admin.py
index 5ed939b0..9bba9550 100755
--- a/dicts/admin.py
+++ b/dicts/admin.py
@@ -14,10 +14,10 @@ class CustomApp(AppConfig):
name = "dicts"
def ready(self):
- models = apps.get_app_config('dicts').get_models()
+ models = apps.get_app_config("dicts").get_models()
for model in models:
admin_class = type("AdminClass", (ListAdminMixin, admin.ModelAdmin), {})
try:
admin.site.register(model, admin_class)
except admin.sites.AlreadyRegistered as e:
- pass
\ No newline at end of file
+ pass
diff --git a/docker-entrypoint-ubuntu.sh b/docker-entrypoint-ubuntu.sh
index 8c150769..53c97455 100755
--- a/docker-entrypoint-ubuntu.sh
+++ b/docker-entrypoint-ubuntu.sh
@@ -145,13 +145,13 @@ username = '$SU_USERNAME';
password = '$SU_PWD';
email = '$SU_EMAIL';
-if Profile.objects.filter(username=username).count()==0:
+if Profile.objects.filter(is_superuser=True).count()==0:
superuser=Profile.objects.create_user(username, email, password);
superuser.is_superuser=True;
superuser.save();
print('Superuser',username,'created.');
else:
- print('Superuser creation skipped.')
+ print('One or more Superuser already exists, creation skipped.')
"
printf "$script" | python3 manage.py shell
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
index 1bd1ea1e..813ef746 100755
--- a/docker-entrypoint.sh
+++ b/docker-entrypoint.sh
@@ -101,7 +101,7 @@ if [ ! -d /dbchiro/media ]; then
echo "Create media dir"
mkdir /dbchiro/media
else
- echo "Media dir already exusts"
+ echo "Media dir already exists"
fi
rm -rf /app/media
@@ -145,13 +145,13 @@ username = '$SU_USERNAME';
password = '$SU_PWD';
email = '$SU_EMAIL';
-if Profile.objects.filter(username=username).count()==0:
+if Profile.objects.filter(is_superuser=True).count()==0:
superuser=Profile.objects.create_user(username, email, password);
superuser.is_superuser=True;
superuser.save();
print('Superuser',username,'created.');
else:
- print('Superuser creation skipped.')
+ print('One or more Superuser already exists, creation skipped.')
"
printf "$script" | python manage.py shell
diff --git a/geodata/models.py b/geodata/models.py
index 551cba32..0872e863 100755
--- a/geodata/models.py
+++ b/geodata/models.py
@@ -52,11 +52,14 @@ class Municipality(models.Model):
class LandCover(models.Model):
id = models.AutoField(primary_key=True)
code = models.ForeignKey(
- LandCoverCLC, verbose_name=_("Code"), blank=True, null=True, on_delete=models.CASCADE)
+ LandCoverCLC,
+ verbose_name=_("Code"),
+ blank=True,
+ null=True,
+ on_delete=models.CASCADE,
+ )
geom = models.MultiPolygonField(
- srid=settings.GEODATA_SRID,
- verbose_name=_("Géométries"),
- spatial_index=True,
+ srid=settings.GEODATA_SRID, verbose_name=_("Géométries"), spatial_index=True,
)
def __str__(self):
@@ -75,4 +78,3 @@ class Elevation(models.Model):
class Meta:
verbose_name = _("Altitude")
-
diff --git a/management/models.py b/management/models.py
index b6d06fa6..ba81cffd 100755
--- a/management/models.py
+++ b/management/models.py
@@ -15,17 +15,13 @@ class CatchAuth(models.Model):
related_name="catchauth",
)
date_start = models.DateField(
- verbose_name=_("Date de début d'application"),
- help_text=_("format jj/mm/aaaa"),
+ verbose_name=_("Date de début d'application"), help_text=_("format jj/mm/aaaa"),
)
date_end = models.DateField(
- verbose_name=_("Date de fin d'application"),
- help_text=_("format jj/mm/aaaa"),
+ verbose_name=_("Date de fin d'application"), help_text=_("format jj/mm/aaaa"),
)
official_reference = models.CharField(
- max_length=255,
- unique=True,
- verbose_name=_("Référence du texte officiel"),
+ max_length=255, unique=True, verbose_name=_("Référence du texte officiel"),
)
file = models.FileField(
upload_to="catchauth/%Y/",
@@ -42,7 +38,7 @@ class CatchAuth(models.Model):
db_index=True,
editable=False,
related_name="catchauth_creator",
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
@@ -51,7 +47,7 @@ class CatchAuth(models.Model):
db_index=True,
editable=False,
related_name="catchauth_modifier",
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
def __str__(self):
@@ -75,9 +71,7 @@ class Study(models.Model):
max_length=255, db_index=True, verbose_name="nom du l'étude"
)
year = models.CharField(
- max_length=10,
- db_index=True,
- verbose_name="Année de réalisation l'étude",
+ max_length=10, db_index=True, verbose_name="Année de réalisation l'étude",
)
project_manager = models.ForeignKey(
settings.AUTH_USER_MODEL,
@@ -86,7 +80,7 @@ class Study(models.Model):
related_name="study",
null=True,
blank=True,
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
# study_organism = models.ForeignKey(
# 'Organism',
@@ -111,9 +105,7 @@ class Study(models.Model):
type_espace = models.CharField(
max_length=255, blank=True, null=True, verbose_name="Type d'espace"
)
- comment = models.TextField(
- blank=True, null=True, verbose_name="Commentaire"
- )
+ comment = models.TextField(blank=True, null=True, verbose_name="Commentaire")
timestamp_create = models.DateTimeField(auto_now_add=True, editable=False)
timestamp_update = models.DateTimeField(auto_now=True, editable=False)
created_by = models.ForeignKey(
@@ -123,7 +115,7 @@ class Study(models.Model):
db_index=True,
editable=False,
related_name="study_creator",
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
@@ -132,7 +124,7 @@ class Study(models.Model):
db_index=True,
editable=False,
related_name="study_modifier",
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
def __str__(self):
@@ -170,9 +162,7 @@ class Transmitter(models.Model):
max_length=30, unique=True, null=True, verbose_name="Référence"
)
frequency = models.FloatField(null=True, verbose_name="Fréquence en MHz")
- weight = models.FloatField(
- null=True, blank=True, verbose_name="Poids (en grammes)"
- )
+ weight = models.FloatField(null=True, blank=True, verbose_name="Poids (en grammes)")
autonomy = models.FloatField(
null=True, blank=True, verbose_name="Autonomie (en jours)"
)
@@ -185,24 +175,17 @@ class Transmitter(models.Model):
owner = models.CharField(
max_length=100, null=True, blank=True, verbose_name="Propriétaire"
)
- buying_date = models.DateField(
- null=True, blank=True, verbose_name="Date d'achat"
- )
+ buying_date = models.DateField(null=True, blank=True, verbose_name="Date d'achat")
last_recond_date = models.DateField(
null=True, blank=True, verbose_name="Date de dernier reconditionnement"
)
status = models.CharField(
- max_length=50,
- choices=TRANSMITTER_STATUS,
- default="ok",
- verbose_name="Statut",
+ max_length=50, choices=TRANSMITTER_STATUS, default="ok", verbose_name="Statut",
)
available = models.BooleanField(
verbose_name="Disponible pour la saisie", default=True
)
- comment = models.TextField(
- blank=True, null=True, verbose_name="Commentaire"
- )
+ comment = models.TextField(blank=True, null=True, verbose_name="Commentaire")
timestamp_create = models.DateTimeField(auto_now_add=True, editable=False)
timestamp_update = models.DateTimeField(auto_now=True, editable=False)
created_by = models.ForeignKey(
@@ -212,7 +195,7 @@ class Transmitter(models.Model):
db_index=True,
editable=False,
related_name="transmitter_creator",
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
updated_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
@@ -221,7 +204,7 @@ class Transmitter(models.Model):
db_index=True,
editable=False,
related_name="transmitter_modifier",
- on_delete=models.SET_NULL
+ on_delete=models.SET_NULL,
)
def __str__(self):
diff --git a/management/tables.py b/management/tables.py
index 1022552d..3caf985f 100644
--- a/management/tables.py
+++ b/management/tables.py
@@ -4,7 +4,7 @@ from .models import Study, Transmitter, CatchAuth
class StudyTable(tables.Table):
- ACTIONS = '''
+ ACTIONS = """
- '''
- actions = tables.TemplateColumn(
- ACTIONS, verbose_name="Actions", orderable=False)
+ """
+ actions = tables.TemplateColumn(ACTIONS, verbose_name="Actions", orderable=False)
class Meta:
model = Study
- template = 'table_bootstrap.html'
- attrs = {'class': 'table table-striped table-condensed'}
- fields = ('actions', 'name', 'year', 'project_manager', 'type_etude', 'type_espace',
- 'public_funding', 'public_report', 'public_raw_data', 'confidential', 'confidential_end_data',
- 'timestamp_create', 'timestamp_update', 'created_by', 'comment')
+ template = "table_bootstrap.html"
+ attrs = {"class": "table table-striped table-condensed"}
+ fields = (
+ "actions",
+ "name",
+ "year",
+ "project_manager",
+ "type_etude",
+ "type_espace",
+ "public_funding",
+ "public_report",
+ "public_raw_data",
+ "confidential",
+ "confidential_end_data",
+ "timestamp_create",
+ "timestamp_update",
+ "created_by",
+ "comment",
+ )
class TransmitterTable(tables.Table):
- ACTIONS = '''
+ ACTIONS = """
- '''
- COMMENT = '''
+ """
+ COMMENT = """
{% if record.comment %}
';
layer.bindPopup(content);
}
- }).addTo(map).bringToBack();
+ ,
+ pointToLayer: function (feature, latlng) {
+ // Set a different color if location is in a metaplace
+ if (feature.properties.metaplace_data) {
+ return L.circleMarker(latlng, style_data_metasite);
+ }
+ return L.circleMarker(latlng, style_data);
+ }
+ });
+ markers.addLayer(locationLayer).addTo(searchMap).bringToFront();
+ searchMap.fitBounds(locationLayer.getBounds());
})
.then(function () {
- map.spin(false);
- })
- .catch(function (error) {
- console.log(error);
+ searchMap.spin(false);
});
+ };
- // Download GeoJSON data with Ajax
- const loadPlaces = function () {
- fetch(dataUrl, {
- credentials: "include"
- })
- .then(function (resp) {
- return resp.json();
- })
- .then(function (data) {
- markers.clearLayers();
- var locationLayer = L.geoJson(data, {
- onEachFeature: function onEachFeature(feature, layer) {
- var props = feature.properties;
- var content = '' + props.name + '
- Type: ' + (props.type_data ? props.type_data.descr : "Non défini") + '
- Nombre de sessions ' + (props.total_sessions ? props.total_sessions : "Aucune") + ' (Dernière: ' + (props.last_session ? props.last_session.date_start__max : "Aucune") + ')
';
- layer.bindPopup(content);
- }
- ,
- pointToLayer: function (feature, latlng) {
- // Set a different color if location is in a metaplace
- if (feature.properties.metaplace_data) {
- return L.circleMarker(latlng, style_data_metasite);
- }
- return L.circleMarker(latlng, style_data);
- }
- });
- markers.addLayer(locationLayer).addTo(map).bringToFront();
- map.fitBounds(locationLayer.getBounds());
- })
- .then(function () {
- map.spin(false);
- });
- };
-
- $("input[type='radio'], input[type='checkbox']").on("click", loadPlaces);
- $("input[type='select'], input[type='text'], input[type='number'], input[type='date'],select").on("change", loadPlaces);
- loadPlaces();
-
- var handler = function (e) {
- var position = e.currentTarget.getAttribute('data-position');
- console.log('position : ' + position);
- var zoom = e.currentTarget.getAttribute('data-zoom');
- console.log('zoom : ' + zoom);
- if (position && zoom) {
- console.log('if position && zoom');
- var location = position.replace(/,/g, '.').split('-');
- console.log('location : ' + location);
- if (circlemarker !== null) {
- map.removeLayer(circlemarker);
- }
- // var marker = L.marker(location).addTo(map);
- circlemarker = new L.circleMarker(location,
- {
- radius: 20,
- color: 'red',
- fillColor: 'transparent',
- })
- .addTo(map)
- // .bindPopup('lien')
- // .openPopup()
- ;
- console.log('circlemarker');
- map.setView(location, 15, {
- animation: true,
- });
- console.log('zoom')
+ var handler = function (e) {
+ var position = e.currentTarget.getAttribute('data-position');
+ console.log('position : ' + position);
+ var zoom = e.currentTarget.getAttribute('data-zoom');
+ console.log('zoom : ' + zoom);
+ if (position && zoom) {
+ console.log('if position && zoom');
+ var location = position.replace(/,/g, '.').split('-');
+ console.log('location : ' + location);
+ if (circlemarker !== null) {
+ searchMap.removeLayer(circlemarker);
}
- };
-
- var elements = document.getElementsByClassName('map-navigation');
+ // var marker = L.marker(location).addTo(map);
+ circlemarker = new L.circleMarker(location,
+ {
+ radius: 20,
+ color: 'red',
+ fillColor: 'transparent',
+ })
+ .addTo(searchMap)
+ // .bindPopup('lien')
+ // .openPopup()
+ ;
+ console.log('circlemarker');
+ searchMap.setView(location, 15, {
+ animation: true,
+ });
+ console.log('zoom')
- for (var i = 0; i < elements.length; i++) {
- elements[i].onclick = handler;
}
+ };
+ var elements = document.getElementsByClassName('map-navigation');
+
+ for (var i = 0; i < elements.length; i++) {
+ elements[i].onclick = handler;
+ }
- });
function showValues() {
var str = $('#searchForm input').map(function () {
@@ -459,6 +469,7 @@
$("#results").text(str);
dataUrl = "/place/api/search?format=json&" + str;
table.ajax.url(dataUrl).load();
+ loadPlaces();
};
$("input[type='radio'], input[type='checkbox']").on("click", showValues);
@@ -490,11 +501,14 @@
{% endif %}
+ {# #}
+ {# {% leaflet_map "main" %}#}
+ {#
#}
- {% leaflet_map "main" %}
+
-
{% endblock %}
\ No newline at end of file
--
GitLab
From d530b272be1c486f0f954fefa2306dfe1ba29ce1 Mon Sep 17 00:00:00 2001
From: "fred.perso"
Date: Tue, 21 Jan 2020 00:55:18 +0100
Subject: [PATCH 7/9] searches improvements
---
dbchiro/settings/base.py | 2 -
sights/filters.py | 6 +-
sights/forms.py | 12 +-
sights/place/api.py | 7 +
sights/place/views.py | 28 +-
templates/main/footer.html | 2 +-
templates/sights/place_search.html | 104 ++++----
templates/sights/sighting_search.html | 368 +++++++++++++-------------
8 files changed, 268 insertions(+), 261 deletions(-)
diff --git a/dbchiro/settings/base.py b/dbchiro/settings/base.py
index 3c712883..89dda3d0 100755
--- a/dbchiro/settings/base.py
+++ b/dbchiro/settings/base.py
@@ -210,7 +210,6 @@ AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
]
-
# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/
@@ -337,6 +336,5 @@ AUTHENTICATION_BACKENDS = ("django.contrib.auth.backends.ModelBackend",) # defa
INTERNAL_IPS = "127.0.0.1"
-
IMAGE_FILE_TYPES = ["png", "jpg", "jpeg"]
DOCUMENT_FILE_TYPES = ["doc", "docx", "odt", "pdf", "xls", "csv", "xlsx", "ods"]
diff --git a/sights/filters.py b/sights/filters.py
index 1f086b33..3f96e666 100755
--- a/sights/filters.py
+++ b/sights/filters.py
@@ -12,9 +12,9 @@ class PlaceFilter(django_filters.FilterSet):
label=_("Nom de la localité"), lookup_expr="icontains"
)
municipality = django_filters.CharFilter(
- label=_("Commune"),
- widget=autocomplete.ListSelect2(
- url="api:municipality_autocomplete", attrs={"class": "listselect2"}
+ label=_("Zonage"),
+ widget=autocomplete.Select2Multiple(
+ url="api:area_autocomplete", attrs={"class": "listselect2"}
),
)
territory = django_filters.CharFilter(
diff --git a/sights/forms.py b/sights/forms.py
index 1c7f6b58..13427e47 100755
--- a/sights/forms.py
+++ b/sights/forms.py
@@ -288,9 +288,10 @@ class PlaceSearchFilterForm(forms.Form):
class PlaceSearchAdvancedFilterForm(forms.Form):
- # class Meta:
- # widgets = {'territory': autocomplete.ListSelect2(url='api:territory_autocomplete'),
- # 'municipality': autocomplete.ListSelect2(url='api:municipality_autocomplete')}
+ class Meta:
+ widgets = {
+ "area": autocomplete.Select2Multiple(url="api:area_autocomplete"),
+ }
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
@@ -298,11 +299,10 @@ class PlaceSearchAdvancedFilterForm(forms.Form):
self.helper.layout = Layout(
Row(
- Column("name", css_class="col-sm-12 col-md-4"),
+ Column("area", css_class="col-sm-12 col-md-4"),
Column("type", css_class="col-sm-12 col-md-4"),
Column("metaplace", css_class="col-sm-12 col-md-4"),
- Column("municipality", css_class="col-sm-12 col-md-6 col-lg-6"),
- Column("territory", css_class="col-sm-12 col-md-6 col-lg-6"),
+ Column("is_gite", css_class="col-sm-12 col-md-4"),
),
Submit("submit", _("Rechercher"), css_class="btn-primary btn-sm"),
)
diff --git a/sights/place/api.py b/sights/place/api.py
index e64da9cb..c76eb960 100644
--- a/sights/place/api.py
+++ b/sights/place/api.py
@@ -33,6 +33,7 @@ class GeoJSONPlaces(LoginRequiredMixin, CountModelMixin, generics.ListAPIView):
metaplace = self.request.query_params.get("metaplace", None)
convention = self.request.query_params.get("convention", None)
managed = self.request.query_params.get("managed", None)
+ creator = self.request.query_params.get("creator", None)
qs = Place.objects.order_by("-timestamp_create")
@@ -69,6 +70,12 @@ class GeoJSONPlaces(LoginRequiredMixin, CountModelMixin, generics.ListAPIView):
qs = qs.filter(convention=True)
if managed is not None:
qs = qs.filter(is_managed=True)
+ if creator is not None:
+ qs = qs.filter(
+ Q(created_by__first_name__icontains=creator)
+ | Q(created_by__last_name__icontains=creator)
+ | Q(created_by__username__icontains=creator)
+ )
if user.access_all_data:
logger.debug("Chargement de la carte pour l'utilisateur avec accès total")
diff --git a/sights/place/views.py b/sights/place/views.py
index 26d5512c..ead9ee5f 100644
--- a/sights/place/views.py
+++ b/sights/place/views.py
@@ -631,21 +631,28 @@ class PlaceList(LoginRequiredMixin, TemplateView):
return context
-class PlaceMyList(LoginRequiredMixin, FilterView, ExportMixin, SingleTableView):
- table_class = PlaceTable
- model = Place
+class PlaceList(LoginRequiredMixin, TemplateView):
template_name = "sights/place_search.html"
- table_pagination = {"per_page": 15}
- filterset_class = PlaceFilter
+ def get_context_data(self, **kwargs):
+ context = super(PlaceList, self).get_context_data(**kwargs)
+ context["icon"] = "fa fa-fw fa-map"
+ context["title"] = _("Rechercher une localité")
+ context["createplacebtn"] = True
+ context[
+ "js"
+ ] = """
+ """
+ context["dataUrl"] = "/place/api/search?format=json"
+ return context
- def get_queryset(self):
- loggeduser = self.request.user
- user = get_user_model().objects.get(id=loggeduser.id)
- new_context = Place.objects.filter(created_by=user)
- return new_context
+
+class PlaceMyList(LoginRequiredMixin, TemplateView):
+ template_name = "sights/place_search.html"
def get_context_data(self, **kwargs):
+ logged_user = self.request.user
+ user = get_user_model().objects.get(id=logged_user.id)
context = super(PlaceMyList, self).get_context_data(**kwargs)
context["icon"] = "fa fa-fw fa-map"
context["title"] = _("Rechercher dans mes localités")
@@ -653,6 +660,7 @@ class PlaceMyList(LoginRequiredMixin, FilterView, ExportMixin, SingleTableView):
"js"
] = """
"""
+ context["dataUrl"] = "/place/api/search?format=json&creator=" + user.username
return context
diff --git a/templates/main/footer.html b/templates/main/footer.html
index e8af2b6e..0a70d07f 100755
--- a/templates/main/footer.html
+++ b/templates/main/footer.html
@@ -13,7 +13,7 @@
dbchiro.org
{% if filter %}
diff --git a/templates/sights/sighting_search.html b/templates/sights/sighting_search.html
index d8407cc8..2fd5a2c9 100644
--- a/templates/sights/sighting_search.html
+++ b/templates/sights/sighting_search.html
@@ -35,6 +35,11 @@
border-radius: 50%;
}
+ #searchMap {
+ height: 800px;
+ min-height: 800px;
+ }
+