territories-dashboard-lib 0.1.10__py3-none-any.whl → 0.1.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of territories-dashboard-lib might be problematic. Click here for more details.

@@ -0,0 +1,35 @@
1
+ import os
2
+ from functools import lru_cache
3
+
4
+ import geoip2.database
5
+
6
+
7
+ def _get_client_ip(request):
8
+ x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
9
+ if x_forwarded_for:
10
+ ip = x_forwarded_for.split(",")[0]
11
+ else:
12
+ ip = request.META.get("REMOTE_ADDR")
13
+ return ip
14
+
15
+
16
+ @lru_cache(maxsize=100_000)
17
+ def _get_country_from_geolite(ip_address):
18
+ database_name = "GeoLite2-Country.mmdb"
19
+ database_path = os.path.join(os.path.dirname(__file__), database_name)
20
+ reader = geoip2.database.Reader(database_path)
21
+ try:
22
+ response = reader.country(ip_address)
23
+ country = response.country.iso_code
24
+ except geoip2.errors.AddressNotFoundError:
25
+ country = "UNKNOWN"
26
+ reader.close()
27
+ return country
28
+
29
+
30
+ def get_country_of_ip(request):
31
+ """
32
+ Guess the country of an ip thanks to the geoip2 library and the Geolite mmdb database file.
33
+ """
34
+ ip_address = _get_client_ip(request)
35
+ return _get_country_from_geolite(ip_address)
@@ -6,7 +6,10 @@ from django.http import HttpRequest, HttpResponse
6
6
  from django.urls import resolve
7
7
 
8
8
  from territories_dashboard_lib.tracking_lib.enums import TRACKING_COOKIE_NAME, EventType
9
- from territories_dashboard_lib.tracking_lib.models import Event, Page
9
+ from territories_dashboard_lib.tracking_lib.geolocalisation.logic import (
10
+ get_country_of_ip,
11
+ )
12
+ from territories_dashboard_lib.tracking_lib.models import CookieInfo, Event, Page
10
13
 
11
14
  if TYPE_CHECKING:
12
15
  from territories_dashboard_lib.indicators_lib.models import Indicator, Theme
@@ -21,6 +24,11 @@ def get_or_set_tracking_cookie(request: HttpRequest, response: HttpResponse) ->
21
24
  value=tracking_cookie,
22
25
  max_age=timedelta(days=365),
23
26
  )
27
+ try:
28
+ CookieInfo.objects.get(id=tracking_cookie)
29
+ except CookieInfo.DoesNotExist:
30
+ country = get_country_of_ip(request)
31
+ CookieInfo.objects.create(id=tracking_cookie, country=country)
24
32
  return tracking_cookie
25
33
 
26
34
 
@@ -0,0 +1,24 @@
1
+ # Generated by Django 5.2.3 on 2025-06-26 12:58
2
+
3
+ import django.utils.timezone
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('tracking_lib', '0001_initial'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AlterField(
15
+ model_name='event',
16
+ name='created_at',
17
+ field=models.DateTimeField(default=django.utils.timezone.now),
18
+ ),
19
+ migrations.AlterField(
20
+ model_name='page',
21
+ name='created_at',
22
+ field=models.DateTimeField(default=django.utils.timezone.now),
23
+ ),
24
+ ]
@@ -0,0 +1,20 @@
1
+ # Generated by Django 5.1.6 on 2025-06-30 12:50
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('tracking_lib', '0002_alter_event_created_at_alter_page_created_at'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.CreateModel(
14
+ name='CookieInfo',
15
+ fields=[
16
+ ('id', models.TextField(primary_key=True, serialize=False)),
17
+ ('country', models.TextField(blank=True, null=True)),
18
+ ],
19
+ ),
20
+ ]
@@ -1,4 +1,5 @@
1
1
  from django.db import models
2
+ from django.utils import timezone
2
3
 
3
4
  from territories_dashboard_lib.indicators_lib.enums import MeshLevel
4
5
  from territories_dashboard_lib.tracking_lib.enums import EventType
@@ -10,7 +11,7 @@ class Page(models.Model):
10
11
  À chaque changement de paramètre (territoire, maille, territoire de comparaison) une nouvelle vue est enregistrée.
11
12
  """
12
13
 
13
- created_at = models.DateTimeField(auto_now_add=True)
14
+ created_at = models.DateTimeField(default=timezone.now)
14
15
  cookie = models.TextField(
15
16
  help_text="Un cookie sans durée d'expiration est placé dans chaque nouvelle session, il possède une valeur aléatoire qui permet de tracer le navigateur du visiteur entre plusieurs visites."
16
17
  )
@@ -69,7 +70,7 @@ class Event(models.Model):
69
70
  Tracking des autres événements de l'application
70
71
  """
71
72
 
72
- created_at = models.DateTimeField(auto_now_add=True)
73
+ created_at = models.DateTimeField(default=timezone.now)
73
74
  cookie = models.TextField(
74
75
  help_text="Un cookie sans durée d'expiration est placé dans chaque nouvelle session, il possède une valeur aléatoire qui permet de tracer le navigateur du visiteur entre plusieurs visites."
75
76
  )
@@ -77,3 +78,8 @@ class Event(models.Model):
77
78
  data = models.JSONField(null=True, blank=True)
78
79
  url = models.TextField(help_text="URL brut de la page")
79
80
  view = models.TextField(help_text="Nom de la vue dans Django")
81
+
82
+
83
+ class CookieInfo(models.Model):
84
+ id = models.TextField(primary_key=True)
85
+ country = models.TextField(null=True, blank=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: territories-dashboard-lib
3
- Version: 0.1.10
3
+ Version: 0.1.12
4
4
  Summary: Librairie pour la visualisation d'indicateurs territoriaux.
5
5
  Author-email: Bastien <bastien@prune.sh>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -11,6 +11,17 @@ Classifier: Topic :: Software Development :: Libraries
11
11
  Requires-Python: >=3.13
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: licence.md
14
+ Requires-Dist: django>=5.1.6
15
+ Requires-Dist: django-nested-admin>=4.1.1
16
+ Requires-Dist: geoip2>=5.1.0
17
+ Requires-Dist: gunicorn>=23.0.0
18
+ Requires-Dist: ipython>=8.32.0
19
+ Requires-Dist: martor>=1.6.45
20
+ Requires-Dist: pre-commit>=4.2.0
21
+ Requires-Dist: psycopg2-binary>=2.9.10
22
+ Requires-Dist: pydantic>=2.10.6
23
+ Requires-Dist: pydantic-settings>=2.7.1
24
+ Requires-Dist: whitenoise>=6.9.0
14
25
  Dynamic: license-file
15
26
 
16
27
  # Tableau de bord des indicateurs territoriaux
@@ -44,12 +44,16 @@ territories_dashboard_lib/superset_lib/migrations/0001_initial.py,sha256=Y6iY33E
44
44
  territories_dashboard_lib/superset_lib/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
45
  territories_dashboard_lib/tracking_lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  territories_dashboard_lib/tracking_lib/enums.py,sha256=-w2ndwXfY8PqElJvO7i_MVMAP_95QYoQ8NZGjoGgHAM,443
47
- territories_dashboard_lib/tracking_lib/logic.py,sha256=9kr3Q1dwRfkNB1mWq3EQd5KViziZ6ur0lyFVVMIuhGY,2507
48
- territories_dashboard_lib/tracking_lib/models.py,sha256=hvB5gu3o-zZH2hjUsRf_8YF57XkVqQSsnTjSOWRoGIY,3110
47
+ territories_dashboard_lib/tracking_lib/logic.py,sha256=GXqQoE1e3P-QtMEwQIgL16F3fhDZ-5I0nwDFhW2fOjg,2831
48
+ territories_dashboard_lib/tracking_lib/models.py,sha256=pFW45xqhraQ49B9EX-ADHXKkk5HEZygYRwDnEmX1CCg,3282
49
49
  territories_dashboard_lib/tracking_lib/payloads.py,sha256=iX0uUxAKEOmYe8nKJATu52zqFTdCzzxxgE5FuTOBpj8,201
50
50
  territories_dashboard_lib/tracking_lib/urls.py,sha256=-Wd2EYQRLimUQHswTu8x_23movgzYH2ZPG5dbOAaCNI,202
51
51
  territories_dashboard_lib/tracking_lib/views.py,sha256=8K1q9LfpU1ygO3CFQSPN5_gLIMWkVe9kN0kuIdiKEjQ,1298
52
+ territories_dashboard_lib/tracking_lib/geolocalisation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ territories_dashboard_lib/tracking_lib/geolocalisation/logic.py,sha256=BbwGMXtnJAPzAJ9RrsfTuMqc3jHR072uD70b1si0e0M,987
52
54
  territories_dashboard_lib/tracking_lib/migrations/0001_initial.py,sha256=eH6eegaxN6LuSerZ80_N8iXixF6-YKw79nqmIPimXPY,3494
55
+ territories_dashboard_lib/tracking_lib/migrations/0002_alter_event_created_at_alter_page_created_at.py,sha256=rC0_09acozzUXkujPG0fs3wcenjAmqy4rS5SK17Anjo,615
56
+ territories_dashboard_lib/tracking_lib/migrations/0003_cookieinfo.py,sha256=To1I_see_Aw66P6I67a0PQQntZ2Iw7a3G0P9O236L0A,521
53
57
  territories_dashboard_lib/tracking_lib/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
58
  territories_dashboard_lib/website_lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
59
  territories_dashboard_lib/website_lib/admin.py,sha256=jq0KgN8CPVqJQ1IMq8kaoWqqxzpPDyW0z7cTatmrmi0,952
@@ -148,8 +152,8 @@ territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/websit
148
152
  territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/svg/delete-back.svg,sha256=fJPjkZT2jdTcW2nmwr7YtBayOmQKOxiGNyO8bM8jP2U,618
149
153
  territories_dashboard_lib/website_lib/templatetags/htmlparams.py,sha256=jWXlmT-nFh7YefVP_zJSXEA1YgT37wnWqelPhmj7UoM,2092
150
154
  territories_dashboard_lib/website_lib/templatetags/other_filters.py,sha256=EEczSQi8lJZ_rfceuXQz3iF1SIxh5d-3-liTY8lkKtU,944
151
- territories_dashboard_lib-0.1.10.dist-info/licenses/licence.md,sha256=9Tat8mM_Yyww-wmWps8avlOhzumqEUGYy8853tKy7aE,7804
152
- territories_dashboard_lib-0.1.10.dist-info/METADATA,sha256=74F9zN7-hCjMvTfKvYBFA_digN-CRcjucKXRhmzI0RA,5821
153
- territories_dashboard_lib-0.1.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
154
- territories_dashboard_lib-0.1.10.dist-info/top_level.txt,sha256=Cih-lil8CSXTpDZV6fgHKIKIBtUjDaNpmkiuW2TSzsk,26
155
- territories_dashboard_lib-0.1.10.dist-info/RECORD,,
155
+ territories_dashboard_lib-0.1.12.dist-info/licenses/licence.md,sha256=9Tat8mM_Yyww-wmWps8avlOhzumqEUGYy8853tKy7aE,7804
156
+ territories_dashboard_lib-0.1.12.dist-info/METADATA,sha256=XvoI7VVPvmvqPj3bC0UbTg3hZ9YXgjM5IYjWQPa0nQY,6191
157
+ territories_dashboard_lib-0.1.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
158
+ territories_dashboard_lib-0.1.12.dist-info/top_level.txt,sha256=Cih-lil8CSXTpDZV6fgHKIKIBtUjDaNpmkiuW2TSzsk,26
159
+ territories_dashboard_lib-0.1.12.dist-info/RECORD,,