Skip to content

Commit

Permalink
Merge pull request #24 from City-of-Turku/develop
Browse files Browse the repository at this point in the history
Release 1.0
  • Loading branch information
ezkat authored Apr 22, 2024
2 parents f304b52 + 7171a72 commit 86b8e82
Show file tree
Hide file tree
Showing 38 changed files with 749 additions and 268 deletions.
42 changes: 42 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
**/__pycache__
**/**.mo
**/*.py[cod]
**/.classpath
**/.coverage
**/.django_secret
**/.dockerignore
**/.editorconfig
**/.env
**/.env.example
**/.git
**/.gitignore
**/.github
**/.hound.yml
**/.mypy_cache
**/.project
**/.pytest_cache
**/.settings
**/.travis.yml
**/.toolstarget
**/venv*
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/coverage.xml
**/docker-compose*
**/compose*
**/Dockerfile*
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
htmlcov
/docs/
/media/
/static/
README.md
docker-compose.env
docker-compose.env.template
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DEBUG=1
ALLOWED_HOSTS=127.0.0.1,localhost
DATABASE_URL=postgis://arkiymparisto:password@localhost:5432/arkiymparisto
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,6 @@ sftp-config.json
target/
var/
venv/
.django_secret
static/
media/
47 changes: 44 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ To setup a database compatible with default database settings:

Create user and database

sudo -u postgres createuser -P -R -S living_environment # use password `living_environment`
sudo -u postgres createuser -P -R -S living_environment
sudo -u postgres createdb -O living_environment living_environment

Allow user to create test database

sudo -u postgres psql -c "ALTER USER living_environment CREATEDB;"

Create extensions

sudo -u postgres psql -d living_environment -c "CREATE EXTENSION IF NOT EXISTS hstore"
sudo -u postgres psql -d living_environment -c "CREATE EXTENSION IF NOT EXISTS postgis"

### Daily running

* Set the `DEBUG` environment variable to `1`.
Expand All @@ -55,8 +60,44 @@ CORS_ORIGIN_WHITELIST | list | A list of origin hostnames that are authorized to
FRONTEND_APP_URL | str | absolute site url used as a link from admin page
STATIC_URL | str | absolute or relative site url used for serving static files
MEDIA_URL | str | absolute or relative site url used for serving media files
DATABASE_URL | str | Database URL with credentials
STATIC_ROOT | str | Path to static files
MEDIA_ROOT | str | Path to media files


### Starting with docker-compose

.env file example:
```
POSTGRES_USER=example_user
POSTGRES_PASSWORD=example_password
POSTGRES_DB=example_database
DATABASE_URL=postgis://example_user:example_password@db:5432/example_database
ALLOWED_HOSTS=example.domain.org
```

Build and start container (production):
```sh
docker compose -f docker-compose.yml -f docker-compose.prod.yml up --force-recreate --build --detach --no-start
docker compose -f docker-compose.yml -f docker-compose.prod.yml start
```

Build and start container (development):
```sh
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --force-recreate --build --detach --no-start
docker compose -f docker-compose.yml -f docker-compose.dev.yml start
```


Apply migrations and create a superuser
```sh
docker compose run --env DATABASE_HOST=db --rm api apply_migrations
docker compose run --env DATABASE_HOST=db --rm api createsuperuser
```


## Running tests

* Set the `DEBUG` environment variable to `1`.
* Run `py.test`.
- Set the `DEBUG` environment variable to `1`.
- Run `py.test .`
2 changes: 1 addition & 1 deletion assignments/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib import admin
from django.shortcuts import reverse
from django.utils.html import format_html
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from leaflet.admin import LeafletGeoAdmin
from polymorphic.admin import PolymorphicInlineSupportMixin, StackedPolymorphicInline

Expand Down
2 changes: 1 addition & 1 deletion assignments/apps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _


class AssignmentsConfig(AppConfig):
Expand Down
8 changes: 3 additions & 5 deletions assignments/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from django.conf import settings
from django.contrib.admin import widgets
from django.forms import ModelForm
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from sortedm2m.forms import SortedMultipleChoiceField

Expand Down Expand Up @@ -46,12 +46,10 @@ class SortedAsSelectedMultipleChoiceField(SortedMultipleChoiceField):
"""
Use select widget that preserves order of selected options
"""
def __init__(self, queryset, required=True, label=None,
initial=None, help_text='', *args, **kwargs):
def __init__(self, queryset, *args, **kwargs):
widget = SortedAsSelectedMultiple(verbose_name=queryset.model._meta.verbose_name_plural,
is_stacked=kwargs.get('is_stacked', False))
super(SortedAsSelectedMultipleChoiceField, self).__init__(queryset, required, widget, label, initial,
help_text=help_text, *args, **kwargs)
super(SortedAsSelectedMultipleChoiceField, self).__init__(queryset, *args, **kwargs)


class AssignmentForm(ModelForm):
Expand Down
5 changes: 4 additions & 1 deletion assignments/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import urllib.parse
import urllib.request

from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _

from assignments.exceptions import FeedbackSystemException

Expand All @@ -21,6 +21,9 @@ def get_description_from_errors(errors):


def post_to_feedback_system(url, data, api_key=None):
if api_key:
data['api_key'] = api_key

data = urllib.parse.urlencode(data)
data = data.encode('utf-8')
try:
Expand Down
11 changes: 3 additions & 8 deletions assignments/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Generated by Django 1.11 on 2017-05-05 08:31
from __future__ import unicode_literals

import ckeditor_uploader.fields
import django_ckeditor_5.fields
from django.db import migrations, models
import django.db.models.deletion
import django.db.models.manager
Expand All @@ -24,7 +24,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128, unique=True, verbose_name='name')),
('header', models.CharField(max_length=255, null=True, verbose_name='header')),
('description', ckeditor_uploader.fields.RichTextUploadingField(blank=True, verbose_name='description')),
('description', django_ckeditor_5.fields.CKEditor5Field(blank=True, verbose_name='description')),
('area', djgeojson.fields.GeometryField(verbose_name='area')),
('status', models.IntegerField(choices=[(0, 'Open'), (1, 'Closed')], default=0, verbose_name='status')),
('budget', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='budget')),
Expand Down Expand Up @@ -94,7 +94,7 @@ class Migration(migrations.Migration):
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255, verbose_name='title')),
('description', ckeditor_uploader.fields.RichTextUploadingField(blank=True, verbose_name='description')),
('description', django_ckeditor_5.fields.CKEditor5Field(blank=True, verbose_name='description')),
('video', models.URLField(blank=True, null=True)),
('order_number', models.IntegerField(default=0, help_text='Order in which sections are shown', verbose_name='order number')),
('assignment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sections', to='assignments.Assignment', verbose_name='Assignment')),
Expand All @@ -120,12 +120,10 @@ class Migration(migrations.Migration):
('order_number', models.IntegerField(default=0, help_text='Order in which tasks are shown', verbose_name='order number')),
],
options={
'base_manager_name': 'base_objects',
'ordering': ['order_number'],
},
managers=[
('objects', django.db.models.manager.Manager()),
('base_objects', django.db.models.manager.Manager()),
],
),
migrations.CreateModel(
Expand All @@ -144,7 +142,6 @@ class Migration(migrations.Migration):
bases=('assignments.task',),
managers=[
('objects', django.db.models.manager.Manager()),
('base_objects', django.db.models.manager.Manager()),
],
),
migrations.CreateModel(
Expand All @@ -160,7 +157,6 @@ class Migration(migrations.Migration):
bases=('assignments.task',),
managers=[
('objects', django.db.models.manager.Manager()),
('base_objects', django.db.models.manager.Manager()),
],
),
migrations.CreateModel(
Expand All @@ -176,7 +172,6 @@ class Migration(migrations.Migration):
bases=('assignments.task',),
managers=[
('objects', django.db.models.manager.Manager()),
('base_objects', django.db.models.manager.Manager()),
],
),
migrations.AddField(
Expand Down
6 changes: 3 additions & 3 deletions assignments/migrations/0012_help_text_on_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from __future__ import unicode_literals

import assignments.fields
import ckeditor_uploader.fields
import django_ckeditor_5.fields
from django.db import migrations, models
import django.db.models.deletion
import djgeojson.fields
Expand Down Expand Up @@ -33,7 +33,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='assignment',
name='description',
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True, help_text='Text used as a description of the landing section', verbose_name='description'),
field=django_ckeditor_5.fields.CKEditor5Field(blank=True, help_text='Text used as a description of the landing section', verbose_name='description'),
),
migrations.AlterField(
model_name='assignment',
Expand Down Expand Up @@ -133,7 +133,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='section',
name='description',
field=ckeditor_uploader.fields.RichTextUploadingField(blank=True, help_text='Text used as a section description', verbose_name='description'),
field=django_ckeditor_5.fields.CKEditor5Field(blank=True, help_text='Text used as a section description', verbose_name='description'),
),
migrations.AlterField(
model_name='section',
Expand Down
50 changes: 50 additions & 0 deletions assignments/migrations/0015_upgrade_django_v5.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Generated by Django 5.0.2 on 2024-02-23 03:41

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


class Migration(migrations.Migration):

dependencies = [
('assignments', '0014_add_km_unit'),
('contenttypes', '0002_remove_content_type_name'),
]

operations = [
migrations.AlterModelManagers(
name='budgetingtask',
managers=[
],
),
migrations.AlterModelManagers(
name='opentexttask',
managers=[
],
),
migrations.AlterModelManagers(
name='task',
managers=[
],
),
migrations.AlterModelManagers(
name='voluntarysignuptask',
managers=[
],
),
migrations.AlterField(
model_name='submission',
name='school',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='assignments.school'),
),
migrations.AlterField(
model_name='submission',
name='school_class',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='%(class)ss', to='assignments.schoolclass'),
),
migrations.AlterField(
model_name='task',
name='polymorphic_ctype',
field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_%(app_label)s.%(class)s_set+', to='contenttypes.contenttype'),
),
]
28 changes: 12 additions & 16 deletions assignments/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ckeditor_uploader.fields import RichTextUploadingField
from django_ckeditor_5.fields import CKEditor5Field
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from djgeojson.fields import GeometryField, PointField
from polymorphic.models import PolymorphicModel

Expand All @@ -24,7 +24,7 @@ class Assignment(models.Model):
name = models.CharField(_('name'), max_length=128, unique=True, help_text=_('Assignment name'))
header = models.CharField(_('header'), max_length=255, null=True,
help_text=_('Text used as a header of the landing section'))
description = RichTextUploadingField(_('description'), blank=True,
description = CKEditor5Field(_('description'), blank=True,
help_text=_('Text used as a description of the landing section'))
image = models.ImageField(_('image'), upload_to='assignment/image/',
blank=True, null=True, help_text=_('Main image of the landing section'))
Expand Down Expand Up @@ -65,10 +65,10 @@ class Section(models.Model):
Section is a part of assignment with tasks related to it.
"""
title = models.CharField(_('title'), max_length=255, help_text=_('Section title'))
description = RichTextUploadingField(_('description'), blank=True,
description = CKEditor5Field(_('description'), blank=True,
help_text=_('Text used as a section description'))
assignment = models.ForeignKey(Assignment, related_name='sections', verbose_name=_('Assignment'),
help_text=_('Assignment this section is related to'))
help_text=_('Assignment this section is related to'), on_delete=models.CASCADE)
video = models.URLField(null=True, blank=True, help_text=_('YouTube URL of the video embedded in the section'))
order_number = models.IntegerField(_('order number'), default=0,
help_text=_('Order in which sections are shown'))
Expand All @@ -92,10 +92,6 @@ class Task(PolymorphicModel):

class Meta:
ordering = ['order_number']
# Fix delete.
# Workaround for https://github.com/django-polymorphic/django-polymorphic/issues/229#issuecomment-246613138
base_manager_name = 'base_objects'

@property
def task_type(self):
return 'basic_task'
Expand Down Expand Up @@ -249,17 +245,17 @@ def __str__(self):


class Submission(models.Model):
school = models.ForeignKey(School, related_name='%(class)ss')
school_class = models.ForeignKey(SchoolClass, related_name='%(class)ss')
school = models.ForeignKey(School, related_name='%(class)ss', on_delete=models.CASCADE)
school_class = models.ForeignKey(SchoolClass, related_name='%(class)ss', on_delete=models.CASCADE)


class OpenTextAnswer(models.Model):
"""
Answer on OpenTextTask
"""

submission = models.ForeignKey(Submission, related_name='open_text_answers')
task = models.ForeignKey(OpenTextTask, related_name='open_text_answers')
submission = models.ForeignKey(Submission, related_name='open_text_answers', on_delete=models.CASCADE)
task = models.ForeignKey(OpenTextTask, related_name='open_text_answers', on_delete=models.CASCADE)
answer = models.TextField()


Expand All @@ -269,9 +265,9 @@ class BudgetingTargetAnswer(models.Model):
uniquely connect budgeting answer with related task
"""

submission = models.ForeignKey(Submission, related_name='budgeting_answers')
task = models.ForeignKey(BudgetingTask, related_name='budgeting_answers')
target = models.ForeignKey(BudgetingTarget, related_name='budgeting_answers')
submission = models.ForeignKey(Submission, related_name='budgeting_answers', on_delete=models.CASCADE)
task = models.ForeignKey(BudgetingTask, related_name='budgeting_answers', on_delete=models.CASCADE)
target = models.ForeignKey(BudgetingTarget, related_name='budgeting_answers', on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=10, decimal_places=2, default=0)
point = PointField(null=True, blank=True)

Expand Down
Loading

0 comments on commit 86b8e82

Please sign in to comment.