Skip to content

Commit

Permalink
Merge pull request #1159 from p2pu/2024-django-lts
Browse files Browse the repository at this point in the history
Update to Django 4.2 (LTS)
  • Loading branch information
dirkcuys authored May 15, 2024
2 parents 2a4a6dc + 778eb4f commit 66a7ad6
Show file tree
Hide file tree
Showing 47 changed files with 296 additions and 285 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:

- name: start postgres container

run: docker run -d --name=postgres -e POSTGRES_PASSWORD=password postgres:11
run: docker run -d --name=postgres -e POSTGRES_PASSWORD=password postgres:15

- name: start selenium container
run: docker run -d --name=selenium --shm-size="2g" -e SCREEN_HEIGHT=2048 selenium/standalone-chrome:4.0.0-20211102
Expand All @@ -38,9 +38,9 @@ jobs:
run: docker run --rm -i --link postgres --link selenium -e DATABASE_URL=postgres://postgres:password@postgres/lc -e SECRET_KEY=abc -e ADMIN_EMAIL=admin@localhost -e RECAPTCHA_SITE_KEY=6Le0DW8bAAAAAJUHXcKkkASxZWMIwDypy1DiBBEX p2pu/learning-circles:${IMAGE_TAG} dockerize -wait tcp://postgres:5432 /opt/django-venv/bin/python /opt/app/manage.py test
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/release'

- name: run tests and continue even if failed
- name: run tests and continue even if failed (put back hard fail until LTS is merged)
run: docker run --rm -i --link postgres --link selenium -e DATABASE_URL=postgres://postgres:password@postgres/lc -e SECRET_KEY=abc -e ADMIN_EMAIL=admin@localhost -e RECAPTCHA_SITE_KEY=6Le0DW8bAAAAAJUHXcKkkASxZWMIwDypy1DiBBEX p2pu/learning-circles:${IMAGE_TAG} dockerize -wait tcp://postgres:5432 /opt/django-venv/bin/python /opt/app/manage.py test
continue-on-error: true
continue-on-error: false
if: github.ref != 'refs/heads/master' && github.ref != 'refs/heads/release'

- name: log into registry
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WORKDIR /opt/app/
COPY package.json package-lock.json /opt/app/
COPY p2pu-theme/ /opt/app/p2pu-theme/
COPY p2pu-components/ /opt/app/p2pu-components/
RUN npm install --quiet --production
RUN npm install --omit=dev
COPY . /opt/app/
RUN npm run build

Expand Down
2 changes: 1 addition & 1 deletion announce/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.conf import settings
from django.urls import reverse
from studygroups.utils import render_to_string_ctx
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

import requests
from requests.auth import HTTPBasicAuth
Expand Down
6 changes: 3 additions & 3 deletions announce/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from django.conf.urls import url
from django.urls import re_path

from . import views

urlpatterns = [
url(r'^send/$', views.announce_webhook, name='announce_webhook'),
url(r'^mailchimp/(?P<webhook_secret>[\w-]+)$', views.mailchimp_webhook, name='announce_webhook'),
re_path(r'^send/$', views.announce_webhook, name='announce_webhook'),
re_path(r'^mailchimp/(?P<webhook_secret>[\w-]+)$', views.mailchimp_webhook, name='announce_webhook'),
]
2 changes: 1 addition & 1 deletion backup/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def backup_db():
make a backup of the database
'''

if settings.DATABASES['default']['ENGINE'] != 'django.db.backends.postgresql_psycopg2':
if settings.DATABASES['default']['ENGINE'] != 'django.db.backends.postgresql':
raise BackupFailed('Database engine not supported')

timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%d')
Expand Down
4 changes: 2 additions & 2 deletions client_logging/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.conf.urls import url
from django.urls import re_path

from . import views

urlpatterns = [
url(r'^$', views.LogPostView.as_view(), name='client_logging_logpost'),
re_path(r'^$', views.LogPostView.as_view(), name='client_logging_logpost'),
]
6 changes: 3 additions & 3 deletions community_calendar/api_urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.conf.urls import url, include
from django.urls import re_path, include

from rest_framework import routers
from .api import EventViewSet
Expand All @@ -9,6 +9,6 @@
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
url(r'^', include(router.urls)),
#url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
re_path(r'^', include(router.urls)),
#re_path(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
2 changes: 1 addition & 1 deletion community_calendar/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# coding=utf-8
from django import forms
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.utils import timezone

from .models import Event
Expand Down
10 changes: 5 additions & 5 deletions community_calendar/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from django.conf.urls import url
from django.urls import re_path

from .views import *

urlpatterns = [
url(r'^event/add/$', EventCreate.as_view(), name='community_calendar_event_create'),
url(r'^event/(?P<pk>[\d]+)/edit/$', EventUpdate.as_view(), name='community_calendar_event_edit'),
url(r'^event/(?P<pk>[\d]+)/delete/$', EventDelete.as_view(), name='community_calendar_event_delete'),
url(r'^event/(?P<pk>[\d]+)/moderate/$', EventModerate.as_view(), name='community_calendar_event_moderate'),
re_path(r'^event/add/$', EventCreate.as_view(), name='community_calendar_event_create'),
re_path(r'^event/(?P<pk>[\d]+)/edit/$', EventUpdate.as_view(), name='community_calendar_event_edit'),
re_path(r'^event/(?P<pk>[\d]+)/delete/$', EventDelete.as_view(), name='community_calendar_event_delete'),
re_path(r'^event/(?P<pk>[\d]+)/moderate/$', EventModerate.as_view(), name='community_calendar_event_moderate'),
]
6 changes: 3 additions & 3 deletions community_calendar/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.utils import formats
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django import http

from .models import Event
Expand Down Expand Up @@ -57,9 +57,9 @@ class EventDelete(DeleteView):
model = Event
success_url = reverse_lazy('studygroups_facilitator')

def delete(self, request, *args, **kwargs):
def form_valid(self, form):
messages.success(self.request, _('Your event has been deleted.'))
return super().delete(request, *args, **kwargs)
return super().form_valid(request, form)


@method_decorator(login_required, name="dispatch")
Expand Down
4 changes: 2 additions & 2 deletions contact/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.conf.urls import url
from django.urls import re_path

from contact import views

urlpatterns = [
url(r'^contact/$', views.ContactAPIView.as_view(), name='api_contact_form')
re_path(r'^contact/$', views.ContactAPIView.as_view(), name='api_contact_form')
]
2 changes: 1 addition & 1 deletion contact/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def post(self, request, *args, **kwargs):
# call async task to send email
send_contact_form_inquiry.delay(**serializer.data)

if request.GET.get('next') and not request.is_ajax():
if request.GET.get('next') and not request.headers.get('Content-Type') == 'application/json':
# TODO should this be validated?
return http.HttpResponseRedirect(request.GET.get('next'))

Expand Down
1 change: 0 additions & 1 deletion custom_registration/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
default_app_config = 'custom_registration.apps.CustomRegistrationConfig'
2 changes: 1 addition & 1 deletion custom_registration/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import PasswordResetForm
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.forms import ValidationError
from django.contrib.auth import password_validation
from django.contrib.auth.forms import UserCreationForm
Expand Down
26 changes: 13 additions & 13 deletions custom_registration/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.conf.urls import include, url
from django.urls import re_path, include
from django.contrib.auth.views import LoginView
from django.contrib.auth.views import PasswordResetView
from django.contrib.auth.views import PasswordResetConfirmView
Expand All @@ -15,16 +15,16 @@


urlpatterns = [
url(r'^fe/register/', AjaxSignupView.as_view(), name='fe_register'),
url(r'^fe/login/', AjaxLoginView.as_view(), name='fe_login'),
url(r'^fe/whoami/', WhoAmIView.as_view(), name='fe_whoami'),
url(r'^register/', SignupView.as_view(), name='register'),
url(r'^email_confirm/$', EmailConfirmRequestView.as_view(), name="email_confirm_request"),
url(r'^email_confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z\-]+)/$', EmailConfirmView.as_view(), name="email_confirm"),
url(r'^login/', LoginView.as_view(redirect_authenticated_user=True), name='login'),
url(r'^password_reset/$', PasswordResetView.as_view(form_class=CustomPasswordResetForm), name="password_reset"),
url(r'^settings/$', AccountSettingsView.as_view(), name="account_settings"),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z\-]+)/$', PasswordResetConfirmView.as_view(post_reset_login=True, success_url=reverse_lazy('studygroups_login_redirect') ), name='password_reset_confirm'),
url(r'^delete/$', AccountDeleteView.as_view(), name='account_delete'),
url(r'^', include('django.contrib.auth.urls')),
re_path(r'^fe/register/', AjaxSignupView.as_view(), name='fe_register'),
re_path(r'^fe/login/', AjaxLoginView.as_view(), name='fe_login'),
re_path(r'^fe/whoami/', WhoAmIView.as_view(), name='fe_whoami'),
re_path(r'^register/', SignupView.as_view(), name='register'),
re_path(r'^email_confirm/$', EmailConfirmRequestView.as_view(), name="email_confirm_request"),
re_path(r'^email_confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z\-]+)/$', EmailConfirmView.as_view(), name="email_confirm"),
re_path(r'^login/', LoginView.as_view(redirect_authenticated_user=True), name='login'),
re_path(r'^password_reset/$', PasswordResetView.as_view(form_class=CustomPasswordResetForm), name="password_reset"),
re_path(r'^settings/$', AccountSettingsView.as_view(), name="account_settings"),
re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z\-]+)/$', PasswordResetConfirmView.as_view(post_reset_login=True, success_url=reverse_lazy('studygroups_login_redirect') ), name='password_reset_confirm'),
re_path(r'^delete/$', AccountDeleteView.as_view(), name='account_delete'),
re_path(r'^', include('django.contrib.auth.urls')),
]
7 changes: 5 additions & 2 deletions custom_registration/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.utils.http import urlsafe_base64_decode
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.debug import sensitive_post_parameters
Expand Down Expand Up @@ -290,7 +290,7 @@ class AccountDeleteView(DeleteView):
def get_object(self):
return self.request.user

def delete(self, request, *args, **kwargs):
def form_valid(self, form):
user = self.request.user

# mark user account as deleted
Expand All @@ -310,6 +310,7 @@ def delete(self, request, *args, **kwargs):
user.username = random_username
user.save()

# ?? delete learning circles if user is deleted? Should this maybe only happen for upcoming and draft lerning circles?
for lc in StudyGroup.objects.active().filter(facilitator__user=user):
if lc.facilitator_set.count() == 1:
lc.deleted_at = timezone.now()
Expand All @@ -319,6 +320,8 @@ def delete(self, request, *args, **kwargs):

lc.save()

# TODO delete team membership

# delete profile data
profile = user.profile
profile.avatar = ''
Expand Down
4 changes: 2 additions & 2 deletions discourse_sso/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.conf.urls import url
from django.urls import re_path

from . import views

urlpatterns = [
url(r'^sso_redirect/$', views.discourse_sso, name='discourse_sso'),
re_path(r'^sso_redirect/$', views.discourse_sso, name='discourse_sso'),
]
9 changes: 5 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
version: '3'
services:
postgres:
image: postgres:11
image: postgres:15
ports:
- 5432:5432
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- ./compose/postgres:/var/lib/postgresql/data
- ./compose/postgres-15:/var/lib/postgresql/data
rabbitmq:
image: rabbitmq:3
email:
Expand All @@ -22,8 +21,10 @@ services:
- .:/opt/app
command: sh -c "npm i && npm run watch"
learning-circles:
build: .
image: p2pu/learning-circles:local
build:
context: .
network: host
ports:
- 8000:8000
volumes:
Expand Down
2 changes: 1 addition & 1 deletion e2e/tests/selenium/page_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def click_schedule_meetings_button(self):
meetings_button.click()

def click_login_link(self):
self.driver.find_element_by_css_selector('.registration-modal-content button:first-child').click()
self.driver.find_element(By.CSS_SELECTOR, '.registration-modal-content button:first-child').click()

def fill_out_login_modal(self, user_data):
self.fill_text_field(RegistrationModalLocators.EMAIL_FIELD, user_data["email"])
Expand Down
6 changes: 3 additions & 3 deletions e2e/tests/test_learning_circle_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ def setUpClass(cls):
chrome_options.add_argument('--disable-gpu')
#chrome_options.add_argument('--auto-open-devtools-for-tabs')
#chrome_options.add_argument('--start-maximized')
capabilities = DesiredCapabilities.CHROME
capabilities['loggingPrefs'] = { 'browser':'ALL' }
#capabilities = DesiredCapabilities.CHROME
#capabilities['loggingPrefs'] = { 'browser':'ALL' }
cls.driver = webdriver.Remote(
command_executor='http://selenium:4444/wd/hub',
desired_capabilities=capabilities,
#desired_capabilities=capabilities,
options=chrome_options
)
timeout = 10
Expand Down
13 changes: 7 additions & 6 deletions e2e/tests/test_learning_circle_manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ def setUpClass(cls):
chrome_options.add_argument('--disable-gpu')
#chrome_options.add_argument('--auto-open-devtools-for-tabs')
chrome_options.add_argument('--start-maximized')
capabilities = DesiredCapabilities.CHROME
capabilities['loggingPrefs'] = { 'browser':'ALL' }
#capabilities = DesiredCapabilities.CHROME
#capabilities['loggingPrefs'] = { 'browser':'ALL' }
cls.driver = webdriver.Remote(
command_executor='http://selenium:4444/wd/hub',
desired_capabilities=capabilities,
#desired_capabilities=capabilities,
options=chrome_options
)
timeout = 10
Expand Down Expand Up @@ -125,7 +125,7 @@ def test_meeting_feedback(self):
(By.CSS_SELECTOR, "#meeting-1-feedback #id_attendance")
))

attendance = self.driver.find_element_by_css_selector("#meeting-1-feedback #id_attendance")
attendance = self.driver.find_element(By.CSS_SELECTOR, "#meeting-1-feedback #id_attendance")
actions = ActionChains(self.driver)
actions.pause(1)
actions.move_to_element(attendance).perform()
Expand Down Expand Up @@ -170,7 +170,7 @@ def test_learning_circle_rating(self):
(By.CSS_SELECTOR, rating_qs)
))

rating_feedback = self.driver.find_element_by_css_selector(rating_qs)
rating_feedback = self.driver.find_element(By.CSS_SELECTOR, rating_qs)
actions = ActionChains(self.driver)
actions.pause(1)
actions.move_to_element(rating_feedback)
Expand Down Expand Up @@ -201,7 +201,8 @@ def test_course_rating(self):

self.driver.execute_script('window.scrollBy(0, 800);')
self.assertEquals(StudyGroup.objects.get(pk=1).course_rating, None)
course_rating = self.driver.find_element_by_css_selector(
course_rating = self.driver.find_element(
By.CSS_SELECTOR,
"div.star-rating-input:nth-child(2) > label:nth-child(4) > svg:nth-child(2)"
)
actions = ActionChains(self.driver)
Expand Down
11 changes: 7 additions & 4 deletions learnwithpeople/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,13 @@

# Exempt trusted domains
CSRF_TRUSTED_ORIGINS = [
'.p2pu.org',
'https://*.p2pu.org',
]
if DEBUG:
CSRF_TRUSTED_ORIGINS += [
'localhost:8000',
'localhost:3001',
'localhost:4000',
'http://localhost:8000',
'http://localhost:3001',
'http://localhost:4000',
]

# CORS config
Expand Down Expand Up @@ -342,6 +342,9 @@
# Explicitly set DEFAULT_AUTO_FIELD. Option added Django 3.2
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

# Update for Django 4.0 - Keep on using pytz until it's deprecated
USE_DEPRECATED_PYTZ = True

#### Backup config ####

BACKUP_DIR = os.environ.get('BACKUP_DIR', '/tmp') # Directory where backups will be stored locally
Expand Down
Loading

0 comments on commit 66a7ad6

Please sign in to comment.