Skip to content

Commit

Permalink
Merge branch 'develop' into add-redis-cache
Browse files Browse the repository at this point in the history
  • Loading branch information
deawer234 committed Sep 19, 2024
2 parents 1f7fdb4 + 6f40a55 commit e028e9a
Show file tree
Hide file tree
Showing 35 changed files with 702 additions and 398 deletions.
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ default_language_version:
repos:
# basic hooks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand All @@ -23,37 +23,37 @@ repos:
- id: detect-private-key

- repo: https://github.com/pycqa/isort
rev: 5.12.0
rev: 5.13.2
hooks:
- id: isort
args: [ "--profile", "black", "--filter-files" ]

# security linter on
- repo: https://github.com/pycqa/bandit
rev: 1.7.5
rev: 1.7.9
hooks:
- id: bandit
name: check security by Bandit
args: [ '-iii', '-ll' ]

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: 'v0.1.6'
rev: 'v0.6.5'
hooks:
- id: ruff
name: lint by Ruff
args: [ --fix, --exit-non-zero-on-fix ]

# uncompromise python formatter
- repo: https://github.com/psf/black
rev: 23.11.0
rev: 24.8.0
hooks:
- id: black
name: format by black
exclude: ^.*\b(migrations)\b.*$

- repo: https://github.com/Riverside-Healthcare/djlint
rev: 'v1.34.0' # replace with the latest tag on GitHub
rev: 'v1.35.2' # replace with the latest tag on GitHub
hooks:
- id: djlint-django
entry: djlint --reformat
Expand Down
8 changes: 5 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ ARG DJANGO_RELEASE_NAME
ARG SENTRY_RELEASE_NAME
ARG SENTRY_RELEASE_ENVIRONMENT

ARG PYTHON_IMAGE=python:3.12.6-alpine3.20

#
# wiki renderer image
#
Expand Down Expand Up @@ -91,7 +93,7 @@ RUN \
#

# venv builder
FROM python:3.11.3-alpine3.17 as web-venv-builder
FROM ${PYTHON_IMAGE} as web-venv-builder

ARG POETRY_EXPORT_ARGS

Expand All @@ -113,7 +115,7 @@ RUN poetry export --without-hashes ${POETRY_EXPORT_ARGS} -o /tmp/requirements.tx
RUN --mount=type=cache,target=/root/.cache/pip /venv/bin/pip install -r /tmp/requirements.txt

# base runtime image
FROM python:3.11.3-alpine3.17 as web-base
FROM ${PYTHON_IMAGE} as web-base

COPY --from=web-venv-builder /venv /venv

Expand Down Expand Up @@ -178,7 +180,7 @@ CMD ["python -m gunicorn -b [::]:8000 fiesta.wsgi:application"]
#
# proxy image
#
FROM nginx:1.25.2-alpine as proxy-base
FROM nginx:1.26.0-alpine as proxy-base

RUN rm /etc/nginx/conf.d/default.conf

Expand Down
42 changes: 23 additions & 19 deletions charts/templates/web-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ metadata:
{{- include "fiesta.labels" . | nindent 4 }}
{{- include "fiesta.componentLabels" "web" | nindent 4 }}
spec:
replicas: 3
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
Expand Down Expand Up @@ -37,24 +37,28 @@ spec:
- containerPort: {{ .Values.web.port }}
protocol: TCP
name: web
{{/* readinessProbe:*/}}
{{/* initialDelaySeconds: 5*/}}
{{/* */}}{{/* httpget doesn't work, timeouted */}}
{{/* exec:*/}}
{{/* command:*/}}
{{/* - wget*/}}
{{/* - 'http://localhost:{{ .Values.web.port }}/!/web'*/}}
{{/* - --header*/}}
{{/* - 'Host: {{ .Values.ingress.host | quote }}'*/}}
{{/* livenessProbe:*/}}
{{/* initialDelaySeconds: 5*/}}
{{/* periodSeconds: 20*/}}
{{/* exec:*/}}
{{/* command:*/}}
{{/* - wget*/}}
{{/* - 'http://localhost:{{ .Values.web.port }}/!/web'*/}}
{{/* - --header*/}}
{{/* - 'Host: {{ .Values.ingress.host | quote }}'*/}}
readinessProbe:
initialDelaySeconds: 3
# httpget doesn't work, timeouted
exec:
command:
- wget
- 'http://localhost:{{ .Values.web.port }}/!/web'
- --header
- 'Host: {{ .Values.ingress.host }}'
- -O
- /dev/null
livenessProbe:
initialDelaySeconds: 3
periodSeconds: 20
exec:
command:
- wget
- 'http://localhost:{{ .Values.web.port }}/!/web'
- --header
- 'Host: {{ .Values.ingress.host }}'
- -O
- /dev/null
envFrom:
- secretRef:
name: {{ .Values.web.secretName }}
Expand Down
2 changes: 1 addition & 1 deletion docs
Submodule docs updated from ac4e17 to 31f325
3 changes: 1 addition & 2 deletions fiesta/apps/accounts/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
from django_htmx.http import HttpResponseClientRedirect


class SocialAccountAdapter(DefaultSocialAccountAdapter):
...
class SocialAccountAdapter(DefaultSocialAccountAdapter): ...


class AccountAdapter(DefaultAccountAdapter):
Expand Down
3 changes: 1 addition & 2 deletions fiesta/apps/accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,4 @@ def get_queryset(self, request):


@admin.register(EmailAddress)
class FiestaEmailAddressAdmin(EmailAddressAdmin):
... # to have it in accounts admin
class FiestaEmailAddressAdmin(EmailAddressAdmin): ... # to have it in accounts admin
2 changes: 1 addition & 1 deletion fiesta/apps/accounts/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Meta(AbstractUser.Meta):

@property
def primary_email(self):
return self.emailaddress_set.filter(primary=True).first() or self.email
return next((email for email in self.emailaddress_set.all() if email.primary), self.email)


__all__ = ["User"]
12 changes: 8 additions & 4 deletions fiesta/apps/buddy_system/views/matches.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ class MyBuddies(EnsureLocalUserViewMixin, ListView):

def get_queryset(self):
return (
self.request.user.buddy_system_request_matches.prefetch_related("request__issuer__profile")
.select_related("request", "matcher")
.filter(
request__state=BaseRequestProtocol.State.MATCHED,
self.request.user.buddy_system_request_matches.prefetch_related(
"request__issuer__emailaddress_set",
)
.select_related(
"request__issuer__profile__user",
"request__issuer__profile__university",
"request__issuer__profile__faculty",
)
.filter(request__state=BaseRequestProtocol.State.MATCHED)
)
16 changes: 10 additions & 6 deletions fiesta/apps/buddy_system/views/matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,19 @@ def has_permission(self):
)

def get_permission_denied_message(self):
if not self._policy.can_member_match(membership=self.request.membership):
# can be called even in the context of unauthorized user (so no policy available)
if self._policy and not self._policy.can_member_match(membership=self.request.membership):
return _("You have reached the limit of request matches in time window.")
return super().get_permission_denied_message()

def get_queryset(self):
return self.configuration.matching_policy_instance.limit_requests(
qs=BuddyRequest.objects.get_queryset(),
qs=BuddyRequest.objects.get_queryset().select_related(
# select all potentially necessary fields in the template afterward
"issuer__profile__user",
"issuer__profile__university",
"issuer__profile__faculty",
),
membership=self.request.membership,
)

Expand Down Expand Up @@ -95,12 +101,10 @@ def get_request_queryset(cls, request: HttpRequest):
return request.membership.section.buddy_system_requests


class IssuerPictureServeView(ServeFilesFromBuddiesMixin, BaseIssuerPictureServeView):
...
class IssuerPictureServeView(ServeFilesFromBuddiesMixin, BaseIssuerPictureServeView): ...


class MatcherPictureServeView(
ServeFilesFromBuddiesMixin,
BaseMatcherPictureServeView,
):
...
): ...
1 change: 0 additions & 1 deletion fiesta/apps/dashboard/models/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


class DashboardConfiguration(BasePluginConfiguration):
...

class Meta:
verbose_name = _("dashboard configuration")
Expand Down
5 changes: 1 addition & 4 deletions fiesta/apps/events/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,7 @@ class State(models.TextChoices):


def has_permission_for_cover_photo_view(request: HttpRequest, name: str) -> bool: # TODO
if request.user.is_authenticated:
return True

return False
return request.user.is_authenticated


class Event(BaseTimestampedModel):
Expand Down
7 changes: 2 additions & 5 deletions fiesta/apps/events/models/price_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,11 @@ def is_available(self, variant: PriceVariant, user: User):
if to_ is not None and to_ != "" and to_ > datetime.now(UTC):
return False

if variant.type == self.STANDARD or (
return variant.type == self.STANDARD or (
variant.type == self.WITH_ESN_CARD
and user.profile_or_none is not None
and user.profile.is_esn_card_holder()
):
return True

return False
)


class PriceVariant(BaseModel):
Expand Down
5 changes: 5 additions & 0 deletions fiesta/apps/fiestarequests/forms/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ class Meta:
def clean_matcher(self):
matcher: User = self.cleaned_data["matcher"]

if not matcher.profile_or_none:
raise ValidationError(
_("This user has not completed their profile. Please ask them to do so before matching.")
)

if not matcher.profile_or_none.faculty:
raise ValidationError(_("This user has not set their faculty. Please ask them to do so or do it yourself."))

Expand Down
3 changes: 1 addition & 2 deletions fiesta/apps/fiestarequests/matching_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ def can_member_match(self, membership: SectionMembership) -> bool:
def on_created_request(
self,
request: BuddyRequest,
) -> None:
...
) -> None: ...

@classmethod
def _base_filter(cls, membership: SectionMembership) -> Q:
Expand Down
1 change: 0 additions & 1 deletion fiesta/apps/fiestatables/views/htmx.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,3 @@ def get_context_data(self, **kwargs):
except EmptyPage:
if self.request.GET.get("page"):
...
...
3 changes: 3 additions & 0 deletions fiesta/apps/files/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,7 @@ def object_response_headers(self, name: str) -> dict[str, str]:
# TODO: think about defining public url of bucket directly to nginx proxypass conf
"X-Accel-Redirect-Host": settings.S3_PUBLIC_URL,
"X-Accel-Redirect-Path": f"{self.namespace}/{name}",
# https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering
# waiting for a client is fine here, it's not blocking us but the S3
"X-Accel-Buffering": "no",
}
1 change: 0 additions & 1 deletion fiesta/apps/pages/models/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


class PagesConfiguration(BasePluginConfiguration):
...

class Meta:
verbose_name = _("pages configuration")
Expand Down
8 changes: 6 additions & 2 deletions fiesta/apps/pickup_system/views/matches.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ class MyPickups(EnsureLocalUserViewMixin, ListView):

def get_queryset(self):
return (
self.request.user.pickup_system_request_matches.prefetch_related("request__issuer__profile")
.select_related("request", "matcher")
self.request.user.pickup_system_request_matches.prefetch_related("request__issuer__emailaddress_set")
.select_related(
"request__issuer__profile__user",
"request__issuer__profile__university",
"request__issuer__profile__faculty",
)
.filter(
request__state=BaseRequestProtocol.State.MATCHED,
)
Expand Down
12 changes: 7 additions & 5 deletions fiesta/apps/pickup_system/views/matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ class MatchingRequestsView(
model = PickupRequest

def get_queryset(self):
return self.request.in_space_of_section.pickup_system_requests.filter(
return self.request.in_space_of_section.pickup_system_requests.select_related(
"issuer__profile__user",
"issuer__profile__university",
"issuer__profile__faculty",
).filter(
state=PickupRequest.State.CREATED,
)

Expand Down Expand Up @@ -69,12 +73,10 @@ def get_request_queryset(cls, request: HttpRequest):
return request.membership.section.pickup_system_requests


class IssuerPictureServeView(ServeFilesFromPickupsMixin, BaseIssuerPictureServeView):
...
class IssuerPictureServeView(ServeFilesFromPickupsMixin, BaseIssuerPictureServeView): ...


class MatcherPictureServeView(
ServeFilesFromPickupsMixin,
BaseMatcherPictureServeView,
):
...
): ...
2 changes: 1 addition & 1 deletion fiesta/apps/plugins/models/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __str__(self):

def clean(self):
# cannot use isinstance, since children are allowed to create
if type(self) == BasePluginConfiguration:
if type(self) == BasePluginConfiguration: # noqa: E721
raise ValidationError(_("Base plugin configuration cannot be saved directly, only children."))


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def _check_for_plugin(self, plugin: Plugin):
# }

match plugin.app_config:
case (BuddySystemConfig() | PickupSystemConfig()):
case BuddySystemConfig() | PickupSystemConfig():
self._check_field_dependency(
plugin=plugin,
field_value=sections_conf.required_faculty,
Expand Down
3 changes: 1 addition & 2 deletions fiesta/apps/sections/views/membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
with_object_breadcrumb,
with_plugin_home_breadcrumb,
)
from apps.utils.models.query import get_single_object_or_none


def page_title(view: DetailView | View) -> BreadcrumbItem:
Expand Down Expand Up @@ -161,7 +160,7 @@ class UserDetailRedirectView(
):
def get_redirect_url(self, *args, **kwargs):
user = get_object_or_404(User, pk=kwargs.get("pk"))
membership = get_single_object_or_none(
membership = get_object_or_404(
self.request.in_space_of_section.memberships,
user=user,
)
Expand Down
7 changes: 2 additions & 5 deletions fiesta/apps/sections/views/mixins/membership.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,8 @@ def test_func(self):
# !membership OR (membership.section==in_space_of_section)
return False

if not self.test_membership(membership=membership):
# right section, but without sufficient role
return False

return True
return self.test_membership(membership=membership)
# False = right section, but without sufficient role

def test_membership(self, membership: SectionMembership) -> bool:
raise NotImplementedError("To be overriden")
Expand Down
Loading

0 comments on commit e028e9a

Please sign in to comment.