4 Commits

Author SHA1 Message Date
Aarni Halinen ee1345c90c Merge branch 'develop' into clean-old-templates 2022-01-14 00:00:54 +02:00
Aarni Halinen 28cd34e973 common footer template 2021-11-17 18:16:27 +02:00
Aarni Halinen bfa11ba4fc move footer out of webapp 2021-11-17 18:16:27 +02:00
Aarni Halinen 52f536d350 remove old templates 2021-11-17 18:16:27 +02:00
136 changed files with 2358 additions and 3281 deletions
-32
View File
@@ -1,32 +0,0 @@
.DS_Store
.dockerignore
.git/
.husky/
.venv/
.vscode/
collected_static/
logs/
!logs/README
media/
!media/REMOVE_ME
misc/
node_modules/
scripts/
.coverage
.coveragerc
.env*
.eslintignore
.eslintrc.json
.gitignore
.gitlab-ci.yml
.python-version
docker-compose.yml
!manage.py
package*.json
!poetry.lock
!production_entrypoint.sh
pycodestyle.cfg
!pyproject.toml
pyright.json
README.md
stack-compose*.yml
+1
View File
@@ -3,6 +3,7 @@ SENTRY_DSN=
HOST=api.dev.sahkoinsinoorikilta.fi
DEBUG=True
SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(
TG_BOT_TOKEN=
DB_NAME=postgres
DB_USER=postgres
DB_PASSWD=postgres
+1 -2
View File
@@ -3,11 +3,10 @@ DEPLOY_ENV=local
HOST=localhost
DEBUG=True
SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(
TG_BOT_TOKEN=
DB_NAME=postgres
DB_USER=postgres
DB_PASSWD=postgres
DB_HOST=db
DB_PORT=5432
EMAIL_API_KEY=
GROUP_KEY=
GOOGLE_CREDS='{}'
-1
View File
@@ -1,6 +1,5 @@
members/static/js/lib
infoscreen/static/js/lib
webapp/static/js/lib
static/js/lib
collected_static
venv
+1 -1
View File
@@ -11,4 +11,4 @@ node_modules/
.idea/
*.code-workspace
venv/
.venv/
.venv/
+6 -6
View File
@@ -7,7 +7,7 @@ stages:
- deploy
install:
image: node:16
image: node:14
stage: setup
script:
- npm ci
@@ -21,7 +21,7 @@ audit:
stage: audit
needs: []
before_script:
- pip install poetry==1.1.13
- pip install poetry==1.1.4
- poetry config virtualenvs.create false
- poetry install --no-interaction --no-ansi
script:
@@ -40,7 +40,7 @@ test:
DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/$POSTGRES_DB"
DB_HOST: postgres
before_script:
- pip install poetry==1.1.13
- pip install poetry==1.1.4
- poetry config virtualenvs.create false
- poetry install --no-interaction --no-ansi
script:
@@ -53,18 +53,18 @@ lint:py:
stage: lint
needs: []
script:
- pip install black==22.3.0
- pip install black==21.12b0
- black --check .
lint:js:
image: node:16
image: node:14
stage: lint
needs: ["install"]
script:
- npm run lint:js
lint:md:
image: node:16
image: node:14
stage: lint
needs: ["install"]
script:
-15
View File
@@ -1,15 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
. "${VIRTUAL_ENV}/bin/activate"
if [ $? -ne 0 ]
then
printf "${PURPLE}Failed to find virtualenv. Skipping pre-commit hook.\n${NC}"
exit 0
fi
npm run lint
+1 -1
View File
@@ -4,7 +4,7 @@
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
. "${VIRTUAL_ENV}/bin/activate"
source "${VIRTUAL_ENV}/bin/activate"
if [ $? -ne 0 ]
then
-1
View File
@@ -1 +0,0 @@
16
+3 -3
View File
@@ -2,10 +2,10 @@ FROM python:3.9-slim-buster as builder
ENV PYTHONUNBUFFERED 1
COPY . ./
ENV POETRY_VERSION=1.1.13
ENV POETRY_VERSION=1.1.4
RUN pip install "poetry==$POETRY_VERSION"
RUN poetry export --without-hashes > requirements.txt
RUN poetry export > requirements.txt
FROM python:3.9-slim-buster as server
@@ -22,7 +22,7 @@ ENV PYTHONUNBUFFERED=1 \
PIP_DEFAULT_TIMEOUT=100
RUN apt-get update && apt-get install --no-install-recommends -y build-essential
RUN pip install --no-deps -r requirements.txt
RUN pip install -r requirements.txt
RUN python manage.py collectstatic --noinput
CMD ["sh", "-c", "./production_entrypoint.sh"]
@@ -1,28 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-01 19:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("infoscreen", "0007_lunchitem"),
]
operations = [
migrations.AlterField(
model_name="infoinstance",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name="infoitem",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name="rotation",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
]
-5
View File
@@ -16,7 +16,6 @@ class InfoItem(models.Model):
class __meta__:
abstract = True
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
# expire_date = None means never expiring item
expire_date = models.DateTimeField(blank=True, null=True)
@@ -317,7 +316,6 @@ class ExternalImageInfoItem(InfoItem):
class InfoInstance(models.Model):
"""Class for Info instance in Infoscreen."""
id = models.AutoField(primary_key=True)
rotation = models.ForeignKey(
"Rotation", related_name="instances", on_delete=models.CASCADE
)
@@ -358,7 +356,6 @@ class InfoInstance(models.Model):
class Rotation(models.Model):
"""Class for rotation model."""
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
def get_dict(self):
@@ -391,7 +388,6 @@ class Rotation(models.Model):
class ImageUploadForm(forms.Form):
"""Form used to handle imageuploads to infoscreen app."""
id = models.AutoField(primary_key=True)
name = forms.CharField()
image = forms.ImageField()
@@ -399,6 +395,5 @@ class ImageUploadForm(forms.Form):
class UploadFileForm(forms.Form):
"""Form used for uploading file."""
id = models.AutoField(primary_key=True)
name = forms.CharField()
video = forms.FileField()
+1 -1
View File
@@ -3,7 +3,7 @@ body {
}
#header:after {
content: " ";
content: " ";
display: block;
clear: both;
}
+2 -2
View File
@@ -12,7 +12,7 @@ body {
.event {
font-size: 100px;
font-weight: bold;
margin-left: 20px;
margin-left: 20px;
}
.event-col{
padding-top:1vh;
@@ -21,7 +21,7 @@ body {
.header-row{
margin: 30px;
margin-left: 20px;
margin-left: 20px;
font-size: 130px;
padding-bottom:20px;
color:#24a05f;
@@ -1,8 +1,8 @@
#infocontent {
width: 100%;
height: 100%;
position: fixed;
left: 0px;
width: 100%;
height: 100%;
position: fixed;
left: 0px;
top: 0px;
z-index: -1; /* Ensure div tag stays behind content; -999 might work, too. */
}
+3 -3
View File
@@ -31,10 +31,10 @@
max-height 200px;
}
#sossoimage {
#sossoimage {
height:300px;
position: relative;
left: 0px;
position: relative;
left: 0px;
top: 0px;
}
@@ -1,5 +1,5 @@
<link rel="stylesheet" href="/static/infoscreen/css/events.css">
<link href="https://fonts.googleapis.com/css?family=Droid+Sans+Mono" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Droid+Sans+Mono" rel="stylesheet">
<div class="container" ng-app="myApp" ng-controller="EventController">
<div class="header-row row">
<div class="col-sm-6">Tapahtuma</div>
@@ -1,5 +1,6 @@
{% load i18n %}
{% load static %}
{% load staticfiles %}
<!DOCTYPE html>
@@ -28,7 +29,7 @@
{% block styles %}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="{% static "webapp/css/footer.css" %}">
<link rel="stylesheet" href="{% static "css/footer.css" %}">
{% endblock styles %}
{% block controllers %}
@@ -1,7 +1,8 @@
{% extends "infoscreen/base.html" %}
{% extends "infoscreen:base.html" %}
{% load i18n %}
{% load static %}
{% load staticfiles %}
{% block appname %}infoAdmin{% endblock appname %}
@@ -32,11 +33,11 @@
<h1>{% trans "Infoscreen Admin Pane" %}</h1>
</div>
</div>
{% include "infoscreen/nav.html" %}
{% include "infoscreen:nav.html" %}
<div class="tab-content" id="tabContent">
{% include "infoscreen/tabs/slides.html" %}
{% include "infoscreen/tabs/rotations.html" %}
{% include "infoscreen/tabs/add_remove.html" %}
{% include "infoscreen:tabs/slides.html" %}
{% include "infoscreen:tabs/rotations.html" %}
{% include "infoscreen:tabs/add_remove.html" %}
</div>
</div>
@@ -1,4 +1,4 @@
{% extends "infoscreen/base.html" %}
{% extends "infoscreen:base.html" %}
{% load static %}
{% load i18n %}
@@ -26,7 +26,7 @@
<div class="col">
<div class="rotation-title-row">
<h2>{% trans "Rotation" %}: {$ selected_rot.name $}</h2>
<a class="btn btn-primary" href="/infoscreen/{$ selected_rot.id $}">{% trans "Preview" %}</a>
<a class="btn btn-primary" href="/infoscreen/{$ selected_rot.id $}">{% trans "Preview" %}</a>
</div>
<div>{% trans "Instances in currently selected rotation" %}:</div>
<table class="table table-striped">
+1 -1
View File
@@ -36,7 +36,7 @@ from infoscreen.models import (
@permission_required("infoscreen.change_infoinstance", raise_exception=True)
def admin(request, *args, **kwargs):
"""Render infoscreen admin page."""
return render(request, "infoscreen/infoscreen_admin.html", {})
return render(request, "infoscreen:infoscreen_admin.html", {})
def create_item_generator(model):
+1 -1
View File
@@ -15,7 +15,7 @@ import requests
@require_http_methods(["GET"])
def index(request, idx, *args, **kwargs):
"""Render infoscreen index page."""
return render(request, "infoscreen/infoscreen_index.html", {"rotation": idx})
return render(request, "infoscreen_index.html", {"rotation": idx})
@require_http_methods(["GET"])
+5 -5
View File
@@ -2,19 +2,19 @@ from django import forms
from django.utils.translation import ugettext_lazy as _
from django.core.exceptions import ValidationError
from kaehmy.models import PresetRole, CustomRole, Application, Comment, BaseRole
from kaehmy.models import PresetRole, CustomRole, Application, Comment, KaehmyBaseRole
class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
option_template_name = "checkbox_option.html"
def create_option(
self, name, formIterator, label, selected, index, subindex=None, attrs=None
self, name, value, label, selected, index, subindex=None, attrs=None
):
dic = super(CheckboxSelectMultiple, self).create_option(
name, formIterator, label, selected, index, subindex, attrs
name, value, label, selected, index, subindex, attrs
)
description = PresetRole.objects.get(id=formIterator.value).description
description = PresetRole.objects.get(id=value).description
dic["description"] = description
return dic
@@ -57,7 +57,7 @@ class ApplicationForm(forms.ModelForm):
self.fields["custom_roles"].label = _("Custom roles")
self.fields["custom_roles"].queryset = CustomRole.objects.all()
for cat_id, category in BaseRole.CATEGORIES:
for cat_id, category in KaehmyBaseRole.CATEGORIES:
key = "preset_roles_{}".format(cat_id)
qset = PresetRole.objects.filter(category=cat_id).order_by(
"category", "-is_board"
@@ -1,18 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-01 19:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("kaehmy", "0006_delete_telegramchannel"),
]
operations = [
migrations.AlterField(
model_name="commentparent",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
]
-44
View File
@@ -1,44 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-03 20:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("kaehmy", "0007_alter_commentparent_id"),
]
operations = [
migrations.CreateModel(
name="BaseRole",
fields=[
("id", models.AutoField(primary_key=True, serialize=False)),
("name", models.CharField(max_length=255, verbose_name="Name")),
("is_board", models.BooleanField(verbose_name="Board member")),
(
"category",
models.CharField(
choices=[
("corporate", "Corporate affairs"),
("freshman", "Freshmen"),
("international", "International"),
("external", "External affairs"),
("media", "Media"),
("tech", "Technology"),
("wellbeing", "Wellbeing"),
("elepaja", "Elepaja"),
("ceremonies", "Ceremonies"),
("studies", "Studies"),
("sosso", "Sössö magazine"),
("alumni", "Alumni relations"),
("others", "Others"),
],
default="others",
max_length=255,
verbose_name="Category",
),
),
],
),
]
@@ -1,29 +0,0 @@
# Generated by Django 2.2.28 on 2022-07-26 17:15
from unicodedata import category
from django.db import migrations
def copyBaseRolesToNewTable(apps, schema_editor):
Old = apps.get_model("kaehmy", "KaehmyBaseRole")
New = apps.get_model("kaehmy", "BaseRole")
for bases in Old.objects.all():
New.objects.create(
id=bases.id,
name=bases.name,
is_board=bases.is_board,
category=bases.category,
)
class Migration(migrations.Migration):
dependencies = [
("kaehmy", "0008_baserole"),
]
operations = [
migrations.RunPython(
copyBaseRolesToNewTable, reverse_code=migrations.RunPython.noop
),
]
@@ -1,51 +0,0 @@
# Generated by Django 2.2.28 on 2022-07-26 17:33
from django.db import migrations, models
import django.db.models.deletion
from sikweb.custom_operations import AlterModelBases
class Migration(migrations.Migration):
dependencies = [
("kaehmy", "0009_auto_20220726_2015"),
]
operations = [
AlterModelBases("customrole", (models.Model,)),
AlterModelBases("presetrole", (models.Model,)),
migrations.AlterField(
model_name="customrole",
name="kaehmybaserole_ptr",
field=models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="BaseRole",
),
),
migrations.AlterField(
model_name="presetrole",
name="kaehmybaserole_ptr",
field=models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="BaseRole",
),
),
migrations.RenameField(
model_name="customrole",
old_name="kaehmybaserole_ptr",
new_name="baserole_ptr",
),
migrations.RenameField(
model_name="presetrole",
old_name="kaehmybaserole_ptr",
new_name="baserole_ptr",
),
]
@@ -1,16 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-03 20:19
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("kaehmy", "0010_auto_20220726_2033"),
]
operations = [
migrations.DeleteModel(
name="KaehmyBaseRole",
),
]
+13 -17
View File
@@ -1,19 +1,22 @@
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from webapp.models import BaseRole
# TODO: Move BaseRole to Kaehmt App; will fuck up the DB since table is removed, if no data migration is done before-hand.
# Either reconstruct all kaehmy roles from scratch then, or do these migrations:
# 1. Create table here
# 2. Data migrate from webapp BaseRole to new kaehmy BaseRole
# 3. Delete webapp BaseRole table
VERBOSE_NAME = _("Kaehmy")
class BaseRole(models.Model):
"""Base model for occupations/roles."""
id = models.AutoField(primary_key=True)
name = models.CharField(_("Name"), max_length=255)
is_board = models.BooleanField(_("Board member"))
class KaehmyBaseRole(BaseRole):
"""ABC"""
CATEGORIES = (
("board", _("Board")),
("corporate", _("Corporate affairs")),
("freshman", _("Freshmen")),
("international", _("International")),
@@ -21,25 +24,19 @@ class BaseRole(models.Model):
("media", _("Media")),
("tech", _("Technology")),
("wellbeing", _("Wellbeing")),
("sikpaja", _("Sik-paja")),
("elepaja", _("Elepaja")),
("ceremonies", _("Ceremonies")),
("studies", _("Studies")),
("sosso", _("Sössö magazine")),
("pota", _("PoTa")),
("alumni", _("Alumni relations")),
("n", _("N")),
("others", _("Others")),
)
category = models.CharField(
_("Category"), choices=CATEGORIES, default="others", max_length=255
)
def __str__(self):
n = self.name.capitalize()
return "{} ({})".format(n, _("board member")) if self.is_board else n
class PresetRole(BaseRole):
class PresetRole(KaehmyBaseRole):
"""Model for kaehmy role."""
description = models.TextField(_("Description"))
@@ -49,7 +46,7 @@ class PresetRole(BaseRole):
verbose_name_plural = _("Preset kaehmy roles")
class CustomRole(BaseRole):
class CustomRole(KaehmyBaseRole):
"""Model representing a user-specified custom occupation."""
class Meta:
@@ -59,7 +56,6 @@ class CustomRole(BaseRole):
class CommentParent(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(_("Name"), max_length=255, default="")
email = models.EmailField(_("Email"), default="")
timestamp = models.DateTimeField(_("Timestamp"), default=timezone.now)
+6 -4
View File
@@ -5,6 +5,12 @@
margin-right: auto;
}
body {
max-width: 1000px;
margin-left: auto !important;
margin-right: auto !important;
}
div.tooltip-inner {
max-width: 25rem;
}
@@ -22,10 +28,6 @@ div.tooltip-inner {
.kaehmy-content {
padding-left: 0.5rem;
padding-right: 0.5rem;
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
p {
+5 -2
View File
@@ -3,9 +3,13 @@
}
footer {
/* position: absolute; */
bottom: 0;
width: 100%;
margin: 1rem;
height: 60px; /* Set the fixed height of the footer here */
/* line-height: 60px; /* Vertically center the text there */
margin-top: 2rem;
margin-bottom: 1rem;
}
footer .container .col .nav .nav-item {
@@ -22,7 +26,6 @@ footer .container .col .nav .nav-item {
.lang-select {
width: 10rem;
margin-bottom: 1rem;
display: inline-block;
}
+27 -18
View File
@@ -1,28 +1,37 @@
.kaehmy-header {
background-color: #0c2938;
.header-content {
}
.kaehmy-header-content {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
.header-content .logo {
}
.header-content .logo img {
display: block;
height: auto;
margin: auto;
}
.kaehmy-banner {
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
.kaehmy-banner-image {
max-height: 10rem;
max-width: 100%;
@media screen and (min-width: 1000px) {
.kaehmy_header-content {
position: absolute;
left: 0;
top: 0;
background-color: #0c2938;
width: 100%;
}
.kaehmy_header {
margin-bottom: 331px;
}
}
.heading {
display: flex;
place-content: center;
flex-direction: column;
text-align: center;
margin: 1rem;
}
.kaehmy-banner-image {
width: 100%;
}
+3 -7
View File
@@ -1,15 +1,11 @@
.kaehmy_navigation {
margin-bottom: 10px;
}
.navbar-border {
border-bottom: 2px solid #282b3b;
}
.navbar-light .navbar-nav .nav-link {
color: black;
}
.navbar {
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
@@ -7,19 +7,18 @@
<link rel="stylesheet" href="{% static "kaehmy/css/base.css" %}">
<link rel="stylesheet" href="{% static "kaehmy/css/header.css" %}">
<link rel="stylesheet" href="{% static "kaehmy/css/nav.css" %}">
<link rel="stylesheet" href="{% static "kaehmy/css/footer.css" %}">
{% endblock styles %}
{% block body %}
{% block header %}
<div class="kaehmy-header">
{% include "kaehmy/header.html" %}
<div class="kaehmy_header">
{% include "kaehmy:header.html" %}
</div>
{% endblock header %}
{% block navigation %}
{% include "kaehmy/navigation.html" %}
{% include "kaehmy:navigation.html" %}
{% endblock %}
<div class="kaehmy-content">
@@ -1,4 +1,4 @@
{% extends "kaehmy/base.html" %}
{% extends "kaehmy:base.html" %}
{% load static %}
{% load i18n %}
@@ -1,4 +1,4 @@
{% extends "kaehmy/base.html" %}
{% extends "base.html" %}
{% load static %}
{% load i18n %}
@@ -18,7 +18,7 @@
<h4>{% trans "Non-board applications" %}</h4>
{{ non_board_table|safe }}
</div>
<div>
<a href="/kaehmy" class="btn btn-primary">{% trans "Front page" %}</a>
</div>
+7
View File
@@ -0,0 +1,7 @@
{% load i18n %}
<div class="kaehmy_header-content">
<div class="kaehmy-banner logo">
<a href="/kaehmy"><img class="kaehmy-banner-image" src="/static/kaehmy/img/kaehmy_banner.png" alt="Aalto-yliopiston Sähköinsinöörikilta ry"></a>
</div>
</div>
@@ -1,10 +1,10 @@
{% extends "kaehmy/base.html" %}
{% extends "kaehmy:base.html" %}
{% load bootstrap3 %}
{% load i18n %}
{% block navigation %}
{% include "kaehmy/navigation.html" %}
{% include "kaehmy:navigation.html" %}
{% endblock %}
{% block content %}
@@ -28,12 +28,10 @@
</p>
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
<ul>
<li><strong>11.10.</strong> {% blocktrans %}Toimikuntamessut @OK20{% endblocktrans %}</li>
<li><strong>24.10.</strong> {% blocktrans %}Deadline hallitusvirkoihin hakemiselle.{% endblocktrans %}</li>
<li><strong>25.10.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta) ja hallitustyrkkypaneeli{% endblocktrans %}</li>
<li><strong>07.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
<li><strong>18.11.</strong> {% blocktrans %}Deadline toimivirkoihin hakemiselle.{% endblocktrans %}</li>
<li><strong>24.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
<li><strong>25.10.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta) ja hallitustyrkkypaneeli{% endblocktrans %}</li>
<li><strong>01.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
<li><strong>09.11.</strong> {% blocktrans %}Toimikunta-appro{% endblocktrans %}</li>
<li><strong>17.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
</ul>
<form name="kaehmyForm" action="/kaehmy/submit/" method="post" class="form">{% csrf_token %}
{% bootstrap_field form.name %}
@@ -77,7 +75,7 @@
<input type="checkbox" required name="gdpr" value="1">
<span>{% blocktrans %}
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Tietosuojaseloste%20%E2%80%93%20Toimihenkil%C3%B6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Tietosuojaseloste%20%23U2013%20Toimihenkil%23U00f6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
{% endblocktrans %}
</span>
{% buttons %}
@@ -1,21 +1,21 @@
{% extends "kaehmy/base.html" %}
{% extends "kaehmy:base.html" %}
{% load static %}
{% load i18n %}
{% block navigation %}
{% include "kaehmy/navigation.html" %}
{% include "kaehmy:navigation.html" %}
{% endblock %}
{% block content %}
<script>
function commentOn(id, op) {
setTimeout(function() {
document.getElementById("commentNameField").focus();
document.getElementById("commentNameField").focus();
}, 50);
document.getElementById("collapse_add_comment").scrollIntoView();
document.getElementById("commentOP").innerHTML = op;
document.getElementById("collapse_add_comment").scrollIntoView();
document.getElementById("commentOP").innerHTML = op;
document.getElementById("commentId").value = id;
}
</script>
@@ -24,7 +24,7 @@
<h2 style="padding-top: 1rem">{% trans "All kaehmys" %}</h2>
</div>
<div class="collapse" id="collapse_add_comment">
<div class="collapse" id="collapse_add_comment">
<div class="card">
<div class="card-block">
<form method="POST" action="/kaehmy/add_comment" class="form">{% csrf_token %}
@@ -69,18 +69,18 @@
<div>
<h6 style="padding-bottom: 1rem">{% trans "Total kaehmys:" %} {{ application_count }}</h6>
</div>
{% for application in applications %}
<div class="card">
<h4 class="card-header">{{ application.name }}</h4>
<h4 class="card-header">{{ application.name }}</h4>
<div class="card-block">
{% if application.board_roles|length > 0 %}
<h5 style="padding-bottom: 1rem" class="card-subtitle mb-2 text-muted">{{ application.board_roles }}</h5>
<h5 style="padding-bottom: 1rem" class="card-subtitle mb-2 text-muted">{{ application.board_roles }}</h5>
{% endif %}
{% if application.official_roles|length > 0 %}
<h5 style="padding-bottom: 1rem" class="card-subtitle mb-2 text-muted">{{ application.official_roles }}</h5>
{% endif %}
<h5 style="padding-bottom: 1rem" class="card-subtitle mb-2 text-muted">{{ application.official_roles }}</h5>
{% endif %}
<p class="card-text">{{ application.text|linebreaks|urlize }}</p>
{% if application.comment_count > 0 %}
@@ -95,9 +95,9 @@
</a>
</div>
<div class="collapse" id="collapse_{{ application.id }}">
<div class="collapse" id="collapse_{{ application.id }}">
{% for message in application.messages.all %}
{% include "kaehmy/message.html" with messages=message.messages.all %}
{% include "kaehmy:message.html" with messages=message.messages.all %}
{% endfor %}
</div>
</div>
@@ -2,7 +2,7 @@
<div class="card" style="margin-top: 0.5rem; margin-bottom: 0">
<div class="card-block">
<h4>{{ message.name }}</h4>
<h4>{{ message.name }}</h4>
<p>{{ message.message|linebreaks|urlize }}</p>
<h6 class="card-subtitle mb-2 text-muted">{{ message.timestamp }}</h6>
@@ -13,9 +13,9 @@
</div>
<div>
{% for message in messages %}
{% include "kaehmy/message.html" with messages=message.messages.all %}
{% include "message.html" with messages=message.messages.all %}
{% endfor %}
</div>
</div>
</div>
@@ -1,8 +1,8 @@
{% load i18n %}
{% load static %}
<div class="kaehmy_navigation bg-faded">
<nav class="navbar navbar-toggleable-md navbar-light">
<div class="kaehmy_navigation">
<nav class="navbar-border navbar navbar-toggleable-md navbar-light bg-faded">
<div class="navbar-nav">
<a class="nav-item nav-link" href="/kaehmy">{% trans "List kaehmys" %}</a>
<a class="nav-item nav-link" href="/kaehmy/new">{% trans "New kaehmy" %} <span class="sr-only">(current)</span></a>
@@ -1,21 +1,21 @@
{% extends "kaehmy/base.html" %}
{% extends "kaehmy:base.html" %}
{% load bootstrap3 %}
{% load i18n %}
{% block navigation %}
{% include "kaehmy/navigation.html" %}
{% include "kaehmy:navigation.html" %}
{% endblock %}
{% block content %}
<div>
<div>
<h2 style="padding-top: 1rem">{% trans "Statistics" %}</h2>
<h2 style="padding-top: 1rem">{% trans "Statistics" %}</h2>
</div>
<div style="margin-top: 1rem" class="card">
<div class="card-header">
<h5>{% trans "Total kaehmys:" %} {{ application_count }}</h5>
<h5>{% trans "Total kaehmys:" %} {{ application_count }}</h5>
</div>
<div class="card-block">
{% for role in role_list %}
@@ -25,6 +25,6 @@
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
+22 -18
View File
@@ -1,12 +1,15 @@
from django.db.models import Count
from django.shortcuts import render, redirect
from django.contrib.auth import login, logout, authenticate
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.template.loader import render_to_string
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import permission_required, login_required
from django.conf import settings
import logging
import requests
from dealer.git import git
from sikweb.settings import URL
from members.views.utils import *
@@ -53,7 +56,7 @@ def list_view(request, *args, **kwargs):
"filter_options": filter_options,
}
return render(request, "kaehmy/list.html", context)
return render(request, "kaehmy:list.html", context)
@ensure_csrf_cookie
@@ -65,21 +68,20 @@ def comment(request, *args, **kwargs):
if form.is_valid():
comment = form.save()
name = comment.name
url = f"https://{URL}/kaehmy"
to_email = comment.parent.email
subject = "Kaehmyysi tai kommenttiisi on vastattu!"
message = render_to_string(
"kaehmy/email_comment.html", {"name": name, "url": url}
email_body = (
f"{name.capitalize()} on vastannut kaehmyhakemukseesi tai kommenttiisi kaehmypalvelussa.\r\n\r\n"
"Käy lukemassa viesti osoitteessa https://{URL}/kaehmy"
)
send_email(to=to_email, subject=subject, body=message, html=True)
send_email(to=to_email, subject=subject, body=email_body)
logging.debug(f"Sent kaehmy comment email to recipient <{to_email}>")
return redirect("/kaehmy")
else:
context = {"error": form.errors}
return render(request, "kaehmy/error.html", context)
return render(request, "kaehmy:error.html", context)
@require_http_methods(["GET"])
@@ -104,14 +106,14 @@ def statistics_view(request, *args, **kwargs):
"application_count": len(applications),
"role_list": role_list,
}
return render(request, "kaehmy/statistics.html", context)
return render(request, "kaehmy:statistics.html", context)
@require_http_methods(["GET"])
def view(request, *args, **kwargs):
"""Render Kaehmy form page."""
form = ApplicationForm()
return render(request, "kaehmy/kaehmy.html", {"form": form})
return render(request, "kaehmy:kaehmy.html", {"form": form})
@ensure_csrf_cookie
@@ -131,20 +133,22 @@ def submit(request, *args, **kwargs):
url = f"https://{URL}/kaehmy"
name = form.cleaned_data.get("name", "Anonymous")
email_body = (
f"Moikka {name}!\r\n\r\nHienoa, että kilta kiinnostaa! Kaehmysi on vastaanotettu.\r\n"
"Mahdollisista kommenteista tulee ilmoitus sähköpostitse.\r\n\r\n"
"Käy katsomassa kaehmytilanne osoitteessa {url}"
)
to_email = form.cleaned_data.get("email", "")
subject = "Arwokas kirjattu kirje mahdolliselle tulewalle kiltahenkilölle"
message = render_to_string(
"kaehmy/email_kaehmy.html", {"name": name, "url": url}
)
send_email(to=to_email, subject=subject, body=message, html=True)
send_email(to_email, subject, email_body)
logging.debug(f"Sent kaehmy email to recipient <{to_email}>")
processHooks(message=f"Uusi New kaehmy! {name} -> {url}", eventType="kaehmy")
else:
context = {"error": form.errors}
return render(request, "kaehmy/error.html", context)
return render(request, "kaehmy:error.html", context)
return HttpResponseRedirect("/kaehmy")
@@ -171,4 +175,4 @@ def export_view(request, *args, **kwargs):
"non_board_table": make_table(non_board),
"board_table": make_table(board),
}
return render(request, "kaehmy/export.html", context)
return render(request, "kaehmy:export.html", context)
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -1,18 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-01 19:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("members", "0019_auto_20171029_1143"),
]
operations = [
migrations.AlterField(
model_name="payment",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
]
@@ -1,23 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-01 19:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("members", "0020_alter_payment_id"),
]
operations = [
migrations.AlterField(
model_name="member",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
migrations.AlterField(
model_name="request",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
]
-2
View File
@@ -9,7 +9,6 @@ from django.db.models import Q, OuterRef, Subquery
class BaseMember(models.Model):
"""Abstract base model for member."""
id = models.AutoField(primary_key=True)
first_name = models.CharField(_("First name"), max_length=127)
last_name = models.CharField(_("Last name"), max_length=127)
email = models.EmailField(_("Email"), unique=True)
@@ -61,7 +60,6 @@ class Payment(models.Model):
class Meta:
permissions = (("read_payment", "Can see payment in list"),)
id = models.AutoField(primary_key=True)
date = models.DateTimeField(_("Date"), default=timezone.now)
source = models.CharField(
_("Source"),
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load bootstrap3 %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load bootstrap3 %}
@@ -11,7 +11,7 @@
<div id="input_form">
<form name="applicationForm" action="/members/accept_application" method="post" class="form">{% csrf_token %}
<input type="hidden" name="id" value="{{ application_id }}">
<input type="hidden" name="id" value="{{ application_id }}">
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
@@ -1,4 +1,4 @@
{% extends "members/application_form_base.html" %}
{% extends "application_form_base.html" %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
@@ -17,7 +17,7 @@
{{ table|safe }}
<div>
<a href="/members/export_applications" class="btn btn-info">{% trans "Download Excel" %}</a>
<a href="/members/export_applications" class="btn btn-info">{% trans "Download Excel" %}</a>
</div>
</div>
@@ -1,4 +1,4 @@
{% extends "members/application_form_base.html" %}
{% extends "application_form_base.html" %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
@@ -7,5 +7,5 @@
<link rel="stylesheet" href="{% static "css/application.css" %}">
<h3>{% trans "Hienoa! Jäsenhakemuksesi on nyt lähetetty." %}</h3>
<p>{% trans "Vahvistusviesti on lähetetty sähköpostiisi. Ota yhteyttä admin@sahkoinsinoorikilta.fi jos viestiä ei näy." %}</p>
<a href="https://sahkoinsinoorikilta.fi/"><h4>{% trans "Takaisin Sähköinsinöörikillan web-sivuille" %}</h4></a>
<a href="/"><h4>{% trans "Takaisin Sähköinsinöörikillan web-sivuille" %}</h4></a>
{% endblock content %}
@@ -1,5 +1,6 @@
<!DOCTYPE html>
{% load staticfiles %}
{% load static %}
{% load i18n %}
@@ -21,7 +22,7 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="{% static "members/css/simple-sidebar.css" %}">
<link rel="stylesheet" href="{% static "members/css/members.css" %}">
<link rel="stylesheet" href="{% static "webapp/css/footer.css" %}">
<link rel="stylesheet" href="{% static "css/footer.css" %}">
</head>
<body>
@@ -0,0 +1,11 @@
{% load i18n %}
{% trans "Moi" %} {{ first_name }}!
{% trans "Onnittelut! Sinut on hyväksytty Sähköinsinöörikillan jäseneksi." %}
{% trans "Käy kurkkaamassa killan nettisivuilta" %} (https://sik.ayy.fi) {% trans "tulevia tapahtumia ja piipahda kiltahuoneella tutustumassa uusiin kiltatovereihisi!" %}
{% trans "Liity myös killan TG-kanaville" %}:
{% trans "SIK" %}: https://t.me/joinchat/A6EViD5FCWLxPcXCggY7hw
{% trans "SIK-fuksit 2019" %}: http://tinyurl.com/sikfuksit19-tg
{% trans "SIK-fuksit 2019 -tiedotuskanava" %}: http://tinyurl.com/sikfuksit19-tiedotus
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load bootstrap3 %}
{% load i18n %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load static %}
@@ -11,7 +11,7 @@
<div>
<p>
{% blocktrans %}
Enter member information in CSV format, separate members on separate lines.
Enter member information in CSV format, separate members on separate lines.
If a new member already exists in the database, a new payment event will be created for that member instead.
{% endblocktrans %}
</p>
@@ -20,7 +20,7 @@
<div>
<label>{% trans "Format the member table like this:" %}</label>
<div>
<img src="{% static "members/img/excel_csv_save_example.png" %}">
<img src="{% static "members/img/excel_csv_save_example.png" %}">
</div>
<p>{% blocktrans %}Columns: First name, last name, email address, place of origin, AYY member, JAS recipient{% endblocktrans %}</p>
</div>
@@ -28,10 +28,10 @@
<label>{% trans "Save the file as CSV" %}</label>
<div><img src="{% static "members/img/excel_csv_save_tutorial.png" %}"></div>
</div>
<form name="memberTextForm" action="/members/import_csv" enctype="multipart/form-data" method="POST">{% csrf_token %}
<h3>{% trans "Upload file" %}</h3>
<input class="form-control-file" type="file" accept=".csv" name="csvFile" />
<input class="form-control-file" type="file" accept=".csv" name="csvFile" />
<div class="form-group">
<label>{% trans "Payment source" %}</label>
@@ -42,7 +42,7 @@
</select>
<small class="form-text text-muted">
{% trans "This payment source will be used to create any payments for new members that already exist in the database." %}
</small>
</small>
</div>
<div class="form-group">
<label>{% trans "CSV delimiter" %}</label>
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load bootstrap3 %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load bootstrap3 %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load static %}
{% load i18n %}
@@ -41,7 +41,7 @@
{{ table|safe }}
<div>
<a href="/members/export_members" class="btn btn-info">{% trans "Download Excel" %}</a>
<a href="/members/export_members" class="btn btn-info">{% trans "Download Excel" %}</a>
</div>
</div>
{% endblock content %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load bootstrap3 %}
{% load i18n %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load bootstrap3 %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load i18n %}
{% load bootstrap3 %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load static %}
{% load i18n %}
@@ -38,7 +38,7 @@
{{ table|safe }}
<div>
<a href="/members/export_payments" class="btn btn-info">{% trans "Download Excel" %}</a>
<a href="/members/export_payments" class="btn btn-info">{% trans "Download Excel" %}</a>
</div>
</div>
{% endblock content %}
@@ -1,4 +1,4 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% load static %}
{% load i18n %}
@@ -1,10 +1,10 @@
{% extends "members/base.html" %}
{% extends "members:base.html" %}
{% block content %}
<h1>{{ title }}</h1>
<h3>{{ header }}</h3>
<form method="POST" action="/members/import_excel" enctype="multipart/form-data">{% csrf_token %}
{{ form }}
<input type="submit" class="btn btn-primary">
<input type="submit" class="btn btn-primary">
</form>
{% endblock %}
+5 -13
View File
@@ -5,7 +5,6 @@ from unittest import skip
from django.contrib.auth.models import User
from members.models import Member, Payment, Request
from rest_framework.authtoken.models import Token
from datetime import timezone
import logging
@@ -109,11 +108,8 @@ class MemberRegisterTestCase(TestCase):
content = resp.content
arrays = pyexcel.get_array(file_content=content, file_type="xlsx")
created = (
Payment.objects.get(member__email="tidus@tester.fi")
.date.replace(tzinfo=timezone.utc)
.astimezone(tz=None)
.strftime("%Y-%m-%d %H:%M:%S")
created = Payment.objects.get(member__email="tidus@tester.fi").date.strftime(
"%Y-%m-%d %H:%M:%S"
)
tidus_array = ["Tidus Tester", created, "AYY"]
self.assertIn(tidus_array, arrays)
@@ -126,13 +122,9 @@ class MemberRegisterTestCase(TestCase):
content = resp.content
arrays = pyexcel.get_array(file_content=content, file_type="xlsx")
submitted = (
Request.objects.get(email="liisa.mattila@pylly.com")
.submitted.replace(tzinfo=timezone.utc)
.astimezone(tz=None)
.strftime("%Y-%m-%d %H:%M:%S")
)
submitted = Request.objects.get(
email="liisa.mattila@pylly.com"
).submitted.strftime("%Y-%m-%d %H:%M:%S")
liisa_array = [
"Liisa",
"Mattila",
+8 -14
View File
@@ -12,7 +12,6 @@ import logging
import html
from webapp.utils import send_email
from webapp.utils import add_to_mailinglist
from members.views.utils import *
from members.tables import RequestTable
@@ -42,7 +41,7 @@ def application_list(request, *args, **kwargs):
"application_count": application_count,
"notification": request.GET.get("notification", None),
}
return render(request, "members/application_list.html", context)
return render(request, "application_list.html", context)
@ensure_csrf_cookie
@@ -58,9 +57,7 @@ def application_edit(request, *args, **kwargs):
application = Request.objects.get(id=i)
form = ApplicationForm(instance=application)
return render(
request,
"members/application_edit.html",
{"application_id": i, "form": form},
request, "application_edit.html", {"application_id": i, "form": form}
)
@@ -89,9 +86,6 @@ def application_accept(request, *args, **kwargs):
).format(application.email),
)
if application.jas:
add_to_mailinglist(application.email)
member = application.to_member()
member.save()
application.delete()
@@ -107,10 +101,10 @@ def application_accept(request, *args, **kwargs):
subject = _("Jäsenhakemuksesi Sähköinsinöörikiltaan on hyväksytty!")
message = render_to_string(
"members/email_application_accept.html",
"members:email_application_accept.html",
{"first_name": application.first_name},
)
send_email(member.email, subject, message, True)
send_email(member.email, subject, message)
return HttpResponseRedirect(
"/members/list?notification={}".format(html.escape(notification))
@@ -164,7 +158,7 @@ def application_delete_confirm(request, *args, **kwargs):
form = ApplicationForm(instance=application)
return render(
request,
"members/application_delete_confirm.html",
"application_delete_confirm.html",
{"application_id": i, "form": form},
)
@@ -173,7 +167,7 @@ def application_delete_confirm(request, *args, **kwargs):
def application_form(request, *args, **kwargs):
"""Render member application form."""
form = ApplicationForm()
return render(request, "members/application_index.html", {"form": form})
return render(request, "application_index.html", {"form": form})
@ensure_csrf_cookie
@@ -192,7 +186,7 @@ def application_submit(request, *args, **kwargs):
)
message = render_to_string(
"members/email_application_submit.html",
"members:email_application_submit.html",
{
"application": application,
"ayy": _("Kyllä") if application.AYY else _("Ei"),
@@ -201,6 +195,6 @@ def application_submit(request, *args, **kwargs):
)
send_email(email, subject, message)
finally:
return render(request, "members/application_success.html", {})
return render(request, "application_success.html", {})
else:
return error_view(request, form.errors)
+5 -9
View File
@@ -70,7 +70,7 @@ def member_list(request, *args, **kwargs):
"paid_count": len(queryset.filter(last_paid__gte=filter_date)),
"notification": request.GET.get("notification", None),
}
return render(request, "members/member_list.html", context)
return render(request, "member_list.html", context)
@ensure_csrf_cookie
@@ -80,7 +80,7 @@ def member_list(request, *args, **kwargs):
def member_add(request, *args, **kwargs):
"""Render add member page."""
form = MemberForm()
return render(request, "members/member_add.html", {"form": form})
return render(request, "member_add.html", {"form": form})
@ensure_csrf_cookie
@@ -96,9 +96,7 @@ def member_delete_confirm(request, *args, **kwargs):
member = Member.objects.get(id=i)
form = MemberForm(instance=member)
return render(
request,
"members/member_delete_confirm.html",
{"member_id": i, "form": form},
request, "member_delete_confirm.html", {"member_id": i, "form": form}
)
@@ -108,7 +106,7 @@ def member_delete_confirm(request, *args, **kwargs):
@permission_required("members.add_member", raise_exception=True)
def member_add_many(request, *args, **kwargs):
"""Render add multiple members page."""
return render(request, "members/member_add_many.html", {})
return render(request, "member_add_many.html", {})
@ensure_csrf_cookie
@@ -235,9 +233,7 @@ def member_edit(request, *args, **kwargs):
else:
member = Member.objects.get(id=i)
form = MemberForm(instance=member)
return render(
request, "members/member_edit.html", {"member_id": i, "form": form}
)
return render(request, "member_edit.html", {"member_id": i, "form": form})
@method_decorator(login_required(login_url="/admin/login"), name="dispatch")
+4 -8
View File
@@ -43,7 +43,7 @@ def payment_list(request, *args, **kwargs):
"payment_count": len(payments),
"notification": request.GET.get("notification", None),
}
return render(request, "members/payment_list.html", context)
return render(request, "payment_list.html", context)
@ensure_csrf_cookie
@@ -53,7 +53,7 @@ def payment_list(request, *args, **kwargs):
def payment_add(request, *args, **kwargs):
"""Render add payment form."""
form = PaymentForm()
return render(request, "members/payment_add.html", {"form": form})
return render(request, "payment_add.html", {"form": form})
@ensure_csrf_cookie
@@ -92,9 +92,7 @@ def payment_edit(request, *args, **kwargs):
else:
payment = Payment.objects.get(id=i)
form = PaymentForm(instance=payment)
return render(
request, "members/payment_edit.html", {"payment_id": i, "form": form}
)
return render(request, "payment_edit.html", {"payment_id": i, "form": form})
@ensure_csrf_cookie
@@ -110,9 +108,7 @@ def payment_delete_confirm(request, *args, **kwargs):
payment = Payment.objects.get(id=i)
form = PaymentForm(instance=payment)
return render(
request,
"members/payment_delete_confirm.html",
{"payment_id": i, "form": form},
request, "payment_delete_confirm.html", {"payment_id": i, "form": form}
)
+3 -3
View File
@@ -46,7 +46,7 @@ class MemberDetail(generics.RetrieveAPIView):
def error_view(request, message, status=400):
return render(request, "members/error.html", {"error": message}, status=400)
return render(request, "error.html", {"error": message}, status=400)
def validate_recaptcha(response):
@@ -100,7 +100,7 @@ def convert_table_to_html(table, request):
@permission_required("members.change_member", raise_exception=True)
def settings_page(request, *args, **kwargs):
"""Render member app settings page."""
return render(request, "members/settings.html", {})
return render(request, "settings.html", {})
@ensure_csrf_cookie
@@ -155,7 +155,7 @@ def import_csv(request, *args, **kwargs):
request.session["models"] = result
request.session["payment_source"] = payment_source
context = {"members": member_table_html, "payments": payment_table_html}
return render(request, "members/member_add_many_confirm.html", context)
return render(request, "member_add_many_confirm.html", context)
def make_excel_response(Resource):
@@ -1,18 +0,0 @@
# Generated by Django 3.2.14 on 2022-08-01 19:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("ohlhafv", "0002_remove_ohlhafvchallenge_challenger_email"),
]
operations = [
migrations.AlterField(
model_name="ohlhafvchallenge",
name="id",
field=models.AutoField(primary_key=True, serialize=False),
),
]
-1
View File
@@ -29,7 +29,6 @@ class OhlhafvChallenge(models.Model):
("Team", _("Team Challenge (1 x 0.33 L, 2 x 0.5 L, 1 x 1.0 L)")),
)
id = models.AutoField(primary_key=True)
challenger = models.CharField(_("Challenger"), max_length=255)
victim = models.CharField(_("Victim"), max_length=255)
victim_email = models.EmailField(_("Victim email"))
-34
View File
@@ -1,34 +0,0 @@
#footer-div {
height:10vh;
}
footer {
/* position: absolute; */
bottom: 0;
width: 100%;
height: 60px; /* Set the fixed height of the footer here */
/* line-height: 60px; /* Vertically center the text there */
margin-top: 2rem;
margin-bottom: 1rem;
}
footer .container .col .nav .nav-item {
display: inline-block;
margin-right: 3vh;
}
.lang-button {
height: 4vh;
width: 6vh;
margin-left: 1vh;
margin-right: 1vh;
}
.lang-select {
width: 10rem;
display: inline-block;
}
footer .lang-form {
margin: 1rem auto 0;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

@@ -7,16 +7,15 @@
<link rel="stylesheet" href="{% static "ohlhafv/css/base.css" %}">
<link rel="stylesheet" href="{% static "ohlhafv/css/header.css" %}">
<link rel="stylesheet" href="{% static "ohlhafv/css/nav.css" %}">
<link rel="stylesheet" href="{% static "ohlhafv/css/footer.css" %}">
{% endblock styles %}
{% block body %}
{% block header %}
{% include "ohlhafv/header.html" %}
{% include "ohlhafv:header.html" %}
{% endblock header %}
{% block navigation %}
{% include "ohlhafv/navigation.html" %}
{% include "ohlhafv:navigation.html" %}
{% endblock %}
{% block content %}
@@ -5,6 +5,6 @@
{{ challenge.message }}
{% trans "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 26.5" %}.
{% trans "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 14.2" %}.
{% trans "Käy kurkkaamassa muutkin haasteet osoitteessa" %} {{ url }}
@@ -1,4 +1,4 @@
{% extends "ohlhafv/base.html" %}
{% extends "ohlhafv:base.html" %}
{% load static %}
{% load i18n %}
@@ -14,7 +14,7 @@
{% for challenge in challenges %}
<div class="card">
<h4 class="card-header">{{ challenge.challenger }} vs. {{ challenge.victim }}</h4>
<h4 class="card-header">{{ challenge.challenger }} vs. {{ challenge.victim }}</h4>
<div class="card-block">
<h5 class="card-subtitle mb-2">{{ challenge.get_series_display }}</h5>
<p class="card-text">{{ challenge.message|linebreaks|urlize }}</p>
@@ -1,10 +1,10 @@
{% extends "ohlhafv/base.html" %}
{% extends "ohlhafv:base.html" %}
{% load bootstrap3 %}
{% load i18n %}
{% block navigation %}
{% include "ohlhafv/navigation.html" %}
{% include "ohlhafv:navigation.html" %}
{% endblock %}
{% block content %}
+4 -4
View File
@@ -18,7 +18,7 @@ from webapp.models import processHooks
def ohlhafv_view(request, *args, **kwargs):
"""Render Ohlhafv form page."""
form = OhlhafvForm()
return render(request, "ohlhafv/new.html", {"form": form})
return render(request, "ohlhafv:new.html", {"form": form})
@ensure_csrf_cookie
@@ -32,7 +32,7 @@ def ohlhafv_submit(request, *args, **kwargs):
url = f"https://{URL}/ohlhafv/list"
email_body = render_to_string(
"ohlhafv/email.html",
"ohlhafv:email.html",
{
"challenge": challenge,
"url": url,
@@ -46,7 +46,7 @@ def ohlhafv_submit(request, *args, **kwargs):
try:
webhook_message = render_to_string(
"ohlhafv/tgmsg.tpl", {"challenge": challenge, "url": url}
"ohlhafv:tgmsg.tpl", {"challenge": challenge, "url": url}
)
processHooks(message=webhook_message, eventType="ohlhafv")
except Exception:
@@ -67,4 +67,4 @@ def ohlhafv_list(request, *args, **kwargs):
"challenges": challenges,
"challenge_count": len(challenges),
}
return render(request, "ohlhafv/list.html", context)
return render(request, "ohlhafv:list.html", context)
+1 -1
View File
@@ -6,7 +6,7 @@
"lint": "run-p lint:js lint:md lint:py",
"lint:js": "eslint .",
"lint:md": "remark .",
"lint:py": "black --diff --check .",
"lint:py": "black --diff .",
"lint:py:fix": "black .",
"lint:py-type": "pyright",
"prepare": "husky install"
Generated
+510 -503
View File
File diff suppressed because it is too large Load Diff
+3 -18
View File
@@ -4,30 +4,15 @@
if test -f "$SECRET_KEY_FILE"; then
export SECRET_KEY=$(cat $SECRET_KEY_FILE)
fi
if test -f "$TG_BOT_TOKEN_FILE"; then
export TG_BOT_TOKEN=$(cat $TG_BOT_TOKEN_FILE)
fi
if test -f "$EMAIL_API_KEY_FILE"; then
export EMAIL_API_KEY=$(cat $EMAIL_API_KEY_FILE)
fi
if test -f "$DB_PASSWD_FILE"; then
export DB_PASSWD=$(cat $DB_PASSWD_FILE)
fi
if test -f "$G_PRIVATE_KEY_ID_FILE"; then
export G_PRIVATE_KEY_ID=$(cat $G_PRIVATE_KEY_ID_FILE)
fi
if test -f "$G_PRIVATE_KEY_FILE"; then
export G_PRIVATE_KEY="$(cat $G_PRIVATE_KEY_FILE)"
fi
if test -f "$G_CLIENT_EMAIL_FILE"; then
export G_CLIENT_EMAIL=$(cat $G_CLIENT_EMAIL_FILE)
fi
if test -f "$G_CLIENT_ID_FILE"; then
export G_CLIENT_ID=$(cat $G_CLIENT_ID_FILE)
fi
if test -f "$G_CLIENT_URL_FILE"; then
export G_CLIENT_URL=$(cat $G_CLIENT_URL_FILE)
fi
if test -f "$GROUP_KEY_FILE"; then
export GROUP_KEY=$(cat $GROUP_KEY_FILE)
fi
# Collect static files
echo "Collect static files"
+22 -21
View File
@@ -7,42 +7,43 @@ authors = ["Aarni Halinen aarni.halinen@sahkoinsinoorikilta.fi"]
[tool.poetry.dependencies]
python = "^3.9"
decorator = "^4.0.9"
Django = "^3.2.14"
requests = "^2.28.1"
django-cors-headers = "^3.13.0"
Django = "^2.2.19"
requests = "^2.11.1"
django-cors-headers = "^3.7.0"
djangorestframework = "^3.12.4"
psycopg2-binary = "^2.9.3"
django-bootstrap3 = "^21.2"
django-tables2 = "^2.4.1"
django-modeltranslation = "^0.18.4"
django-auditlog = "^2.1.1"
django-phonenumber-field = {version = "^6.3.0", extras = ["phonenumbers"]}
djangorestframework-jwt = "^1.11.0"
django-nose = "^1.4.5"
psycopg2-binary = "2.8.6"
django-bootstrap3 = "^11.1.0"
django-tables2 = "^1.6.1"
dealer = "^2.0.5"
django-modeltranslation = "^0.13b1"
django-auditlog = "^0.4.5"
django-phonenumber-field = {version = "^4.0.0", extras = ["phonenumbers"]}
django-autocomplete-light = "^3.4.1"
six = "^1.12.0"
django-suit = "^0.2.26"
pyexcel = "^0.5.14"
pyexcel-xlsx = "^0.5.8"
django-import-export = "^2.8.0"
django-import-export = "^0.7.0"
openpyxl = "^2.6.4"
django-app-namespace-template-loader = "^0.4.1"
django-filter = "^22.1"
whitenoise = "^6.2.0"
jsonschema = "^4.9.0"
django-filter = "^2.0.0"
whitenoise = "^4.1.4"
jsonschema = "^3.2.0"
Markdown = "^3.2.2"
uWSGI = "^2.0.18"
gunicorn = "^20.1.0"
Pillow = "^9.1.1"
Pillow = "^8.4.0"
sendgrid = "^6.7.0"
sentry-sdk = "^1.4.3"
django-polymorphic = "^3.1.0"
python-dotenv = "^0.20.0"
djangorestframework-simplejwt = "^5.2.0"
google-auth = "^2.9.1"
google-api-python-client = "^2.54.0"
[tool.poetry.dev-dependencies]
coverage = "^6.4.2"
safety = "^2.1.1"
black = "^22.6.0"
coverage = "^5.5"
nose-exclude = "^0.5.0"
safety = "^1.10.3"
black = "^21.12b0"
[build-system]
requires = ["poetry-core>=1.0.0"]
+2 -2
View File
@@ -3,8 +3,8 @@ CREATE USER sik WITH PASSWORD 'password123';
ALTER ROLE sik SET client_encoding TO 'utf8';
ALTER ROLE sik SET default_transaction_isolation TO 'read committed';
ALTER ROLE sik SET timezone TO 'UTC';
CREATE DATABASE sik
ENCODING 'UTF8'
CREATE DATABASE sik
ENCODING 'UTF8'
OWNER sik;
GRANT ALL PRIVILEGES ON DATABASE sik TO sik;
ALTER USER sik CREATEDB;
+92 -23
View File
@@ -7,26 +7,14 @@ from django.utils.translation import ugettext_lazy as _
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATIC_URL = "static/"
STATIC_ROOT = os.path.join(BASE_DIR, "collected_static")
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
# Login paths
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL = "/admin"
# Might need to be changed to JSON serializer
# https://docs.djangoproject.com/en/4.0/topics/http/sessions/#django.contrib.sessions.serializers.JSONSerializer
SESSION_SERIALIZER = "django.contrib.sessions.serializers.PickleSerializer"
# Logger level
# Logging
LOGGERLEVEL = logging.DEBUG
LOGPATH = os.path.join(BASE_DIR, "logs", "debug.log")
@@ -79,15 +67,10 @@ LOGGING = {
# Application definition
IMPORT_EXPORT_USE_TRANSACTIONS = True
# Could be replaced with CORS_ALLOWED_ORIGINS list.
# See (check correct package version in the link) https://github.com/adamchainz/django-cors-headers/tree/3.7.0#configuration
CORS_ALLOW_ALL_ORIGINS = True
ROOT_URLCONF = "sikweb.urls"
WSGI_APPLICATION = "sikweb.wsgi.application"
INSTALLED_APPS = [
"modeltranslation", # has to be before admin for translation admin to work
"suit",
"dal",
"dal_select2",
"django.contrib.admin",
@@ -104,7 +87,8 @@ INSTALLED_APPS = [
"kaehmy",
"ohlhafv",
"rest_framework",
"rest_framework_simplejwt",
"rest_framework_jwt",
"django_nose",
"bootstrap3",
"django_tables2",
"auditlog",
@@ -113,6 +97,18 @@ INSTALLED_APPS = [
"django_filters",
]
IMPORT_EXPORT_USE_TRANSACTIONS = True
TEST_RUNNER = "django_nose.NoseTestSuiteRunner"
NOSE_ARGS = [
"--with-coverage",
"--cover-package=webapp,members,infoscreen",
"--exclude-dir={}".format(os.path.join(BASE_DIR, "members", "migrations")),
"--exclude-dir={}".format(os.path.join(BASE_DIR, "infoscreen", "migrations")),
"--exclude-dir={}".format(os.path.join(BASE_DIR, "webapp", "migrations")),
]
MIDDLEWARE = [
"sikweb.middleware.ForceDefaultLanguageMiddleware",
"django.middleware.security.SecurityMiddleware",
@@ -128,12 +124,17 @@ MIDDLEWARE = [
"auditlog.middleware.AuditlogMiddleware",
]
CORS_ORIGIN_ALLOW_ALL = True
ROOT_URLCONF = "sikweb.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": ["templates"],
"OPTIONS": {
"loaders": [
"app_namespace.Loader",
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
],
@@ -144,14 +145,17 @@ TEMPLATES = [
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.static",
"dealer.contrib.django.context_processor",
],
},
},
]
WSGI_APPLICATION = "sikweb.wsgi.application"
# Password validation
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation."
@@ -175,23 +179,88 @@ REST_FRAMEWORK = {
"rest_framework.permissions.IsAdminUser",
),
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
"rest_framework_jwt.authentication.JSONWebTokenAuthentication",
),
# 'DEFAULT_THROTTLE_CLASSES': (
# 'members.throttles.BurstRateThrottle',
# 'members.throttles.SustainedRateThrottle'
# ),
# 'DEFAULT_THROTTLE_RATES': {
# 'burst': '60/min',
# 'sustained': '1000/day'
# },
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
"PAGE_SIZE": 1000,
"DEFAULT_FILTER_BACKENDS": ("django_filters.rest_framework.DjangoFilterBackend",),
}
# Email settings (tested working with gmail)
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# EMAIL_USE_TLS = True
# EMAIL_HOST = 'smtp.gmail.com'
# EMAIL_PORT = 587
# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/
LANGUAGES = (
("fi", _("Finnish")),
("en", _("English")),
)
LANGUAGE_CODE = "fi"
LOCALE_PATHS = (os.path.join(BASE_DIR, "locale"),)
TIME_ZONE = "Europe/Helsinki"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
"django.contrib.staticfiles.finders.FileSystemFinder",
)
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "collected_static")
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"
LOGIN_URL = "/login/"
LOGIN_REDIRECT_URL = "/admin"
SUIT_CONFIG = {
# header
"ADMIN_NAME": "SIK Admin",
# 'HEADER_DATE_FORMAT': 'l, j. F Y',
# 'HEADER_TIME_FORMAT': 'H:i',
# forms
# 'SHOW_REQUIRED_ASTERISK': True, # Default True
# 'CONFIRM_UNSAVED_CHANGES': True, # Default True
# menu
# 'SEARCH_URL': '/admin/auth/user/',
# 'MENU_ICONS': {
# 'sites': 'icon-leaf',
# 'auth': 'icon-lock',
# },
# 'MENU_OPEN_FIRST_CHILD': True, # Default True
# 'MENU_EXCLUDE': ('auth.group',),
# 'MENU': (
# 'sites',
# {'app': 'auth', 'icon':'icon-lock', 'models': ('user', 'group')},
# {'label': 'Settings', 'icon':'icon-cog', 'models': ('auth.user', 'auth.group')},
# {'label': 'Support', 'icon':'icon-question-sign', 'url': '/support/'},
# ),
# misc
# 'LIST_PER_PAGE': 15
}
JWT_AUTH = {"JWT_EXPIRATION_DELTA": datetime.timedelta(days=7)}
-30
View File
@@ -1,30 +0,0 @@
# contents of yourapp/migrations/custom_operations.py
from django.db.migrations.operations.models import ModelOperation
class AlterModelBases(ModelOperation):
reduce_to_sql = False
reversible = True
def __init__(self, name, bases):
self.bases = bases
super().__init__(name)
def state_forwards(self, app_label, state):
"""
Overwrite a models base classes with a custom list of
bases instead, then force Django to reload the model
with this (probably completely) different class hierarchy.
"""
state.models[app_label, self.name_lower].bases = self.bases
state.reload_model(app_label, self.name_lower)
def database_forwards(self, app_label, schema_editor, from_state, to_state):
pass
def database_backwards(self, app_label, schema_editor, from_state, to_state):
pass
def describe(self):
return "Update %s bases to %s" % (self.name, self.bases)

Some files were not shown because too many files have changed in this diff Show More