Merge branch 'develop' into django-v4
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
DEPLOY_ENV=local
|
DEPLOY_ENV=local
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
HOST=api.dev.sahkoinsinoorikilta.fi
|
HOST=localhost
|
||||||
DEBUG=True
|
DEBUG=True
|
||||||
SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(
|
SECRET_KEY=7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp(
|
||||||
DB_NAME=postgres
|
DB_NAME=postgres
|
||||||
DB_USER=postgres
|
DB_USER=postgres
|
||||||
DB_PASSWD=postgres
|
DB_PASSWD=postgres
|
||||||
DB_HOST=db
|
DB_HOST=localhost
|
||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
EMAIL_API_KEY=
|
EMAIL_API_KEY=
|
||||||
|
GROUP_KEY=
|
||||||
|
GOOGLE_CREDS='{}'
|
||||||
|
|||||||
+1
-1
@@ -10,4 +10,4 @@ DB_HOST=db
|
|||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
EMAIL_API_KEY=
|
EMAIL_API_KEY=
|
||||||
GROUP_KEY=
|
GROUP_KEY=
|
||||||
GOOGLE_CREDS_JSON='{}'
|
GOOGLE_CREDS='{}'
|
||||||
|
|||||||
+59
-2
@@ -5,10 +5,13 @@ stages:
|
|||||||
- test
|
- test
|
||||||
- publish
|
- publish
|
||||||
- deploy
|
- deploy
|
||||||
|
- cleanup
|
||||||
|
|
||||||
install:
|
install:
|
||||||
image: node:14
|
image: node:14
|
||||||
stage: setup
|
stage: setup
|
||||||
|
only:
|
||||||
|
- pushes
|
||||||
script:
|
script:
|
||||||
- npm ci
|
- npm ci
|
||||||
artifacts:
|
artifacts:
|
||||||
@@ -19,6 +22,8 @@ install:
|
|||||||
audit:
|
audit:
|
||||||
image: python:3.9
|
image: python:3.9
|
||||||
stage: audit
|
stage: audit
|
||||||
|
only:
|
||||||
|
- pushes
|
||||||
needs: []
|
needs: []
|
||||||
before_script:
|
before_script:
|
||||||
- pip install poetry==1.1.13
|
- pip install poetry==1.1.13
|
||||||
@@ -30,6 +35,8 @@ audit:
|
|||||||
test:
|
test:
|
||||||
image: python:3.9
|
image: python:3.9
|
||||||
stage: test
|
stage: test
|
||||||
|
only:
|
||||||
|
- pushes
|
||||||
needs: []
|
needs: []
|
||||||
services:
|
services:
|
||||||
- postgres:12
|
- postgres:12
|
||||||
@@ -51,6 +58,8 @@ test:
|
|||||||
lint:py:
|
lint:py:
|
||||||
image: python:3.9
|
image: python:3.9
|
||||||
stage: lint
|
stage: lint
|
||||||
|
only:
|
||||||
|
- pushes
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- pip install black==22.3.0
|
- pip install black==22.3.0
|
||||||
@@ -59,6 +68,8 @@ lint:py:
|
|||||||
lint:js:
|
lint:js:
|
||||||
image: node:14
|
image: node:14
|
||||||
stage: lint
|
stage: lint
|
||||||
|
only:
|
||||||
|
- pushes
|
||||||
needs: ["install"]
|
needs: ["install"]
|
||||||
script:
|
script:
|
||||||
- npm run lint:js
|
- npm run lint:js
|
||||||
@@ -66,13 +77,15 @@ lint:js:
|
|||||||
lint:md:
|
lint:md:
|
||||||
image: node:14
|
image: node:14
|
||||||
stage: lint
|
stage: lint
|
||||||
|
only:
|
||||||
|
- pushes
|
||||||
needs: ["install"]
|
needs: ["install"]
|
||||||
script:
|
script:
|
||||||
- npm run lint:md
|
- npm run lint:md
|
||||||
|
|
||||||
publish:
|
publish:
|
||||||
stage: publish
|
|
||||||
image: docker:stable
|
image: docker:stable
|
||||||
|
stage: publish
|
||||||
needs: ["test", "lint:py", "lint:js", "lint:md"]
|
needs: ["test", "lint:py", "lint:js", "lint:md"]
|
||||||
services:
|
services:
|
||||||
- docker:stable-dind
|
- docker:stable-dind
|
||||||
@@ -86,8 +99,8 @@ publish:
|
|||||||
- docker push "$IMAGE_NAME"
|
- docker push "$IMAGE_NAME"
|
||||||
|
|
||||||
deploy:dev:
|
deploy:dev:
|
||||||
stage: deploy
|
|
||||||
image: docker:stable
|
image: docker:stable
|
||||||
|
stage: deploy
|
||||||
only:
|
only:
|
||||||
- develop
|
- develop
|
||||||
environment:
|
environment:
|
||||||
@@ -129,3 +142,47 @@ deploy:production:
|
|||||||
- docker stack deploy --with-registry-auth -c stack-compose.yml "$SERVICE_NAME"
|
- docker stack deploy --with-registry-auth -c stack-compose.yml "$SERVICE_NAME"
|
||||||
after_script:
|
after_script:
|
||||||
- docker logout "$CI_REGISTRY"
|
- 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
@@ -4,7 +4,7 @@
|
|||||||
PURPLE='\033[0;35m'
|
PURPLE='\033[0;35m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
source "${VIRTUAL_ENV}/bin/activate"
|
. "${VIRTUAL_ENV}/bin/activate"
|
||||||
|
|
||||||
if [ $? -ne 0 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
PURPLE='\033[0;35m'
|
PURPLE='\033[0;35m'
|
||||||
NC='\033[0m' # No Color
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
source "${VIRTUAL_ENV}/bin/activate"
|
. "${VIRTUAL_ENV}/bin/activate"
|
||||||
|
|
||||||
if [ $? -ne 0 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
|
|||||||
@@ -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
|
* **Web app:** Backend for the main website.
|
||||||
|
* **Member register:** Data table app for viewing and modifying the member register, member applications and membership payments.
|
||||||
### Infoscreen
|
* **Kaehmy:** Form for creating and listing kaehmys
|
||||||
|
* **Ohlhafv:** Form for creating and listing ohlhafv challenges.
|
||||||
Angular-based slideshow app for the guild room's screens.
|
* **Infoscreen:** Angular-based slideshow app for the guild room's screens.
|
||||||
|
## Installation
|
||||||
### 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
|
|
||||||
|
|
||||||
Set up your SSH key authentication in GitLab Profile Settings. Then clone the repository and checkout the development branch:
|
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
|
git checkout develop
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development
|
Copy env file for local use:
|
||||||
|
```bash
|
||||||
|
cp .env.dev .env
|
||||||
|
```
|
||||||
|
|
||||||
### Poetry
|
### 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
|
```bash
|
||||||
poetry config virtualenvs.in-project true
|
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
|
Install dependencies
|
||||||
|
|
||||||
@@ -46,12 +71,6 @@ Install dependencies
|
|||||||
poetry install
|
poetry install
|
||||||
```
|
```
|
||||||
|
|
||||||
Activate virtual environment in shell
|
|
||||||
|
|
||||||
```bash
|
|
||||||
poetry shell
|
|
||||||
```
|
|
||||||
|
|
||||||
### npm scripts
|
### 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).
|
We use Node.js for few development tasks, like linting. Easiest way to install Node is [nvm](https://github.com/nvm-sh/nvm).
|
||||||
@@ -60,9 +79,10 @@ TODO: List scripts
|
|||||||
|
|
||||||
### Initializing data
|
### 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
|
```bash
|
||||||
|
python manage.py migrate # run migrations
|
||||||
python manage.py createdefaultadmin # creates an admin user
|
python manage.py createdefaultadmin # creates an admin user
|
||||||
python manage.py initialize # creates user groups
|
python manage.py initialize # creates user groups
|
||||||
python manage.py createdummydata # creates dummy members to the member register
|
python manage.py createdummydata # creates dummy members to the member register
|
||||||
@@ -74,10 +94,6 @@ python manage.py createdummydata # creates dummy members to the member regis
|
|||||||
python manage.py runserver 0.0.0.0:8000
|
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!
|
Visit [https://localhost:8000](https://localhost:8000) in your browser!
|
||||||
|
|
||||||
### Development workflow
|
### 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:
|
Example of creating a feature branch:
|
||||||
|
|
||||||
```bash
|
```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.
|
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
|
### Linting
|
||||||
|
|
||||||
Lint python files using `pycodestyle` with
|
Lint python files using `black` with
|
||||||
|
|
||||||
```bash
|
```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
|
Lint javascript and markdown using `eslint` and `remark` with
|
||||||
|
|
||||||
```bash
|
```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_.
|
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.
|
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
|
## 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`.
|
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
@@ -6,15 +6,15 @@ from kaehmy.models import PresetRole, CustomRole, Application, Comment, BaseRole
|
|||||||
|
|
||||||
|
|
||||||
class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
|
class CheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple):
|
||||||
option_template_name = "kaehmy/checkbox_option.html"
|
option_template_name = "checkbox_option.html"
|
||||||
|
|
||||||
def create_option(
|
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(
|
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
|
dic["description"] = description
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -13,6 +13,7 @@ class BaseRole(models.Model):
|
|||||||
is_board = models.BooleanField(_("Board member"))
|
is_board = models.BooleanField(_("Board member"))
|
||||||
|
|
||||||
CATEGORIES = (
|
CATEGORIES = (
|
||||||
|
("board", _("Board")),
|
||||||
("corporate", _("Corporate affairs")),
|
("corporate", _("Corporate affairs")),
|
||||||
("freshman", _("Freshmen")),
|
("freshman", _("Freshmen")),
|
||||||
("international", _("International")),
|
("international", _("International")),
|
||||||
@@ -20,11 +21,13 @@ class BaseRole(models.Model):
|
|||||||
("media", _("Media")),
|
("media", _("Media")),
|
||||||
("tech", _("Technology")),
|
("tech", _("Technology")),
|
||||||
("wellbeing", _("Wellbeing")),
|
("wellbeing", _("Wellbeing")),
|
||||||
("elepaja", _("Elepaja")),
|
("sikpaja", _("Sik-paja")),
|
||||||
("ceremonies", _("Ceremonies")),
|
("ceremonies", _("Ceremonies")),
|
||||||
("studies", _("Studies")),
|
("studies", _("Studies")),
|
||||||
("sosso", _("Sössö magazine")),
|
("sosso", _("Sössö magazine")),
|
||||||
|
("pota", _("PoTa")),
|
||||||
("alumni", _("Alumni relations")),
|
("alumni", _("Alumni relations")),
|
||||||
|
("n", _("N")),
|
||||||
("others", _("Others")),
|
("others", _("Others")),
|
||||||
)
|
)
|
||||||
category = models.CharField(
|
category = models.CharField(
|
||||||
|
|||||||
@@ -5,12 +5,6 @@
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
|
||||||
max-width: 1000px;
|
|
||||||
margin-left: auto !important;
|
|
||||||
margin-right: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.tooltip-inner {
|
div.tooltip-inner {
|
||||||
max-width: 25rem;
|
max-width: 25rem;
|
||||||
}
|
}
|
||||||
@@ -28,6 +22,10 @@ div.tooltip-inner {
|
|||||||
.kaehmy-content {
|
.kaehmy-content {
|
||||||
padding-left: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
padding-right: 0.5rem;
|
padding-right: 0.5rem;
|
||||||
|
max-width: 1000px;
|
||||||
|
width: 100%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
|||||||
@@ -3,13 +3,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
/* position: absolute; */
|
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 60px; /* Set the fixed height of the footer here */
|
margin: 1rem;
|
||||||
/* line-height: 60px; /* Vertically center the text there */
|
|
||||||
margin-top: 2rem;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
footer .container .col .nav .nav-item {
|
footer .container .col .nav .nav-item {
|
||||||
@@ -26,6 +22,7 @@ footer .container .col .nav .nav-item {
|
|||||||
|
|
||||||
.lang-select {
|
.lang-select {
|
||||||
width: 10rem;
|
width: 10rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
max-width: 1000px;
|
||||||
|
width: 100%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: 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 {
|
.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;
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
.kaehmy_navigation {
|
.kaehmy_navigation {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-border {
|
|
||||||
border-bottom: 2px solid #282b3b;
|
border-bottom: 2px solid #282b3b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-light .navbar-nav .nav-link {
|
.navbar-light .navbar-nav .nav-link {
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
max-width: 1000px;
|
||||||
|
width: 100%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
+10
-10
@@ -4,6 +4,7 @@ from django.views.decorators.http import require_http_methods
|
|||||||
from django.views.decorators.csrf import ensure_csrf_cookie
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.template.loader import render_to_string
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from sikweb.settings import URL
|
from sikweb.settings import URL
|
||||||
@@ -64,14 +65,15 @@ def comment(request, *args, **kwargs):
|
|||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
comment = form.save()
|
comment = form.save()
|
||||||
name = comment.name
|
name = comment.name
|
||||||
|
url = f"https://{URL}/kaehmy"
|
||||||
|
|
||||||
to_email = comment.parent.email
|
to_email = comment.parent.email
|
||||||
subject = "Kaehmyysi tai kommenttiisi on vastattu!"
|
subject = "Kaehmyysi tai kommenttiisi on vastattu!"
|
||||||
email_body = (
|
message = render_to_string(
|
||||||
f"{name.capitalize()} on vastannut kaehmyhakemukseesi tai kommenttiisi kaehmypalvelussa.\r\n\r\n"
|
"kaehmy/email_comment.html", {"name": name, "url": url}
|
||||||
"Käy lukemassa viesti osoitteessa https://{URL}/kaehmy"
|
|
||||||
)
|
)
|
||||||
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}>")
|
logging.debug(f"Sent kaehmy comment email to recipient <{to_email}>")
|
||||||
|
|
||||||
return redirect("/kaehmy")
|
return redirect("/kaehmy")
|
||||||
@@ -129,16 +131,14 @@ def submit(request, *args, **kwargs):
|
|||||||
|
|
||||||
url = f"https://{URL}/kaehmy"
|
url = f"https://{URL}/kaehmy"
|
||||||
name = form.cleaned_data.get("name", "Anonymous")
|
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", "")
|
to_email = form.cleaned_data.get("email", "")
|
||||||
subject = "Arwokas kirjattu kirje mahdolliselle tulewalle kiltahenkilölle"
|
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}>")
|
logging.debug(f"Sent kaehmy email to recipient <{to_email}>")
|
||||||
|
|
||||||
processHooks(message=f"Uusi New kaehmy! {name} -> {url}", eventType="kaehmy")
|
processHooks(message=f"Uusi New kaehmy! {name} -> {url}", eventType="kaehmy")
|
||||||
|
|||||||
Binary file not shown.
+644
-632
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+785
-792
File diff suppressed because it is too large
Load Diff
Generated
+5
-8
@@ -241,14 +241,14 @@ Django = ">=3.2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-phonenumber-field"
|
name = "django-phonenumber-field"
|
||||||
version = "6.3.0"
|
version = "6.4.0"
|
||||||
description = "An international phone number field for django models."
|
description = "An international phone number field for django models."
|
||||||
category = "main"
|
category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
Django = ">=2.2"
|
Django = ">=3.2"
|
||||||
phonenumbers = {version = ">=7.0.2", optional = true, markers = "extra == \"phonenumbers\""}
|
phonenumbers = {version = ">=7.0.2", optional = true, markers = "extra == \"phonenumbers\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@@ -314,7 +314,7 @@ test = ["cryptography", "pytest-cov", "pytest-django", "pytest-xdist", "pytest",
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dparse"
|
name = "dparse"
|
||||||
version = "0.5.1"
|
version = "0.6.2"
|
||||||
description = "A parser for Python dependency files"
|
description = "A parser for Python dependency files"
|
||||||
category = "dev"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
@@ -322,11 +322,11 @@ python-versions = ">=3.5"
|
|||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
packaging = "*"
|
packaging = "*"
|
||||||
pyyaml = "*"
|
|
||||||
toml = "*"
|
toml = "*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
pipenv = ["pipenv"]
|
pipenv = ["pipenv"]
|
||||||
|
conda = ["pyyaml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "et-xmlfile"
|
name = "et-xmlfile"
|
||||||
@@ -1092,10 +1092,7 @@ djangorestframework = [
|
|||||||
{file = "djangorestframework-3.13.1.tar.gz", hash = "sha256:0c33407ce23acc68eca2a6e46424b008c9c02eceb8cf18581921d0092bc1f2ee"},
|
{file = "djangorestframework-3.13.1.tar.gz", hash = "sha256:0c33407ce23acc68eca2a6e46424b008c9c02eceb8cf18581921d0092bc1f2ee"},
|
||||||
]
|
]
|
||||||
djangorestframework-simplejwt = []
|
djangorestframework-simplejwt = []
|
||||||
dparse = [
|
dparse = []
|
||||||
{file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"},
|
|
||||||
{file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"},
|
|
||||||
]
|
|
||||||
et-xmlfile = [
|
et-xmlfile = [
|
||||||
{file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"},
|
{file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"},
|
||||||
{file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"},
|
{file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"},
|
||||||
|
|||||||
@@ -10,8 +10,23 @@ fi
|
|||||||
if test -f "$DB_PASSWD_FILE"; then
|
if test -f "$DB_PASSWD_FILE"; then
|
||||||
export DB_PASSWD=$(cat $DB_PASSWD_FILE)
|
export DB_PASSWD=$(cat $DB_PASSWD_FILE)
|
||||||
fi
|
fi
|
||||||
if test -f "$GOOGLE_CREDS_JSON"; then
|
if test -f "$G_PRIVATE_KEY_ID_FILE"; then
|
||||||
export GOOGLE_CREDS_JSON=$(cat $GOOGLE_CRED_JSON_FILE)
|
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
|
fi
|
||||||
|
|
||||||
# Collect static files
|
# Collect static files
|
||||||
|
|||||||
+13
-1
@@ -82,7 +82,19 @@ DATABASES = {
|
|||||||
|
|
||||||
# Google api settings
|
# Google api settings
|
||||||
GROUP_KEY = os.getenv("GROUP_KEY", "")
|
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
|
# JWT authentication
|
||||||
SIMPLE_JWT = {
|
SIMPLE_JWT = {
|
||||||
|
|||||||
@@ -29,15 +29,39 @@ services:
|
|||||||
- FRONTEND_URL=dev.sahkoinsinoorikilta.fi
|
- FRONTEND_URL=dev.sahkoinsinoorikilta.fi
|
||||||
- DEBUG=True
|
- DEBUG=True
|
||||||
- EMAIL_API_KEY_FILE=/run/secrets/DJANGO_EMAIL_API_KEY
|
- 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_HOST=db
|
||||||
- DB_PORT=5432
|
- DB_PORT=5432
|
||||||
|
|
||||||
secrets:
|
secrets:
|
||||||
- DJANGO_EMAIL_API_KEY
|
- 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:
|
secrets:
|
||||||
DJANGO_EMAIL_API_KEY:
|
DJANGO_EMAIL_API_KEY:
|
||||||
external: true
|
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:
|
volumes:
|
||||||
dbdata:
|
dbdata:
|
||||||
|
|||||||
+25
-4
@@ -34,13 +34,24 @@ services:
|
|||||||
- SECRET_KEY_FILE=/run/secrets/BACKEND_SECRET_KEY
|
- SECRET_KEY_FILE=/run/secrets/BACKEND_SECRET_KEY
|
||||||
- DB_PASSWD_FILE=/run/secrets/BACKEND_DB_PASSWD
|
- DB_PASSWD_FILE=/run/secrets/BACKEND_DB_PASSWD
|
||||||
- EMAIL_API_KEY_FILE=/run/secrets/BACKEND_EMAIL_API_KEY
|
- 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:
|
secrets:
|
||||||
- BACKEND_SECRET_KEY
|
- BACKEND_SECRET_KEY
|
||||||
- BACKEND_DB_PASSWD
|
- BACKEND_DB_PASSWD
|
||||||
- BACKEND_EMAIL_API_KEY
|
- 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:
|
secrets:
|
||||||
BACKEND_SECRET_KEY:
|
BACKEND_SECRET_KEY:
|
||||||
external: true
|
external: true
|
||||||
@@ -48,5 +59,15 @@ secrets:
|
|||||||
external: true
|
external: true
|
||||||
BACKEND_EMAIL_API_KEY:
|
BACKEND_EMAIL_API_KEY:
|
||||||
external: true
|
external: true
|
||||||
GOOGLE_CREDS_JSON:
|
BACKEND_G_PRIVATE_KEY_ID:
|
||||||
EXTERNAL: true
|
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
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{% block body %}
|
{% block body %}
|
||||||
|
|
||||||
{% block header %}
|
{% block header %}
|
||||||
<div class="kaehmy_header">
|
<div class="kaehmy-header">
|
||||||
{% include "kaehmy/header.html" %}
|
{% include "kaehmy/header.html" %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock header %}
|
{% endblock header %}
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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,4 +1,4 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "kaehmy/base.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<div class="kaehmy_header-content">
|
<div class="kaehmy-header-content center">
|
||||||
<div class="kaehmy-banner logo">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -28,10 +28,12 @@
|
|||||||
</p>
|
</p>
|
||||||
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
|
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
|
||||||
<ul>
|
<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>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>07.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
|
||||||
<li><strong>09.11.</strong> {% blocktrans %}Toimikunta-appro{% endblocktrans %}</li>
|
<li><strong>18.11.</strong> {% blocktrans %}Deadline toimivirkoihin hakemiselle.{% endblocktrans %}</li>
|
||||||
<li><strong>17.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
|
<li><strong>24.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form name="kaehmyForm" action="/kaehmy/submit/" method="post" class="form">{% csrf_token %}
|
<form name="kaehmyForm" action="/kaehmy/submit/" method="post" class="form">{% csrf_token %}
|
||||||
{% bootstrap_field form.name %}
|
{% bootstrap_field form.name %}
|
||||||
@@ -75,7 +77,7 @@
|
|||||||
|
|
||||||
<input type="checkbox" required name="gdpr" value="1">
|
<input type="checkbox" required name="gdpr" value="1">
|
||||||
<span>{% blocktrans %}
|
<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 %}
|
{% endblocktrans %}
|
||||||
</span>
|
</span>
|
||||||
{% buttons %}
|
{% buttons %}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<div class="card" style="margin-top: 0.5rem; margin-bottom: 0">
|
<div class="card" style="margin-top: 0.5rem; margin-bottom: 0">
|
||||||
<div class="card-block">
|
<div class="card-block">
|
||||||
<h4>{{ message.name }}</h4>
|
<h4>{{ message.name }}</h4>
|
||||||
<p>{{ message.message|linebreaks|urlize }}</p>
|
<p>{{ message.message|linebreaks|urlize }}</p>
|
||||||
|
|
||||||
<h6 class="card-subtitle mb-2 text-muted">{{ message.timestamp }}</h6>
|
<h6 class="card-subtitle mb-2 text-muted">{{ message.timestamp }}</h6>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
<div class="kaehmy_navigation">
|
<div class="kaehmy_navigation bg-faded">
|
||||||
<nav class="navbar-border navbar navbar-toggleable-md navbar-light bg-faded">
|
<nav class="navbar navbar-toggleable-md navbar-light">
|
||||||
<div class="navbar-nav">
|
<div class="navbar-nav">
|
||||||
<a class="nav-item nav-link" href="/kaehmy">{% trans "List kaehmys" %}</a>
|
<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>
|
<a class="nav-item nav-link" href="/kaehmy/new">{% trans "New kaehmy" %} <span class="sr-only">(current)</span></a>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "members/base.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|||||||
+13
-2
@@ -25,7 +25,7 @@ from sikweb.settings import (
|
|||||||
DEFAULT_EMAIL_FROM_ADDR,
|
DEFAULT_EMAIL_FROM_ADDR,
|
||||||
ENABLE_AUTOMATIC_EMAILS,
|
ENABLE_AUTOMATIC_EMAILS,
|
||||||
GROUP_KEY,
|
GROUP_KEY,
|
||||||
GOOGLE_SERVICE_ACCOUNT,
|
GOOGLE_CREDS,
|
||||||
)
|
)
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ def add_to_mailinglist(email: str):
|
|||||||
# create credentials, with subject is used to impersonate admin account
|
# create credentials, with subject is used to impersonate admin account
|
||||||
# jas_manager has groups editor rights in google admin
|
# jas_manager has groups editor rights in google admin
|
||||||
credentials = service_account.Credentials.from_service_account_info(
|
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")
|
).with_subject("jas_manager@sahkoinsinoorikilta.fi")
|
||||||
|
|
||||||
service = build("admin", "directory_v1", credentials=credentials)
|
service = build("admin", "directory_v1", credentials=credentials)
|
||||||
@@ -156,4 +156,15 @@ def add_to_mailinglist(email: str):
|
|||||||
err.status_code, err.error_details, email
|
err.status_code, err.error_details, email
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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)
|
send_email(to, subject, body)
|
||||||
|
|||||||
Reference in New Issue
Block a user