Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions adhocracy-plus/config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

# Link to a dokuwiki instance containing a manual for aplus
# Leave blank to disable
# For guest users this is hardcoded in indicator.html
APLUS_MANUAL_URL = ""

# Application definition
Expand All @@ -42,6 +43,7 @@
"allauth",
"allauth.account",
"allauth.socialaccount",
"guest_user",
"rules.apps.AutodiscoverRulesConfig",
"easy_thumbnails",
"parler",
Expand Down Expand Up @@ -280,6 +282,7 @@
"rules.permissions.ObjectPermissionBackend",
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
"guest_user.backends.GuestBackend",
)

ACCOUNT_ADAPTER = "apps.users.adapters.AccountAdapter"
Expand Down Expand Up @@ -719,3 +722,13 @@
},
},
}

GUEST_USER = {
"NAME_GENERATOR": "guest_user.functions.generate_uuid_username",
}


GUEST_USER_REQUIRED_ANON_URL = "/accounts/guests/login"
# Redirects below when guest user is required but currently regular user.
# Currently only guest dashboard views use this, so redirects to user profile.
GUEST_USER_REQUIRED_USER_URL = "/account/profile/"
8 changes: 5 additions & 3 deletions apps/account/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@
from apps.users.models import User
from apps.users.utils import set_session_language

from guest_user.functions import is_guest_user
from guest_user.mixins import GuestUserRequiredMixin, RegularUserRequiredMixin

from . import forms
from .emails import AccountDeletionEmail


class AccountView(RedirectView):
class AccountView(RegularUserRequiredMixin, RedirectView):
permanent = False
pattern_name = "account_profile"
# Placeholder View to be replaced if we want to use a custom account
# dashboard function overview.


class ProfileUpdateView(LoginRequiredMixin, SuccessMessageMixin, generic.UpdateView):
class ProfileUpdateView(LoginRequiredMixin, SuccessMessageMixin, RegularUserRequiredMixin, generic.UpdateView):
model = User
template_name = "a4_candy_account/profile.html"
form_class = forms.ProfileForm
Expand Down
9 changes: 8 additions & 1 deletion apps/augmentedreality/api.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
from guest_user.mixins import AllowGuestUserMixin

from adhocracy4.comments_async.api import CommentViewSet
from adhocracy4.ratings.api import RatingViewSet


class CombinedRatingViewSet(AllowGuestUserMixin, RatingViewSet):
http_method_names = ["post", "patch"]


class CombinedCommentViewSet(CommentViewSet):
class CombinedCommentViewSet(AllowGuestUserMixin, CommentViewSet):
def get_queryset(self):
comments = super().get_queryset()
return comments
24 changes: 24 additions & 0 deletions apps/augmentedreality/migrations/0005_alter_scene_content_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 4.2.18 on 2025-07-01 15:42

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("contenttypes", "0002_remove_content_type_name"),
("arpas_augmentedreality", "0004_alter_arobject_scene"),
]

operations = [
migrations.AlterField(
model_name="scene",
name="content_type",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="scenes",
to="contenttypes.contenttype",
),
),
]
4 changes: 3 additions & 1 deletion apps/augmentedreality/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ def validate_item_content_type(content_type):


class Scene(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE, related_name="scenes"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shn-liqd This is from one of your changes but I thought it already went to main, does it look alright to you if this is merged as part of my PR or does it suggest something went wrong in git?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ContentType stuff is from @glanzel

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@glanzel with the more simplified API now, do we still need the scenes related name?

)
object_id = models.PositiveIntegerField()
item = GenericForeignKey("content_type", "object_id")

Expand Down
4 changes: 3 additions & 1 deletion apps/augmentedreality/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from adhocracy4.api import routers as a4routers

from .api import CombinedCommentViewSet
from .api import CombinedRatingViewSet

ct_router = a4routers.ContentTypeDefaultRouter()
ct_router.register(r"arpas_comments", CombinedCommentViewSet, basename="arpas_comments")
ct_router.register(r"arpas-comments", CombinedCommentViewSet, basename="arpas-comments")
ct_router.register(r"arpas-ratings", CombinedRatingViewSet, basename="arpas-ratings")

urlpatterns = ct_router.urls
2 changes: 2 additions & 0 deletions apps/userdashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views import generic
from guest_user.mixins import RegularUserRequiredMixin

from adhocracy4.actions.models import Action
from adhocracy4.comments.models import Comment
Expand All @@ -18,6 +19,7 @@

class UserDashboardBaseMixin(
LoginRequiredMixin,
RegularUserRequiredMixin,
generic.base.ContextMixin,
generic.base.TemplateResponseMixin,
generic.base.View,
Expand Down
1 change: 1 addition & 0 deletions apps/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class User(auth_models.AbstractBaseUser, auth_models.PermissionsMixin):
objects = auth_models.UserManager()

USERNAME_FIELD = "username"
PASSWORD_FIELD = "username" # for django-guest-user
REQUIRED_FIELDS = ["email"]

def get_projects_follow_list(self, exclude_private_projects=False):
Expand Down
132 changes: 72 additions & 60 deletions apps/users/templates/a4_candy_users/indicator.html
Original file line number Diff line number Diff line change
@@ -1,65 +1,77 @@
{% load i18n static thumbnail settings %}
{% load i18n static thumbnail settings guest_user %}
{% if request.user.is_authenticated %}
<div class="dropdown userindicator__dropdown">
<button title="{% translate 'Menu' %}"
class="d-md-none dropdown-toggle btn btn--secondary-filled btn--attached-top header-upper__mobile-toggle"
data-bs-toggle="dropdown"
data-flip="false"
aria-haspopup="true"
aria-expanded="false"
id="user-actions-mobile">
<span class="d-none d-sm-inline-block pe-1">{% translate 'Menu' %}</span>
</button>
<button title="{% translate 'Menu' %}"
class="d-none d-md-inline-block dropdown-toggle btn btn--secondary-filled btn--attached-top btn--align-left header-upper__toggle"
data-bs-toggle="dropdown"
data-flip="false"
aria-haspopup="true"
aria-expanded="false"
id="user-actions">
<div class="userindicator__btn-img"
style="background-image: {% if request.user.avatar %} url({{ request.user.avatar|thumbnail_url:'avatar' }}) {% else %} url({{ request.user.avatar_fallback }}) {% endif %}">
{% with is_guest=user|is_guest_user %}
<div class="dropdown userindicator__dropdown">
<button title="{% translate 'Menu' %}"
class="d-md-none dropdown-toggle btn btn--secondary-filled btn--attached-top header-upper__mobile-toggle"
data-bs-toggle="dropdown"
data-flip="false"
aria-haspopup="true"
aria-expanded="false"
id="user-actions-mobile">
<span class="d-none d-sm-inline-block pe-1">{% translate 'Menu' %}</span>
</button>
<button title="{% translate 'Menu' %}"
class="d-none d-md-inline-block dropdown-toggle btn btn--secondary-filled btn--attached-top btn--align-left header-upper__toggle"
data-bs-toggle="dropdown"
data-flip="false"
aria-haspopup="true"
aria-expanded="false"
id="user-actions">
{% if not is_guest %}
<div class="userindicator__btn-img"
style="background-image: {% if request.user.avatar %} url({{ request.user.avatar|thumbnail_url:'avatar' }}) {% else %} url({{ request.user.avatar_fallback }}) {% endif %}">
</div>
{% endif %}
<div class="userindicator__btn-text text-start">
<span class="userindicator__hello">{% translate "Hello" %}, </span>
{% if not is_guest %}
<br>
<div class="u-overflow-ellipsis">{{ request.user.username }}</div>
{% else %}
<span>{% translate "Guest" %}</span>
{% endif %}
</div>
<i class="fa fa-chevron-down" aria-hidden="true"></i>
</button>
<div class="dropdown-menu dropdown-menu-end userindicator__dropdown-menu"
aria-labelledby="user-actions user-actions-mobile">
{% if request.user.is_superuser %}
<a class="dropdown-item" href="{% url 'admin:index' %}">{% translate "Admin" %}</a>
{% endif %}
{% if not is_guest %}
<a class="dropdown-item" href="{% url 'userdashboard-overview' %}">{% translate 'My Overview' %}</a>
<a class="dropdown-item" href="{% url 'account' %}">{% translate "Account Settings" %}</a>
{% for organisation in request.user.organisations %}
<a class="dropdown-item"
href="{% url 'a4dashboard:project-list' organisation_slug=organisation.slug %}">
{{ organisation.name }}
</a>
{% endfor %}
{% settings_value "APLUS_MANUAL_URL" as manual_url %}
{% if manual_url %}
<a class="dropdown-item"
href="{{ manual_url }}/{{ LANGUAGE_CODE }}:start"
target="_blank">{% translate 'Help' %}</a>
{% endif %}
{% else %}
<a class="dropdown-item" href="https://manual.adhocracy.plus/de:start" target="_blank">{% translate "Help" %}</a>
{% endif %}
<form class="form--inline"
action="{% url 'account_logout' %}"
method="post"
aria-label="{% translate 'Logout' %}">
{% csrf_token %}
<input type="hidden" name="next" value="{{ redirect_field_value }}">
<button type="submit" class="dropdown-item">{% translate "Logout" %}</button>
</form>
</div>
<div class="userindicator__btn-text text-start">
<span class="userindicator__hello">{% translate "Hello" %}</span>
<br>
<div class="u-overflow-ellipsis">{{ request.user.username }}</div>
{% endwith %}
{% else %}
<div class="btn btn--secondary-filled btn--huge btn--attached-top">
<span class="navi__item"><a href="{% url 'account_login' %}?next={{ redirect_field_value }}">{% translate "Login" %}</a></span>
<span class="d-none d-md-inline">/</span>
<span class="navi__item"><a href="{% url 'account_signup' %}?next={{ redirect_field_value }}">{% translate "Register" %}</a></span>
</div>
<i class="fa fa-chevron-down" aria-hidden="true"></i>
</button>
<div class="dropdown-menu dropdown-menu-end userindicator__dropdown-menu"
aria-labelledby="user-actions user-actions-mobile">
{% if request.user.is_superuser %}
<a class="dropdown-item" href="{% url 'admin:index' %}">{% translate "Admin" %}</a>
{% endif %}
<a class="dropdown-item" href="{% url 'userdashboard-overview' %}">{% translate 'My Overview' %}</a>
<a class="dropdown-item" href="{% url 'account' %}">{% translate "Account Settings" %}</a>
{% for organisation in request.user.organisations %}
<a class="dropdown-item"
href="{% url 'a4dashboard:project-list' organisation_slug=organisation.slug %}">
{{ organisation.name }}
</a>
{% endfor %}
{% settings_value "APLUS_MANUAL_URL" as manual_url %}
{% if manual_url %}
<a class="dropdown-item"
href="{{ manual_url }}/{{ LANGUAGE_CODE }}:start"
target="_blank">{% translate 'Help' %}</a>
{% endif %}
<form class="form--inline"
action="{% url 'account_logout' %}"
method="post"
aria-label="{% translate 'Logout' %}">
{% csrf_token %}
<input type="hidden" name="next" value="{{ redirect_field_value }}">
<button type="submit" class="dropdown-item">{% translate "Logout" %}</button>
</form>
</div>
{% else %}
<div class="btn btn--secondary-filled btn--huge btn--attached-top">
<span class="navi__item"><a href="{% url 'account_login' %}?next={{ redirect_field_value }}">{% translate "Login" %}</a></span>
<span class="d-none d-md-inline">/</span>
<span class="navi__item"><a href="{% url 'account_signup' %}?next={{ redirect_field_value }}">{% translate "Register" %}</a></span>
</div>
</div>
{% endif %}
8 changes: 8 additions & 0 deletions changelog/490.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
### Added

- unauthenticated users can add comments and ratings and a guest user will be created for them
- deps: django-guest-user (liqd fork)

### Changed

- deps: a4 branch-off for AR comment labeling
8 changes: 2 additions & 6 deletions changelog/526.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
### Added
- New Api Endpoint for the ARC Part of this Project
- Passing Variant Content Type to ARC App
- Adding propertys to Variant so it works with Comments and Ratings

### Changed
- Comments and Variants on Desktop are bound to Variant instead of Topics

### Added
- Passing Variant Content Type to ARC App

### Added
- Adding propertys to Variant so it works with Comments and Ratings

Loading
Loading