Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
supertom01 committed Sep 2, 2024
2 parents 93b7157 + fc1b23e commit 358b157
Show file tree
Hide file tree
Showing 118 changed files with 3,474 additions and 1,734 deletions.
85 changes: 85 additions & 0 deletions .github/workflows/build_docker_image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Build docker image and run tests

on: [push, pull_request]

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

services:
mariadb:
image: mariadb:10.2
env:
MARIADB_USER: amelie_test
MARIADB_PASSWORD: amelie_test
MYSQL_DATABASE: amelie_test
MYSQL_ROOT_PASSWORD: amelie_test
ports: ['3306:3306']
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Build and push Docker image
id: push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

- name: Verify MariaDB connection
run: |
while ! mysqladmin ping -h"127.0.0.1" -P"3306" --silent; do
sleep 1
done
- name: Run Amelie tests
run: |
docker run --rm --entrypoint "/amelie/scripts/run_tests.sh" ghcr.io/inter-actief/amelie@${{ steps.push.outputs.digest }}
- name: Cleanup untagged images older than 1 week
uses: snok/container-retention-policy@v2
with:
image-names: amelie
cut-off: 1 week ago UTC
account-type: org
org-name: Inter-Actief
token: ${{ secrets.GITHUB_TOKEN }}
token-type: github-token
untagged-only: true
dry-run: true

- name: Cleanup tagged images (except main, production and graphql) older than 1 month
uses: snok/container-retention-policy@v2
with:
image-names: amelie
cut-off: 1 month ago UTC
account-type: org
org-name: Inter-Actief
token: ${{ secrets.GITHUB_TOKEN }}
token-type: github-token
skip-tags: main, production, 741-graphql-api
dry-run: true
13 changes: 0 additions & 13 deletions .github/workflows/ia_gitlab_ci.yml

This file was deleted.

32 changes: 0 additions & 32 deletions .github/workflows/ia_gitlab_ci_retrieve.yml

This file was deleted.

42 changes: 42 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Build the amelie docker image based on Debian 11 (Bullseye)
FROM debian:bullseye

# Copy amelie sources
COPY . /amelie

# Set /amelie as startup working directory
WORKDIR /amelie

# Install required packages for amelie and prepare the system to run Amelie
RUN echo "Updating repostitories..." && \
apt-get update -y && \
echo "Upgrading base debian system..." && \
apt-get upgrade -y && \
echo "Installing Amelie required packages..." && \
apt-get install -y apt-utils git net-tools python3 python3-pip mariadb-client libmariadb-dev xmlsec1 libssl-dev libldap-dev libsasl2-dev libjpeg-dev zlib1g-dev gettext locales acl && \
echo "Enabling 'nl_NL' and 'en_US' locales..." && \
sed -i -e 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/' /etc/locale.gen && \
sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
echo "Rebuilding locales..." && \
dpkg-reconfigure --frontend=noninteractive locales && \
echo "Creating directories for amelie..." && \
mkdir -p /amelie /config /static /media /photo_upload /data_exports /homedir_exports /var/log /var/run && \
echo "Installing python requirements..." && \
pip3 install -r requirements.txt && \
echo "Correcting permissions on directories..." && \
chown -R 1000:1000 /amelie /config /static /media /photo_upload /data_exports /homedir_exports /var/log

# Switch back to a local user
USER 1000:1000

# Check if Django can run
RUN python3 manage.py check

# Expose volumes
VOLUME ["/config", "/static", "/media", "/photo_upload", "/data_exports", "/homedir_exports"]

# Expose the web port
EXPOSE 8000

# Start the website
CMD ["/amelie/scripts/start_web.sh"]
16 changes: 8 additions & 8 deletions amelie/about/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.translation import get_language
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_lazy as _l


class Page(models.Model):
name_nl = models.CharField(max_length=100, verbose_name=_('Name'))
name_en = models.CharField(max_length=100, verbose_name=_('Name (en)'), blank=True)
name_nl = models.CharField(max_length=100, verbose_name=_l('Name'))
name_en = models.CharField(max_length=100, verbose_name=_l('Name (en)'), blank=True)
slug_nl = models.SlugField(max_length=100, editable=False)
slug_en = models.SlugField(max_length=100, editable=False)
educational = models.BooleanField(default=False, verbose_name=_("Educational page?"))
content_nl = models.TextField(verbose_name=_('Content'))
content_en = models.TextField(verbose_name=_('Content (en)'), blank=True)
educational = models.BooleanField(default=False, verbose_name=_l("Educational page?"))
content_nl = models.TextField(verbose_name=_l('Content'))
content_en = models.TextField(verbose_name=_l('Content (en)'), blank=True)
last_modified = models.DateTimeField(auto_now=True)

class Meta:
ordering = ['name_nl']
verbose_name = _('Page')
verbose_name_plural = _("Pages")
verbose_name = _l('Page')
verbose_name_plural = _l("Pages")

def __str__(self):
return self.name
Expand Down
6 changes: 3 additions & 3 deletions amelie/activities/feeds.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from django.contrib.syndication.views import Feed
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_lazy as _l

from amelie.activities.models import Activity


class Activities(Feed):
link = '/activities/'
title = _('IA Events')
description = _('Inter-Actief\'s activities in the coming weeks')
title = _l('IA Events')
description = _l('Inter-Actief\'s activities in the coming weeks')

title_template = "feeds/news_title.html"
description_template = "feeds/news_content.html"
Expand Down
52 changes: 26 additions & 26 deletions amelie/activities/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pathlib import Path
from django.forms import widgets, SplitDateTimeField
from django.utils import formats, timezone
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext_lazy as _l

from amelie.activities.models import Activity, EnrollmentoptionQuestion, \
EnrollmentoptionCheckbox, EnrollmentoptionCheckboxAnswer, \
Expand All @@ -25,7 +25,7 @@ class PaymentForm(forms.Form):
(Participation.PaymentMethodChoices.CASH.value,
Participation.PaymentMethodChoices.CASH.label),
],
label=_('Method of payment'))
label=_l('Method of payment'))

def __init__(self, mandate=False, waiting_list=False, board=False, *args, **kwargs):
super(PaymentForm, self).__init__(*args, **kwargs)
Expand All @@ -38,17 +38,17 @@ def __init__(self, mandate=False, waiting_list=False, board=False, *args, **kwar

if waiting_list:
self.fields['waiting_list'] = forms.ChoiceField(choices=[
('Wait', _("Place on bottom of waiting list")),
], label=_("Waiting list action"))
('Wait', _l("Place on bottom of waiting list")),
], label=_l("Waiting list action"))
if board:
choices = self.fields['waiting_list'].choices
choices.append(('Skip', _("Skip waiting list and enroll immediately")))
choices.append(('Skip', _l("Skip waiting list and enroll immediately")))
self.fields['waiting_list'].choices = choices


class ActivityForm(forms.ModelForm):

price = forms.DecimalField(required=False, initial="0.00", min_value=0, decimal_places=2, label=_('Price'))
price = forms.DecimalField(required=False, initial="0.00", min_value=0, decimal_places=2, label=_l('Price'))

class Meta:
model = Activity
Expand Down Expand Up @@ -93,18 +93,18 @@ def clean(self):
self.cleaned_data['price'] = 0

if self.cleaned_data["price"] > settings.PERSONAL_TAB_MAXIMUM_ACTIVITY_PRICE and self.cleaned_data["enrollment"]:
raise forms.ValidationError(_("Website enrolment has a maximum of {0} euro. Either turn off the ability to enrol or decrease the cost of the activity.").format(settings.PERSONAL_TAB_MAXIMUM_ACTIVITY_PRICE))
raise forms.ValidationError(_l("Website enrolment has a maximum of {0} euro. Either turn off the ability to enrol or decrease the cost of the activity.").format(settings.PERSONAL_TAB_MAXIMUM_ACTIVITY_PRICE))

if self.cleaned_data["enrollment"]:
if not self.cleaned_data.get('enrollment_begin', None):
self.add_error('enrollment_begin', _('There is no enrollment start date entered.'))
self.add_error('enrollment_begin', _l('There is no enrollment start date entered.'))

if not self.cleaned_data.get('enrollment_end'):
self.add_error('enrollment_end', _('There is no enrollment end date entered.'))
self.add_error('enrollment_end', _l('There is no enrollment end date entered.'))

if self.cleaned_data.get('enrollment_begin', None) and self.cleaned_data.get('enrollment_stop', None) \
and self.cleaned_data['enrollment_stop'] < self.cleaned_data['enrollment_begin']:
self.add_error('enrollment_stop', _("Signup end must be after the signup start."))
self.add_error('enrollment_stop', _l("Signup end must be after the signup start."))

return self.cleaned_data

Expand Down Expand Up @@ -185,7 +185,7 @@ def __init__(self, enrollmentoption, checked, *args, **kwargs):
def clean_answer(self):
data = self.cleaned_data['answer']
if data and not self.enrollmentoption.spots_left():
self.add_error('answer', _("Sorry, but the last spot has been claimed already!"))
self.add_error('answer', _l("Sorry, but the last spot has been claimed already!"))
return data

class Meta:
Expand All @@ -207,9 +207,9 @@ def clean_answer(self):
if not data:
data = 0
if max_per_person is not None and data > max_per_person:
self.add_error('answer', _("Sorry, but you cannot exceed the maximum amount per person!"))
self.add_error('answer', _l("Sorry, but you cannot exceed the maximum amount per person!"))
if data > 0 and not self.enrollmentoption.spots_left():
self.add_error('answer', _("Sorry, but there are not enough spots left!"))
self.add_error('answer', _l("Sorry, but there are not enough spots left!"))
return data

class Meta:
Expand All @@ -232,17 +232,17 @@ class PhotoCheckboxSelectMultiple(widgets.CheckboxSelectMultiple):


class PhotoUploadForm(forms.Form):
photographer = forms.ModelChoiceField(Person.objects.none(), label=_('Photographer'), required=False)
first_name = forms.CharField(max_length=50, label=_('First name'), required=False,
help_text=_('Use this field if a non-member is the owner of these pictures'))
last_name_prefix = forms.CharField(max_length=25, label=_('Last name pre-fix'), required=False,
help_text=_('Use this field if a non-member is the owner of these pictures'))
last_name = forms.CharField(max_length=50, label=_('Last name'), required=False,
help_text=_('Use this field if a non-member is the owner of these pictures'))
activity = ActivityModelChoiceField(Activity.objects.none(), label=_('Activities'))
public = forms.BooleanField(label=_('Public'), required=False,
help_text=_('Photos are also available without logging in'), initial=True)
photos = forms.MultipleChoiceField(widget=PhotoCheckboxSelectMultiple, label=_('Photos'))
photographer = forms.ModelChoiceField(Person.objects.none(), label=_l('Photographer'), required=False)
first_name = forms.CharField(max_length=50, label=_l('First name'), required=False,
help_text=_l('Use this field if a non-member is the owner of these pictures'))
last_name_prefix = forms.CharField(max_length=25, label=_l('Last name pre-fix'), required=False,
help_text=_l('Use this field if a non-member is the owner of these pictures'))
last_name = forms.CharField(max_length=50, label=_l('Last name'), required=False,
help_text=_l('Use this field if a non-member is the owner of these pictures'))
activity = ActivityModelChoiceField(Activity.objects.none(), label=_l('Activities'))
public = forms.BooleanField(label=_l('Public'), required=False,
help_text=_l('Photos are also available without logging in'), initial=True)
photos = forms.MultipleChoiceField(widget=PhotoCheckboxSelectMultiple, label=_l('Photos'))

def __init__(self, photos, *args, **kwargs):
super(PhotoUploadForm, self).__init__(*args, **kwargs)
Expand Down Expand Up @@ -281,7 +281,7 @@ def clean_photo_files(self):
extension = Path(file.name).suffix[1:].lower()
if extension not in allowed_extensions:
raise ValidationError(
message=_('File extension “%(extension)s” is not allowed. '
message=_l('File extension “%(extension)s” is not allowed. '
'Allowed extensions are: %(allowed_extensions)s.'),
code='invalid_extension',
params={'extension': extension,
Expand All @@ -291,7 +291,7 @@ def clean_photo_files(self):


class EventDeskActivityMatchForm(forms.Form):
activity = ActivityModelChoiceField(Activity.objects.none(), label=_('Activity'))
activity = ActivityModelChoiceField(Activity.objects.none(), label=_l('Activity'))

def __init__(self, activities, *args, **kwargs):
super(EventDeskActivityMatchForm, self).__init__(*args, **kwargs)
Expand Down
6 changes: 6 additions & 0 deletions amelie/activities/graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,18 @@ class Meta:

class ActivitiesQuery(graphene.ObjectType):
activities = DjangoPaginationConnectionField(ActivityType, organizer=graphene.ID())
activity = graphene.Field(ActivityType, id=graphene.ID())

def resolve_activities(self, info, organizer=None, *args, **kwargs):
if organizer:
return Activity.objects.filter(organizer__pk=organizer)
return Activity.objects.all()

def resolve_activity(self, info, id, *args, **kwargs):
if id:
return Activity.objects.get(pk=id)
return None

# Exports
GRAPHQL_QUERIES = [ActivitiesQuery]
GRAPHQL_MUTATIONS = []
Loading

0 comments on commit 358b157

Please sign in to comment.