diff --git a/README.md b/README.md index f985ad0..bc646ee 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## O projekte Trojsten ID vznikol ako náhrada predchádzajúceho `login.trojsten.sk` riešenia. Jeho snahou je vytvoriť jednotný -prihlasovací systém pre všetky Trojsten stránky a služby. Taktiež poskytuje informácie o používateľoch a (čoskoro) +prihlasovací systém pre všetky Trojsten stránky a služby. Taktiež poskytuje informácie o používateľoch a verejné profily. ## Inštalácia a quick-start diff --git a/trojstenid/badges/__init__.py b/trojstenid/badges/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/trojstenid/badges/admin.py b/trojstenid/badges/admin.py new file mode 100644 index 0000000..99a8287 --- /dev/null +++ b/trojstenid/badges/admin.py @@ -0,0 +1,18 @@ +from django.contrib import admin + +from trojstenid.badges.models import Badge, BadgeAssignment, BadgeGroup + + +class BadgeAssignmentInline(admin.TabularInline): + model = BadgeAssignment + + +@admin.register(Badge) +class BadgeAdmin(admin.ModelAdmin): + list_filter = ["group", "title"] + inlines = [BadgeAssignmentInline] + + +@admin.register(BadgeGroup) +class BadgeGroupAdmin(admin.ModelAdmin): + list_filter = ["title"] diff --git a/trojstenid/badges/apps.py b/trojstenid/badges/apps.py new file mode 100644 index 0000000..1d58983 --- /dev/null +++ b/trojstenid/badges/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class BadgesConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "trojstenid.badges" diff --git a/trojstenid/badges/migrations/0001_initial.py b/trojstenid/badges/migrations/0001_initial.py new file mode 100644 index 0000000..9b53f92 --- /dev/null +++ b/trojstenid/badges/migrations/0001_initial.py @@ -0,0 +1,97 @@ +# Generated by Django 4.2.4 on 2023-09-10 19:09 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name="Badge", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("image", models.ImageField(upload_to="")), + ("title", models.CharField(max_length=100)), + ("description", models.CharField(max_length=300)), + ("order", models.IntegerField(default=0)), + ], + options={ + "ordering": ["group", "order", "title"], + }, + ), + migrations.CreateModel( + name="BadgeGroup", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=100)), + ], + options={ + "ordering": ["title"], + }, + ), + migrations.CreateModel( + name="BadgeAssignment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "badge", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="badges.badge" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.AddField( + model_name="badge", + name="group", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="badges.badgegroup" + ), + ), + migrations.AddConstraint( + model_name="badgeassignment", + constraint=models.UniqueConstraint( + models.F("badge"), models.F("user"), name="badge_assignment__unique" + ), + ), + ] diff --git a/trojstenid/badges/migrations/__init__.py b/trojstenid/badges/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/trojstenid/badges/models.py b/trojstenid/badges/models.py new file mode 100644 index 0000000..0d064ac --- /dev/null +++ b/trojstenid/badges/models.py @@ -0,0 +1,38 @@ +from django.conf import settings +from django.db import models +from django.db.models import UniqueConstraint + + +class BadgeGroup(models.Model): + title = models.CharField(max_length=100) + + class Meta: + ordering = ["title"] + + def __str__(self): + return self.title + + +class Badge(models.Model): + image = models.ImageField() + title = models.CharField(max_length=100) + description = models.CharField(max_length=300) + group = models.ForeignKey(BadgeGroup, on_delete=models.CASCADE) + order = models.IntegerField(default=0) + + class Meta: + ordering = ["group", "order", "title"] + + def __str__(self): + return self.title + + +class BadgeAssignment(models.Model): + badge = models.ForeignKey(Badge, on_delete=models.CASCADE) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + constraints = [ + UniqueConstraint("badge", "user", name="badge_assignment__unique"), + ] diff --git a/trojstenid/badges/views.py b/trojstenid/badges/views.py new file mode 100644 index 0000000..60f00ef --- /dev/null +++ b/trojstenid/badges/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/trojstenid/profiles/templates/profile/profile.html b/trojstenid/profiles/templates/profile/profile.html new file mode 100644 index 0000000..342ce11 --- /dev/null +++ b/trojstenid/profiles/templates/profile/profile.html @@ -0,0 +1,53 @@ +{% extends "base.html" %} + +{% block title %}{{ object.get_full_name }} - {{ block.super }}{% endblock %} + +{% block body %} + +
+
+
+ {{ object.get_full_name }} +

+ {{ object.get_full_name }} +

+
+ {% if "trojsten:veduci" in groups %} + + + Vedúci + + {% endif %} +
+
+ +
+ +

Odznaky

+ + {% if badges %} + {% regroup badges by group as groups %} + {% for group, items in groups %} +

{{ group.title }}

+
+ {% for item in items %} +
+ {{ item.title }} +
+

{{ item.title }}

+

{{ item.description }}

+
+
+ {% endfor %} +
+ {% endfor %} + {% else %} +
+ +

Žiadne odznaky

+

Tento používateľ zatiaľ nezískal žiadne odznaky.

+
+ {% endif %} +
+ +{% endblock %} diff --git a/trojstenid/profiles/urls.py b/trojstenid/profiles/urls.py index f66c1f6..a82eda5 100644 --- a/trojstenid/profiles/urls.py +++ b/trojstenid/profiles/urls.py @@ -4,4 +4,5 @@ urlpatterns = [ path("/avatar/", views.AvatarView.as_view(), name="profile_avatar"), + path("/", views.ProfileView.as_view(), name="profile"), ] diff --git a/trojstenid/profiles/views.py b/trojstenid/profiles/views.py index dc9437f..fa9495c 100644 --- a/trojstenid/profiles/views.py +++ b/trojstenid/profiles/views.py @@ -1,10 +1,12 @@ import random +from django.contrib.auth.mixins import LoginRequiredMixin from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404 -from django.views.generic import TemplateView +from django.views.generic import DetailView, TemplateView from PIL import ImageColor +from trojstenid.badges.models import Badge from trojstenid.users.models import User @@ -34,3 +36,17 @@ def get_context_data(self, **kwargs): ctx["color"] = self.get_text_color(background) ctx["text"] = initials return ctx + + +class ProfileView(LoginRequiredMixin, DetailView): + template_name = "profile/profile.html" + + def get_object(self, queryset=None): + return get_object_or_404(User, username=self.kwargs["user"]) + + def get_context_data(self, **kwargs): + ctx = super().get_context_data(**kwargs) + user = ctx["object"] + ctx["groups"] = user.groups.values_list("name", flat=True) + ctx["badges"] = Badge.objects.filter(badgeassignment__user=user) + return ctx diff --git a/trojstenid/settings.py b/trojstenid/settings.py index 8556dfe..e4afa2c 100644 --- a/trojstenid/settings.py +++ b/trojstenid/settings.py @@ -44,6 +44,7 @@ "debug_toolbar", "trojstenid.users", "trojstenid.profiles", + "trojstenid.badges", "widget_tweaks", "captcha", "allauth", diff --git a/trojstenid/users/templates/_partials/navbar.html b/trojstenid/users/templates/_partials/navbar.html index 69297df..f43efe6 100644 --- a/trojstenid/users/templates/_partials/navbar.html +++ b/trojstenid/users/templates/_partials/navbar.html @@ -21,7 +21,7 @@
{% csrf_token %}
diff --git a/trojstenid/users/templates/_partials/navbar_items.html b/trojstenid/users/templates/_partials/navbar_items.html index 7956946..ba4d9fc 100644 --- a/trojstenid/users/templates/_partials/navbar_items.html +++ b/trojstenid/users/templates/_partials/navbar_items.html @@ -2,7 +2,7 @@
  • - + {{ item.1 }}
  • diff --git a/trojstenid/users/templates/base.html b/trojstenid/users/templates/base.html index 80a3849..189096e 100644 --- a/trojstenid/users/templates/base.html +++ b/trojstenid/users/templates/base.html @@ -16,7 +16,7 @@ {% block body %}{% endblock %} {% include "_partials/messages.html" %} - + diff --git a/trojstenid/users/templates/landing.html b/trojstenid/users/templates/landing.html index 91c5fa3..98a09a7 100644 --- a/trojstenid/users/templates/landing.html +++ b/trojstenid/users/templates/landing.html @@ -14,7 +14,7 @@ Prihlásiť sa - + diff --git a/trojstenid/users/templates/oauth2_provider/authorize.html b/trojstenid/users/templates/oauth2_provider/authorize.html index 8098432..f15515f 100644 --- a/trojstenid/users/templates/oauth2_provider/authorize.html +++ b/trojstenid/users/templates/oauth2_provider/authorize.html @@ -35,7 +35,7 @@

    {% else %}
    - +

    Chyba: {{ error.error }}
    {{ error.description }} diff --git a/trojstenid/users/templates/oauth2_provider/logout_confirm.html b/trojstenid/users/templates/oauth2_provider/logout_confirm.html index 2afa569..e345d3e 100644 --- a/trojstenid/users/templates/oauth2_provider/logout_confirm.html +++ b/trojstenid/users/templates/oauth2_provider/logout_confirm.html @@ -33,7 +33,7 @@

    {% else %}
    - +

    Chyba: {{ error.error }}
    {{ error.description }} diff --git a/trojstenid/users/templates/settings_base.html b/trojstenid/users/templates/settings_base.html index 2839fe2..4e0120d 100644 --- a/trojstenid/users/templates/settings_base.html +++ b/trojstenid/users/templates/settings_base.html @@ -36,7 +36,7 @@ >

    @@ -59,7 +59,7 @@
    diff --git a/trojstenid/users/templates/socialaccount/connections.html b/trojstenid/users/templates/socialaccount/connections.html index 00c9e22..134a132 100644 --- a/trojstenid/users/templates/socialaccount/connections.html +++ b/trojstenid/users/templates/socialaccount/connections.html @@ -40,7 +40,7 @@

    Externé účty

    {% else %}
    - +

    Nemáš pripojené žiadne externé účty

    {% endif %} diff --git a/trojstenid/users/templates/socialaccount/partials/providers.html b/trojstenid/users/templates/socialaccount/partials/providers.html index 0580db4..b80fea1 100644 --- a/trojstenid/users/templates/socialaccount/partials/providers.html +++ b/trojstenid/users/templates/socialaccount/partials/providers.html @@ -9,7 +9,7 @@