summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2024-09-23 12:42:55 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2024-09-26 11:25:16 +0200
commit440038531ae041a4800b11921197616c34f577f2 (patch)
tree8e6b609f0b9f64885cf718a14f44468054941aa2
parent8a3db7ab932730fb78a093ba4820cee5939bb805 (diff)
downloadIshtar-440038531ae041a4800b11921197616c34f577f2.tar.bz2
Ishtar-440038531ae041a4800b11921197616c34f577f2.zip
✨ homepage: statistics and more customizations
-rw-r--r--ishtar_common/admin.py4
-rw-r--r--ishtar_common/migrations/0250_profile_homepage.py33
-rw-r--r--ishtar_common/models.py10
-rw-r--r--ishtar_common/templates/index.html23
-rw-r--r--ishtar_common/templates/welcome.html26
-rw-r--r--ishtar_common/views.py60
6 files changed, 131 insertions, 25 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index 76b52460c..7da231e30 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -560,6 +560,10 @@ class IshtarSiteProfileAdmin(admin.ModelAdmin):
"slug",
"active",
"homepage",
+ "homepage_title",
+ "homepage_statistics_available",
+ "homepage_statistics_available_offline",
+ "homepage_random_image_available",
)
}),
(_("Detail"), {
diff --git a/ishtar_common/migrations/0250_profile_homepage.py b/ishtar_common/migrations/0250_profile_homepage.py
new file mode 100644
index 000000000..be151d13c
--- /dev/null
+++ b/ishtar_common/migrations/0250_profile_homepage.py
@@ -0,0 +1,33 @@
+# Generated by Django 2.2.24 on 2024-09-23 12:15
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0249_town_notice'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='ishtarsiteprofile',
+ name='homepage_random_image_available',
+ field=models.BooleanField(default=False, verbose_name='Homepage - Random image available'),
+ ),
+ migrations.AddField(
+ model_name='ishtarsiteprofile',
+ name='homepage_statistics_available',
+ field=models.BooleanField(default=False, verbose_name='Homepage - Statistics available'),
+ ),
+ migrations.AddField(
+ model_name='ishtarsiteprofile',
+ name='homepage_statistics_available_offline',
+ field=models.BooleanField(default=False, verbose_name='Homepage - Statistics available off-line'),
+ ),
+ migrations.AddField(
+ model_name='ishtarsiteprofile',
+ name='homepage_title',
+ field=models.CharField(blank=True, default='', max_length=100, verbose_name='Homepage - Title'),
+ ),
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index b9bd1351e..f45ebe069 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -1178,6 +1178,16 @@ class IshtarSiteProfile(models.Model, Cached):
"can be used to display a random image."
),
)
+ homepage_title = models.CharField(_("Homepage - Title"), max_length=100, default="", blank=True)
+ homepage_statistics_available = models.BooleanField(
+ _("Homepage - Statistics available"), default=False
+ )
+ homepage_statistics_available_offline = models.BooleanField(
+ _("Homepage - Statistics available off-line"), default=False
+ )
+ homepage_random_image_available = models.BooleanField(
+ _("Homepage - Random image available"), default=False
+ )
operation_prefix = models.CharField(
_("Main operation code prefix"),
default="OA",
diff --git a/ishtar_common/templates/index.html b/ishtar_common/templates/index.html
index c86413380..d1000396a 100644
--- a/ishtar_common/templates/index.html
+++ b/ishtar_common/templates/index.html
@@ -1,3 +1,24 @@
{% extends "base.html" %}
{% load i18n %}
-{% block content %}<div id="welcome" class="container">{% if homepage %}{{homepage|safe}}{% else %}{% include "welcome.html" %}{% endif %}</div>{% endblock %}
+{% block content %}<div id="welcome" class="container">
+ <h2>{% if welcome_title %}{{welcome_title}}{% else %}{% trans "Welcome in Ishtar, open source software for management and inventory of archaeological data" %}{% endif %}</h2>
+ <div class="row">
+ {% if display_random_image %}
+ {{random_image}}
+ {% endif %}
+ <div class="col col-lg-9">
+ <div class="card">
+ <div class="card-body">
+ {% if homepage %}{{homepage|safe}}{% else %}{% include "welcome.html" %}{% endif %}
+ </div>
+ </div>
+ </div>
+ {% if display_statistics %}
+ <div class="col col-lg-12 lead mt-4">
+ {% for label, number in statistics %}
+ <span class="badge badge-secondary">{{label}} &nbsp;<span class="badge badge-light">{{number}}</span></span>
+ {% endfor %}
+ </div>
+ {% endif %}
+ </div>
+</div>{% endblock %}
diff --git a/ishtar_common/templates/welcome.html b/ishtar_common/templates/welcome.html
index c6ee5c81f..c5d21cecc 100644
--- a/ishtar_common/templates/welcome.html
+++ b/ishtar_common/templates/welcome.html
@@ -1,20 +1,10 @@
{% load i18n %}
-<h2>{% trans "Welcome in Ishtar, open source software for management and inventory of archaeological data" %}</h2>
-<div class="row">
- {{random_image}}
- <div class="col col-lg-9">
- <div class="card">
- <div class="card-body">
- <p>{% trans "Some useful links:" %}</p>
- <ul>
- <li><a href='https://ishtar-archeo.net' target="_blank">{% trans "Presentation site and blog" %}</a>{% trans ":"%} {% trans "stay tuned with Ishtar news!" %}</li>
- <li><a href="https://ishtar.readthedocs.io/fr/{{ISHTAR_DOCUMENT_VERSION}}/" target="_blank">{% trans "Documentation" %}</a>{% trans ":"%} {% trans "inline documentation." %}</li>
- <li><a href="{% url 'admin:index' %}" target="_blank">{% trans "Admin interface" %}</a>{% trans ":"%} {% trans "for admin only." %}</li>
- <li><a href="https://discourse.ishtar-archeo.net/" target="_blank">{% trans "Forum" %}</a>{% trans ":"%} {% trans "need help? find a new bug? a fantastic feature to propose? Here is the place to go." %}</li>
- <li><a href="https://gitlab.com/iggdrasil/ishtar" target="_blank">{% trans "Source code" %}</a> &ndash; <a href="https://tickets.iggdrasil.net/projects/ishtar" target="_blank">{% trans "tickets" %}</a>{% trans ":"%} {% trans "where the magic happens." %}</li>
- </ul>
- </div>
- </div>
- </div>
-</div>
+<p>{% trans "Some useful links:" %}</p>
+<ul>
+ <li><a href='https://ishtar-archeo.net' target="_blank">{% trans "Presentation site and blog" %}</a>{% trans ":"%} {% trans "stay tuned with Ishtar news!" %}</li>
+ <li><a href="https://ishtar.readthedocs.io/fr/{{ISHTAR_DOCUMENT_VERSION}}/" target="_blank">{% trans "Documentation" %}</a>{% trans ":"%} {% trans "inline documentation." %}</li>
+ <li><a href="{% url 'admin:index' %}" target="_blank">{% trans "Admin interface" %}</a>{% trans ":"%} {% trans "for admin only." %}</li>
+ <li><a href="https://discourse.ishtar-archeo.net/" target="_blank">{% trans "Forum" %}</a>{% trans ":"%} {% trans "need help? find a new bug? a fantastic feature to propose? Here is the place to go." %}</li>
+ <li><a href="https://gitlab.com/iggdrasil/ishtar" target="_blank">{% trans "Source code" %}</a> &ndash; <a href="https://tickets.iggdrasil.net/projects/ishtar" target="_blank">{% trans "tickets" %}</a>{% trans ":"%} {% trans "where the magic happens." %}</li>
+</ul>
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 5627f4a93..2772bd44f 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -142,11 +142,48 @@ def tiny_redirect(request, url_id):
return redirect(link_db.link)
+def _count_stats(model):
+ cache_key = f"{settings.PROJECT_SLUG}-stats-{model.__name__}"
+ value = cache.get(cache_key)
+ if value:
+ return value
+ value = model.objects.count()
+ cache.set(cache_key, value, settings.CACHE_TIMEOUT)
+ return value
+
+
+def _get_statistics(profile):
+ stats = [
+ (_("Operations"), _count_stats(apps.get_model("archaeological_operations", "Operation")))
+ ]
+ if profile.archaeological_site:
+ stats.append((_("Archaeological sites"),
+ _count_stats(apps.get_model("archaeological_operations", "ArchaeologicalSite"))))
+ if profile.context_record:
+ stats.append((_("Context records"),
+ _count_stats(apps.get_model("archaeological_context_records", "ContextRecord"))))
+ if profile.find:
+ stats.append((_("Finds"),
+ _count_stats(apps.get_model("archaeological_finds", "Find"))))
+ if profile.warehouse:
+ stats.append((_("Warehouses"),
+ _count_stats(apps.get_model("archaeological_warehouse", "Warehouse"))))
+ stats.append((_("Containers"),
+ _count_stats(apps.get_model("archaeological_warehouse", "Container"))))
+ if profile.files:
+ stats.append((_("Archaeological files"), _count_stats(apps.get_model("archaeological_files", "File"))))
+ stats.append((_("Administrative acts"),
+ _count_stats(apps.get_model("archaeological_operations", "AdministrativeAct"))))
+ return stats
+
+
def index(request):
"""
Main page
"""
- dct = {"warnings": [], "extra_form_modals": wizards.EXTRA_FORM_MODALS}
+ profile = get_current_profile()
+ dct = {"warnings": [], "extra_form_modals": wizards.EXTRA_FORM_MODALS,
+ "welcome_title": profile.homepage_title}
if settings.PROJECT_SLUG == "default":
dct["warnings"].append(
_(
@@ -154,7 +191,6 @@ def index(request):
"local_settings (or ask your admin to do it)."
)
)
- profile = get_current_profile()
if profile.slug == "default":
dct["warnings"].append(
_(
@@ -162,13 +198,25 @@ def index(request):
"on the administration page (or ask your admin to do it)."
)
)
- image = get_random_item_image_link(request)
+ authenticated = request.user.is_authenticated
+ display_random_image = authenticated and profile.homepage_random_image_available
+ if display_random_image:
+ dct["display_random_image"] = True
+ dct["random_image"] = get_random_item_image_link(request)
+
if hasattr(profile, "homepage") and profile.homepage:
dct["homepage"] = markdown(profile.homepage)
+ # remove old hardcoded "{random_image}" from custom templates
if "{random_image}" in dct["homepage"]:
- dct["homepage"] = dct["homepage"].replace("{random_image}", image)
- else:
- dct["random_image"] = image
+ dct["homepage"] = dct["homepage"].replace("{random_image}", "")
+
+ display_statistics = profile.homepage_statistics_available and (
+ authenticated or profile.homepage_statistics_available_offline
+ )
+ if display_statistics:
+ dct["display_statistics"] = True
+ dct["statistics"] = _get_statistics(profile)
+
try:
return render(request, "index.html", dct)
except NoReverseMatch: