diff --git a/TEMPLATE.env b/TEMPLATE.env index 57c2d6e..efdba95 100644 --- a/TEMPLATE.env +++ b/TEMPLATE.env @@ -98,3 +98,6 @@ LOCATION_URL=https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE # How many services should be displayed on dashboard page? # Set to big number if you don't want pagination at all. DASHBOARD_PAGE_SIZE=5 + +# Should background bars be scaled to full width? +USE_RELATIVE_MAX_IN_BAR_VISUALIZATION=True diff --git a/app.json b/app.json index 3a62e51..7f54f36 100644 --- a/app.json +++ b/app.json @@ -132,6 +132,11 @@ "description": "How many services should be displayed on dashboard page?", "value": "5", "required": false + }, + "USE_RELATIVE_MAX_IN_BAR_VISUALIZATION": { + "description": "Should background bars be scaled to full width?", + "value": "True", + "required": false } } } diff --git a/shynet/dashboard/templates/dashboard/includes/bar.html b/shynet/dashboard/templates/dashboard/includes/bar.html new file mode 100644 index 0000000..a6ad23c --- /dev/null +++ b/shynet/dashboard/templates/dashboard/includes/bar.html @@ -0,0 +1,6 @@ +{% load helpers %} +
+
diff --git a/shynet/dashboard/templates/dashboard/pages/service.html b/shynet/dashboard/templates/dashboard/pages/service.html index d005b1b..d249755 100644 --- a/shynet/dashboard/templates/dashboard/pages/service.html +++ b/shynet/dashboard/templates/dashboard/pages/service.html @@ -109,8 +109,20 @@ {% for location in stats.locations %} - {{location.location|default:"Unknown"|urldisplay}} - {{location.count|intcomma}} + + {% include 'dashboard/includes/bar.html' with count=location.count max=stats.locations.0.count total=stats.hit_count %} +
+ {{location.location|default:"Unknown"|urldisplay}} +
+ + +
+ {{location.count|intcomma}} + + ({{location.count|percent:stats.hit_count}}) + +
+ {% empty %} @@ -131,8 +143,20 @@ {% for referrer in stats.referrers %} - {{referrer.referrer|default:"Direct"|urldisplay}} - {{referrer.count|intcomma}} + + {% include 'dashboard/includes/bar.html' with count=referrer.count max=stats.referrers.0.count total=stats.session_count %} +
+ {{referrer.referrer|default:"Direct"|urldisplay}} +
+ + +
+ {{referrer.count|intcomma}} + + ({{referrer.count|percent:stats.session_count}}) + +
+ {% empty %} @@ -153,10 +177,20 @@ {% for country in stats.countries %} - - {{country.country|country_name}} + + {% include 'dashboard/includes/bar.html' with count=country.count max=stats.countries.0.count total=stats.session_count %} +
+ {{country.country|country_name}} +
+ + +
+ {{country.count|intcomma}} + + ({{country.count|percent:stats.session_count}}) + +
- {{country.count|intcomma}} {% empty %} @@ -177,10 +211,20 @@ {% for os in stats.operating_systems %} - - {{os.os|iconify}}{{os.os|default:"Unknown"}} + + {% include 'dashboard/includes/bar.html' with count=os.count max=stats.operating_systems.0.count total=stats.session_count %} +
+ {{os.os|iconify}}{{os.os|default:"Unknown"}} +
+ + +
+ {{os.count|intcomma}} + + ({{os.count|percent:stats.session_count}}) + +
- {{os.count|intcomma}} {% empty %} @@ -201,9 +245,21 @@ {% for browser in stats.browsers %} - - {{browser.browser|iconify}}{{browser.browser|default:"Unknown"}} - {{browser.count|intcomma}} + + {% include 'dashboard/includes/bar.html' with count=browser.count max=stats.browsers.0.count total=stats.session_count %} + +
+ {{browser.browser|iconify}}{{browser.browser|default:"Unknown"}} +
+ + +
+ {{browser.count|intcomma}} + + ({{browser.count|percent:stats.session_count}}) + +
+ {% empty %} @@ -224,8 +280,20 @@ {% for device_type in stats.device_types %} - {{device_type.device_type|default:"Unknown"|title}} - {{device_type.count|intcomma}} + + {% include 'dashboard/includes/bar.html' with count=device_type.count max=stats.device_types.0.count total=stats.session_count %} +
+ {{device_type.device_type|default:"Unknown"|title}} +
+ + +
+ {{device_type.count|intcomma}} + + ({{device_type.count|percent:stats.session_count}}) + +
+ {% empty %} @@ -243,4 +311,4 @@ sessions → -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/shynet/dashboard/templatetags/helpers.py b/shynet/dashboard/templatetags/helpers.py index f456be4..245bbfa 100644 --- a/shynet/dashboard/templatetags/helpers.py +++ b/shynet/dashboard/templatetags/helpers.py @@ -186,6 +186,7 @@ def urldisplay(url): else: return url + class ContextualURLNode(template.Node): """Extension of the Django URLNode to support including contextual parameters in URL outputs. In other words, URLs generated will keep the start and end date parameters.""" @@ -205,9 +206,13 @@ class ContextualURLNode(template.Node): url_parts = list(urlparse(url)) query = dict(urllib.parse.parse_qsl(url_parts[4])) - query.update({ - param: context.request.GET.get(param) for param in self.CONTEXT_PARAMS if param in context.request.GET and param not in query - }) + query.update( + { + param: context.request.GET.get(param) + for param in self.CONTEXT_PARAMS + if param in context.request.GET and param not in query + } + ) url_parts[4] = urllib.parse.urlencode(query) @@ -224,7 +229,39 @@ class ContextualURLNode(template.Node): def contextual_url(*args, **kwargs): urlnode = url_tag(*args, **kwargs) return ContextualURLNode(urlnode) - + + @register.filter def location_url(session): - return settings.LOCATION_URL.replace("$LATITUDE", str(session.latitude)).replace("$LONGITUDE", str(session.longitude)) + return settings.LOCATION_URL.replace("$LATITUDE", str(session.latitude)).replace( + "$LONGITUDE", str(session.longitude) + ) + + +@register.filter +def percent(value, total): + if total == 0: + return "N/A" + + percent = value / total + + if percent < 0.001: + return "<0.1%" + + return f'{percent:.1%}' + + +@register.simple_tag +def bar_width(count, max, total): + if total == 0 or max == 0: + return "0" + + if settings.USE_RELATIVE_MAX_IN_BAR_VISUALIZATION: + percent = count / max + else: + percent = count / total + + if percent < 0.001: + return "0" + + return f'{percent:.1%}' diff --git a/shynet/shynet/settings.py b/shynet/shynet/settings.py index bb9c24d..9c960c8 100644 --- a/shynet/shynet/settings.py +++ b/shynet/shynet/settings.py @@ -310,7 +310,10 @@ NPM_FILE_PATTERNS = { "stimulus": [os.path.join("dist", "stimulus.umd.js")], "inter-ui": [os.path.join("Inter (web)", "*")], "@fortawesome": [os.path.join("fontawesome-free", "js", "all.min.js")], - "flag-icon-css": [os.path.join("css", "flag-icon.min.css"), os.path.join("flags", "*")], + "flag-icon-css": [ + os.path.join("css", "flag-icon.min.css"), + os.path.join("flags", "*"), + ], } # Shynet @@ -346,7 +349,14 @@ BLOCK_ALL_IPS = os.getenv("BLOCK_ALL_IPS", "False") == "True" AGGRESSIVE_HASH_SALTING = os.getenv("AGGRESSIVE_HASH_SALTING", "False") == "True" # What location url should be linked to in the frontend? -LOCATION_URL = os.getenv("LOCATION_URL", "https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE") +LOCATION_URL = os.getenv( + "LOCATION_URL", "https://www.openstreetmap.org/?mlat=$LATITUDE&mlon=$LONGITUDE" +) # How many services should be displayed on dashboard page? DASHBOARD_PAGE_SIZE = int(os.getenv("DASHBOARD_PAGE_SIZE", "5")) + +# Should background bars be scaled to full width? +USE_RELATIVE_MAX_IN_BAR_VISUALIZATION = ( + os.getenv("USE_RELATIVE_MAX_IN_BAR_VISUALIZATION", "True") == "True" +)