pretix-map 0.1.4__tar.gz → 0.1.6__tar.gz

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.
Files changed (68) hide show
  1. {pretix_map-0.1.4 → pretix_map-0.1.6}/LICENSE +15 -15
  2. {pretix_map-0.1.4 → pretix_map-0.1.6}/MANIFEST.in +5 -5
  3. pretix_map-0.1.6/PKG-INFO +88 -0
  4. pretix_map-0.1.6/README.md +73 -0
  5. pretix_map-0.1.6/pretix_map.egg-info/PKG-INFO +88 -0
  6. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_map.egg-info/SOURCES.txt +3 -3
  7. pretix_map-0.1.6/pretix_mapplugin/__init__.py +1 -0
  8. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/apps.py +28 -28
  9. pretix_map-0.1.6/pretix_mapplugin/geocoding.py +162 -0
  10. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/locale/de/LC_MESSAGES/django.po +12 -12
  11. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/locale/de_Informal/LC_MESSAGES/django.po +12 -12
  12. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/management/commands/geocode_existing_orders.py +271 -271
  13. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/migrations/0001_initial.py +27 -27
  14. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/migrations/0002_remove_ordergeocodedata_geocoded_timestamp_and_more.py +32 -32
  15. pretix_map-0.1.6/pretix_mapplugin/migrations/0003_mapmilestone.py +27 -0
  16. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/models.py +71 -47
  17. pretix_map-0.1.6/pretix_mapplugin/signals.py +77 -0
  18. pretix_map-0.1.6/pretix_mapplugin/static/pretix_mapplugin/css/salesmap.css +101 -0
  19. pretix_map-0.1.6/pretix_mapplugin/static/pretix_mapplugin/js/salesmap.js +611 -0
  20. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/MarkerCluster.Default.css +59 -59
  21. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/MarkerCluster.css +14 -14
  22. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-heat.js +10 -10
  23. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-src.esm.js +14419 -14419
  24. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-src.js +14512 -14512
  25. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.css +661 -661
  26. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.js +5 -5
  27. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.markercluster.js +2 -2
  28. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/tasks.py +144 -113
  29. pretix_map-0.1.6/pretix_mapplugin/templates/pretix_mapplugin/map_page.html +189 -0
  30. pretix_map-0.1.6/pretix_mapplugin/templates/pretix_mapplugin/milestones.html +53 -0
  31. pretix_map-0.1.6/pretix_mapplugin/urls.py +38 -0
  32. pretix_map-0.1.6/pretix_mapplugin/views.py +295 -0
  33. {pretix_map-0.1.4 → pretix_map-0.1.6}/pyproject.toml +44 -44
  34. {pretix_map-0.1.4 → pretix_map-0.1.6}/setup.cfg +49 -49
  35. {pretix_map-0.1.4 → pretix_map-0.1.6}/setup.py +3 -3
  36. {pretix_map-0.1.4 → pretix_map-0.1.6}/tests/test_main.py +3 -3
  37. pretix_map-0.1.4/PKG-INFO +0 -195
  38. pretix_map-0.1.4/README.rst +0 -180
  39. pretix_map-0.1.4/pretix_map.egg-info/PKG-INFO +0 -195
  40. pretix_map-0.1.4/pretix_mapplugin/__init__.py +0 -1
  41. pretix_map-0.1.4/pretix_mapplugin/geocoding.py +0 -102
  42. pretix_map-0.1.4/pretix_mapplugin/locale/de/LC_MESSAGES/django.mo +0 -0
  43. pretix_map-0.1.4/pretix_mapplugin/locale/de_Informal/LC_MESSAGES/django.mo +0 -0
  44. pretix_map-0.1.4/pretix_mapplugin/signals.py +0 -92
  45. pretix_map-0.1.4/pretix_mapplugin/static/pretix_mapplugin/css/salesmap.css +0 -52
  46. pretix_map-0.1.4/pretix_mapplugin/static/pretix_mapplugin/js/salesmap.js +0 -452
  47. pretix_map-0.1.4/pretix_mapplugin/templates/pretix_mapplugin/map_page.html +0 -88
  48. pretix_map-0.1.4/pretix_mapplugin/urls.py +0 -21
  49. pretix_map-0.1.4/pretix_mapplugin/views.py +0 -163
  50. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_map.egg-info/dependency_links.txt +0 -0
  51. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_map.egg-info/entry_points.txt +0 -0
  52. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_map.egg-info/requires.txt +0 -0
  53. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_map.egg-info/top_level.txt +0 -0
  54. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/locale/de_Informal/.gitkeep +0 -0
  55. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/management/__init__.py +0 -0
  56. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/management/commands/__init__.py +0 -0
  57. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/migrations/__init__.py +0 -0
  58. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/.gitkeep +0 -0
  59. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/layers-2x.png +0 -0
  60. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/layers.png +0 -0
  61. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/marker-icon-2x.png +0 -0
  62. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/marker-icon.png +0 -0
  63. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/marker-shadow.png +0 -0
  64. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-src.esm.js.map +0 -0
  65. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-src.js.map +0 -0
  66. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.js.map +0 -0
  67. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.markercluster.js.map +0 -0
  68. {pretix_map-0.1.4 → pretix_map-0.1.6}/pretix_mapplugin/templates/pretix_mapplugin/.gitkeep +0 -0
@@ -1,15 +1,15 @@
1
-
2
- Copyright 2025 MarkenJaden
3
-
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
15
-
1
+
2
+ Copyright 2025 MarkenJaden
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+
@@ -1,5 +1,5 @@
1
- recursive-include pretix_mapplugin/static *
2
- recursive-include pretix_mapplugin/templates *
3
- recursive-include pretix_mapplugin/locale *
4
- include LICENSE
5
- exclude .gitlab-ci.yml
1
+ recursive-include pretix_mapplugin/static *
2
+ recursive-include pretix_mapplugin/templates *
3
+ recursive-include pretix_mapplugin/locale *
4
+ include LICENSE
5
+ exclude .gitlab-ci.yml
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: pretix-map
3
+ Version: 0.1.6
4
+ Summary: An overview map of the catchment area of previous orders. Measured by postcode
5
+ Author-email: MarkenJaden <jjsch1410@gmail.com>
6
+ Maintainer-email: MarkenJaden <jjsch1410@gmail.com>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: homepage, https://github.com/MarkenJaden/pretix-map
9
+ Project-URL: repository, https://github.com/MarkenJaden/pretix-map
10
+ Keywords: pretix
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: geopy
14
+ Dynamic: license-file
15
+
16
+ # Pretix Sales Map Plugin
17
+
18
+ A powerful geographic analytics and visualization plugin for [pretix](https://github.com/pretix/pretix). This plugin allows you to visualize where your attendees are coming from, track sales growth over time, and analyze regional market penetration.
19
+
20
+ ## ✨ Features
21
+
22
+ - **📍 Automatic Geocoding:** Automatically converts attendee addresses to map coordinates upon payment.
23
+ - **🗺️ Interactive Map:** Switch between **Pin View** (with clustering), **Heatmap**, and **Density Grid**.
24
+ - **📈 Sales Analytics:** Track total revenue, average travel distance, and top regions (cities/items).
25
+ - **⏱️ Timeline Animation:** Play back the history of your sales to see geographic growth over time.
26
+ - **★ Marketing Milestones:** Define important dates (e.g., newsletters) in the UI to see their impact on the timeline.
27
+ - **🔄 Event Comparison:** Overlay data from previous events to compare reach and performance.
28
+ - **⚠️ Quality Control:** Dedicated view for orders with failed geocoding to manage data issues.
29
+ - **🌙 Nightly Sync:** Automated background task to retry failed geocoding attempts.
30
+ - **🔘 Manual Trigger:** Admin button to re-run geocoding for all orders of an event.
31
+
32
+ ## 🚀 Installation & Setup
33
+
34
+ To use this plugin with your local pretix instance (`C:\Users\SCJA03\Desktop\Programmieren\pretix`):
35
+
36
+ ### 1. Register the Plugin
37
+ Open your terminal, navigate to this directory, and ensure your pretix virtual environment is active.
38
+ ```bash
39
+ python setup.py develop
40
+ ```
41
+
42
+ ### 2. Run Migrations
43
+ Apply the database changes for geodata and milestones:
44
+ ```bash
45
+ # From your pretix/src directory
46
+ python manage.py migrate
47
+ ```
48
+
49
+ ### 3. Configuration
50
+ Add a User-Agent for the geocoding service in your `pretix.cfg`:
51
+ ```ini
52
+ [pretix_mapplugin]
53
+ nominatim_user_agent = YourProjectName/1.0 (contact@yourdomain.com)
54
+ ```
55
+
56
+ ### 4. Enable the Plugin
57
+ 1. Log in to your Pretix Control Panel.
58
+ 2. Go to **Organizer Settings > Plugins** and enable **Map-Plugin**.
59
+ 3. In your specific **Event > Settings > Plugins**, also enable **Map-Plugin**.
60
+
61
+ ## 🛠️ Usage
62
+
63
+ - **Map View:** Navigate to **Sales Map > Map View** in the event sidebar.
64
+ - **Milestones:** Go to **Sales Map > Milestones** to add marketing dates.
65
+ - **Revenue Weighting:** Use the toggle button on the map to see "where the money comes from" instead of just "where the people are".
66
+
67
+ ## 🚀 Starting the Application (Development)
68
+
69
+ 1. **Pretix Server:**
70
+ ```bash
71
+ cd C:\Users\SCJA03\Desktop\Programmieren\pretix\src
72
+ python manage.py runserver
73
+ ```
74
+ 2. **Celery Worker:**
75
+ ```bash
76
+ cd C:\Users\SCJA03\Desktop\Programmieren\pretix\src
77
+ celery -A pretix.celery_app worker -l info
78
+ ```
79
+ *Note: If you don't have a broker like Redis or RabbitMQ running, the plugin will automatically fall back to synchronous geocoding (eager mode) if configured in `pretix.cfg`.*
80
+
81
+ ## 🛡️ Requirements
82
+
83
+ - pretix >= 2.7
84
+ - geopy
85
+ - A running Celery worker (essential for background geocoding)
86
+
87
+ ---
88
+ Developed by MarkenJaden. Released under the Apache License 2.0.
@@ -0,0 +1,73 @@
1
+ # Pretix Sales Map Plugin
2
+
3
+ A powerful geographic analytics and visualization plugin for [pretix](https://github.com/pretix/pretix). This plugin allows you to visualize where your attendees are coming from, track sales growth over time, and analyze regional market penetration.
4
+
5
+ ## ✨ Features
6
+
7
+ - **📍 Automatic Geocoding:** Automatically converts attendee addresses to map coordinates upon payment.
8
+ - **🗺️ Interactive Map:** Switch between **Pin View** (with clustering), **Heatmap**, and **Density Grid**.
9
+ - **📈 Sales Analytics:** Track total revenue, average travel distance, and top regions (cities/items).
10
+ - **⏱️ Timeline Animation:** Play back the history of your sales to see geographic growth over time.
11
+ - **★ Marketing Milestones:** Define important dates (e.g., newsletters) in the UI to see their impact on the timeline.
12
+ - **🔄 Event Comparison:** Overlay data from previous events to compare reach and performance.
13
+ - **⚠️ Quality Control:** Dedicated view for orders with failed geocoding to manage data issues.
14
+ - **🌙 Nightly Sync:** Automated background task to retry failed geocoding attempts.
15
+ - **🔘 Manual Trigger:** Admin button to re-run geocoding for all orders of an event.
16
+
17
+ ## 🚀 Installation & Setup
18
+
19
+ To use this plugin with your local pretix instance (`C:\Users\SCJA03\Desktop\Programmieren\pretix`):
20
+
21
+ ### 1. Register the Plugin
22
+ Open your terminal, navigate to this directory, and ensure your pretix virtual environment is active.
23
+ ```bash
24
+ python setup.py develop
25
+ ```
26
+
27
+ ### 2. Run Migrations
28
+ Apply the database changes for geodata and milestones:
29
+ ```bash
30
+ # From your pretix/src directory
31
+ python manage.py migrate
32
+ ```
33
+
34
+ ### 3. Configuration
35
+ Add a User-Agent for the geocoding service in your `pretix.cfg`:
36
+ ```ini
37
+ [pretix_mapplugin]
38
+ nominatim_user_agent = YourProjectName/1.0 (contact@yourdomain.com)
39
+ ```
40
+
41
+ ### 4. Enable the Plugin
42
+ 1. Log in to your Pretix Control Panel.
43
+ 2. Go to **Organizer Settings > Plugins** and enable **Map-Plugin**.
44
+ 3. In your specific **Event > Settings > Plugins**, also enable **Map-Plugin**.
45
+
46
+ ## 🛠️ Usage
47
+
48
+ - **Map View:** Navigate to **Sales Map > Map View** in the event sidebar.
49
+ - **Milestones:** Go to **Sales Map > Milestones** to add marketing dates.
50
+ - **Revenue Weighting:** Use the toggle button on the map to see "where the money comes from" instead of just "where the people are".
51
+
52
+ ## 🚀 Starting the Application (Development)
53
+
54
+ 1. **Pretix Server:**
55
+ ```bash
56
+ cd C:\Users\SCJA03\Desktop\Programmieren\pretix\src
57
+ python manage.py runserver
58
+ ```
59
+ 2. **Celery Worker:**
60
+ ```bash
61
+ cd C:\Users\SCJA03\Desktop\Programmieren\pretix\src
62
+ celery -A pretix.celery_app worker -l info
63
+ ```
64
+ *Note: If you don't have a broker like Redis or RabbitMQ running, the plugin will automatically fall back to synchronous geocoding (eager mode) if configured in `pretix.cfg`.*
65
+
66
+ ## 🛡️ Requirements
67
+
68
+ - pretix >= 2.7
69
+ - geopy
70
+ - A running Celery worker (essential for background geocoding)
71
+
72
+ ---
73
+ Developed by MarkenJaden. Released under the Apache License 2.0.
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: pretix-map
3
+ Version: 0.1.6
4
+ Summary: An overview map of the catchment area of previous orders. Measured by postcode
5
+ Author-email: MarkenJaden <jjsch1410@gmail.com>
6
+ Maintainer-email: MarkenJaden <jjsch1410@gmail.com>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: homepage, https://github.com/MarkenJaden/pretix-map
9
+ Project-URL: repository, https://github.com/MarkenJaden/pretix-map
10
+ Keywords: pretix
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: geopy
14
+ Dynamic: license-file
15
+
16
+ # Pretix Sales Map Plugin
17
+
18
+ A powerful geographic analytics and visualization plugin for [pretix](https://github.com/pretix/pretix). This plugin allows you to visualize where your attendees are coming from, track sales growth over time, and analyze regional market penetration.
19
+
20
+ ## ✨ Features
21
+
22
+ - **📍 Automatic Geocoding:** Automatically converts attendee addresses to map coordinates upon payment.
23
+ - **🗺️ Interactive Map:** Switch between **Pin View** (with clustering), **Heatmap**, and **Density Grid**.
24
+ - **📈 Sales Analytics:** Track total revenue, average travel distance, and top regions (cities/items).
25
+ - **⏱️ Timeline Animation:** Play back the history of your sales to see geographic growth over time.
26
+ - **★ Marketing Milestones:** Define important dates (e.g., newsletters) in the UI to see their impact on the timeline.
27
+ - **🔄 Event Comparison:** Overlay data from previous events to compare reach and performance.
28
+ - **⚠️ Quality Control:** Dedicated view for orders with failed geocoding to manage data issues.
29
+ - **🌙 Nightly Sync:** Automated background task to retry failed geocoding attempts.
30
+ - **🔘 Manual Trigger:** Admin button to re-run geocoding for all orders of an event.
31
+
32
+ ## 🚀 Installation & Setup
33
+
34
+ To use this plugin with your local pretix instance (`C:\Users\SCJA03\Desktop\Programmieren\pretix`):
35
+
36
+ ### 1. Register the Plugin
37
+ Open your terminal, navigate to this directory, and ensure your pretix virtual environment is active.
38
+ ```bash
39
+ python setup.py develop
40
+ ```
41
+
42
+ ### 2. Run Migrations
43
+ Apply the database changes for geodata and milestones:
44
+ ```bash
45
+ # From your pretix/src directory
46
+ python manage.py migrate
47
+ ```
48
+
49
+ ### 3. Configuration
50
+ Add a User-Agent for the geocoding service in your `pretix.cfg`:
51
+ ```ini
52
+ [pretix_mapplugin]
53
+ nominatim_user_agent = YourProjectName/1.0 (contact@yourdomain.com)
54
+ ```
55
+
56
+ ### 4. Enable the Plugin
57
+ 1. Log in to your Pretix Control Panel.
58
+ 2. Go to **Organizer Settings > Plugins** and enable **Map-Plugin**.
59
+ 3. In your specific **Event > Settings > Plugins**, also enable **Map-Plugin**.
60
+
61
+ ## 🛠️ Usage
62
+
63
+ - **Map View:** Navigate to **Sales Map > Map View** in the event sidebar.
64
+ - **Milestones:** Go to **Sales Map > Milestones** to add marketing dates.
65
+ - **Revenue Weighting:** Use the toggle button on the map to see "where the money comes from" instead of just "where the people are".
66
+
67
+ ## 🚀 Starting the Application (Development)
68
+
69
+ 1. **Pretix Server:**
70
+ ```bash
71
+ cd C:\Users\SCJA03\Desktop\Programmieren\pretix\src
72
+ python manage.py runserver
73
+ ```
74
+ 2. **Celery Worker:**
75
+ ```bash
76
+ cd C:\Users\SCJA03\Desktop\Programmieren\pretix\src
77
+ celery -A pretix.celery_app worker -l info
78
+ ```
79
+ *Note: If you don't have a broker like Redis or RabbitMQ running, the plugin will automatically fall back to synchronous geocoding (eager mode) if configured in `pretix.cfg`.*
80
+
81
+ ## 🛡️ Requirements
82
+
83
+ - pretix >= 2.7
84
+ - geopy
85
+ - A running Celery worker (essential for background geocoding)
86
+
87
+ ---
88
+ Developed by MarkenJaden. Released under the Apache License 2.0.
@@ -1,6 +1,6 @@
1
1
  LICENSE
2
2
  MANIFEST.in
3
- README.rst
3
+ README.md
4
4
  pyproject.toml
5
5
  setup.cfg
6
6
  setup.py
@@ -18,16 +18,15 @@ pretix_mapplugin/signals.py
18
18
  pretix_mapplugin/tasks.py
19
19
  pretix_mapplugin/urls.py
20
20
  pretix_mapplugin/views.py
21
- pretix_mapplugin/locale/de/LC_MESSAGES/django.mo
22
21
  pretix_mapplugin/locale/de/LC_MESSAGES/django.po
23
22
  pretix_mapplugin/locale/de_Informal/.gitkeep
24
- pretix_mapplugin/locale/de_Informal/LC_MESSAGES/django.mo
25
23
  pretix_mapplugin/locale/de_Informal/LC_MESSAGES/django.po
26
24
  pretix_mapplugin/management/__init__.py
27
25
  pretix_mapplugin/management/commands/__init__.py
28
26
  pretix_mapplugin/management/commands/geocode_existing_orders.py
29
27
  pretix_mapplugin/migrations/0001_initial.py
30
28
  pretix_mapplugin/migrations/0002_remove_ordergeocodedata_geocoded_timestamp_and_more.py
29
+ pretix_mapplugin/migrations/0003_mapmilestone.py
31
30
  pretix_mapplugin/migrations/__init__.py
32
31
  pretix_mapplugin/static/pretix_mapplugin/.gitkeep
33
32
  pretix_mapplugin/static/pretix_mapplugin/css/salesmap.css
@@ -51,4 +50,5 @@ pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/marker-ic
51
50
  pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/images/marker-shadow.png
52
51
  pretix_mapplugin/templates/pretix_mapplugin/.gitkeep
53
52
  pretix_mapplugin/templates/pretix_mapplugin/map_page.html
53
+ pretix_mapplugin/templates/pretix_mapplugin/milestones.html
54
54
  tests/test_main.py
@@ -0,0 +1 @@
1
+ __version__ = "0.1.6"
@@ -1,28 +1,28 @@
1
- from django.utils.translation import gettext_lazy
2
-
3
- from . import __version__
4
-
5
- try:
6
- from pretix.base.plugins import PluginConfig
7
- except ImportError:
8
- raise RuntimeError("Please use pretix 2.7 or above to run this plugin!")
9
-
10
-
11
- class PluginApp(PluginConfig):
12
- default = True
13
- name = "pretix_mapplugin"
14
- verbose_name = "Map-Plugin"
15
-
16
- class PretixPluginMeta:
17
- name = gettext_lazy("Map-Plugin")
18
- author = "MarkenJaden"
19
- description = gettext_lazy("An overview map of the catchment area of previous orders. Measured by postcode")
20
- visible = True
21
- version = __version__
22
- category = "FEATURE"
23
- compatibility = "pretix>=2.7.0"
24
- settings_links = []
25
- navigation_links = []
26
-
27
- def ready(self):
28
- from . import signals # NOQA
1
+ from django.utils.translation import gettext_lazy
2
+
3
+ from . import __version__
4
+
5
+ try:
6
+ from pretix.base.plugins import PluginConfig
7
+ except ImportError:
8
+ raise RuntimeError("Please use pretix 2.7 or above to run this plugin!")
9
+
10
+
11
+ class PluginApp(PluginConfig):
12
+ default = True
13
+ name = "pretix_mapplugin"
14
+ verbose_name = "Map-Plugin"
15
+
16
+ class PretixPluginMeta:
17
+ name = gettext_lazy("Map-Plugin")
18
+ author = "MarkenJaden"
19
+ description = gettext_lazy("An overview map of the catchment area of previous orders. Measured by postcode")
20
+ visible = True
21
+ version = __version__
22
+ category = "FEATURE"
23
+ compatibility = "pretix>=2.7.0"
24
+ settings_links = []
25
+ navigation_links = []
26
+
27
+ def ready(self):
28
+ from . import signals # NOQA
@@ -0,0 +1,162 @@
1
+ import logging
2
+ from geopy.geocoders import Nominatim
3
+ from geopy.exc import GeocoderTimedOut, GeocoderServiceError
4
+ from geopy.distance import distance as geopy_distance
5
+ from time import sleep
6
+
7
+ # DO NOT import settings here, as it won't work reliably in Celery
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ # Define a default/fallback User-Agent. Users *should* override this in pretix.cfg.
12
+ DEFAULT_NOMINATIM_USER_AGENT = "pretix-map-plugin/unknown (Please configure nominatim_user_agent in pretix.cfg)"
13
+
14
+
15
+ # --- Geocoding Function (Accepts user_agent) ---
16
+ def geocode_address(address_string: str, nominatim_user_agent: str | None = None) -> tuple[float, float] | None:
17
+ """
18
+ Tries to geocode a given address string using Nominatim, using the
19
+ provided User-Agent string.
20
+
21
+ Args:
22
+ address_string: A single string representing the address.
23
+ nominatim_user_agent: The User-Agent string to use for Nominatim.
24
+
25
+ Returns:
26
+ A tuple (latitude, longitude) if successful, otherwise None.
27
+ """
28
+ # Use the provided User-Agent or the default
29
+ user_agent = nominatim_user_agent or DEFAULT_NOMINATIM_USER_AGENT
30
+
31
+ if user_agent == DEFAULT_NOMINATIM_USER_AGENT:
32
+ # Log warning if default is used - admins should configure this
33
+ logger.warning(
34
+ "Using default Nominatim User-Agent. Please set a specific "
35
+ "'nominatim_user_agent' under [pretix_mapplugin] in your "
36
+ "pretix.cfg according to Nominatim's usage policy."
37
+ )
38
+
39
+ # Initialize the geolocator with the determined user_agent
40
+ geolocator = Nominatim(user_agent=user_agent)
41
+
42
+ try:
43
+ # Add a 1-second delay to respect Nominatim's usage policy (1 req/sec)
44
+ sleep(1)
45
+
46
+ # Perform geocoding
47
+ location = geolocator.geocode(address_string, timeout=10) # 10-second timeout
48
+
49
+ if location:
50
+ logger.debug(
51
+ f"Geocoded '{address_string}' to ({location.latitude}, {location.longitude}) using User-Agent: {user_agent}"
52
+ )
53
+ return (location.latitude, location.longitude)
54
+ else:
55
+ logger.warning(f"Could not geocode address: {address_string} (Address not found by Nominatim)")
56
+ return None
57
+
58
+ except GeocoderTimedOut:
59
+ logger.error(f"Geocoding timed out for address: {address_string}")
60
+ return None
61
+ except GeocoderServiceError as e:
62
+ # Log specific service errors (e.g., API limits, server issues)
63
+ logger.error(f"Geocoding service error for address '{address_string}': {e}")
64
+ return None
65
+ except Exception as e:
66
+ # Catch any other unexpected exceptions during geocoding
67
+ logger.exception(f"An unexpected error occurred during geocoding for address '{address_string}': {e}")
68
+ return None
69
+
70
+
71
+ # --- Helper to Format Address Candidates from Pretix Order ---
72
+ def get_address_candidates_from_order(order) -> list[str]:
73
+ """
74
+ Creates a list of formatted address strings from a Pretix order's invoice address,
75
+ ordered from most specific to least specific (fallback).
76
+
77
+ Args:
78
+ order: A Pretix `Order` object.
79
+
80
+ Returns:
81
+ A list of address strings (e.g., ["Street, City, Zip, Country", "Zip City, Country"]).
82
+ """
83
+ # Ensure order and invoice_address exist
84
+ if not order or not order.invoice_address:
85
+ return []
86
+
87
+ candidates = []
88
+ addr = order.invoice_address # Shortcut
89
+ country_name = str(addr.country.name) if addr.country else ""
90
+
91
+ # Strategy 1: Full Address (Street, Zip City, State, Country)
92
+ parts_full = []
93
+ if addr.street: parts_full.append(addr.street)
94
+ if addr.zipcode and addr.city:
95
+ parts_full.append(f"{addr.zipcode} {addr.city}")
96
+ elif addr.city:
97
+ parts_full.append(addr.city)
98
+ elif addr.zipcode:
99
+ parts_full.append(addr.zipcode)
100
+
101
+ if addr.state: parts_full.append(addr.state)
102
+ if country_name: parts_full.append(country_name)
103
+
104
+ full_address = ", ".join(filter(None, parts_full))
105
+ if full_address:
106
+ candidates.append(full_address)
107
+
108
+ # Strategy 2: Zip + City + Country (No Street) - Good for privacy or if street is weird
109
+ parts_zip_city = []
110
+ if addr.zipcode and addr.city:
111
+ parts_zip_city.append(f"{addr.zipcode} {addr.city}")
112
+ elif addr.city: # Fallback if only city
113
+ parts_zip_city.append(addr.city)
114
+
115
+ if country_name: parts_zip_city.append(country_name)
116
+
117
+ zip_city_address = ", ".join(filter(None, parts_zip_city))
118
+ if zip_city_address and zip_city_address not in candidates:
119
+ candidates.append(zip_city_address)
120
+
121
+ # Strategy 3: Just Zip + Country (Coarse location)
122
+ parts_zip = []
123
+ if addr.zipcode: parts_zip.append(addr.zipcode)
124
+ if country_name: parts_zip.append(country_name)
125
+
126
+ zip_address = ", ".join(filter(None, parts_zip))
127
+ if zip_address and zip_address not in candidates:
128
+ candidates.append(zip_address)
129
+
130
+ return candidates
131
+
132
+
133
+ def get_best_address_string(order) -> str | None:
134
+ """Returns the most specific address string for an order."""
135
+ candidates = get_address_candidates_from_order(order)
136
+ return candidates[0] if candidates else None
137
+
138
+
139
+ def geocode_event_location(event, nominatim_user_agent: str | None = None) -> tuple[float, float] | None:
140
+ """
141
+ Tries to geocode the event's location field.
142
+ """
143
+ if not event or not event.location:
144
+ return None
145
+
146
+ location_str = str(event.location)
147
+ logger.info(f"Geocoding event location: {location_str}")
148
+ return geocode_address(location_str, nominatim_user_agent=nominatim_user_agent)
149
+
150
+
151
+ def calculate_distance(coord1: tuple[float, float], coord2: tuple[float, float]) -> float | None:
152
+ """
153
+ Calculates the distance in kilometers between two coordinates (lat, lon).
154
+ Returns None if coordinates are invalid.
155
+ """
156
+ try:
157
+ if not coord1 or not coord2:
158
+ return None
159
+ return geopy_distance(coord1, coord2).km
160
+ except Exception as e:
161
+ logger.warning(f"Error calculating distance: {e}")
162
+ return None
@@ -1,12 +1,12 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: \n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2017-03-07 19:01+0100\n"
6
- "PO-Revision-Date: \n"
7
- "Last-Translator: MarkenJaden\n"
8
- "Language-Team: \n"
9
- "Language: de\n"
10
- "MIME-Version: 1.0\n"
11
- "Content-Type: text/plain; charset=UTF-8\n"
12
- "Content-Transfer-Encoding: 8bit\n"
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: \n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2017-03-07 19:01+0100\n"
6
+ "PO-Revision-Date: \n"
7
+ "Last-Translator: MarkenJaden\n"
8
+ "Language-Team: \n"
9
+ "Language: de\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"
@@ -1,12 +1,12 @@
1
- msgid ""
2
- msgstr ""
3
- "Project-Id-Version: \n"
4
- "Report-Msgid-Bugs-To: \n"
5
- "POT-Creation-Date: 2017-03-07 19:01+0100\n"
6
- "PO-Revision-Date: \n"
7
- "Last-Translator: MarkenJaden\n"
8
- "Language-Team: \n"
9
- "Language: de\n"
10
- "MIME-Version: 1.0\n"
11
- "Content-Type: text/plain; charset=UTF-8\n"
12
- "Content-Transfer-Encoding: 8bit\n"
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: \n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2017-03-07 19:01+0100\n"
6
+ "PO-Revision-Date: \n"
7
+ "Last-Translator: MarkenJaden\n"
8
+ "Language-Team: \n"
9
+ "Language: de\n"
10
+ "MIME-Version: 1.0\n"
11
+ "Content-Type: text/plain; charset=UTF-8\n"
12
+ "Content-Transfer-Encoding: 8bit\n"