Merge branch 'develop' into django-v4

This commit is contained in:
Ojakoo
2022-12-21 18:34:39 +02:00
34 changed files with 1588 additions and 1399 deletions
+4 -2
View File
@@ -1,11 +1,13 @@
DEPLOY_ENV=local
SENTRY_DSN=
HOST=api.dev.sahkoinsinoorikilta.fi
HOST=localhost
DEBUG=True
SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(
DB_NAME=postgres
DB_USER=postgres
DB_PASSWD=postgres
DB_HOST=db
DB_HOST=localhost
DB_PORT=5432
EMAIL_API_KEY=
GROUP_KEY=
GOOGLE_CREDS='{}'
+1 -1
View File
@@ -10,4 +10,4 @@ DB_HOST=db
DB_PORT=5432
EMAIL_API_KEY=
GROUP_KEY=
GOOGLE_CREDS_JSON='{}'
GOOGLE_CREDS='{}'
+59 -2
View File
@@ -5,10 +5,13 @@ stages:
- test
- publish
- deploy
- cleanup
install:
image: node:14
stage: setup
only:
- pushes
script:
- npm ci
artifacts:
@@ -19,6 +22,8 @@ install:
audit:
image: python:3.9
stage: audit
only:
- pushes
needs: []
before_script:
- pip install poetry==1.1.13
@@ -30,6 +35,8 @@ audit:
test:
image: python:3.9
stage: test
only:
- pushes
needs: []
services:
- postgres:12
@@ -51,6 +58,8 @@ test:
lint:py:
image: python:3.9
stage: lint
only:
- pushes
needs: []
script:
- pip install black==22.3.0
@@ -59,6 +68,8 @@ lint:py:
lint:js:
image: node:14
stage: lint
only:
- pushes
needs: ["install"]
script:
- npm run lint:js
@@ -66,13 +77,15 @@ lint:js:
lint:md:
image: node:14
stage: lint
only:
- pushes
needs: ["install"]
script:
- npm run lint:md
publish:
stage: publish
image: docker:stable
stage: publish
needs: ["test", "lint:py", "lint:js", "lint:md"]
services:
- docker:stable-dind
@@ -86,8 +99,8 @@ publish:
- docker push "$IMAGE_NAME"
deploy:dev:
stage: deploy
image: docker:stable
stage: deploy
only:
- develop
environment:
@@ -129,3 +142,47 @@ deploy:production:
- docker stack deploy --with-registry-auth -c stack-compose.yml "$SERVICE_NAME"
after_script:
- docker logout "$CI_REGISTRY"
docker_prune:dev:
image: docker:stable
stage: cleanup
only:
- schedules
environment:
name: dev
url: http://api.dev.sahkoinsinoorikilta.fi
variables:
DOCKER_HOST: $DEV_CI_DOCKER_HOST
DOCKER_TLS_VERIFY: 1
before_script:
- mkdir -p ~/.docker
- echo "$DEV_TLSCACERT" > ~/.docker/ca.pem
- echo "$DEV_TLSCERT" > ~/.docker/cert.pem
- echo "$DEV_TLSKEY" > ~/.docker/key.pem
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
script:
- docker system prune
after_script:
- docker logout "$CI_REGISTRY"
docker_prune:prod:
image: docker:stable
stage: cleanup
only:
- schedules
environment:
name: production
url: https://api.sahkoinsinoorikilta.fi
variables:
DOCKER_HOST: $CI_DOCKER_HOST
DOCKER_TLS_VERIFY: 1
before_script:
- mkdir -p ~/.docker
- echo "$TLSCACERT" > ~/.docker/ca.pem
- echo "$TLSCERT" > ~/.docker/cert.pem
- echo "$TLSKEY" > ~/.docker/key.pem
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
script:
- docker system prune
after_script:
- docker logout "$CI_REGISTRY"
+1 -1
View File
@@ -4,7 +4,7 @@
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
source "${VIRTUAL_ENV}/bin/activate"
. "${VIRTUAL_ENV}/bin/activate"
if [ $? -ne 0 ]
then
+1 -1
View File
@@ -4,7 +4,7 @@
PURPLE='\033[0;35m'
NC='\033[0m' # No Color
source "${VIRTUAL_ENV}/bin/activate"
. "${VIRTUAL_ENV}/bin/activate"
if [ $? -ne 0 ]
then
+60 -40
View File
@@ -1,24 +1,13 @@
# SIKWEB 2.0
# Web 2.0 Backend
A modern web app using a Django backend and an Angular frontend.
[Django](https://www.djangoproject.com/) backend containing multiple small applications and api for Next.js frontend.
## Components
### Infoscreen
Angular-based slideshow app for the guild room's screens.
### Member register
Data table app for viewing and modifying the member register, member applications and membership payments.
### Web app
Mostly static website with an event calendar and news feed.
## Accessing the source
### Clone this repository and enter it
* **Web app:** Backend for the main website.
* **Member register:** Data table app for viewing and modifying the member register, member applications and membership payments.
* **Kaehmy:** Form for creating and listing kaehmys
* **Ohlhafv:** Form for creating and listing ohlhafv challenges.
* **Infoscreen:** Angular-based slideshow app for the guild room's screens.
## Installation
Set up your SSH key authentication in GitLab Profile Settings. Then clone the repository and checkout the development branch:
@@ -28,17 +17,53 @@ cd web2.0-backend
git checkout develop
```
## Development
Copy env file for local use:
```bash
cp .env.dev .env
```
### Poetry
For depedencies and virtual environment, we use [poetry](https://python-poetry.org/). The easiest integration with VSCode is to have poetry install virtual environment in project folder, configured with
For depedencies and virtual environment, we use [poetry](https://python-poetry.org/).
First install [python](https://wiki.python.org/moin/BeginnersGuide/Download). Then install poetry:
```bash
python3 -m pip install poetry
```
The easiest integration with VSCode is to have poetry install virtual environment in project folder, configured with
```bash
poetry config virtualenvs.in-project true
```
#### CMDs
### Node
We use Node.js for few development tasks, like linting. Easiest way to install Node is [nvm](https://github.com/nvm-sh/nvm). After installing install dependencies:
```
npm install
```
TODO: List scripts
### Database
To run a local development database **[docker](https://docs.docker.com/engine/install/)** is recommended. If you want to additianally use a db management tool **[pgAdmin](https://www.pgadmin.org/download/)** is nice.
After installing docker use the following to create a database:
```bash
docker run --name postgres:12 -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres:12
```
## Development
Activate virtual environment in shell
```bash
python3 -m poetry shell
```
Install dependencies
@@ -46,12 +71,6 @@ Install dependencies
poetry install
```
Activate virtual environment in shell
```bash
poetry shell
```
### npm scripts
We use Node.js for few development tasks, like linting. Easiest way to install Node is [nvm](https://github.com/nvm-sh/nvm).
@@ -60,12 +79,13 @@ TODO: List scripts
### Initializing data
Run the following `manage.py` commands. Do not run these in production without thinking!
Run the following `manage.py` commands to initialize a new database. Do not run these in production without thinking!
```bash
python manage.py createdefaultadmin # creates an admin user
python manage.py initialize # creates user groups
python manage.py createdummydata # creates dummy members to the member register
python manage.py migrate # run migrations
python manage.py createdefaultadmin # creates an admin user
python manage.py initialize # creates user groups
python manage.py createdummydata # creates dummy members to the member register
```
### Running
@@ -74,10 +94,6 @@ python manage.py createdummydata # creates dummy members to the member regis
python manage.py runserver 0.0.0.0:8000
```
Using address `0.0.0.0` will bind to all IP addresses. Using `localhost` will only bind to your machine.
#### Visit the page
Visit [https://localhost:8000](https://localhost:8000) in your browser!
### Development workflow
@@ -87,7 +103,7 @@ When you start working on a feature, create a feature branch for your changes. T
Example of creating a feature branch:
```bash
git checkout -b feature-error-page
git checkout -b feature-branch-name
```
When your changes are ready and the code works without errors, submit a merge request to `develop` in GitLab. Another developer reviews your changes and runs the merge. Feature branches should be closed on merge.
@@ -98,16 +114,18 @@ Merge requests to `master` should be reviewed by multiple developers. Only a mod
### Linting
Lint python files using `pycodestyle` with
Lint python files using `black` with
```bash
pycodestyle --config=pycodestyle.cfg --count .
npm run lint:py # check changes
npm run lint:py:fix # fix errors
```
Lint javascript and markdown using `eslint` and `remark` with
```bash
npm test
npm run lint:md # markdown
npm run lint:js # javascript
```
Use an editor with linting capabilities to write pretty code that passes linting. Examples include _VSCode_, _Atom_ and _Pycharm_.
@@ -128,6 +146,8 @@ Tests are located in `tests.py` under every subproject.
Project is run in production with Docker. See `Dockerfile` for details.
For more information about deployment check **[infra](https://gitlab.com/sahkoinsinoorikilta/vtmk/infra)** repository.
## GitLab CI
All pushed changes go through the GitLab Continuous Integration, which consists of automated unit testing and linting. Make sure your changes pass both before merging to `develop` or `master`.
+4 -4
View File
@@ -6,15 +6,15 @@ from kaehmy.models import PresetRole, CustomRole, Application, Comment, BaseRole
class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
option_template_name = "kaehmy/checkbox_option.html"
option_template_name = "checkbox_option.html"
def create_option(
self, name, value, label, selected, index, subindex=None, attrs=None
self, name, formIterator, label, selected, index, subindex=None, attrs=None
):
dic = super(CheckboxSelectMultiple, self).create_option(
name, value, label, selected, index, subindex, attrs
name, formIterator, label, selected, index, subindex, attrs
)
description = PresetRole.objects.get(id=value).description
description = PresetRole.objects.get(id=formIterator.value).description
dic["description"] = description
return dic
+4 -1
View File
@@ -13,6 +13,7 @@ class BaseRole(models.Model):
is_board = models.BooleanField(_("Board member"))
CATEGORIES = (
("board", _("Board")),
("corporate", _("Corporate affairs")),
("freshman", _("Freshmen")),
("international", _("International")),
@@ -20,11 +21,13 @@ class BaseRole(models.Model):
("media", _("Media")),
("tech", _("Technology")),
("wellbeing", _("Wellbeing")),
("elepaja", _("Elepaja")),
("sikpaja", _("Sik-paja")),
("ceremonies", _("Ceremonies")),
("studies", _("Studies")),
("sosso", _("Sössö magazine")),
("pota", _("PoTa")),
("alumni", _("Alumni relations")),
("n", _("N")),
("others", _("Others")),
)
category = models.CharField(
+4 -6
View File
@@ -5,12 +5,6 @@
margin-right: auto;
}
body {
max-width: 1000px;
margin-left: auto !important;
margin-right: auto !important;
}
div.tooltip-inner {
max-width: 25rem;
}
@@ -28,6 +22,10 @@ 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 {
+2 -5
View File
@@ -3,13 +3,9 @@
}
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;
margin: 1rem;
}
footer .container .col .nav .nav-item {
@@ -26,6 +22,7 @@ footer .container .col .nav .nav-item {
.lang-select {
width: 10rem;
margin-bottom: 1rem;
display: inline-block;
}
+18 -27
View File
@@ -1,37 +1,28 @@
.header-content {
.kaehmy-header {
background-color: #0c2938;
}
.header-content .logo {
.kaehmy-header-content {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
}
.header-content .logo img {
display: block;
height: auto;
margin: auto;
}
.kaehmy-banner {
max-width: 1000px;
width: 100%;
margin-left: auto;
margin-right: auto;
}
@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;
}
}
.kaehmy-banner-image {
width: 100%;
max-height: 10rem;
max-width: 100%;
}
.heading {
display: flex;
place-content: center;
flex-direction: column;
text-align: center;
margin: 1rem;
}
+7 -3
View File
@@ -1,11 +1,15 @@
.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;
}
+10 -10
View File
@@ -4,6 +4,7 @@ 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
import logging
from sikweb.settings import URL
@@ -64,14 +65,15 @@ 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!"
email_body = (
f"{name.capitalize()} on vastannut kaehmyhakemukseesi tai kommenttiisi kaehmypalvelussa.\r\n\r\n"
"Käy lukemassa viesti osoitteessa https://{URL}/kaehmy"
message = render_to_string(
"kaehmy/email_comment.html", {"name": name, "url": url}
)
send_email(to=to_email, subject=subject, body=email_body)
send_email(to=to_email, subject=subject, body=message, html=True)
logging.debug(f"Sent kaehmy comment email to recipient <{to_email}>")
return redirect("/kaehmy")
@@ -129,16 +131,14 @@ 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_email, subject, email_body)
send_email(to=to_email, subject=subject, body=message, html=True)
logging.debug(f"Sent kaehmy email to recipient <{to_email}>")
processHooks(message=f"Uusi New kaehmy! {name} -> {url}", eventType="kaehmy")
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
Generated
+5 -8
View File
@@ -241,14 +241,14 @@ Django = ">=3.2"
[[package]]
name = "django-phonenumber-field"
version = "6.3.0"
version = "6.4.0"
description = "An international phone number field for django models."
category = "main"
optional = false
python-versions = ">=3.7"
[package.dependencies]
Django = ">=2.2"
Django = ">=3.2"
phonenumbers = {version = ">=7.0.2", optional = true, markers = "extra == \"phonenumbers\""}
[package.extras]
@@ -314,7 +314,7 @@ test = ["cryptography", "pytest-cov", "pytest-django", "pytest-xdist", "pytest",
[[package]]
name = "dparse"
version = "0.5.1"
version = "0.6.2"
description = "A parser for Python dependency files"
category = "dev"
optional = false
@@ -322,11 +322,11 @@ python-versions = ">=3.5"
[package.dependencies]
packaging = "*"
pyyaml = "*"
toml = "*"
[package.extras]
pipenv = ["pipenv"]
conda = ["pyyaml"]
[[package]]
name = "et-xmlfile"
@@ -1092,10 +1092,7 @@ djangorestframework = [
{file = "djangorestframework-3.13.1.tar.gz", hash = "sha256:0c33407ce23acc68eca2a6e46424b008c9c02eceb8cf18581921d0092bc1f2ee"},
]
djangorestframework-simplejwt = []
dparse = [
{file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"},
{file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"},
]
dparse = []
et-xmlfile = [
{file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"},
{file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"},
+17 -2
View File
@@ -10,8 +10,23 @@ fi
if test -f "$DB_PASSWD_FILE"; then
export DB_PASSWD=$(cat $DB_PASSWD_FILE)
fi
if test -f "$GOOGLE_CREDS_JSON"; then
export GOOGLE_CREDS_JSON=$(cat $GOOGLE_CRED_JSON_FILE)
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
+13 -1
View File
@@ -82,7 +82,19 @@ DATABASES = {
# Google api settings
GROUP_KEY = os.getenv("GROUP_KEY", "")
GOOGLE_SERVICE_ACCOUNT = json.loads(os.getenv("GOOGLE_CREDS_JSON", "{}"))
GOOGLE_CREDS = {
"type": "service_account",
"project_id": "web2-backend",
"private_key_id": os.getenv("G_PRIVATE_KEY_ID", ""),
"private_key": os.getenv("G_PRIVATE_KEY", ""),
"client_email": os.getenv("G_CLIENT_EMAIL", ""),
"client_id": os.getenv("G_CLIENT_ID", ""),
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": os.getenv("G_CLIENT_URL", ""),
}
# JWT authentication
SIMPLE_JWT = {
+24
View File
@@ -29,15 +29,39 @@ services:
- FRONTEND_URL=dev.sahkoinsinoorikilta.fi
- DEBUG=True
- EMAIL_API_KEY_FILE=/run/secrets/DJANGO_EMAIL_API_KEY
- G_PRIVATE_KEY_ID_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY_ID
- G_PRIVATE_KEY_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY
- G_CLIENT_EMAIL_FILE=/run/secrets/BACKEND_G_CLIENT_EMAIL
- G_CLIENT_ID_FILE=/run/secrets/BACKEND_G_CLIENT_ID
- G_CLIENT_URL_FILE=/run/secrets/BACKEND_G_CLIENT_URL
- GROUP_KEY_FILE=/run/secrets/BACKEND_GROUP_KEY
- DB_HOST=db
- DB_PORT=5432
secrets:
- DJANGO_EMAIL_API_KEY
- BACKEND_G_PRIVATE_KEY_ID
- BACKEND_G_PRIVATE_KEY
- BACKEND_G_CLIENT_EMAIL
- BACKEND_G_CLIENT_ID
- BACKEND_G_CLIENT_URL
- BACKEND_GROUP_KEY
secrets:
DJANGO_EMAIL_API_KEY:
external: true
BACKEND_G_PRIVATE_KEY_ID:
external: true
BACKEND_G_PRIVATE_KEY:
external: true
BACKEND_G_CLIENT_EMAIL:
external: true
BACKEND_G_CLIENT_ID:
external: true
BACKEND_G_CLIENT_URL:
external: true
BACKEND_GROUP_KEY:
external: true
volumes:
dbdata:
+25 -4
View File
@@ -34,13 +34,24 @@ services:
- SECRET_KEY_FILE=/run/secrets/BACKEND_SECRET_KEY
- DB_PASSWD_FILE=/run/secrets/BACKEND_DB_PASSWD
- EMAIL_API_KEY_FILE=/run/secrets/BACKEND_EMAIL_API_KEY
- GOOGLE_CREDS_JSON=/run/secrets/GOOGLE_CREDS_JSON
- G_PRIVATE_KEY_ID_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY_ID
- G_PRIVATE_KEY_FILE=/run/secrets/BACKEND_G_PRIVATE_KEY
- G_CLIENT_EMAIL_FILE=/run/secrets/BACKEND_G_CLIENT_EMAIL
- G_CLIENT_ID_FILE=/run/secrets/BACKEND_G_CLIENT_ID
- G_CLIENT_URL_FILE=/run/secrets/BACKEND_G_CLIENT_URL
- GROUP_KEY_FILE=/run/secrets/BACKEND_GROUP_KEY
secrets:
- BACKEND_SECRET_KEY
- BACKEND_DB_PASSWD
- BACKEND_EMAIL_API_KEY
- GOOGLE_CREDS_JSON
- BACKEND_G_PRIVATE_KEY_ID
- BACKEND_G_PRIVATE_KEY
- BACKEND_G_CLIENT_EMAIL
- BACKEND_G_CLIENT_ID
- BACKEND_G_CLIENT_URL
- BACKEND_GROUP_KEY
secrets:
BACKEND_SECRET_KEY:
external: true
@@ -48,5 +59,15 @@ secrets:
external: true
BACKEND_EMAIL_API_KEY:
external: true
GOOGLE_CREDS_JSON:
EXTERNAL: true
BACKEND_G_PRIVATE_KEY_ID:
external: true
BACKEND_G_PRIVATE_KEY:
external: true
BACKEND_G_CLIENT_EMAIL:
external: true
BACKEND_G_CLIENT_ID:
external: true
BACKEND_G_CLIENT_URL:
external: true
BACKEND_GROUP_KEY:
external: true
+1 -1
View File
@@ -13,7 +13,7 @@
{% block body %}
{% block header %}
<div class="kaehmy_header">
<div class="kaehmy-header">
{% include "kaehmy/header.html" %}
</div>
{% endblock header %}
+10
View File
@@ -0,0 +1,10 @@
{% load i18n %}
<p>
Hei!
</p>
<p>
{{ name }} on vastannut kaehmyhakemukseesi tai kommenttiisi kaehmypalvelussa.
Käy lukemassa viesti
<a href={{ url }}>täältä.</a>
</p>
+13
View File
@@ -0,0 +1,13 @@
{% load i18n %}
<p>
Moikka {{ name }}!
</p>
<p>
Hienoa, että kilta kiinnostaa! Kaehmysi on vastaanotettu.
Mahdollisista kommenteista tulee ilmoitus sähköpostitse.
</p>
<p>
Käy katsomassa kaehmytilanne
<a href={{ url }}>täältä.</a>
</p>
+1 -1
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "kaehmy/base.html" %}
{% load static %}
{% load i18n %}
+9 -2
View File
@@ -1,7 +1,14 @@
{% load i18n %}
<div class="kaehmy_header-content">
<div class="kaehmy-header-content center">
<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>
<a href="/kaehmy">
<img class="kaehmy-banner-image" src="https://static.sahkoinsinoorikilta.fi/logot-ja-grafiikka/web/side/SIK_RGB_W_side.png" alt="Aalto-yliopiston Sähköinsinöörikilta ry">
</a>
</div>
<div class="kaehmy-banner heading">
<p style="color:#D57A2D; font-size:2rem">{% blocktrans %}Kähmyt ovat auki!{% endblocktrans %}</p>
<p style="color:#BFDBD9; font-size:1rem">{% blocktrans %}Haku hallitukseen 24.10. mennessä ja toimihenkilöksi 18.11 mennessä.{% endblocktrans %}</p>
<p style="color:#BFDBD9; font-size:1.5rem">{% blocktrans %}Hae nyt!{% endblocktrans %}</p>
</div>
</div>
+7 -5
View File
@@ -28,10 +28,12 @@
</p>
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
<ul>
<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>
<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>
</ul>
<form name="kaehmyForm" action="/kaehmy/submit/" method="post" class="form">{% csrf_token %}
{% bootstrap_field form.name %}
@@ -75,7 +77,7 @@
<input type="checkbox" required name="gdpr" value="1">
<span>{% blocktrans %}
Hyväksyn <a href="https://static.sahkoinsinoorikilta.fi/GDPR/Tietosuojaseloste%20%23U2013%20Toimihenkil%23U00f6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
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.
{% endblocktrans %}
</span>
{% buttons %}
+1 -1
View File
@@ -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>
+2 -2
View File
@@ -1,8 +1,8 @@
{% load i18n %}
{% load static %}
<div class="kaehmy_navigation">
<nav class="navbar-border navbar navbar-toggleable-md navbar-light bg-faded">
<div class="kaehmy_navigation bg-faded">
<nav class="navbar navbar-toggleable-md navbar-light">
<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 -1
View File
@@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "members/base.html" %}
{% load static %}
{% load i18n %}
View File
+13 -2
View File
@@ -25,7 +25,7 @@ from sikweb.settings import (
DEFAULT_EMAIL_FROM_ADDR,
ENABLE_AUTOMATIC_EMAILS,
GROUP_KEY,
GOOGLE_SERVICE_ACCOUNT,
GOOGLE_CREDS,
)
from datetime import timedelta
@@ -136,7 +136,7 @@ def add_to_mailinglist(email: str):
# create credentials, with subject is used to impersonate admin account
# jas_manager has groups editor rights in google admin
credentials = service_account.Credentials.from_service_account_info(
info=GOOGLE_SERVICE_ACCOUNT, scopes=SCOPES
info=GOOGLE_CREDS, scopes=SCOPES
).with_subject("jas_manager@sahkoinsinoorikilta.fi")
service = build("admin", "directory_v1", credentials=credentials)
@@ -157,3 +157,14 @@ def add_to_mailinglist(email: str):
)
send_email(to, subject, body)
except ValueError as err:
logging.exception("Formatting of google credentials is incorrect")
if DEPLOY_ENV == "production":
to = "ilari.ojakorpi@sahkoinsinoorikilta.fi"
subject = "Web error: Failed adding to google groups"
body = "Google credential formatted incorretly\nEmail that was not added: {}\n\nAdd user manually to jäsenet groups.".format(
email
)
send_email(to, subject, body)