Skip to content
This repository has been archived by the owner on Oct 6, 2024. It is now read-only.

Upgrade to django42 #1341

Merged
merged 16 commits into from
Apr 3, 2024
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
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ jobs:
- name: run pytest
shell: bash
run: docker-compose run --use-aliases web-e2e pytest

4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM nikolaik/python-nodejs:python3.9-nodejs14
FROM nikolaik/python-nodejs:python3.9-nodejs18


RUN mkdir /app
Expand All @@ -13,7 +13,7 @@ COPY webpack.config.js .
COPY tsconfig.json .
RUN npm ci
COPY /eahub/base/static/ ./eahub/base/static/
RUN npm run build
RUN NODE_OPTIONS=--openssl-legacy-provider npm run build

COPY . .
RUN mkdir /app/static_build
Expand Down
15 changes: 8 additions & 7 deletions SETUP.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,28 @@ Instructions for developers on how to build and run the project, how to run test
- Clone [repo](https://github.com/rtcharity/eahub.org)
- Build and run frontend
- In main folder, run ```npm ci``` to install node dependencies
- Run ```npm run build-watch``` to serve frontend files
- Run ```NODE_OPTIONS=--openssl-legacy-provider npm run build-watch``` to serve frontend files
- Build and run backend
- In main folder in separate terminal window, run ```docker-compose run --rm web bash -c "python manage.py migrate"```
to build docker container and create database tables
- Run ```docker-compose up web``` to start docker container
- Load seed data: ```docker-compose run --rm web bash -c "python manage.py load_seed_data"```
- Project will be served on ```localhost:8000```
- The email client will be served on ```localhost:1080```

### Running after changes to ```packages.json```
```npm install```
You have to run this if new node dependencies have been added since you've last built the project.

### Running after changes to ```requirements.txt```
```docker-compose build --no-cache web```
You have to run this if new python dependencies have been added since you've last built the project in order to rebuild
the django backend.
You have to run this if new node dependencies have been added since you've last built the project.

### Running after adding new python package
```docker-compose run --rm web bash -c "pip-compile requirements.in > requirements.txt"```
You have to run this if you want to a new python package.

### Running after changes to ```requirements.txt```
```docker-compose build --no-cache web```
You have to run this if new python dependencies have been added since you've last built the project in order to rebuild
the django backend.

### Running after new migration files have been added
```docker-compose run --rm web bash -c "python manage.py migrate"```
You have to run this if new migration files have been added since you've last built the project.
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ services:
links:
- db:postgres
db:
image: postgres:9.6
image: postgres:13
ports:
- 5432:5432
environment:
Expand Down
2 changes: 1 addition & 1 deletion eahub/base/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from authtools import admin as authtools_admin
from django.contrib import admin
from enumfields.admin import EnumFieldListFilter
from rangefilter.filter import DateRangeFilter
from rangefilter.filters import DateRangeFilter
from solo.admin import SingletonModelAdmin

from eahub.base import models
Expand Down
20 changes: 20 additions & 0 deletions eahub/base/management/commands/load_seed_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.core.management.base import BaseCommand
from allauth.socialaccount.models import SocialApp
from django.contrib.sites.models import Site
from eahub.config.settings import DjangoEnv


import environ


class Command(BaseCommand):
help = 'Loads seed data into test and local database'

def handle(self, *args, **kwargs):
env = environ.Env().get_value("DJANGO_ENV", DjangoEnv, default=DjangoEnv.LOCAL)

if env == DjangoEnv.LOCAL or env == DjangoEnv.E2E:
socialApp = SocialApp(provider="google")
socialApp.save()
socialApp.sites.set([Site.objects.first()])

96 changes: 0 additions & 96 deletions eahub/base/static/components/tables.js

This file was deleted.

1 change: 0 additions & 1 deletion eahub/base/static/global/styles/main.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
import './fonts/open-sans.css';
import 'datatables.net-dt/css/jquery.dataTables.css';
import './main.css';
13 changes: 10 additions & 3 deletions eahub/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ class DjangoEnv(Enum):
"authtools",
"algoliasearch_django",
"sekizai",
"captcha",
"django_recaptcha",
"crispy_forms",
"crispy_bootstrap3",
"django_object_actions",
"django_cleanup.apps.CleanupConfig",
"django_pwned_passwords",
"django_extensions",
"rules.apps.AutodiscoverRulesConfig",
"sorl.thumbnail",
Expand Down Expand Up @@ -84,6 +84,8 @@ class DjangoEnv(Enum):
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"admin_reorder.middleware.ModelAdminReorder",
"django.contrib.redirects.middleware.RedirectFallbackMiddleware",
'allauth.account.middleware.AccountMiddleware',
"pwned_passwords_django.middleware.pwned_passwords_middleware",
]


Expand Down Expand Up @@ -179,7 +181,7 @@ class DjangoEnv(Enum):
AUTH_USER_MODEL = "base.User"
AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django_pwned_passwords.password_validation.PWNEDPasswordValidator"},
{"NAME": "pwned_passwords_django.validators.PwnedPasswordsValidator"},
{
"NAME": (
"django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
Expand Down Expand Up @@ -244,6 +246,7 @@ class DjangoEnv(Enum):
ACCOUNT_SIGNUP_REDIRECT_URL = reverse_lazy("profiles_app:edit_profile")
ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = ACCOUNT_SIGNUP_REDIRECT_URL
ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = ACCOUNT_SIGNUP_REDIRECT_URL

SOCIALACCOUNT_ADAPTER = "eahub.base.adapter.EAHubSocialAccountAdapter"
SOCIALACCOUNT_PROVIDERS = {
"google": {
Expand Down Expand Up @@ -385,4 +388,8 @@ class DjangoEnv(Enum):
},
]

CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap3"

CRISPY_TEMPLATE_PACK = "bootstrap3"


7 changes: 3 additions & 4 deletions eahub/config/urls.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from django.conf import settings
from django.conf.urls import url
from django.conf.urls.static import static
from django.contrib import admin
from django.contrib.auth.decorators import user_passes_test
from django.contrib.sitemaps.views import sitemap
from django.http import Http404
from django.urls import include, path
from django.urls import include, path, re_path
from django.views.generic import TemplateView
from django.views.generic.base import RedirectView

Expand Down Expand Up @@ -35,12 +34,12 @@ def staff_or_404(u):
views.CustomisedPasswordChangeView.as_view(),
name="account_reset_password",
),
url(
re_path(
"accounts/password/reset/key/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/$",
views.CustomisedPasswordResetFromKeyView.as_view(),
name="account_reset_password_from_key",
),
url(
re_path(
"profile/import-confirmation/set-password/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/$",
views.ImportPasswordResetFromKeyView.as_view(),
name="profile_import_password_set",
Expand Down
2 changes: 1 addition & 1 deletion eahub/localgroups/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from import_export import fields, widgets
from import_export.admin import ImportExportMixin
from import_export.resources import ModelResource
from rangefilter.filter import DateRangeFilter
from rangefilter.filters import DateRangeFilter

from eahub.base.models import User
from eahub.base.utils import ExportCsvMixin
Expand Down
2 changes: 1 addition & 1 deletion eahub/localgroups/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self, *, user, local_group, **kwargs):
| models.Q(pk=user.pk)
)
queryset = queryset.order_by(
"-already_selected", "profile__name", "profile__slug", "email"
"-already_selected", "profile__last_name", "profile__slug", "email"
)
forms.ModelMultipleChoiceField.__init__(self, queryset=queryset, **kwargs)

Expand Down
2 changes: 1 addition & 1 deletion eahub/localgroups/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def public_and_internal_organisers(self) -> List[User]:

return self.organisers.filter(
profile__visibility__in=[VisibilityEnum.PUBLIC, VisibilityEnum.INTERNAL]
).order_by("profile__name", "profile__slug")
).order_by("profile__last_name", "profile__slug")

def organisers_names(self):
profile_names = []
Expand Down
4 changes: 2 additions & 2 deletions eahub/localgroups/tests/test_localgroups_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def test_organisers_field(self):
form = LocalGroupForm(user=profile_public.user)
organisers_to_choose_from = form.fields["organisers"].queryset

self.assertCountEqual(
[profile_public.user, profile_internal.user], organisers_to_choose_from
self.assertQuerySetEqual(
[profile_public.user, profile_internal.user], organisers_to_choose_from, ordered=False
)
self.assertNotIn(profile_private.user, organisers_to_choose_from)
4 changes: 2 additions & 2 deletions eahub/localgroups/tests/test_localgroups_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ def test_public_and_internal_organisers(self):

actual = group.public_and_internal_organisers()

self.assertCountEqual(
[profile_internal, profile_public], [x.profile for x in list(actual)]
self.assertQuerysetEqual(
[profile_internal, profile_public], [x.profile for x in list(actual)], ordered=False
)
38 changes: 28 additions & 10 deletions eahub/localgroups/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from django.views.decorators.http import require_POST
from django.views.generic import detail as detail_views
from django.views.generic import edit as edit_views
from djangocms_helpers.utils.send_email import send_email
from rules.contrib import views as rules_views

from ..base.models import FeedbackURLConfig, MessagingLog
Expand Down Expand Up @@ -119,11 +118,22 @@ def form_valid(self, form):
if len(recipient.get_messaging_emails(self.request)) == 0:
return HttpResponse(status=500)
sender_name = form.cleaned_data["your_name"]

send_email(
email_subject=f"{sender_name} sent you a message",
template_path_without_extension="emails/message_profile",
template_context={
message = render_to_string(
"emails/message_group.txt",
{
"sender_name": sender_name,
"recipient": recipient.name,
"message": form.cleaned_data["your_message"],
"admin_email": settings.DEFAULT_FROM_EMAIL,
"feedback_url": FeedbackURLConfig.get_solo().site_url,
"profile_edit_url": self.request.build_absolute_uri(
reverse("profiles_app:edit_profile")
),
}
)
html_msg = render_to_string(
"emails/message_group.html",
{
"sender_name": sender_name,
"recipient": recipient.name,
"message": form.cleaned_data["your_message"],
Expand All @@ -132,11 +142,19 @@ def form_valid(self, form):
"profile_edit_url": self.request.build_absolute_uri(
reverse("profiles_app:edit_profile")
),
},
email_destination=sorted(recipient.get_messaging_emails(self.request))[0],
email_from=settings.DEFAULT_FROM_EMAIL,
email_reply_to=form.cleaned_data["your_email_address"],
}
)

email = EmailMultiAlternatives(
f"{sender_name} sent you a message",
message,
settings.DEFAULT_FROM_EMAIL,
[sorted(recipient.get_messaging_emails(self.request))[0]],
[],
reply_to=[form.cleaned_data["your_email_address"]]
)
email.attach_alternative(html_msg, "text/html")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

this shouldn't work as it's not EmailMultiAlternatives

email.send()
MessagingLog.objects.create(
sender_email=form.cleaned_data["your_email_address"],
recipient_email=recipient.get_messaging_emails(self.request)[0],
Expand Down
2 changes: 1 addition & 1 deletion eahub/profiles/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django_object_actions import DjangoObjectActions
from enumfields.admin import EnumFieldListFilter
from import_export.admin import ImportExportMixin
from rangefilter.filter import DateRangeFilter
from rangefilter.filters import DateRangeFilter

from eahub.base.models import User
from eahub.profiles.legacy import GivingPledge
Expand Down
2 changes: 1 addition & 1 deletion eahub/profiles/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import django_select2.forms
from captcha import fields
from django_recaptcha import fields
from django import forms
from django.conf import settings
from django.forms import ModelForm
Expand Down
Loading
Loading