pretix-map 0.1.3__py3-none-any.whl → 0.1.5__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.
- pretix_map-0.1.5.dist-info/METADATA +88 -0
- {pretix_map-0.1.3.dist-info → pretix_map-0.1.5.dist-info}/RECORD +32 -30
- {pretix_map-0.1.3.dist-info → pretix_map-0.1.5.dist-info}/WHEEL +1 -1
- {pretix_map-0.1.3.dist-info → pretix_map-0.1.5.dist-info}/licenses/LICENSE +15 -15
- pretix_mapplugin/__init__.py +1 -1
- pretix_mapplugin/apps.py +28 -28
- pretix_mapplugin/geocoding.py +162 -102
- pretix_mapplugin/locale/de/LC_MESSAGES/django.po +12 -12
- pretix_mapplugin/locale/de_Informal/LC_MESSAGES/django.po +12 -12
- pretix_mapplugin/management/commands/geocode_existing_orders.py +271 -271
- pretix_mapplugin/migrations/0001_initial.py +27 -27
- pretix_mapplugin/migrations/0002_remove_ordergeocodedata_geocoded_timestamp_and_more.py +32 -32
- pretix_mapplugin/migrations/0003_mapmilestone.py +27 -0
- pretix_mapplugin/models.py +71 -47
- pretix_mapplugin/signals.py +77 -92
- pretix_mapplugin/static/pretix_mapplugin/css/salesmap.css +51 -51
- pretix_mapplugin/static/pretix_mapplugin/js/salesmap.js +342 -442
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/MarkerCluster.Default.css +59 -59
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/MarkerCluster.css +14 -14
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-heat.js +10 -10
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-src.esm.js +14419 -14419
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet-src.js +14512 -14512
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.css +661 -661
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.js +5 -5
- pretix_mapplugin/static/pretix_mapplugin/libs/leaflet-sales-map/leaflet.markercluster.js +2 -2
- pretix_mapplugin/tasks.py +144 -113
- pretix_mapplugin/templates/pretix_mapplugin/map_page.html +154 -68
- pretix_mapplugin/templates/pretix_mapplugin/milestones.html +53 -0
- pretix_mapplugin/urls.py +38 -21
- pretix_mapplugin/views.py +272 -163
- pretix_map-0.1.3.dist-info/METADATA +0 -195
- {pretix_map-0.1.3.dist-info → pretix_map-0.1.5.dist-info}/entry_points.txt +0 -0
- {pretix_map-0.1.3.dist-info → pretix_map-0.1.5.dist-info}/top_level.txt +0 -0
|
@@ -1,68 +1,154 @@
|
|
|
1
|
-
{% extends "pretixcontrol/event/settings_base.html" %}
|
|
2
|
-
{% load i18n %}
|
|
3
|
-
{% load static %}
|
|
4
|
-
{% load eventurl %}
|
|
5
|
-
|
|
6
|
-
{% block title %}{% trans "Ticket Sales Map" %}{% endblock %}
|
|
7
|
-
|
|
8
|
-
{% block inside %}
|
|
9
|
-
<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
{% extends "pretixcontrol/event/settings_base.html" %}
|
|
2
|
+
{% load i18n %}
|
|
3
|
+
{% load static %}
|
|
4
|
+
{% load eventurl %}
|
|
5
|
+
|
|
6
|
+
{% block title %}{% trans "Ticket Sales Map" %}{% endblock %}
|
|
7
|
+
|
|
8
|
+
{% block inside %}
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
10
|
+
<div class="plugin-map-content-wrapper" style="display: flex; flex-direction: column; min-height: 85vh;">
|
|
11
|
+
|
|
12
|
+
<h1>{% trans "Ticket Sales Map" %}</h1>
|
|
13
|
+
|
|
14
|
+
<div class="form-inline map-controls-row" style="margin-bottom: 1em; display: flex; flex-wrap: wrap; align-items: flex-start; gap: 10px;">
|
|
15
|
+
|
|
16
|
+
<div class="map-buttons-group" style="display: flex; flex-wrap: wrap; gap: 5px; align-items: center;">
|
|
17
|
+
<div class="form-group">
|
|
18
|
+
<button id="view-toggle-btn" class="btn btn-default" disabled>{% trans "Heatmap View" %}</button>
|
|
19
|
+
</div>
|
|
20
|
+
<div class="form-group">
|
|
21
|
+
<button id="cluster-toggle-btn" class="btn btn-default" disabled>{% trans "Clustering" %}</button>
|
|
22
|
+
</div>
|
|
23
|
+
<div class="form-group">
|
|
24
|
+
<button id="grid-toggle-btn" class="btn btn-default" disabled>{% trans "Density Grid" %}</button>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="form-group">
|
|
27
|
+
<button id="weight-toggle-btn" class="btn btn-default" disabled>{% trans "Weight by Revenue" %}</button>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="form-group">
|
|
30
|
+
<div class="checkbox" style="margin-left: 10px; margin-top: 8px;">
|
|
31
|
+
<label><input type="checkbox" id="show-canceled-check"> {% trans "Show Canceled" %}</label>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="form-group">
|
|
35
|
+
<button id="filter-toggle-btn" class="btn btn-default" disabled>{% trans "Filter" %} <span class="caret"></span></button>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="form-group">
|
|
38
|
+
<select id="compare-event-select" class="form-control" style="width: auto;" disabled>
|
|
39
|
+
<option value="">{% trans "Compare..." %}</option>
|
|
40
|
+
{% for e in other_events %}
|
|
41
|
+
<option value="{{ e.slug }}">{{ e.name }}</option>
|
|
42
|
+
{% endfor %}
|
|
43
|
+
</select>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="form-group">
|
|
46
|
+
<button id="list-toggle-btn" class="btn btn-info" disabled>{% trans "Failed Orders" %}</button>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="form-group">
|
|
49
|
+
<button id="stats-toggle-btn" class="btn btn-primary" disabled>{% trans "Analytics View" %}</button>
|
|
50
|
+
</div>
|
|
51
|
+
{% if "can_change_event_settings" in request.eventperm %}
|
|
52
|
+
<div class="form-group">
|
|
53
|
+
<form action="{% url 'plugins:pretix_mapplugin:event.settings.salesmap.trigger' organizer=request.organizer.slug event=request.event.slug %}" method="post" style="display: inline-block;">
|
|
54
|
+
{% csrf_token %}
|
|
55
|
+
<button type="submit" class="btn btn-warning" title="{% trans "Trigger Geocoding" %}"><i class="fa fa-refresh"></i></button>
|
|
56
|
+
</form>
|
|
57
|
+
</div>
|
|
58
|
+
{% endif %}
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div id="heatmap-options-panel" class="panel panel-default" style="display: none; padding: 10px; min-width: 300px;">
|
|
62
|
+
<div style="display: flex; justify-content: space-between;">
|
|
63
|
+
<h5 style="margin: 0;">Heatmap</h5>
|
|
64
|
+
<button id="heatmap-reset-btn" class="btn btn-xs btn-link">Reset</button>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="form-horizontal" style="margin-top: 5px;">
|
|
67
|
+
<div class="form-group form-group-sm"><label class="col-sm-4">Radius</label><div class="col-sm-6"><input type="range" id="heatmap-radius" min="1" max="100" value="25"></div><div class="col-sm-2"><span id="radius-value">25</span></div></div>
|
|
68
|
+
<div class="form-group form-group-sm"><label class="col-sm-4">Blur</label><div class="col-sm-6"><input type="range" id="heatmap-blur" min="1" max="50" value="15"></div><div class="col-sm-2"><span id="blur-value">15</span></div></div>
|
|
69
|
+
<div class="form-group form-group-sm"><label class="col-sm-4">Max Zoom</label><div class="col-sm-6"><input type="range" id="heatmap-maxZoom" min="1" max="18" value="18"></div><div class="col-sm-2"><span id="maxzoom-value">18</span></div></div>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div id="filter-options-panel" class="panel panel-default" style="display: none; padding: 10px; min-width: 200px; max-height: 300px; overflow-y: auto;">
|
|
74
|
+
<h5 style="margin: 0 0 5px 0;">Ticket Types</h5>
|
|
75
|
+
<div id="filter-checkboxes"></div>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
|
|
79
|
+
<div class="map-wrapper" style="position: relative; border: 1px solid #ccc; flex-grow: 1; display: flex; flex-direction: column; min-height: 500px;">
|
|
80
|
+
<div id="sales-map-container" style="flex-grow: 1; min-height: 500px;" data-data-url="{% url 'plugins:pretix_mapplugin:event.settings.salesmap.data' organizer=request.organizer.slug event=request.event.slug %}"></div>
|
|
81
|
+
|
|
82
|
+
<div id="failed-orders-container" style="display: none; padding: 20px; background: white; flex-grow: 1; overflow-y: auto;">
|
|
83
|
+
<h3>{% trans "Orders with missing geodata" %}</h3>
|
|
84
|
+
<table class="table table-hover">
|
|
85
|
+
<thead><tr><th>Code</th><th>Address</th><th>Action</th></tr></thead>
|
|
86
|
+
<tbody id="failed-orders-tbody"></tbody>
|
|
87
|
+
</table>
|
|
88
|
+
</div>
|
|
89
|
+
|
|
90
|
+
<div id="analytics-view-container" style="display: none; padding: 20px; background: #fafafa; flex-grow: 1; overflow-y: auto;">
|
|
91
|
+
<div class="row">
|
|
92
|
+
<div class="col-md-4">
|
|
93
|
+
<div class="panel panel-default">
|
|
94
|
+
<div class="panel-heading">Key Figures</div>
|
|
95
|
+
<div class="panel-body" id="stats-summary-text"></div>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="col-md-8">
|
|
99
|
+
<div class="panel panel-default">
|
|
100
|
+
<div class="panel-heading">Top Cities (Sales Count)</div>
|
|
101
|
+
<div class="panel-body"><canvas id="cities-chart" height="150"></canvas></div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
<div class="row" style="margin-top: 20px;">
|
|
106
|
+
<div class="col-md-6">
|
|
107
|
+
<div class="panel panel-default">
|
|
108
|
+
<div class="panel-heading">Ticket Type Distribution</div>
|
|
109
|
+
<div class="panel-body"><canvas id="items-chart" height="200"></canvas></div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="col-md-6">
|
|
113
|
+
<div class="panel panel-default">
|
|
114
|
+
<div class="panel-heading">Revenue by Ticket Type</div>
|
|
115
|
+
<div class="panel-body"><canvas id="revenue-chart" height="200"></canvas></div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div id="map-status-overlay" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 255, 255, 0.8); z-index: 1000; display: flex; justify-content: center; align-items: center;">
|
|
122
|
+
<p>Loading...</p>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div id="timeline-controls" style="margin-top: 10px; padding: 10px; background: #f5f5f5; border-radius: 4px; border: 1px solid #ddd;">
|
|
127
|
+
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
128
|
+
<div>
|
|
129
|
+
<label style="margin-bottom: 0;">{% trans "Timeline:" %} <span id="timeline-date-display" style="font-weight: normal;"></span></label>
|
|
130
|
+
<span id="timeline-count-display" class="badge"></span>
|
|
131
|
+
</div>
|
|
132
|
+
<div>
|
|
133
|
+
<select id="timeline-interval-select" class="form-control input-sm" style="width: auto; display: inline-block;">
|
|
134
|
+
<option value="hour">{% trans "Hourly" %}</option>
|
|
135
|
+
<option value="day" selected>{% trans "Daily" %}</option>
|
|
136
|
+
<option value="week">{% trans "Weekly" %}</option>
|
|
137
|
+
<option value="month">{% trans "Monthly" %}</option>
|
|
138
|
+
</select>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
<div style="display: flex; gap: 10px; align-items: center; margin-top: 5px;">
|
|
142
|
+
<button id="timeline-play-btn" class="btn btn-sm btn-default"><i class="fa fa-play"></i> Play</button>
|
|
143
|
+
<input type="range" id="timeline-slider" min="0" max="100" value="100" style="flex-grow: 1; cursor: pointer;">
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<script src="{% static 'pretix_mapplugin/libs/leaflet-sales-map/leaflet-heat.js' %}"></script>
|
|
149
|
+
<link rel="stylesheet" href="{% static 'pretix_mapplugin/libs/leaflet-sales-map/MarkerCluster.css' %}"/>
|
|
150
|
+
<link rel="stylesheet" href="{% static 'pretix_mapplugin/libs/leaflet-sales-map/MarkerCluster.Default.css' %}"/>
|
|
151
|
+
<script src="{% static 'pretix_mapplugin/libs/leaflet-sales-map/leaflet.markercluster.js' %}"></script>
|
|
152
|
+
<script src="{% static 'pretix_mapplugin/js/salesmap.js' %}"></script>
|
|
153
|
+
<link rel="stylesheet" href="{% static 'pretix_mapplugin/css/salesmap.css' %}"/>
|
|
154
|
+
{% endblock %}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{% extends "pretixcontrol/event/settings_base.html" %}
|
|
2
|
+
{% load i18n %}
|
|
3
|
+
{% load bootstrap3 %}
|
|
4
|
+
|
|
5
|
+
{% block title %}{% trans "Map Milestones" %}{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block inside %}
|
|
8
|
+
<h1>{% trans "Map Milestones" %}</h1>
|
|
9
|
+
<p>
|
|
10
|
+
{% trans "Define important dates (e.g. newsletter dispatch, ticket start) to see them in the Sales Map timeline." %}
|
|
11
|
+
</p>
|
|
12
|
+
<form action="" method="post" class="form-horizontal">
|
|
13
|
+
{% csrf_token %}
|
|
14
|
+
<div class="formset" data-formset-prefix="{{ formset.prefix }}">
|
|
15
|
+
{{ formset.management_form }}
|
|
16
|
+
{% bootstrap_formset_errors formset %}
|
|
17
|
+
<table class="table table-condensed">
|
|
18
|
+
<thead>
|
|
19
|
+
<tr>
|
|
20
|
+
<th>{% trans "Date" %}</th>
|
|
21
|
+
<th>{% trans "Label" %}</th>
|
|
22
|
+
<th>{% trans "Delete" %}</th>
|
|
23
|
+
</tr>
|
|
24
|
+
</thead>
|
|
25
|
+
<tbody>
|
|
26
|
+
{% for form in formset %}
|
|
27
|
+
<tr class="formset-row">
|
|
28
|
+
<td>
|
|
29
|
+
{{ form.id }}
|
|
30
|
+
{% bootstrap_field form.date layout='inline' %}
|
|
31
|
+
</td>
|
|
32
|
+
<td>
|
|
33
|
+
{% bootstrap_field form.label layout='inline' %}
|
|
34
|
+
</td>
|
|
35
|
+
<td>
|
|
36
|
+
{% if formset.can_delete %}
|
|
37
|
+
{% bootstrap_field form.DELETE layout='inline' %}
|
|
38
|
+
{% endif %}
|
|
39
|
+
</td>
|
|
40
|
+
</tr>
|
|
41
|
+
{% endfor %}
|
|
42
|
+
</tbody>
|
|
43
|
+
</table>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="form-group">
|
|
46
|
+
<div class="col-sm-offset-2 col-sm-10">
|
|
47
|
+
<button type="submit" class="btn btn-primary">
|
|
48
|
+
{% trans "Save" %}
|
|
49
|
+
</button>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</form>
|
|
53
|
+
{% endblock %}
|
pretix_mapplugin/urls.py
CHANGED
|
@@ -1,21 +1,38 @@
|
|
|
1
|
-
from django.urls import re_path
|
|
2
|
-
|
|
3
|
-
from .views import SalesMapDataView, SalesMapView
|
|
4
|
-
|
|
5
|
-
# Define the URL patterns for the event settings area
|
|
6
|
-
# These URLs will be prefixed with /control/event/<organizer>/<event>/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
from django.urls import re_path
|
|
2
|
+
|
|
3
|
+
from .views import SalesMapDataView, SalesMapView, MilestoneSettingsView, TriggerGeocodingView, SingleGeocodeView
|
|
4
|
+
|
|
5
|
+
# Define the URL patterns for the event settings area
|
|
6
|
+
# These URLs will be prefixed with /control/event/<organizer>/<event>/
|
|
7
|
+
urlpatterns = [
|
|
8
|
+
# URL for the API endpoint providing coordinate data
|
|
9
|
+
re_path(
|
|
10
|
+
r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sales-map/data/',
|
|
11
|
+
SalesMapDataView.as_view(),
|
|
12
|
+
name="event.settings.salesmap.data",
|
|
13
|
+
),
|
|
14
|
+
# URL for triggering geocoding for all
|
|
15
|
+
re_path(
|
|
16
|
+
r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sales-map/trigger/',
|
|
17
|
+
TriggerGeocodingView.as_view(),
|
|
18
|
+
name="event.settings.salesmap.trigger",
|
|
19
|
+
),
|
|
20
|
+
# URL for single order geocoding
|
|
21
|
+
re_path(
|
|
22
|
+
r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sales-map/retry/(?P<order>[^/]+)/',
|
|
23
|
+
SingleGeocodeView.as_view(),
|
|
24
|
+
name="event.settings.salesmap.retry",
|
|
25
|
+
),
|
|
26
|
+
# URL for milestone management
|
|
27
|
+
re_path(
|
|
28
|
+
r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sales-map/milestones/',
|
|
29
|
+
MilestoneSettingsView.as_view(),
|
|
30
|
+
name="event.settings.salesmap.milestones",
|
|
31
|
+
),
|
|
32
|
+
# URL for the HTML page displaying the map
|
|
33
|
+
re_path(
|
|
34
|
+
r'^control/event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/sales-map/',
|
|
35
|
+
SalesMapView.as_view(),
|
|
36
|
+
name="event.settings.salesmap.show",
|
|
37
|
+
),
|
|
38
|
+
]
|