Merge branch 'develop' into 'master'

New Sika & Membership application

See merge request sahkoinsinoorikilta/vtmk/web2.0-backend!3
This commit is contained in:
Aarni Halinen
2019-10-07 16:04:32 +00:00
82 changed files with 2334 additions and 1325 deletions
+1
View File
@@ -3,3 +3,4 @@ infoscreen/static/js/lib
webapp/static/js/lib
static/js/lib
collected_static
venv
-1
View File
@@ -5,7 +5,6 @@ sikweb/settings.py
*.sqlite3
uwsgi.ini
uwsgi.log
infoscreen/static/js/hsl.json
members/logs/*
.idea/
logs/
+46 -23
View File
@@ -48,13 +48,14 @@ remark:
publish:
stage: publish
image: docker:latest
image: docker:stable
services:
- docker:stable-dind
only:
- develop
before_script:
- docker info
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $REGISTRY_URL
script:
- docker info
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker build . -t "$IMAGE_NAME"
- docker push "$IMAGE_NAME"
@@ -77,25 +78,47 @@ deploy_dev:
script:
- scp docker-compose.yml $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/docker-compose.yml
- scp .deploy_dev.sh $DEV_SSH_USER@$DEV_SSH_HOST:~/deployment/deploy_dev.sh
- ssh $DEV_SSH_USER@$DEV_SSH_HOST "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY"
- ssh $DEV_SSH_USER@$DEV_SSH_HOST "bash ~/deployment/deploy_dev.sh \"$IMAGE_NAME\""
# deploy_production:
# stage: deploy
# image: alpine:latest
# environment:
# name: production
# url: https://sika.sahkoinsinoorikilta.fi
# when: manual
# only:
# - master
# before_script:
# - pwd
# - apk add --update openssh
# - ssh -V
# - mkdir -p ~/.ssh
# - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
# - chmod 600 ~/.ssh/id_rsa
# - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
# script:
# - ssh $PROD_SSH_USER@$PROD_SSH_HOST "zsh ~/deploy.sh"
deploy_production:
stage: deploy
image: alpine:latest
environment:
name: production
url: https://sika.sahkoinsinoorikilta.fi
when: manual
only:
- master
before_script:
- pwd
- apk add --update openssh
- ssh -V
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
script:
- ssh $PROD_SSH_USER@$PROD_SSH_HOST "zsh ~/deploy.sh"
stage: deploy
image: docker:stable
only:
- master
environment:
name: production
url: sika.sik.party
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 stack deploy --with-registry-auth -c stack-compose.yml "$SERVICE_NAME"
after_script:
- docker logout "$CI_REGISTRY"
+1
View File
@@ -0,0 +1 @@
3.6.8
+52
View File
@@ -0,0 +1,52 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
flake8 = "*"
autopep8 = "*"
[packages]
decorator = "==4.0.9"
ipython = "==4.2.0"
pexpect = "==4.1.0"
pickleshare = "==0.7.2"
ptyprocess = "==0.5.1"
pytz = "==2016.4"
simplegeneric = "==0.8.1"
traitlets = "==4.2.1"
requests = "==2.11.1"
django-nocaptcha-recaptcha = "==0.0.19"
django-cors-headers = "==2.0.1"
djangorestframework = "==3.8.2"
djangorestframework-jwt = "==1.11.0"
coverage = "==4.3.4"
django-nose = "==1.4.5"
nose-exclude = "==0.5.0"
psycopg2-binary = "==2.7.6.1"
django-bootstrap3 = "==11.1.0"
django-tables2 = "==1.6.1"
pycodestyle = "==2.3.1"
dealer = "==2.0.5"
django-modeltranslation = "==0.13b1"
django-auditlog = "==0.4.5"
django-phonenumber-field = "==1.3.0"
django-autocomplete-light = "==3.4.1"
six = "==1.10.0"
django-suit = "==0.2.26"
telepot = "==12.3"
pyexcel = "==0.5.10"
pyexcel-xlsx = "==0.5.5"
django-import-export = "==0.7.0"
openpyxl = "==2.4.11"
django-app-namespace-template-loader = "==0.4.1"
django-filter = "==2.0.0"
"backports.shutil_get_terminal_size" = "==1.0.0"
Django = "==2.1.5"
ipython_genutils = "==0.1.0"
Pillow = "==5.4.1"
PyJWT = "==1.6.4"
[requires]
python_version = "3.7"
Generated
+724
View File
@@ -0,0 +1,724 @@
{
"_meta": {
"hash": {
"sha256": "85a50ecbb054f863d8a149def7c32f916b9cd326aee80c2c86eda2b44ee20e2d"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"aiohttp": {
"hashes": [
"sha256:022c400e30848b1994236e31fb38db1dc4b551efe049f737cbac690ab2cdf5c4",
"sha256:10f9316ef068536dec0b9f09531fa1cb6bfa8394f278022cb96e789c77811ad2",
"sha256:2599b93fd5ba1120b3bd1366d67a7e26bd45b3d5d5548069e00b2fbef7f20ab0",
"sha256:2a1c71e7fb8c50e60fb4c9bab8bd5cf7c07f91a6b27dc2556d7354cd2ebb3689",
"sha256:6a19d34cc01414d94dd5a4466f8f397293fcb8929df8eeb8989119cc5ef928bb",
"sha256:7aab39c2a61a5c6b15bb7e561218ef64770ca1fbf4cc1878c96e630e2b7cc3cc",
"sha256:8959e28bc1b87542b0ee4a8302128f633bee296252f261bf03e118c4dff725f0",
"sha256:89820f7c488f4e9b1f74371da33403181e11e006663ddf074317aacd690838a6",
"sha256:ab761cf0f0b0b90887e276b4a7918f11e323f2228bbb30814bbd538c122028bf",
"sha256:cc648ecaca79e37c6e26f370e802e7ae640a069913f661f66c0421084bef219a",
"sha256:d6f26e80cd55ac88e1f0397fc8d547933225a5dc1add040e27788c2a028c64c6",
"sha256:e7d6ae4a36bfe6d7f93c6f42a0bfa1659f7d011006cb6e8207c85ef5acdb2986",
"sha256:fc55b1fec0e4cc1134ffb09ea3970783ee2906dc5dfd7cd16917913f2cfed65b"
],
"version": "==3.6.1"
},
"appnope": {
"hashes": [
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
],
"markers": "sys_platform == 'darwin'",
"version": "==0.1.0"
},
"async-timeout": {
"hashes": [
"sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f",
"sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3"
],
"version": "==3.0.1"
},
"attrs": {
"hashes": [
"sha256:ec20e7a4825331c1b5ebf261d111e16fa9612c1f7a5e1f884f12bd53a664dfd2",
"sha256:f913492e1663d3c36f502e5e9ba6cd13cf19d7fab50aa13239e420fef95e1396"
],
"version": "==19.2.0"
},
"babel": {
"hashes": [
"sha256:af92e6106cb7c55286b25b38ad7695f8b4efb36a90ba483d7f7a6628c46158ab",
"sha256:e86135ae101e31e2c8ec20a4e0c5220f4eed12487d5cf3f78be7e98d3a57fc28"
],
"version": "==2.7.0"
},
"backports.csv": {
"hashes": [
"sha256:1277dfff73130b2e106bf3dd347adb3c5f6c4340882289d88f31240da92cbd6d",
"sha256:21f6e09bab589e6c1f877edbc40277b65e626262a86e69a70137db714eaac5ce"
],
"version": "==1.0.7"
},
"backports.shutil-get-terminal-size": {
"hashes": [
"sha256:0975ba55054c15e346944b38956a4c9cbee9009391e41b86c68990effb8c1f64",
"sha256:713e7a8228ae80341c70586d1cc0a8caa5207346927e23d09dcbcaf18eadec80"
],
"index": "pypi",
"version": "==1.0.0"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"coverage": {
"hashes": [
"sha256:01406019418aabb2d4741647cc79b0e0deb0b8c5a6f936936c303e2f82ec8e5b",
"sha256:01a07b2b9212d4da3a1294436b58ac53f1d7aa445bda666648a5357048dc7ef3",
"sha256:024682371464c6e3caa975aba12b4d5428f35613489340fce1334c74d590a057",
"sha256:07c15c4a2287116a41d5966f1f5a7be765640c2e5a1917f882850a24615db6d3",
"sha256:1d23dea598fb4d61a8577d0eb0cb2b7932db0c8d2e1394088ad5f64e3fe1febf",
"sha256:1eeb9de833c3b976ee118a8d838af437bfa596bf60a5bf0705f4370e6d181a52",
"sha256:229ab9c0d53c55d698b8784d53077bef7a5f1fb5d27e90dc7b6f91243b024513",
"sha256:2f5a8bf29bdc69976d0913745daab11f8265e46ec41153f5e1e1794088019dad",
"sha256:2f959bc1b40a3ef2c5f0c7bc282226d6d4bd585b239bcce321013afc18ff0a0f",
"sha256:36407249a0b6669c6ad4425b0f29685579df745480c03afa70f101f09f4eead3",
"sha256:3efa49e3da8f32071ee3d5d464cc6b6f8818524d4099b4a94b86a70b8c88d4f5",
"sha256:422bcc6270e1c0cd9043048ce244f49072e9bd78a2c028c2ad2cfd58c79f5936",
"sha256:4fa2b181c3bf94cfdf841148d5d9abcab1890188dd908a639bcf7a38c50092bc",
"sha256:57c0c217270e628380f4befbbf8c5312b88ba7d81fd3d1b2218a25a2608f603c",
"sha256:6ae76a6cd594107ad45525278e8addeae4628a59c8cde3999548d7fe1646465b",
"sha256:6d3c762c87062a29771015f942752caef42fcc7fe4be2b03186f96788242290c",
"sha256:8a82664931a071399d703d65af2521e2202b34f2d8db20fa22a922fec0339022",
"sha256:8b282292973a1dc4eccfcc0776e0fde75b5b3de2e35164c2d854f7dd80149e4b",
"sha256:9a7874ca91cee8714277cd6d1b52374809ab925bf6ae92607bf02509019caadb",
"sha256:9c3e6551597593c1afedcbccf1371995f94457aea82cac726d1f3a25f4507386",
"sha256:a791068e1bbe443fcd3179b1c180c27a7fc58c1554b0d10311b7659d2d2d76f5",
"sha256:adf04843188418b012dd1974e397a7ac3faa1855cbcd69083e3af4da6de9dd81",
"sha256:adfbbd4a1d22fd77b13ff992946b19873407e035504abe9ba537494fe013300f",
"sha256:b25aa3531220faaf1727fc29bc000798476b4a30f429dc07898d5da48caefa15",
"sha256:c12f34c0b50e9e8bf8c049b6c8ca59929c33cea4b1c48362c99c36838c1ee025",
"sha256:c736faa1688222a6c8a5d8be4b66ec373ad6dab27fced8ca0d2c80fed70ac6e3",
"sha256:ca36d83cd591d027952e5019149c4386e7058cd674bf8cb52dc622f768d689e9",
"sha256:e1fb21a807aa0b5cc79806d8ef09078acaa83f994e15f0f7277489ca8eda51b7",
"sha256:e53199ae110cb7e250dd5505fde34452514f4eb2f1fb7532270d2ea037454b09",
"sha256:ea9808001dcf34d368cbef430e7885fdc76a2cf8ea96a8ed8b653797dd9555bb",
"sha256:eaaefe0f6aa33de5a65f48dd0040d7fe08cac9ac6c35a56d0a7db109c3e733df",
"sha256:f27772c9ee88ed3f2a784181f3d1724561499e7e448ed1706153336baa706bd5",
"sha256:f99066d76274800145a2e658026b30962eb5079346249197e88b55c9a7855e6a",
"sha256:fd3373ccd561b79932d12a986674e642816cfc4db4507b6a22ab30c318a85429"
],
"index": "pypi",
"version": "==4.3.4"
},
"dealer": {
"hashes": [
"sha256:0a5a536fdecd9c7679534a19c59392cd21989037c14782328970a185b39e7560",
"sha256:baaac37a4c7928545cb8b0335f48abd0ea51a0274159a9a989afb8b71f8b11c3"
],
"index": "pypi",
"version": "==2.0.5"
},
"decorator": {
"hashes": [
"sha256:90022e83316363788a55352fe39cfbed357aa3a71d90e5f2803a35471de4bba8",
"sha256:f4718552326c99544a6ec602d96b7d03ef61180cf4a492c515ecb2438dd14ccc"
],
"index": "pypi",
"version": "==4.0.9"
},
"defusedxml": {
"hashes": [
"sha256:6687150770438374ab581bb7a1b327a847dd9c5749e396102de3fad4e8a3ef93",
"sha256:f684034d135af4c6cbb949b8a4d2ed61634515257a67299e5f940fbaa34377f5"
],
"version": "==0.6.0"
},
"diff-match-patch": {
"hashes": [
"sha256:a809a996d0f09b9bbd59e9bbd0b71eed8c807922512910e05cbd3f9480712ddb"
],
"version": "==20181111"
},
"django": {
"hashes": [
"sha256:a32c22af23634e1d11425574dce756098e015a165be02e4690179889b207c7a8",
"sha256:d6393918da830530a9516bbbcbf7f1214c3d733738779f06b0f649f49cc698c3"
],
"index": "pypi",
"version": "==2.1.5"
},
"django-app-namespace-template-loader": {
"hashes": [
"sha256:356539413b5d1de0eff91aea7a03806b5ef6874ee5420ea8c273f72bbc601d74",
"sha256:7a450985479a2e07fe8a1e4e8208fc9e1d8b35503526dd28eba5f8ad4ba31d4e"
],
"index": "pypi",
"version": "==0.4.1"
},
"django-auditlog": {
"hashes": [
"sha256:70bfc673e7023d91ab8449d745425e7a4ce5eaaf2bdcbfb9b1a2209a7af60b03"
],
"index": "pypi",
"version": "==0.4.5"
},
"django-autocomplete-light": {
"hashes": [
"sha256:29ce2626a11eab2333e5aa9f95166a6d4400f11b5a05e8f23fa77017b1a9089a"
],
"index": "pypi",
"version": "==3.4.1"
},
"django-bootstrap3": {
"hashes": [
"sha256:c417b25328fb8e97cb89e1f07d35632602d702e6eaca863328e833939d0d1743"
],
"index": "pypi",
"version": "==11.1.0"
},
"django-cors-headers": {
"hashes": [
"sha256:638aaba85f96af62557656ec559672f03d7c61769685acc405eacfaba9d4e93f",
"sha256:c766daf9eefcb9536af9817703ea29124fffee06870f9e523b75144b4d39a694"
],
"index": "pypi",
"version": "==2.0.1"
},
"django-filter": {
"hashes": [
"sha256:6f4e4bc1a11151178520567b50320e5c32f8edb552139d93ea3e30613b886f56",
"sha256:86c3925020c27d072cdae7b828aaa5d165c2032a629abbe3c3a1be1edae61c58"
],
"index": "pypi",
"version": "==2.0.0"
},
"django-import-export": {
"hashes": [
"sha256:6e748fcc647fe2a82a55136ebcbe806a45fd7fb5b1e32b33759181f1e67eeb1b",
"sha256:7e7ebeb40702eafeb2e770914c01b9961063f472b3b395eeffbea5f39efa7257"
],
"index": "pypi",
"version": "==0.7.0"
},
"django-jsonfield": {
"hashes": [
"sha256:431caef3d6a93ad2b1844d26520cd104c474c7dd9dacf3dcb2f72888bf17e284",
"sha256:df2a0cefa4daeb56b074cf178b59ced0d1b4f31e6bbfdfb488755507eabfbf93"
],
"version": "==1.3.1"
},
"django-modeltranslation": {
"hashes": [
"sha256:254ebda6caea5683407e1fb3e45ceaa2275778c6dc2db2b9d4fec3df373c2cdd"
],
"index": "pypi",
"version": "==0.13b1"
},
"django-nocaptcha-recaptcha": {
"hashes": [
"sha256:d2512d5035d5f62aba5009082db28b28995a7e6f4a46713292e0f4f350f337da"
],
"index": "pypi",
"version": "==0.0.19"
},
"django-nose": {
"hashes": [
"sha256:5df2df802c607daeeab8ac1e93abf54508ed6133eb93852310f512000124b4a5",
"sha256:87663f18cb25f01d56c84ac1ff8a0e6e6a6246264b2549b751cb239d0642e76a"
],
"index": "pypi",
"version": "==1.4.5"
},
"django-phonenumber-field": {
"hashes": [
"sha256:8db9d2dc833678b163adabd593cda7ad1dede81a1c18f67c895701fc44dc44f1"
],
"index": "pypi",
"version": "==1.3.0"
},
"django-suit": {
"hashes": [
"sha256:19ed865a478dfca81cb5f50a70317700dd70da92c465093251d0e14330a2b92b"
],
"index": "pypi",
"version": "==0.2.26"
},
"django-tables2": {
"hashes": [
"sha256:d5d3ad99580121f7ec46ea9e2420069bbd6d2f33b4fde73a376c6bf27d551146"
],
"index": "pypi",
"version": "==1.6.1"
},
"djangorestframework": {
"hashes": [
"sha256:b6714c3e4b0f8d524f193c91ecf5f5450092c2145439ac2769711f7eba89a9d9",
"sha256:c375e4f95a3a64fccac412e36fb42ba36881e52313ec021ef410b40f67cddca4"
],
"index": "pypi",
"version": "==3.8.2"
},
"djangorestframework-jwt": {
"hashes": [
"sha256:5efe33032f3a4518a300dc51a51c92145ad95fb6f4b272e5aa24701db67936a7",
"sha256:ab15dfbbe535eede8e2e53adaf52ef0cf018ee27dbfad10cbc4cbec2ab63d38c"
],
"index": "pypi",
"version": "==1.11.0"
},
"et-xmlfile": {
"hashes": [
"sha256:614d9722d572f6246302c4491846d2c393c199cfa4edc9af593437691683335b"
],
"version": "==1.0.1"
},
"gnureadline": {
"hashes": [
"sha256:15518acd534a84d8cd3b2431aeca85132c4892600bf3a64edd76ed265909476c",
"sha256:59369b0eb7210bdb2acf2940c15a6a9d35c70cde9b6d6c5b5c14b0bfd4fd258a",
"sha256:59f6265f24631da28e39054cdd3a52cf02422aa2b955b8d8358b99d4425c3a26",
"sha256:5fe0b973372a6deca9b448178acf8117bc80f0c5113facef0be16712cb98feea",
"sha256:61eef72ed02dad415ede49752e972a1d2bd8c35c1e4464565d7effd806c99476",
"sha256:650986355bfdbe767fd7e9ce4df20ac4993f8c3b60f0829b3c1f951ce31be846",
"sha256:69c9291b6a7bcf768202b78ed1684b515181e20a3cb680b0265da0d6fdc0f697",
"sha256:88c1adf00fa8b2124751d7a6a4f8701cf8677d5caccdb16f6a6b24b3ae4f97c0",
"sha256:8c244130b6e31669f76213ddb249c8673b8573214e80829667f17e18abe27487",
"sha256:e50ae6f49adfc2c89b995a75a0ce2449e553dbd943a4cd1a2d959caccc20247c",
"sha256:fd7ddef98546f1a97eea2ba2120faff4cb7fd52d43f4a16954b5d5531a23eb3e",
"sha256:fe9b42d92dcd83071c82a5dbd33e36a287bb021d2e29f65abfe3192bf13a360d"
],
"markers": "sys_platform == 'darwin' and platform_python_implementation == 'CPython'",
"version": "==8.0.0"
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
],
"version": "==2.8"
},
"ipython": {
"hashes": [
"sha256:0480354f25b2f443e4ef1456b48f28ad1caaa6d316fca5a5eaa9ca7745ae7923",
"sha256:98452af6450e28c9c742d567d75eb6e3a7b391ad4ce8abd5679c5f85ce7fad00",
"sha256:d852fed59da67c7e45cb2192027da8bfd920a7856d295c247a45105968d24d5a",
"sha256:dba42f182b5f6f26630d2202efd30383712d9f7d8d8d9896b37ae2145deca616"
],
"index": "pypi",
"version": "==4.2.0"
},
"ipython-genutils": {
"hashes": [
"sha256:0c43fa84e93ad0e4dbecaffc6656ac1caf1a48359b2bb0a5da3af84164e3f49b",
"sha256:3a0624a251a26463c9dfa0ffa635ec51c4265380980d9a50d65611c3c2bd82a6",
"sha256:6218e9abd612fb5acfb175ea7c7b026006de4df9691d9a73c9b390cfa1a41c2b"
],
"index": "pypi",
"version": "==0.1.0"
},
"jdcal": {
"hashes": [
"sha256:1abf1305fce18b4e8aa248cf8fe0c56ce2032392bc64bbd61b5dff2a19ec8bba",
"sha256:472872e096eb8df219c23f2689fc336668bdb43d194094b5cc1707e1640acfc8"
],
"version": "==1.4.1"
},
"lml": {
"hashes": [
"sha256:b1bef669dc077a1075fa64b99229b6341085b3b3a98d29c66df1853cc14e6c1a",
"sha256:ea5ba817b4adc9e9f5c21725cd2475f912933b7e2dfdf0792aed80077154f63f"
],
"version": "==0.0.9"
},
"multidict": {
"hashes": [
"sha256:024b8129695a952ebd93373e45b5d341dbb87c17ce49637b34000093f243dd4f",
"sha256:041e9442b11409be5e4fc8b6a97e4bcead758ab1e11768d1e69160bdde18acc3",
"sha256:045b4dd0e5f6121e6f314d81759abd2c257db4634260abcfe0d3f7083c4908ef",
"sha256:047c0a04e382ef8bd74b0de01407e8d8632d7d1b4db6f2561106af812a68741b",
"sha256:068167c2d7bbeebd359665ac4fff756be5ffac9cda02375b5c5a7c4777038e73",
"sha256:148ff60e0fffa2f5fad2eb25aae7bef23d8f3b8bdaf947a65cdbe84a978092bc",
"sha256:1d1c77013a259971a72ddaa83b9f42c80a93ff12df6a4723be99d858fa30bee3",
"sha256:1d48bc124a6b7a55006d97917f695effa9725d05abe8ee78fd60d6588b8344cd",
"sha256:31dfa2fc323097f8ad7acd41aa38d7c614dd1960ac6681745b6da124093dc351",
"sha256:34f82db7f80c49f38b032c5abb605c458bac997a6c3142e0d6c130be6fb2b941",
"sha256:3d5dd8e5998fb4ace04789d1d008e2bb532de501218519d70bb672c4c5a2fc5d",
"sha256:4a6ae52bd3ee41ee0f3acf4c60ceb3f44e0e3bc52ab7da1c2b2aa6703363a3d1",
"sha256:4b02a3b2a2f01d0490dd39321c74273fed0568568ea0e7ea23e02bd1fb10a10b",
"sha256:4b843f8e1dd6a3195679d9838eb4670222e8b8d01bc36c9894d6c3538316fa0a",
"sha256:5de53a28f40ef3c4fd57aeab6b590c2c663de87a5af76136ced519923d3efbb3",
"sha256:61b2b33ede821b94fa99ce0b09c9ece049c7067a33b279f343adfe35108a4ea7",
"sha256:6a3a9b0f45fd75dc05d8e93dc21b18fc1670135ec9544d1ad4acbcf6b86781d0",
"sha256:76ad8e4c69dadbb31bad17c16baee61c0d1a4a73bed2590b741b2e1a46d3edd0",
"sha256:7ba19b777dc00194d1b473180d4ca89a054dd18de27d0ee2e42a103ec9b7d014",
"sha256:7c1b7eab7a49aa96f3db1f716f0113a8a2e93c7375dd3d5d21c4941f1405c9c5",
"sha256:7fc0eee3046041387cbace9314926aa48b681202f8897f8bff3809967a049036",
"sha256:8ccd1c5fff1aa1427100ce188557fc31f1e0a383ad8ec42c559aabd4ff08802d",
"sha256:8e08dd76de80539d613654915a2f5196dbccc67448df291e69a88712ea21e24a",
"sha256:c18498c50c59263841862ea0501da9f2b3659c00db54abfbf823a80787fde8ce",
"sha256:c49db89d602c24928e68c0d510f4fcf8989d77defd01c973d6cbe27e684833b1",
"sha256:ce20044d0317649ddbb4e54dab3c1bcc7483c78c27d3f58ab3d0c7e6bc60d26a",
"sha256:d1071414dd06ca2eafa90c85a079169bfeb0e5f57fd0b45d44c092546fcd6fd9",
"sha256:d3be11ac43ab1a3e979dac80843b42226d5d3cccd3986f2e03152720a4297cd7",
"sha256:db603a1c235d110c860d5f39988ebc8218ee028f07a7cbc056ba6424372ca31b"
],
"version": "==4.5.2"
},
"nose": {
"hashes": [
"sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac",
"sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a",
"sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"
],
"version": "==1.3.7"
},
"nose-exclude": {
"hashes": [
"sha256:f78fa8b41eeb815f0486414f710f1eea0949e346cfb11d59ba6295ed69e84304"
],
"index": "pypi",
"version": "==0.5.0"
},
"odfpy": {
"hashes": [
"sha256:596021f0519623ca8717331951c95e3b8d7b21e86edc7efe8cb650a0d0f59a2b"
],
"version": "==1.4.0"
},
"openpyxl": {
"hashes": [
"sha256:626d38647c063d55803ef4971c4d43226538d4e95cb6260c094e363ee33e10c7"
],
"index": "pypi",
"version": "==2.4.11"
},
"pexpect": {
"hashes": [
"sha256:09b0a7727ce012e0fa668ef848591102d6667521655f4e72d51197c872cb9fb9",
"sha256:c381c60f1987355b65df8f08a27f428831914c8a81091bd1778ac336fa2f27e7"
],
"index": "pypi",
"version": "==4.1.0"
},
"phonenumberslite": {
"hashes": [
"sha256:66ec7822322c8a7bbf2063e886b8d9ed479a5b14e5f879443bacd9972ebbdece",
"sha256:a0542bbe3bb47f20523a6bdb2447340afd78aaaf3c6e09ce214a4a2cb1f75492"
],
"version": "==8.10.20"
},
"pickleshare": {
"hashes": [
"sha256:92ee3b0e21632542ecc9a0a245e69a126f62e5114081bdb0d32e0edd10410033",
"sha256:b58cf7d70658a091621c0d8cc35143c8569f3827496b27ed896918c237d05d96"
],
"index": "pypi",
"version": "==0.7.2"
},
"pillow": {
"hashes": [
"sha256:051de330a06c99d6f84bcf582960487835bcae3fc99365185dc2d4f65a390c0e",
"sha256:0ae5289948c5e0a16574750021bd8be921c27d4e3527800dc9c2c1d2abc81bf7",
"sha256:0b1efce03619cdbf8bcc61cfae81fcda59249a469f31c6735ea59badd4a6f58a",
"sha256:163136e09bd1d6c6c6026b0a662976e86c58b932b964f255ff384ecc8c3cefa3",
"sha256:18e912a6ccddf28defa196bd2021fe33600cbe5da1aa2f2e2c6df15f720b73d1",
"sha256:24ec3dea52339a610d34401d2d53d0fb3c7fd08e34b20c95d2ad3973193591f1",
"sha256:267f8e4c0a1d7e36e97c6a604f5b03ef58e2b81c1becb4fccecddcb37e063cc7",
"sha256:3273a28734175feebbe4d0a4cde04d4ed20f620b9b506d26f44379d3c72304e1",
"sha256:4c678e23006798fc8b6f4cef2eaad267d53ff4c1779bd1af8725cc11b72a63f3",
"sha256:4d4bc2e6bb6861103ea4655d6b6f67af8e5336e7216e20fff3e18ffa95d7a055",
"sha256:505738076350a337c1740a31646e1de09a164c62c07db3b996abdc0f9d2e50cf",
"sha256:5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f",
"sha256:5d95cb9f6cced2628f3e4de7e795e98b2659dfcc7176ab4a01a8b48c2c2f488f",
"sha256:7eda4c737637af74bac4b23aa82ea6fbb19002552be85f0b89bc27e3a762d239",
"sha256:801ddaa69659b36abf4694fed5aa9f61d1ecf2daaa6c92541bbbbb775d97b9fe",
"sha256:825aa6d222ce2c2b90d34a0ea31914e141a85edefc07e17342f1d2fdf121c07c",
"sha256:9c215442ff8249d41ff58700e91ef61d74f47dfd431a50253e1a1ca9436b0697",
"sha256:a3d90022f2202bbb14da991f26ca7a30b7e4c62bf0f8bf9825603b22d7e87494",
"sha256:a631fd36a9823638fe700d9225f9698fb59d049c942d322d4c09544dc2115356",
"sha256:a6523a23a205be0fe664b6b8747a5c86d55da960d9586db039eec9f5c269c0e6",
"sha256:a756ecf9f4b9b3ed49a680a649af45a8767ad038de39e6c030919c2f443eb000",
"sha256:b117287a5bdc81f1bac891187275ec7e829e961b8032c9e5ff38b70fd036c78f",
"sha256:ba04f57d1715ca5ff74bb7f8a818bf929a204b3b3c2c2826d1e1cc3b1c13398c",
"sha256:cd878195166723f30865e05d87cbaf9421614501a4bd48792c5ed28f90fd36ca",
"sha256:cee815cc62d136e96cf76771b9d3eb58e0777ec18ea50de5cfcede8a7c429aa8",
"sha256:d1722b7aa4b40cf93ac3c80d3edd48bf93b9208241d166a14ad8e7a20ee1d4f3",
"sha256:d7c1c06246b05529f9984435fc4fa5a545ea26606e7f450bdbe00c153f5aeaad",
"sha256:e9c8066249c040efdda84793a2a669076f92a301ceabe69202446abb4c5c5ef9",
"sha256:f227d7e574d050ff3996049e086e1f18c7bd2d067ef24131e50a1d3fe5831fbc",
"sha256:fc9a12aad714af36cf3ad0275a96a733526571e52710319855628f476dcb144e"
],
"index": "pypi",
"version": "==5.4.1"
},
"psycopg2-binary": {
"hashes": [
"sha256:036bcb198a7cc4ce0fe43344f8c2c9a8155aefa411633f426c8c6ed58a6c0426",
"sha256:1d770fcc02cdf628aebac7404d56b28a7e9ebec8cfc0e63260bd54d6edfa16d4",
"sha256:1fdc6f369dcf229de6c873522d54336af598b9470ccd5300e2f58ee506f5ca13",
"sha256:21f9ddc0ff6e07f7d7b6b484eb9da2c03bc9931dd13e36796b111d631f7135a3",
"sha256:247873cda726f7956f745a3e03158b00de79c4abea8776dc2f611d5ba368d72d",
"sha256:3aa31c42f29f1da6f4fd41433ad15052d5ff045f2214002e027a321f79d64e2c",
"sha256:475f694f87dbc619010b26de7d0fc575a4accf503f2200885cc21f526bffe2ad",
"sha256:4b5e332a24bf6e2fda1f51ca2a57ae1083352293a08eeea1fa1112dc7dd542d1",
"sha256:570d521660574aca40be7b4d532dfb6f156aad7b16b5ed62d1534f64f1ef72d8",
"sha256:59072de7def0690dd13112d2bdb453e20570a97297070f876fbbb7cbc1c26b05",
"sha256:5f0b658989e918ef187f8a08db0420528126f2c7da182a7b9f8bf7f85144d4e4",
"sha256:649199c84a966917d86cdc2046e03d536763576c0b2a756059ae0b3a9656bc20",
"sha256:6645fc9b4705ae8fbf1ef7674f416f89ae1559deec810f6dd15197dfa52893da",
"sha256:6872dd54d4e398d781efe8fe2e2d7eafe4450d61b5c4898aced7610109a6df75",
"sha256:6ce34fbc251fc0d691c8d131250ba6f42fd2b28ef28558d528ba8c558cb28804",
"sha256:73920d167a0a4d1006f5f3b9a3efce6f0e5e883a99599d38206d43f27697df00",
"sha256:8a671732b87ae423e34b51139628123bc0306c2cb85c226e71b28d3d57d7e42a",
"sha256:8d517e8fda2efebca27c2018e14c90ed7dc3f04d7098b3da2912e62a1a5585fe",
"sha256:9475a008eb7279e20d400c76471843c321b46acacc7ee3de0b47233a1e3fa2cf",
"sha256:96947b8cd7b3148fb0e6549fcb31258a736595d6f2a599f8cd450e9a80a14781",
"sha256:abf229f24daa93f67ac53e2e17c8798a71a01711eb9fcdd029abba8637164338",
"sha256:b1ab012f276df584beb74f81acb63905762c25803ece647016613c3d6ad4e432",
"sha256:b22b33f6f0071fe57cb4e9158f353c88d41e739a3ec0d76f7b704539e7076427",
"sha256:b3b2d53274858e50ad2ffdd6d97ce1d014e1e530f82ec8b307edd5d4c921badf",
"sha256:bab26a729befc7b9fab9ded1bba9c51b785188b79f8a2796ba03e7e734269e2e",
"sha256:daa1a593629aa49f506eddc9d23dc7f89b35693b90e1fbcd4480182d1203ea90",
"sha256:dd111280ce40e89fd17b19c1269fd1b74a30fce9d44a550840e86edb33924eb8",
"sha256:e0b86084f1e2e78c451994410de756deba206884d6bed68d5a3d7f39ff5fea1d",
"sha256:eb86520753560a7e89639500e2a254bb6f683342af598088cb72c73edcad21e6",
"sha256:ff18c5c40a38d41811c23e2480615425c97ea81fd7e9118b8b899c512d97c737"
],
"index": "pypi",
"version": "==2.7.6.1"
},
"ptyprocess": {
"hashes": [
"sha256:0530ce63a9295bfae7bd06edc02b6aa935619f486f0f1dc0972f516265ee81a6",
"sha256:464cb76f7a7122743dd25507650db89cd447c51f38e4671602b3eaa2e38e05ae"
],
"index": "pypi",
"version": "==0.5.1"
},
"pycodestyle": {
"hashes": [
"sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766",
"sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9"
],
"index": "pypi",
"version": "==2.3.1"
},
"pyexcel": {
"hashes": [
"sha256:2a32accc28aea3994922606ecf7bef00ef058b56b1bea6af119ae3bb56468333",
"sha256:f1ffe613f09285edf42132b9afc14f81adbd0f56797e5fe05e98307d00ce175f"
],
"index": "pypi",
"version": "==0.5.10"
},
"pyexcel-io": {
"hashes": [
"sha256:08dfe39553b996359b143de3d9ec43e196f1138d47cabb73af04a16821b84d79",
"sha256:2cba956814e72b66072d97b00ede4a084ad881ce72129088eb0dc3c7f3d670cd"
],
"version": "==0.5.20"
},
"pyexcel-xlsx": {
"hashes": [
"sha256:488783c3f5195bed8638f6064b11d97f706641b0f065a5416297a01db6cec5ea",
"sha256:b3566162f7232336ebe0d40dd298145c18715009b020dddc210890cf6436ffb2"
],
"index": "pypi",
"version": "==0.5.5"
},
"pyjwt": {
"hashes": [
"sha256:30b1380ff43b55441283cc2b2676b755cca45693ae3097325dea01f3d110628c",
"sha256:4ee413b357d53fd3fb44704577afac88e72e878716116270d722723d65b42176"
],
"index": "pypi",
"version": "==1.6.4"
},
"python-dateutil": {
"hashes": [
"sha256:3acbef017340600e9ff8f2994d8f7afd6eacb295383f286466a6df3961e486f0",
"sha256:537bf2a8f8ce6f6862ad705cd68f9e405c0b5db014aa40fa29eab4335d4b1716",
"sha256:62a2f8df3d66f878373fd0072eacf4ee52194ba302e00082828e0d263b0418d2"
],
"version": "==2.6.0"
},
"pytz": {
"hashes": [
"sha256:8781cdd3ca70f5a536884e051797ca213b9ff479a5c1cc57240adf37cc1eff1b",
"sha256:be2ff04e94a2b5454ddcfbebb81ee8e46162734d4c2fcc90c422d16ab51f810b",
"sha256:c823de61ff40d1996fe087cec343e0503881ca641b897e0f9b86c7683a0bfee1",
"sha256:ee7c751544e35a7b7fb5e3fb25a49dade37d51e70a93e5107f10575d7102c311"
],
"index": "pypi",
"version": "==2016.4"
},
"pyyaml": {
"hashes": [
"sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
"sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
"sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
"sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
"sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
"sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
"sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
"sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
"sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
"sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
"sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
"sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
"sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
],
"version": "==5.1.2"
},
"requests": {
"hashes": [
"sha256:545c4855cd9d7c12671444326337013766f4eea6068c3f0307fb2dc2696d580e",
"sha256:5acf980358283faba0b897c73959cecf8b841205bb4b2ad3ef545f46eae1a133"
],
"index": "pypi",
"version": "==2.11.1"
},
"simplegeneric": {
"hashes": [
"sha256:dc972e06094b9af5b855b3df4a646395e43d1c9d0d39ed345b7393560d0b9173"
],
"index": "pypi",
"version": "==0.8.1"
},
"six": {
"hashes": [
"sha256:0ff78c403d9bccf5a425a6d31a12aa6b47f1c21ca4dc2573a7e2f32a97335eb1",
"sha256:105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a"
],
"index": "pypi",
"version": "==1.10.0"
},
"tablib": {
"hashes": [
"sha256:0f88a9cebdaa1a2cc29ae57387082ee81015d1149ecd34e48a8c8d3b4dd21670",
"sha256:5f33c079b07eb10cf9c4b4696add2ecf32c89db7729240546ecdcd5c92f67e13"
],
"version": "==0.13.0"
},
"telepot": {
"hashes": [
"sha256:8910fd6fb708e2c3ded7ca82cc945a645b717699d9f82ddff5123bb2e05f780f"
],
"index": "pypi",
"version": "==12.3"
},
"texttable": {
"hashes": [
"sha256:eff3703781fbc7750125f50e10f001195174f13825a92a45e9403037d539b4f4"
],
"version": "==1.6.2"
},
"traitlets": {
"hashes": [
"sha256:05a66843c96a320eec09df674c16ff330a43cb07f731cf2bd88aa3645a180541",
"sha256:76eba33c89723b8fc024f950cacaf5bf2ef37999642cc9a61f4e7c1ca5cf0ac0",
"sha256:d6db3201395f9b955786d25a1817c07291e2bcb96eb7f41683ae3836836179d7"
],
"index": "pypi",
"version": "==4.2.1"
},
"urllib3": {
"hashes": [
"sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398",
"sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"
],
"version": "==1.25.6"
},
"xlrd": {
"hashes": [
"sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2",
"sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"
],
"version": "==1.2.0"
},
"xlwt": {
"hashes": [
"sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e",
"sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88"
],
"version": "==1.3.0"
},
"yarl": {
"hashes": [
"sha256:024ecdc12bc02b321bc66b41327f930d1c2c543fa9a561b39861da9388ba7aa9",
"sha256:2f3010703295fbe1aec51023740871e64bb9664c789cba5a6bdf404e93f7568f",
"sha256:3890ab952d508523ef4881457c4099056546593fa05e93da84c7250516e632eb",
"sha256:3e2724eb9af5dc41648e5bb304fcf4891adc33258c6e14e2a7414ea32541e320",
"sha256:5badb97dd0abf26623a9982cd448ff12cb39b8e4c94032ccdedf22ce01a64842",
"sha256:73f447d11b530d860ca1e6b582f947688286ad16ca42256413083d13f260b7a0",
"sha256:7ab825726f2940c16d92aaec7d204cfc34ac26c0040da727cf8ba87255a33829",
"sha256:b25de84a8c20540531526dfbb0e2d2b648c13fd5dd126728c496d7c3fea33310",
"sha256:c6e341f5a6562af74ba55205dbd56d248daf1b5748ec48a0200ba227bb9e33f4",
"sha256:c9bb7c249c4432cd47e75af3864bc02d26c9594f49c82e2a28624417f0ae63b8",
"sha256:e060906c0c585565c718d1c3841747b61c5439af2211e185f6739a9412dfbde1"
],
"version": "==1.3.0"
}
},
"develop": {
"autopep8": {
"hashes": [
"sha256:4d8eec30cc81bc5617dbf1218201d770dc35629363547f17577c61683ccfb3ee"
],
"index": "pypi",
"version": "==1.4.4"
},
"entrypoints": {
"hashes": [
"sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19",
"sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"
],
"version": "==0.3"
},
"flake8": {
"hashes": [
"sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548",
"sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696"
],
"index": "pypi",
"version": "==3.7.8"
},
"mccabe": {
"hashes": [
"sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
"sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
],
"version": "==0.6.1"
},
"pycodestyle": {
"hashes": [
"sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766",
"sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9"
],
"index": "pypi",
"version": "==2.3.1"
},
"pyflakes": {
"hashes": [
"sha256:17dbeb2e3f4d772725c777fabc446d5634d1038f234e77343108ce445ea69ce0",
"sha256:d976835886f8c5b31d47970ed689944a0262b5f3afa00a5a7b4dc81e5449f8a2"
],
"version": "==2.1.1"
}
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ services:
image: postgres
web:
build: .
image: git.sahkoinsinoorikilta.fi:4567/vtmk/web2.0
image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend
command: ["bash", "-c", "cd /code && ./wait-for-it.sh db:5432 -- bash setup.sh --no-input --no-npm && python manage.py runserver 0.0.0.0:8000"]
ports:
- "8000:8000"
-49
View File
@@ -1,49 +0,0 @@
# Ilmotunkki
## Terms
- Signup, Form with collection of questions
- Response, One answer to some signup
- Quota, Amount of people allowed to respond with some option selected.
- In generic case there is no option and quota is just max number of people.
## Requirements
- Officials may generate signups forms
- Officials may see results from signups
- Officials may see some stats from their signups
- for example distributions of multiple choice answers
- Officials should be able to edit signups wherever possible
- Propably not possible to edit after first response
- Officials should be able to delete responses
- Officials should be able to embed payment information to the signup?
- TODO: is there need for unique reference numbers for every response?
- Officials should be able to save a signup to a reusable template.
- Possibility to save templates?
- Signup may be attached to an event
- Multiple signups to a single event should be possible (FTMK uses for museum visits? Erna asked if it was possible in old web)
- Possibility for external service (Google Form, URL will suffice)
- Signup should support custom quotas
- Atleast quotas from multiple choices and checkboxes
- Text quotas are risky (typos everywhere!!)
- Signup should have start and end times
- Signup should support atleast following questiontypes
- Text
- multiple choice (select one)
- checkbox (boolean yes/no)
- Signup should support reserve slots.
- TODO: quota based reserves or generic? or both?
- Responding should send confirm email
- Response should be editable by responder and only by the responder until the closing of the signup
- TODO: is there need to custom edit period or disable?
- Responders should see amount of quotas left.
- Responders should see some information about other responses
- TODO: names? should this be editable by officials?
- Or superadmin can edit and the one signing up within edit period
- NOTE: Quota related info is exposed if any info is printed
- When quotas need to be hidden? PoTa?
View File
-3
View File
@@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.
-5
View File
@@ -1,5 +0,0 @@
from django.apps import AppConfig
class IlmotunkkiConfig(AppConfig):
name = 'ilmotunkki'
View File
-16
View File
@@ -1,16 +0,0 @@
from django.db import models
from django.utils import timezone
class Signup(models.Model):
start = models.DateTimeField()
end = models.DateTimeField()
class Question(models.Model):
pass
class Answer(models.Model):
signup = models.ForeignKey(Signup, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.PROTECT)
-3
View File
@@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.
-3
View File
@@ -1,3 +0,0 @@
from django.shortcuts import render
# Create your views here.
-70
View File
@@ -1,70 +0,0 @@
"""File containing Infoscreen HSL data fetcher classes."""
import requests
import json
import logging
import os
import pytz
from datetime import timedelta, datetime
from django.utils import timezone, dateparse
from django.utils.dateformat import format
from django.conf import settings
with open(os.path.join(settings.BASE_DIR, 'infoscreen', 'hsl_stops.graphql')) as stops_file:
STOPS_QUERY = stops_file.read()
with open(os.path.join(settings.BASE_DIR, 'infoscreen', 'hsl_stops_variables.json')) as vars_file:
STOPS_VARS = json.loads(vars_file.read())
API_URL = 'https://api.digitransit.fi/routing/v1/routers/hsl/index/graphql'
API_HEADERS = {'Content-Type': 'application/json'}
def fetch():
"""Fetch data from HSL API."""
query_vars = STOPS_VARS.copy()
query_vars['startTime_6'] = format(timezone.now(), 'U')
post_data = json.dumps({
'operationName': 'NearestRoutesContainer',
'query': STOPS_QUERY,
'variables': query_vars,
})
resp = requests.post(API_URL, data=post_data, headers=API_HEADERS)
data = resp.json()
items = data['data']['viewer']['_nearest']['edges']
places = map(lambda item: item['node']['place'], items)
schedule = []
for place in places:
route = place['pattern']['route']['shortName']
stop_times = place['_stoptimes']
for stop_time in stop_times:
timestamp = time_utc = stop_time['serviceDay'] + stop_time['realtimeArrival']
headsign = stop_time['stopHeadsign']
stop_name = stop_time['stop']['name']
time_diff = (timestamp - timezone.now().timestamp()) / 60 # minutes
if time_diff < settings.HSL_DEPARTURE_THRESHOLD:
continue
elif time_diff < settings.HSL_HURRY_THRESHOLD:
time = '{} min'.format(int(time_diff))
else:
time = pytz.utc.localize(datetime.fromtimestamp(timestamp)).strftime('%H:%M')
schedule.append({
'route': route,
'headsign': headsign,
'timestamp': time,
'stop': stop_name,
'utc': time_utc,
})
return schedule
-71
View File
@@ -1,71 +0,0 @@
query NearestRoutesContainer($lat_0: Float!, $lon_1: Float!, $maxDistance_2: Int!, $maxResults_3: Int!, $timeRange_7: Int!, $numberOfDepartures_8: Int!, $filterByModes_4: [Mode]!, $filterByPlaceTypes_5: [FilterPlaceType]!, $startTime_6: Long!) {
viewer {
...F5
}
}
fragment F0 on DepartureRow {
_stoptimes4caEfh: stoptimes(startTime: $startTime_6, timeRange: $timeRange_7, numberOfDepartures: $numberOfDepartures_8) {
pickupType
serviceDay
realtimeDeparture
}
id
}
fragment F1 on DepartureRow {
pattern {
route {
shortName
}
}
_stoptimes: stoptimes(startTime: $startTime_6, timeRange: $timeRange_7, numberOfDepartures: $numberOfDepartures_8) {
realtimeArrival
serviceDay
stopHeadsign
stop {
name
}
}
}
fragment F2 on BikeRentalStation {
id
}
fragment F3 on placeAtDistance {
distance
place {
id
__typename
...F1
...F2
}
id
}
fragment F4 on placeAtDistanceConnection {
edges {
node {
distance
place {
id
__typename
...F0
}
id
...F3
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
}
}
fragment F5 on QueryType {
_nearest: nearest(lat: $lat_0, lon: $lon_1, maxDistance: $maxDistance_2, maxResults: $maxResults_3, first: $maxResults_3, filterByModes: $filterByModes_4, filterByPlaceTypes: $filterByPlaceTypes_5) {
...F4
}
}
-10
View File
@@ -1,10 +0,0 @@
{
"lat_0": 60.190480099999995,
"lon_1": 24.8275665,
"maxDistance_2": 1000,
"maxResults_3": 50,
"numberOfDepartures_8": 2,
"timeRange_7": 7200,
"filterByModes_4": ["BUS"],
"filterByPlaceTypes_5": ["DEPARTURE_ROW"]
}
-10
View File
@@ -1,10 +0,0 @@
from django.core.management.base import BaseCommand
from infoscreen.hsl_fetcher import HSLFetcher
class Command(BaseCommand):
help = 'Loads HSL timetables and save to json file.'
def handle(self, *args, **options):
fetcher = HSLFetcher()
fetcher.fetch()
@@ -15,4 +15,7 @@ class Migration(migrations.Migration):
migrations.DeleteModel(
name='HSLDataModel',
),
migrations.DeleteModel(
name='HslInfoItem',
),
]
+21
View File
@@ -0,0 +1,21 @@
# Generated by Django 2.1.5 on 2019-03-26 12:49
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('infoscreen', '0006_delete_hsldatamodel'),
]
operations = [
migrations.CreateModel(
name='LunchItem',
fields=[
('infoitem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='infoscreen.InfoItem')),
],
bases=('infoscreen.infoitem',),
),
]
+13 -15
View File
@@ -193,6 +193,19 @@ class SossoInfoItem(InfoItem):
return "/static/infoscreen/html/sosso_create.html"
class LunchItem(InfoItem):
"""Class for Lunch Infoscreen item."""
display_name = _("Today's lunch")
def get_template_url(self):
return "/static/infoscreen/html/lunch.html"
@staticmethod
def get_create_template_url():
return "/static/infoscreen/html/lunch_create.html"
class EventInfoItem(InfoItem):
"""Class for Event Infoscreen item."""
@@ -254,21 +267,6 @@ class VideoInfoItem(InfoItem):
return d
class HslInfoItem(InfoItem):
"""Class for HSL Infoscreen item."""
display_name = _("HSL timetables")
def get_template_url(self):
"""Return HSL infoitem template url."""
return "/static/infoscreen/html/hsl.html"
@staticmethod
def get_create_template_url():
"""Call create HSL infoitem template url command."""
return "/static/infoscreen/html/hsl_create.html"
class ExternalImageInfoItem(InfoItem):
"""Class for External Image Infoscreen item."""
-74
View File
@@ -1,74 +0,0 @@
table {
font-size: 4vh;
font-family: 'Droid Sans Mono', monospace;
}
.red {
color: red;
-webkit-animation-name: blinker;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-moz-animation-name: blinker;
-moz-animation-duration: 2s;
-moz-animation-timing-function: linear;
-moz-animation-iteration-count: infinite;
animation-name: blinker;
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
}
.black {
color: black;
}
@-moz-keyframes blinker {
0% { opacity: 1.0; }
50% { opacity: 0.1; }
100% { opacity: 1.0; }
}
@-webkit-keyframes blinker {
0% { opacity: 1.0; }
50% { opacity: 0.1; }
100% { opacity: 1.0; }
}
@keyframes blinker {
0% { opacity: 1.0; }
50% { opacity: 0.1; }
100% { opacity: 1.0; }
}
thead{
background: #f0f0f0;
}
.header-row{
background: #f0f0f0;
font-size: 7vh;
font-family: 'Droid Sans Mono', monospace;
text-align: center;
}
.container {
width: 100vw;
padding: 0 0 0 0;
}
.container .table {
margin-left: 0;
margin-right: 0;
}
.repeat-item.ng-leave {
}
.repeat-item.ng-leave.ng-leave-active {
opacity: 0;
font-size: 0vh;
}
.repeat-item.ng-leave{
opacity: 1;
font-size: 5vh;
}
@@ -0,0 +1,53 @@
#header {
height: 30%;
width: 100%;
background-color:#7c1330;
text-align: center;
}
#header-image {
display: block;
margin-left: auto;
margin-right: auto;
max-width: 100%;
}
.article-row {
min-height: 20vh;
margin: 10px 10px 10px 10px;
}
.article-thumb-col {
max-height: 200px;
text-align: left;
}
.article-title-col {
font-size: 3vw;
}
.thumbnail {
max-width: 355px;
max-height: 200px;
}
#sossoimage {
height: 300px;
position: relative;
left: 0px;
top: 0px;
}
.stretch {
width:100%;
height:100%;
}
#post {
height: 540px;
border:2px solid black;
}
#container {
max-height: 70%;
}
@@ -1,4 +0,0 @@
<link rel="stylesheet" href="/static/infoscreen/css/coffee.css">
<iframe src="https://host2.kilta.aalto.fi/kahvi/cups" allowfullscreen=true sandbox="allow-scripts allow-pointer-lock allow-same-origin">
<p>Your browser does not support iframes.</p>
</iframe>
@@ -1,41 +0,0 @@
<link rel="stylesheet" href="/static/infoscreen/css/hsl.css">
<link href="https://fonts.googleapis.com/css?family=Droid+Sans+Mono" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.1/locale/fi.js"></script>
<div class="container" ng-app="myApp" ng-controller="timetableCtrl">
<div class="header-row row">
<div class="col-sm-2"><p>{{clock | date:'HH:mm'}}</p></div>
<div class="col-sm-8">HSL-Aikataulut</div>
<div class="col-sm-2 time"></div>
</div>
<h1 style="font-size: 10vh; text-align: center" ng-if="error">
{{error}}
</h1>
<table ng-if="!error" class="table table-striped row">
<thead>
<tr>
<th>
Aika
</th>
<th>
Linja
</th>
<th>
Pys&#228;kki
</th>
</tr>
</thead>
<tbody>
<tr class="repeat-item" ng-repeat="x in stoptimes | orderBy: ['utc'] | limitTo: 11">
<td style="min-width: 300px">
{{x.timestamp}}
</td>
<td>
<strong>{{x.route}}</strong>, {{x.headsign}}
</td>
<td>
{{x.stop}}
</td>
</tr>
</tbody>
</table>
</div>
@@ -0,0 +1,11 @@
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<link rel="stylesheet" href="/static/infoscreen/css/lunch.css">
<div ng-controller="LunchController">
<div id="container">
<div class="restaurant row" ng-repeat="restaurant in data">
<div class="lunch-option" ng-repeat="l in lunch">
<h3 ng-bind-html="l.title | unsafe"></h3>
</div>
</div>
</div>
</div>
@@ -1,10 +1,10 @@
<div ng-controller="infoadmin_hslitem_create" style="margin-top:20px;">
<div>
Create new item to show hsl ttimetables. Name is used only as identifier
</div>
<div class="form-group">
<label>Name:</label>
<input type="text" class="form-control" ng-model="item.name"></input>
</div>
<input type="button" class="btn btn-success" ng-click="send()" value="create"></input>
</div>
<div ng-controller="infoadmin_lunchitem_create" style="margin-top:20px;">
<div>
Create new item to show restaurants. Name is used only as identifier
</div>
<div class="form-group">
<label>Name:</label>
<input type="text" class="form-control" ng-model="item.name"></input>
</div>
<input type="button" class="btn btn-success" ng-click="send()" value="create"></input>
</div>
@@ -1 +0,0 @@
<h1>testi2</h1>
@@ -1 +0,0 @@
<h1>testi3</h1>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

@@ -182,8 +182,8 @@ var simple_controllers = [
"external_image",
"abbitem",
"sossoitem",
"lunchitem",
"eventitem",
"hslitem",
"websiteitem",
"apyitem",
];
@@ -82,6 +82,21 @@ app.controller('SossoController', function($scope, $http) {
})
});
app.controller('LunchController', function ($scope, $http) {
$scope.data = [];
var restaurants = [42];
var restaurant_names = ["TUAS"]
var cur_date = new Date().toISOString().split("T")[0]
$http.get("https://kitchen.kanttiinit.fi/menus?restaurants=" + restaurants.join(",") + "&days=" + cur_date).then(function (response) {
$scope.data = restaurant_names.map(function(n, idx) {
return {
name: n,
lunch: response[idx][cur_date],
}
});
})
});
app.controller('ApyController', function($scope, $http) {
$scope.items = [];
$http.get("/infoscreen/apyjson").then(function(response)
@@ -119,35 +134,3 @@ app.filter('unixTimeToDifference', function() {
return res;
}
})
app.controller('timetableCtrl',
function($scope, $http, $interval) {
function load() {
$http.get('/infoscreen/hsl_data')
.then(function(data, status, headers, config) { //eslint-disable-line no-unused-vars
$scope.stoptimes = data.data;
$scope.error = data.data.error || null;
});
$http.get('/infoscreen/hsl_data/settings')
.then(function(data, status, headers, config) { //eslint-disable-line no-unused-vars
$scope.departureThreshold = data.data['departure_threshold'];
$scope.hurryThreshold = data.data['hurry_threshold'];
});
}
function update_clock() {
$scope.clock = Date.now();
}
$scope.$on('$destroy', function() {
$interval.cancel(load_interval);
$interval.cancel(clock_interval);
});
var load_interval = $interval(load, 5000);
var clock_interval = $interval(update_clock, 1000);
update_clock();
load();
}
);
+2 -6
View File
@@ -18,14 +18,12 @@ from infoscreen.views import create_image_item
from infoscreen.views import create_video_item
from infoscreen.views import createABBItem
from infoscreen.views import createSossoItem
from infoscreen.views import createHslItem
from infoscreen.views import createLunchItem
from infoscreen.views import createEventItem
from infoscreen.views import createExternalWebsiteItem
from infoscreen.views import create_rotation
from infoscreen.views import delete_rotation
from infoscreen.views import CurrentHSLView
from infoscreen.views import createApyItem
from infoscreen.views import hsl_timetable_settings
from infoscreen.views import get_apy_json
urlpatterns = [
@@ -44,14 +42,12 @@ urlpatterns = [
url(r'^create_video$', create_video_item),
url(r'^create_abbitem$', createABBItem),
url(r'^create_sossoitem$', createSossoItem),
url(r'^create_lunchitem$', createLunchItem),
url(r'^create_eventitem$', createEventItem),
url(r'^create_hslitem$', createHslItem),
url(r'^create_apyitem$', createApyItem),
url(r'^create_websiteitem$', createExternalWebsiteItem),
url(r'^create_rotation$', create_rotation),
url(r'^delete_rotation/(?P<id>\d+)$', delete_rotation),
url(r'^hsl_data$', CurrentHSLView),
url(r'^hsl_data/settings$', hsl_timetable_settings),
url(r'^apyjson', get_apy_json),
]
+2 -2
View File
@@ -17,7 +17,7 @@ import requests
from infoscreen.models import (
Rotation, InfoItem, InfoInstance, ABBInfoItem, ExternalImageInfoItem,
ImageInfoItem, SossoInfoItem, HslInfoItem, EventInfoItem,
ImageInfoItem, SossoInfoItem, LunchItem, EventInfoItem,
ExternalWebsiteInfoItem, ImageUploadForm, ApyInfoItem, VideoInfoItem)
@@ -179,7 +179,7 @@ createInstance = create_item_generator(InfoInstance)
deleteInstance = delete_item_generator(InfoInstance)
createABBItem = create_item_generator(ABBInfoItem)
createSossoItem = create_item_generator(SossoInfoItem)
createHslItem = create_item_generator(HslInfoItem)
createLunchItem = create_item_generator(LunchItem)
createExternalImageInfoItem = create_item_generator(ExternalImageInfoItem)
createExternalWebsiteItem = create_item_generator(ExternalWebsiteInfoItem)
createEventItem = create_item_generator(EventInfoItem)
-23
View File
@@ -5,7 +5,6 @@ from django.conf import settings
from django.db import DatabaseError
from infoscreen.models import Rotation, InfoItem, InfoInstance
from infoscreen.hsl_fetcher import fetch as hsl_fetch
import json
import logging
@@ -79,25 +78,3 @@ def info_items(request, *args, **kwargs):
items.append(i.get_dict())
return JsonResponse(items, safe=False)
@require_http_methods(["GET"])
def hsl_timetable_settings(request, *args, **kwargs):
"""Set HSL timetable settings."""
d = {"departure_threshold": settings.HSL_DEPARTURE_THRESHOLD,
"hurry_threshold": settings.HSL_HURRY_THRESHOLD}
return JsonResponse(d, status=200)
@require_http_methods(["GET"])
def CurrentHSLView(request, *args, **kwargs):
"""Get HSL data and return it."""
try:
api_resp = hsl_fetch()
except Exception as ex:
logging.exception('Failed to fetch HSL timetables.')
error = {'error': 'Aikataulujen haku epäonnistui.'}
return JsonResponse(error, status=200)
return JsonResponse(api_resp, status=200, safe=False)
@@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-03-12 12:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kaehmy', '0004_auto_20181018_2121'),
]
operations = [
migrations.AlterField(
model_name='application',
name='custom_role_is_board',
field=models.BooleanField(blank=True, verbose_name='Board member'),
),
]
+1 -1
View File
@@ -23,7 +23,7 @@
position: absolute;
left: 0;
top: 0;
background-color: #052f5f;
background-color: #0c2938;
width: 100%;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 74 KiB

+2 -3
View File
@@ -1,5 +1,4 @@
{% if wrap_label %}
<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>{% endif %}
<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>
{% include "django/forms/widgets/input.html" %}
{% if wrap_label %} {{ widget.label }}</label>{% endif %}
{{ widget.label }}</label>
<span class="fa fa-info-circle" data-toggle="tooltip" data-placement="right" title="{{ widget.description }}"></span>
+12 -12
View File
@@ -16,21 +16,21 @@
{% blocktrans %}Kaehmykoneella voit ilmaista kiinnostuksesi toimia killassa ensi vuonna.
Listassa on vastuualueittain sekä hallitus- että toimihenkilövirkoja.
Koska lista ei ole koskaan täydellinen, voit myös ehdottaa ihan uutta toimenkuvaa.
Jos sinulla on kysyttävää mistä tahansa virasta, kannattaa konsultoida <a href="/static/other/kahmyopas.pdf">kaehmyopasta</a>
Jos sinulla on kysyttävää mistä tahansa virasta, kannattaa konsultoida <a href="/static/other/kahmyopas.pdf">kaehmyopasta</a>
tai olla yhteydessä kyseistä virkaa tänä vuonna toimittavaan henkilöön.{% endblocktrans %}
</p>
<p>
{% blocktrans %}Muista, että kaehmyn lähettäminen on kiinnostuksen ilmaus
{% blocktrans %}Muista, että kaehmyn lähettäminen on kiinnostuksen ilmaus
eikä siis missään nimessä sitova ilmoittautumien mihinkään tehtävään!{% endblocktrans %}
</p>
<h5>{% trans "Päivämääriä & deadlineja" %}</h5>
<ul>
<li><strong>29.10.</strong> {% blocktrans %}Hallitustyrkkypaneeli (haku hallitukseen olisi hyvä tehdä ennen tätä!){% endblocktrans %}</li>
<li><strong>5.11.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta){% endblocktrans %}</li>
<li><strong>12.11.</strong> {% blocktrans %}Kiltailta{% endblocktrans %}</li>
<li><strong>15.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
<li><strong>20.11.</strong> {% blocktrans %}Haku toimariksi olisi hyvä tehdä ennen tätä!{% endblocktrans %}</li>
<li><strong>26.11.</strong> {% blocktrans %}Vaalikokous, osa 3 (toimarien valinta){% endblocktrans %}</li>
<li><strong>24.10.</strong> {% blocktrans %}Kiltailta{% endblocktrans %}</li>
<li><strong>28.10.</strong> {% blocktrans %}Hallitustyrkkypaneeli (haku hallitukseen olisi hyvä tehdä ennen tätä!){% endblocktrans %}</li>
<li><strong>4.11.</strong> {% blocktrans %}Vaalikokous, osa 1 (puheenjohtajan valinta){% endblocktrans %}</li>
<li><strong>14.11.</strong> {% blocktrans %}Vaalikokous, osa 2 (hallituksen valinta){% endblocktrans %}</li>
<li><strong>18.11.</strong> {% blocktrans %}Infoilta toimarihakijoille (haku toimariksi olisi hyvä tehdä ennen tätä){% endblocktrans %}</li>
<li><strong>25.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 %}
@@ -46,7 +46,7 @@
{{ preset_field.label }}
</div>
<div class="card-block">
{% bootstrap_field preset_field show_label=False %}
{% bootstrap_field preset_field show_label=False %}
</div>
</div>
{% endif %}
@@ -59,11 +59,11 @@
{{ custom_field.label }}
</div>
<div class="card-block">
{% bootstrap_field custom_field show_label=False %}
{% bootstrap_field custom_field show_label=False %}
</div>
</div>
{% endif %}
{% endfor %}
{% endfor %}
<div class="card">
<div class="card-block">
{% bootstrap_field form.custom_role_name %}
@@ -71,7 +71,7 @@
</div>
</div>
{% bootstrap_field form.text %}
<input type="checkbox" required name="gdpr" value="1">
<span>{% blocktrans %}
Hyväksyn <a href="https://sik.ayy.fi/files/official/Tietosuojaseloste%20%E2%80%93%20Toimihenkil%C3%B6ksi%20hakemisen%20rekisteri.pdf" target="_blank">tietosuojaselosteen</a> ja tietojeni tallentamisen.
+38
View File
@@ -0,0 +1,38 @@
'''
A telegram bot api for whatever purposes.
TODO: kaehmy app is definitely not correct place for this
'''
import logging
import requests
from django.conf import settings
from kaehmy.models import TelegramChannel
class TelegramBot:
'''
A telegram bot api for whatever purposes
Currently only able to broadcast stuff to all registered
channels using broadcast method.
'''
def __init__(self, api_token=None):
self.api_token = api_token or settings.TELEGRAM_BOT_TOKEN
self.send_message_url = "https://api.telegram.org/bot{}/sendMessage".format(self.api_token)
def broadcast(self, message):
channels_ids = TelegramChannel.objects.values_list("channel_id", flat=True)
for id_ in channels_ids:
self.send_message(id_, message)
def send_message(self, channel_id, message):
'''
Send message to a chat with given channel_id
'''
data = {
'chat_id': channel_id,
'text': message,
'parse_mode': 'Markdown'
}
resp = requests.post(self.send_message_url, json=data)
logging.debug(resp.content)
+18 -17
View File
@@ -4,14 +4,15 @@
### Dependency list
* Python >3.5
* PostgreSQL >9.5
* pip3
* virtualenv
* npm
* Python >3.5
* PostgreSQL >9.5
* pip3
* virtualenv
* npm
Install with apt:
```
```bash
sudo apt install python3
sudo apt install python3-pip
sudo apt install postgresql
@@ -24,15 +25,16 @@ More info about PostgreSQL at:
These packages might be needed on certain platforms:
* python3-dev
* libffi-dev
* python3-cffi
* libssl-dev
* python3-dev
* libffi-dev
* python3-cffi
* libssl-dev
## Create a virtual environment for python
Create a virtualenv in the parent directory.
```
```bash
virtualenv -p python3 ../virtualenv.sikweb
```
@@ -40,7 +42,7 @@ virtualenv -p python3 ../virtualenv.sikweb
Assuming we are at the root of this repository and virtualenv is one level above.
```
```bash
. ../virtualenv.sikweb/bin/activate
```
@@ -48,27 +50,26 @@ Assuming we are at the root of this repository and virtualenv is one level above
Run the install wizard with
```
```bash
bash setup.sh
```
and follow the instructions.
## Done!
## Done
## In case of error on macOS Mojave 10.14
If you get an error saying
```
```bash
The headers or library files could not be found for zlib,
a required dependency when compiling Pillow from source.
```
run
```
```bash
xcode-select --install
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```
Binary file not shown.
+182 -54
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-20 23:09+0300\n"
"POT-Creation-Date: 2019-09-16 19:33+0300\n"
"PO-Revision-Date: 2017-11-02 23:09+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -33,19 +33,19 @@ msgstr "External website"
msgid "Sössö articles"
msgstr "Sössö articles"
#: infoscreen/models.py:199 webapp/models.py:72
#: infoscreen/models.py:199
msgid "Today's lunch"
msgstr ""
#: infoscreen/models.py:212 webapp/models.py:74
msgid "Events"
msgstr "Events"
#: infoscreen/models.py:214
#: infoscreen/models.py:227
msgid "Image"
msgstr "Image"
#: infoscreen/models.py:260
msgid "HSL timetables"
msgstr "HSL timetables"
#: infoscreen/models.py:275
#: infoscreen/models.py:273
msgid "External image"
msgstr "External image"
@@ -113,7 +113,7 @@ msgid "Delete"
msgstr "Delete"
#: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:56
#: kaehmy/templates/list.html:36 webapp/models.py:118 webapp/models.py:147
#: kaehmy/templates/list.html:36 webapp/models.py:125 webapp/models.py:154
msgid "Name"
msgstr "Name"
@@ -263,7 +263,7 @@ msgstr ""
msgid "Category"
msgstr ""
#: kaehmy/models.py:39 webapp/models.py:129
#: kaehmy/models.py:39 webapp/models.py:136
msgid "Description"
msgstr "Description"
@@ -311,7 +311,7 @@ msgstr "Kaehmy application"
msgid "Kaehmylomakkeet"
msgstr "Kaehmy applications"
#: kaehmy/models.py:98 webapp/models.py:182
#: kaehmy/models.py:98 webapp/models.py:189
msgid "Phone number"
msgstr ""
@@ -327,7 +327,7 @@ msgstr ""
msgid "Custom role name"
msgstr ""
#: kaehmy/models.py:104 webapp/models.py:119
#: kaehmy/models.py:104 webapp/models.py:126
msgid "Board member"
msgstr "Board member"
@@ -351,7 +351,7 @@ msgstr ""
msgid "Telegram channels"
msgstr ""
#: kaehmy/tables.py:13 webapp/models.py:166
#: kaehmy/tables.py:13 webapp/models.py:173
msgid "Roles"
msgstr ""
@@ -450,12 +450,12 @@ msgid ""
"%%20rekisteri.pdf\" target=\"_blank\">tietosuojaselosteen</a> ja tietojeni "
"tallentamisen.\n"
" "
msgstr
msgstr ""
"\n"
" I accept the <a href=\"https://sik.ayy.fi/files/official/"
"Tietosuojaseloste%%20%%E2%%80%%93%%20Toimihenkil%%C3%%B6ksi%%20hakemisen"
"%%20rekisteri.pdf\" target=\"_blank\">privacy statement</a> and the saving of personal data."
"\n"
"%%20rekisteri.pdf\" target=\"_blank\">privacy statement</a> and the saving "
"of personal data.\n"
" "
#: kaehmy/templates/kaehmy.html:82 members/templates/settings.html:23
@@ -634,6 +634,14 @@ msgid "Hienoa! Jäsenhakemuksesi on nyt lähetetty."
msgstr "Amazing! Your membership application has been sent."
#: members/templates/application_success.html:9
msgid ""
"Vahvistusviesti on lähetetty sähköpostiisi. Ota yhteyttä sik-vtmk@list.ayy."
"fi jos viestiä ei näy."
msgstr ""
"Confirmation email is sent to given email address. Contact sik-vtmk@list.ayy."
"fi if you didn't receive it."
#: members/templates/application_success.html:10
msgid "Takaisin Sähköinsinöörikillan web-sivuille"
msgstr "Back to the front page"
@@ -687,6 +695,107 @@ msgstr "Application form"
msgid "Settings"
msgstr "Settings"
#: members/templates/email_application_accept.html:2
#, fuzzy
#| msgid "Moikka"
msgid "Moi"
msgstr "Hi"
#: members/templates/email_application_accept.html:4
msgid "Onnittelut! Sinut on hyväksytty Sähköinsinöörikillan jäseneksi."
msgstr ""
#: members/templates/email_application_accept.html:6
#, fuzzy
#| msgid "Käy kurkkaamassa muutkin haasteet osoitteessa"
msgid "Käy kurkkaamassa killan nettisivuilta"
msgstr "Also go and check other challenges at"
#: members/templates/email_application_accept.html:6
msgid ""
"tulevia tapahtumia ja piipahda kiltahuoneella tutustumassa uusiin "
"kiltatovereihisi!"
msgstr ""
#: members/templates/email_application_accept.html:8
msgid "Liity myös killan TG-kanaville"
msgstr "Join Guild's Telegram channels"
#: members/templates/email_application_accept.html:9
msgid "SIK"
msgstr "SIK"
#: members/templates/email_application_accept.html:10
msgid "SIK-fuksit 2019"
msgstr "SIK Freshmen 2019"
#: members/templates/email_application_accept.html:11
msgid "SIK-fuksit 2019 -tiedotuskanava"
msgstr "SIK Freshmen 2019 Notification channel"
#: members/templates/email_application_submit.html:2
#: ohlhafv/templates/email.html:2
msgid "Moikka"
msgstr "Hi"
#: members/templates/email_application_submit.html:4
msgid ""
"Sait tämän viestin, sillä olet lähettänyt hakemuksen Aalto-yliopiston "
"Sähköinsinöörikillan jäseneksi alla olevin tiedoin. Siistiä!"
msgstr ""
"You received this email, since you sent a membership application to the "
"Guild of Electrical Engineering. That's so cool!"
#: members/templates/email_application_submit.html:6
msgid "Etunimi"
msgstr "First name"
#: members/templates/email_application_submit.html:7
msgid "Sukunimi"
msgstr "Last name"
#: members/templates/email_application_submit.html:8
msgid "Sähköposti"
msgstr "Email"
#: members/templates/email_application_submit.html:9
msgid "Kotipaikkakunta"
msgstr "Place of origin"
#: members/templates/email_application_submit.html:10
msgid "AYY:n jäsen"
msgstr "Member of AYY"
#: members/templates/email_application_submit.html:11
msgid "Haluan jäsenmailin"
msgstr "I want to receive weekly member email"
#: members/templates/email_application_submit.html:13
msgid ""
"Saat sähköpostiisi tiedon, kun sinut on hallituksen kokouksessa hyväksytty "
"jäseneksi"
msgstr "You will be notified via email once your application has been accepted"
#: members/templates/email_application_submit.html:15
msgid "Muistathan maksaa jäsenmaksun! Alla maksutiedot"
msgstr "Don't forget to pay your membership fee!"
#: members/templates/email_application_submit.html:17
msgid "Saaja"
msgstr "Recepient"
#: members/templates/email_application_submit.html:18
msgid "Tilinumero"
msgstr "Account number"
#: members/templates/email_application_submit.html:20
msgid "Viite"
msgstr "Reference Number"
#: members/templates/email_application_submit.html:21
msgid "Summa"
msgstr "Amount"
#: members/templates/member_add.html:15 members/templates/member_edit.html:18
#: members/templates/payment_add.html:20 members/templates/payment_edit.html:18
msgid "Save"
@@ -804,40 +913,56 @@ msgstr "Payments in register:"
msgid "Language"
msgstr "Language"
#: members/templates/settings.html:20 sikweb/base.py:248
#: members/templates/settings.html:20 sikweb/base.py:255
msgid "Finnish"
msgstr "Finnish"
#: members/templates/settings.html:21 sikweb/base.py:249
#: members/templates/settings.html:21 sikweb/base.py:256
msgid "English"
msgstr "English"
#: members/views/applications.py:51 members/views/applications.py:112
#: members/views/applications.py:137
#: members/views/applications.py:54 members/views/applications.py:125
#: members/views/applications.py:150
msgid "No application id specified"
msgstr "No application id specified"
#: members/views/applications.py:71
#: members/views/applications.py:74
msgid "Application missing 'id' field."
msgstr "Application missing 'id' field."
#: members/views/applications.py:80
#: members/views/applications.py:83
msgid "Email {} is already in use by a member. Application cannot be accepted."
msgstr ""
"Email {} is already in use by a member. Application cannot be accepted."
#: members/views/applications.py:91
#: members/views/applications.py:94
msgid "Successfully accepted application"
msgstr "Successfully accepted application"
#: members/views/applications.py:116
#: members/views/applications.py:97
msgid "Jäsenhakemuksesi Sähköinsinöörikiltaan on hyväksytty!"
msgstr ""
#: members/views/applications.py:129
msgid "Successfully deleted application"
msgstr "Successfully deleted application"
#: members/views/applications.py:126
#: members/views/applications.py:139
msgid "Could not delete application object"
msgstr "Could not delete application object"
#: members/views/applications.py:177
msgid "Jäsenhakemuksesi Sähköinsinöörikiltaan on lähetetty onnistuneesti!"
msgstr "Your membership application was sent successfully!"
#: members/views/applications.py:182 members/views/applications.py:183
msgid "Kyllä"
msgstr "Yes"
#: members/views/applications.py:182 members/views/applications.py:183
msgid "Ei"
msgstr "No"
#: members/views/members.py:86 members/views/members.py:188
#: members/views/members.py:212
msgid "No member id specified"
@@ -932,10 +1057,6 @@ msgstr ""
msgid "Ohlhafv challenge: {} vs. {}"
msgstr ""
#: ohlhafv/templates/email.html:2
msgid "Moikka"
msgstr "Hi"
#: ohlhafv/templates/email.html:4
msgid "on haastanut sinut oluenjuontimittelöön"
msgstr "has challenged you to a beer drinking contest"
@@ -945,9 +1066,9 @@ msgid "-sarjassa"
msgstr "series"
#: ohlhafv/templates/email.html:8
msgid "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 15.2"
msgid "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 14.2"
msgstr ""
"Remeber to confirm the challenge at Smökki on Thursday 15.2. at the event"
"Remeber to confirm the challenge at Smökki on Thursday 14.2. at the event"
#: ohlhafv/templates/email.html:10
msgid "Käy kurkkaamassa muutkin haasteet osoitteessa"
@@ -977,7 +1098,7 @@ msgstr ""
msgid "Challenge"
msgstr "Challenge"
#: ohlhafv/views.py:42
#: ohlhafv/views.py:43
msgid "Sinut on haastettu Øhlhäfviin!"
msgstr "You have been challenged at Ohlhafv!"
@@ -1006,91 +1127,95 @@ msgstr "Tags"
msgid "Tag: {}"
msgstr "Tag: {}"
#: webapp/models.py:52
#: webapp/models.py:53
msgid "Feed: {}"
msgstr "Feed: {}"
#: webapp/models.py:55
#: webapp/models.py:56
msgid "Feed"
msgstr ""
#: webapp/models.py:56
#: webapp/models.py:57
msgid "Feeds"
msgstr ""
#: webapp/models.py:68
#: webapp/models.py:70
msgid "Event: {}"
msgstr ""
#: webapp/models.py:71
#: webapp/models.py:73
msgid "Event"
msgstr ""
#: webapp/models.py:82
#: webapp/models.py:84
msgid "Template questions: {}"
msgstr ""
#: webapp/models.py:85
#: webapp/models.py:87
msgid "Template question"
msgstr ""
#: webapp/models.py:86
#: webapp/models.py:88
msgid "Template questions"
msgstr ""
#: webapp/models.py:98
#: webapp/models.py:102
msgid "#{} {}"
msgstr ""
#: webapp/models.py:105
msgid "Signup form"
msgstr ""
#: webapp/models.py:99
#: webapp/models.py:106
msgid "Signup forms"
msgstr ""
#: webapp/models.py:108
#: webapp/models.py:115
msgid "Sign-ups: {}"
msgstr ""
#: webapp/models.py:111
#: webapp/models.py:118
msgid "Sign-up"
msgstr ""
#: webapp/models.py:112
#: webapp/models.py:119
msgid "Sign-ups"
msgstr ""
#: webapp/models.py:123
#: webapp/models.py:130
msgid "board member"
msgstr "board member"
#: webapp/models.py:141
#: webapp/models.py:148
msgid "Committee"
msgstr ""
#: webapp/models.py:142
#: webapp/models.py:149
msgid "Committees"
msgstr ""
#: webapp/models.py:145
#: webapp/models.py:152
msgid "Committee: {}"
msgstr ""
#: webapp/models.py:165
#: webapp/models.py:172
msgid "Role"
msgstr ""
#: webapp/models.py:168
#: webapp/models.py:175
msgid "Start date"
msgstr ""
#: webapp/models.py:169
#: webapp/models.py:176
msgid "End date"
msgstr ""
#: webapp/models.py:179
#: webapp/models.py:186
msgid "Official"
msgstr ""
#: webapp/models.py:180
#: webapp/models.py:187
msgid "Officials"
msgstr ""
@@ -1138,6 +1263,9 @@ msgstr "Sössö"
msgid "Corporate"
msgstr "Corporate"
#~ msgid "HSL timetables"
#~ msgstr "HSL timetables"
#~ msgid "Username"
#~ msgstr "Username"
Binary file not shown.
+174 -50
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-20 23:09+0300\n"
"POT-Creation-Date: 2019-09-16 19:33+0300\n"
"PO-Revision-Date: 2017-11-02 23:04+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -34,19 +34,19 @@ msgstr "Ulkoinen verkkosivu"
msgid "Sössö articles"
msgstr "Sössön artikkelit"
#: infoscreen/models.py:199 webapp/models.py:72
#: infoscreen/models.py:199
msgid "Today's lunch"
msgstr "Päivän lounas"
#: infoscreen/models.py:212 webapp/models.py:74
msgid "Events"
msgstr "Tapahtumat"
#: infoscreen/models.py:214
#: infoscreen/models.py:227
msgid "Image"
msgstr "Kuva"
#: infoscreen/models.py:260
msgid "HSL timetables"
msgstr "HSL-aikataulut"
#: infoscreen/models.py:275
#: infoscreen/models.py:273
msgid "External image"
msgstr "Ulkoinen kuva"
@@ -114,7 +114,7 @@ msgid "Delete"
msgstr "Poista"
#: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:56
#: kaehmy/templates/list.html:36 webapp/models.py:118 webapp/models.py:147
#: kaehmy/templates/list.html:36 webapp/models.py:125 webapp/models.py:154
msgid "Name"
msgstr "Nimi"
@@ -264,7 +264,7 @@ msgstr "Muut"
msgid "Category"
msgstr "Kategoria"
#: kaehmy/models.py:39 webapp/models.py:129
#: kaehmy/models.py:39 webapp/models.py:136
msgid "Description"
msgstr "Kuvaus"
@@ -312,7 +312,7 @@ msgstr "Kaehmylomake"
msgid "Kaehmylomakkeet"
msgstr "Kaehmylomakkeet"
#: kaehmy/models.py:98 webapp/models.py:182
#: kaehmy/models.py:98 webapp/models.py:189
msgid "Phone number"
msgstr "Puhelinnumero"
@@ -328,7 +328,7 @@ msgstr "Teksti"
msgid "Custom role name"
msgstr "Uusi virka"
#: kaehmy/models.py:104 webapp/models.py:119
#: kaehmy/models.py:104 webapp/models.py:126
msgid "Board member"
msgstr "Hallituksen jäsen"
@@ -352,7 +352,7 @@ msgstr "Telegram-kanava"
msgid "Telegram channels"
msgstr "Telegram-kanavat"
#: kaehmy/tables.py:13 webapp/models.py:166
#: kaehmy/tables.py:13 webapp/models.py:173
msgid "Roles"
msgstr "Roolit"
@@ -632,6 +632,12 @@ msgid "Hienoa! Jäsenhakemuksesi on nyt lähetetty."
msgstr "Hienoa! Jäsenhakemuksesi on nyt lähetetty."
#: members/templates/application_success.html:9
msgid ""
"Vahvistusviesti on lähetetty sähköpostiisi. Ota yhteyttä sik-vtmk@list.ayy."
"fi jos viestiä ei näy."
msgstr ""
#: members/templates/application_success.html:10
msgid "Takaisin Sähköinsinöörikillan web-sivuille"
msgstr "Takaisin Sähköinsinöörikillan web-sivuille"
@@ -685,6 +691,103 @@ msgstr "Jäsenhakemuslomake"
msgid "Settings"
msgstr "Asetukset"
#: members/templates/email_application_accept.html:2
msgid "Moi"
msgstr ""
#: members/templates/email_application_accept.html:4
msgid "Onnittelut! Sinut on hyväksytty Sähköinsinöörikillan jäseneksi."
msgstr ""
#: members/templates/email_application_accept.html:6
msgid "Käy kurkkaamassa killan nettisivuilta"
msgstr ""
#: members/templates/email_application_accept.html:6
msgid ""
"tulevia tapahtumia ja piipahda kiltahuoneella tutustumassa uusiin "
"kiltatovereihisi!"
msgstr ""
#: members/templates/email_application_accept.html:8
msgid "Liity myös killan TG-kanaville"
msgstr ""
#: members/templates/email_application_accept.html:9
msgid "SIK"
msgstr ""
#: members/templates/email_application_accept.html:10
msgid "SIK-fuksit 2019"
msgstr ""
#: members/templates/email_application_accept.html:11
msgid "SIK-fuksit 2019 -tiedotuskanava"
msgstr ""
#: members/templates/email_application_submit.html:2
#: ohlhafv/templates/email.html:2
msgid "Moikka"
msgstr ""
#: members/templates/email_application_submit.html:4
msgid ""
"Sait tämän viestin, sillä olet lähettänyt hakemuksen Aalto-yliopiston "
"Sähköinsinöörikillan jäseneksi alla olevin tiedoin. Siistiä!"
msgstr ""
#: members/templates/email_application_submit.html:6
msgid "Etunimi"
msgstr ""
#: members/templates/email_application_submit.html:7
msgid "Sukunimi"
msgstr ""
#: members/templates/email_application_submit.html:8
msgid "Sähköposti"
msgstr ""
#: members/templates/email_application_submit.html:9
msgid "Kotipaikkakunta"
msgstr ""
#: members/templates/email_application_submit.html:10
msgid "AYY:n jäsen"
msgstr ""
#: members/templates/email_application_submit.html:11
msgid "Haluan jäsenmailin"
msgstr ""
#: members/templates/email_application_submit.html:13
msgid ""
"Saat sähköpostiisi tiedon, kun sinut on hallituksen kokouksessa hyväksytty "
"jäseneksi"
msgstr ""
#: members/templates/email_application_submit.html:15
#, fuzzy
#| msgid "Muista myös maksaa jäsenmaksusi!"
msgid "Muistathan maksaa jäsenmaksun! Alla maksutiedot"
msgstr "Muista myös maksaa jäsenmaksusi!"
#: members/templates/email_application_submit.html:17
msgid "Saaja"
msgstr ""
#: members/templates/email_application_submit.html:18
msgid "Tilinumero"
msgstr ""
#: members/templates/email_application_submit.html:20
msgid "Viite"
msgstr ""
#: members/templates/email_application_submit.html:21
msgid "Summa"
msgstr ""
#: members/templates/member_add.html:15 members/templates/member_edit.html:18
#: members/templates/payment_add.html:20 members/templates/payment_edit.html:18
msgid "Save"
@@ -800,39 +903,57 @@ msgstr "Maksutapahtumia:"
msgid "Language"
msgstr "Kieli"
#: members/templates/settings.html:20 sikweb/base.py:248
#: members/templates/settings.html:20 sikweb/base.py:255
msgid "Finnish"
msgstr "suomi"
#: members/templates/settings.html:21 sikweb/base.py:249
#: members/templates/settings.html:21 sikweb/base.py:256
msgid "English"
msgstr "englanti"
#: members/views/applications.py:51 members/views/applications.py:112
#: members/views/applications.py:137
#: members/views/applications.py:54 members/views/applications.py:125
#: members/views/applications.py:150
msgid "No application id specified"
msgstr "Hakemuksen ID ei määritelty"
#: members/views/applications.py:71
#: members/views/applications.py:74
msgid "Application missing 'id' field."
msgstr "Hakemuksen ID ei määritelty."
#: members/views/applications.py:80
#: members/views/applications.py:83
msgid "Email {} is already in use by a member. Application cannot be accepted."
msgstr "Sähköpostiosoite {} on jo käytössä. Hakemusta ei hyväksytty."
#: members/views/applications.py:91
#: members/views/applications.py:94
msgid "Successfully accepted application"
msgstr "Onnistuneesti hyväksyttiin hakemus"
#: members/views/applications.py:116
#: members/views/applications.py:97
msgid "Jäsenhakemuksesi Sähköinsinöörikiltaan on hyväksytty!"
msgstr ""
#: members/views/applications.py:129
msgid "Successfully deleted application"
msgstr "Onnistuneesti poistettiin hakemus"
#: members/views/applications.py:126
#: members/views/applications.py:139
msgid "Could not delete application object"
msgstr "Hakemusobjektia ei voitu poistaa"
#: members/views/applications.py:177
msgid "Jäsenhakemuksesi Sähköinsinöörikiltaan on lähetetty onnistuneesti!"
msgstr ""
#: members/views/applications.py:182 members/views/applications.py:183
msgid "Kyllä"
msgstr ""
#: members/views/applications.py:182 members/views/applications.py:183
#, fuzzy
#| msgid "Edit"
msgid "Ei"
msgstr "Muokkaa"
#: members/views/members.py:86 members/views/members.py:188
#: members/views/members.py:212
msgid "No member id specified"
@@ -927,10 +1048,6 @@ msgstr "Sarja"
msgid "Ohlhafv challenge: {} vs. {}"
msgstr "Ohlhafv-haaste: {} vs. {}"
#: ohlhafv/templates/email.html:2
msgid "Moikka"
msgstr ""
#: ohlhafv/templates/email.html:4
msgid "on haastanut sinut oluenjuontimittelöön"
msgstr ""
@@ -940,7 +1057,7 @@ msgid "-sarjassa"
msgstr ""
#: ohlhafv/templates/email.html:8
msgid "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 15.2"
msgid "Muistattehan vahvistaa haasteen paikan päällä Smökissä torstaina 14.2"
msgstr ""
#: ohlhafv/templates/email.html:10
@@ -971,7 +1088,7 @@ msgstr "Haasta kaverisi mittelöön!"
msgid "Challenge"
msgstr "Haasta"
#: ohlhafv/views.py:42
#: ohlhafv/views.py:43
msgid "Sinut on haastettu Øhlhäfviin!"
msgstr ""
@@ -1000,91 +1117,95 @@ msgstr "Tunnisteet"
msgid "Tag: {}"
msgstr "Tunniste: {}"
#: webapp/models.py:52
#: webapp/models.py:53
msgid "Feed: {}"
msgstr "Uutinen: {}"
#: webapp/models.py:55
#: webapp/models.py:56
msgid "Feed"
msgstr "Uutinen"
#: webapp/models.py:56
#: webapp/models.py:57
msgid "Feeds"
msgstr "Uutiset"
#: webapp/models.py:68
#: webapp/models.py:70
msgid "Event: {}"
msgstr "Tapahtuma: {}"
#: webapp/models.py:71
#: webapp/models.py:73
msgid "Event"
msgstr "Tapahtuma"
#: webapp/models.py:82
#: webapp/models.py:84
msgid "Template questions: {}"
msgstr "Vakiokysymykset: {}"
#: webapp/models.py:85
#: webapp/models.py:87
msgid "Template question"
msgstr "Vakiokysymys"
#: webapp/models.py:86
#: webapp/models.py:88
msgid "Template questions"
msgstr "Vakiokysymykset"
#: webapp/models.py:98
#: webapp/models.py:102
msgid "#{} {}"
msgstr ""
#: webapp/models.py:105
msgid "Signup form"
msgstr "Ilmoittautumislomake"
#: webapp/models.py:99
#: webapp/models.py:106
msgid "Signup forms"
msgstr "Ilmoittautumislomakkeet"
#: webapp/models.py:108
#: webapp/models.py:115
msgid "Sign-ups: {}"
msgstr "Ilmoittautumiset: {}"
#: webapp/models.py:111
#: webapp/models.py:118
msgid "Sign-up"
msgstr "Ilmoittautuminen"
#: webapp/models.py:112
#: webapp/models.py:119
msgid "Sign-ups"
msgstr "Ilmoittautumiset"
#: webapp/models.py:123
#: webapp/models.py:130
msgid "board member"
msgstr "hallituksen jäsen"
#: webapp/models.py:141
#: webapp/models.py:148
msgid "Committee"
msgstr "Toimikunta"
#: webapp/models.py:142
#: webapp/models.py:149
msgid "Committees"
msgstr "Toimikunnat"
#: webapp/models.py:145
#: webapp/models.py:152
msgid "Committee: {}"
msgstr "Toimikunta: {}"
#: webapp/models.py:165
#: webapp/models.py:172
msgid "Role"
msgstr "Rooli"
#: webapp/models.py:168
#: webapp/models.py:175
msgid "Start date"
msgstr "Alkupäivämäärä"
#: webapp/models.py:169
#: webapp/models.py:176
msgid "End date"
msgstr "Loppupäivämäärä"
#: webapp/models.py:179
#: webapp/models.py:186
msgid "Official"
msgstr "Toimihenkilö"
#: webapp/models.py:180
#: webapp/models.py:187
msgid "Officials"
msgstr "Toimihenkilöt"
@@ -1132,6 +1253,9 @@ msgstr "Sössö"
msgid "Corporate"
msgstr "Yritys"
#~ msgid "HSL timetables"
#~ msgstr "HSL-aikataulut"
#~ msgid "Culture"
#~ msgstr "Kulttuuri"
+1 -1
View File
@@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Aalto-yliopiston Sähköinsinöörikilta ry">
<meta name="author" content="veedeeämkoo">
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.png"/>
<title>Jäsenhakemus</title>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
@@ -6,5 +6,6 @@
{% block content %}
<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ä sik-vtmk@list.ayy.fi jos viestiä ei näy." %}</p>
<a href="/"><h4>{% trans "Takaisin Sähköinsinöörikillan web-sivuille" %}</h4></a>
{% endblock content %}
+1 -1
View File
@@ -11,7 +11,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Member register">
<meta name="author" content="SIK ry">
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.png"/>
<title>{% trans "Member register" %}</title>
@@ -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
@@ -0,0 +1,21 @@
{% load i18n %}
{% trans "Moikka" %} {{ application.first_name }},
{% trans "Sait tämän viestin, sillä olet lähettänyt hakemuksen Aalto-yliopiston Sähköinsinöörikillan jäseneksi alla olevin tiedoin. Siistiä!" %}
{% trans "Etunimi" %}: {{ application.first_name }}
{% trans "Sukunimi" %}: {{ application.last_name }}
{% trans "Sähköposti" %}: {{ application.email }}
{% trans "Kotipaikkakunta" %}: {{ application.POR }}
{% trans "AYY:n jäsen" %}: {{ ayy }}
{% trans "Haluan jäsenmailin" %}: {{ jas }}
{% trans "Saat sähköpostiisi tiedon, kun sinut on hallituksen kokouksessa hyväksytty jäseneksi" %}.
{% trans "Muistathan maksaa jäsenmaksun! Alla maksutiedot" %}:
{% trans "Saaja" %}: Aalto-yliopiston Sähköinsinöörikilta ry
{% trans "Tilinumero" %}: FI97 1309 3000 1118 23
BIC: NDEAFIHH
{% trans "Viite" %}: 1313
{% trans "Summa" %}: 8 €
+29 -3
View File
@@ -7,10 +7,13 @@ from django.core.mail import send_mail
from django.conf import settings
from django.utils.translation import ugettext as _
from django.forms.models import model_to_dict
from django.template.loader import render_to_string
import logging
import html
from webapp.utils import send_email
from members.views.utils import *
from members.tables import RequestTable
from members.forms import ApplicationForm
@@ -90,6 +93,16 @@ def application_accept(request, *args, **kwargs):
.format(form))
notification = "{} {}.".format(_("Successfully accepted application"),
str(application))
subject = _('Jäsenhakemuksesi Sähköinsinöörikiltaan on hyväksytty!')
message = render_to_string(
'members:email_application_accept.html', {
'first_name': application.first_name
}
)
send_email(member.email, subject, message)
return HttpResponseRedirect(
'/members/list?notification={}'.format(html.escape(notification)))
except Exception as ex:
@@ -152,13 +165,26 @@ def application_form(request, *args, **kwargs):
@ensure_csrf_cookie
@require_http_methods(["POST"])
@login_required(login_url='/admin/login')
@permission_required('members.delete_request', raise_exception=True)
def application_submit(request, *args, **kwargs):
"""Submit member application"""
form = ApplicationForm(request.POST)
if form.is_valid():
form.save()
return render(request, 'application_success.html', {})
try:
application = form.instance
email = form.cleaned_data.get('email', '')
subject = _('Jäsenhakemuksesi Sähköinsinöörikiltaan on lähetetty onnistuneesti!')
message = render_to_string(
'members:email_application_submit.html', {
'application': application,
'ayy': _('Kyllä') if application.AYY else _('Ei'),
'jas': _('Kyllä') if application.jas else _('Ei')
}
)
send_email(email, subject, message)
finally:
return render(request, 'application_success.html', {})
else:
return error_view(request, form.errors)
+8
View File
@@ -0,0 +1,8 @@
Uusi Ohlhafv haaste!
====================
Haastaja: {{ challenge.challenger }}
Uhri: {{ challenge.victim }}
Sarja: {{ challenge.get_series_display }}
Terveiset: {{ challenge.message }}
Käy kurkkaamassa muutkin haasteet osoitteessa: {{ url }}
+12
View File
@@ -19,6 +19,7 @@ from ohlhafv.models import OhlhafvChallenge
from ohlhafv.forms import OhlhafvForm
from ohlhafv.tables import OhlhafvTable
from webapp.utils import send_email
from kaehmy.tgbot import TelegramBot
@require_http_methods(["GET"])
@@ -48,6 +49,17 @@ def ohlhafv_submit(request, *args, **kwargs):
}
)
send_email(email, subject, message)
try:
tg_message = render_to_string(
'ohlhafv:tgmsg.tpl', {
'challenge': challenge,
'url': url})
bot = TelegramBot()
bot.broadcast(tg_message)
except Exception: # tg spam is not critical. Ignore on failure
pass
logging.debug(
'Sent ohlhafv email to recipient <{}>'.format(email))
else:
+679 -660
View File
File diff suppressed because it is too large Load Diff
+11 -10
View File
@@ -26,9 +26,9 @@ Shows the current coffee scale status.
Set up your SSH key authentication in GitLab Profile Settings. Then clone the repository and checkout the development branch:
```
git clone git@git.sahkoinsinoorikilta.fi:vtmk/web2.0.git
cd web2.0
```bash
git clone git@gitlab.com:sahkoinsinoorikilta/vtmk/web2.0-backend.git
cd web2.0-backend
git checkout develop
cp scripts/git/pre-push .git/hooks/pre-push # install a script to test code before committing
```
@@ -45,7 +45,7 @@ See [Linux/Mac install instructions](./linux_install.md)
Run the following `manage.py` commands. 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
@@ -55,7 +55,7 @@ python manage.py createdummydata # creates dummy members to the member regis
### Use runserver command
```
```bash
python manage.py runserver 0.0.0.0:8000
```
@@ -71,7 +71,7 @@ Run the project in production with gunicorn. Refer to [this page](https://www.di
Install production dependencies.
```
```bash
pip install -r requirements.production.txt
```
@@ -82,7 +82,8 @@ Do not use `rebase` when pulling or merging changes. Rebasing transforms the com
When you start working on a feature, create a feature branch for your changes. These feature branches should be prefixed with `feature`.
Example of creating a feature branch:
```
```bash
git checkout -b feature-error-page
```
@@ -96,13 +97,13 @@ Merge requests to `master` should be reviewed by multiple developers. Only a mod
Lint python files using `pycodestyle` with
```
```bash
pycodestyle --config=setup.cfg --count .
```
Lint javascript and markdown using `eslint` and `remark` with
```
```bash
npm test
```
@@ -112,7 +113,7 @@ Use an editor with linting capabilities to write pretty code that passes linting
Run unit tests with
```
```bash
python manage.py test -v 2
```
+2 -2
View File
@@ -20,14 +20,14 @@ coverage==4.3.4
django-nose==1.4.5
nose-exclude==0.5.0
psycopg2-binary==2.7.6.1
django-bootstrap3==8.2.3
django-bootstrap3==11.1.0
django-tables2==1.6.1
pycodestyle==2.3.1
dealer==2.0.5
django-modeltranslation==0.13b1
django-auditlog==0.4.5
django-phonenumber-field==1.3.0
django-autocomplete-light==3.2.10
django-autocomplete-light==3.4.1
six==1.10.0
django-suit==0.2.26
telepot==12.3
+1 -1
View File
@@ -1,4 +1,4 @@
[pycodestyle]
max-line-length = 120
ignore = E501,E722
exclude = '*/migrations/*'
exclude = '*/migrations/*', venv/*
+3 -1
View File
@@ -317,4 +317,6 @@ SUIT_CONFIG = {
# 'LIST_PER_PAGE': 15
}
JWT_EXPIRATION_DELTA = datetime.timedelta(days=7)
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7)
}
-5
View File
@@ -21,11 +21,6 @@ DEBUG = True
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '7p$85^4ibb^p4-=vs44b7!y0e-zemugze18@a#30&71=a8)dp('
# HSL API settings
HSL_USERHASH = 'YOUR HSL USERHASH HERE'
HSL_DEPARTURE_THRESHOLD = 8 # minutes
HSL_HURRY_THRESHOLD = 13 # minutes
# MQTT settings
MQTT_SETTINGS = {
'HOST': 'mqtt.sik.party',
+1 -1
View File
@@ -29,7 +29,7 @@ import members.urls
import coffee_scale.urls
favicon_view = RedirectView.as_view(
url='static/img/favicon.ico', permanent=True)
url='static/img/favicon.png', permanent=True)
urlpatterns = [
+6
View File
@@ -0,0 +1,6 @@
version: '3.2'
services:
web20_backend:
image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend:latest
ports:
- 8000:8000
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 74 KiB

+1 -1
View File
@@ -3,7 +3,7 @@
{% load static %}
<html>
<head>
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.png"/>
<link rel="stylesheet" href="{% static "css/about.css" %}">
</head>
<body>
+1 -1
View File
@@ -4,7 +4,7 @@
{% load i18n %}
{# Additional <head> content here, some extra meta tags or favicon #}
{% block extrahead %}
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.png"/>
{% endblock %}
+1 -1
View File
@@ -8,7 +8,7 @@
<head>
{% block head %}
<meta charset="utf-8">
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.ico"/>
<link rel="shortcut icon" type="image/x-icon" href="/static/img/favicon.png"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="Aalto-yliopiston Sähköinsinöörikilta ry">
<meta name="author" content="Aalto-yliopiston Sähköinsinöörikilta ry">
+18
View File
@@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-03-12 12:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('webapp', '0050_signupform_visible'),
]
operations = [
migrations.AddField(
model_name='event',
name='location',
field=models.CharField(blank=True, max_length=255),
),
]
@@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-03-13 11:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('webapp', '0051_event_location'),
]
operations = [
migrations.AddField(
model_name='feed',
name='autohide_enabled',
field=models.BooleanField(default=False),
),
]
@@ -0,0 +1,29 @@
# Generated by Django 2.1.5 on 2019-03-13 13:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('webapp', '0052_feed_autohide_enabled'),
]
operations = [
migrations.RenameField(
model_name='signupform',
old_name='end',
new_name='end_time',
),
migrations.RenameField(
model_name='signupform',
old_name='start',
new_name='start_time',
),
migrations.AddField(
model_name='signupform',
name='title',
field=models.CharField(default='Default signup title', max_length=255),
preserve_default=False,
),
]
@@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-03-13 14:42
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('webapp', '0053_auto_20190313_1505'),
]
operations = [
migrations.AlterField(
model_name='signupform',
name='questions',
field=models.TextField(default='[]'),
),
]
+9 -3
View File
@@ -47,6 +47,7 @@ class Feed(BaseFeed):
publish_time = models.DateTimeField(default=timezone.now)
autohide = models.DateTimeField(default=month_from_now)
autohide_enabled = models.BooleanField(default=False)
def __str__(self):
return _('Feed: {}').format(self.title)
@@ -63,6 +64,7 @@ class Event(BaseFeed):
end_time = models.DateTimeField(default=timezone.now)
signupForm = models.ManyToManyField(
'SignupForm', blank=True)
location = models.CharField(max_length=255, blank=True)
def __str__(self):
return _('Event: {}').format(self.title)
@@ -89,12 +91,16 @@ class TemplateQuestion(models.Model):
class SignupForm(models.Model):
"""Model for event signup form. Stores questions in JSONB."""
start = models.DateTimeField(default=timezone.now)
end = models.DateTimeField(default=timezone.now)
title = models.CharField(max_length=255)
start_time = models.DateTimeField(default=timezone.now)
end_time = models.DateTimeField(default=timezone.now)
# question = JSONField()
questions = models.CharField(max_length=255)
questions = models.TextField(default="[]")
visible = models.BooleanField(default=True)
def __str__(self):
return _('#{} {}').format(self.id, self.title)
class Meta:
verbose_name = _('Signup form')
verbose_name_plural = _('Signup forms')
+10 -13
View File
@@ -3,10 +3,9 @@ from webapp.models import *
class SignupFormSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = SignupForm
fields = ('id', 'start', 'end', 'questions')
fields = ('id', 'title', 'start_time', 'end_time', 'questions')
class EventSerializer(serializers.HyperlinkedModelSerializer):
@@ -25,7 +24,7 @@ class EventSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Event
fields = ('id', 'tag_id', 'tags', 'visible', 'title', 'description',
'content', 'start_time', 'end_time', 'signup_id', 'signupForm')
'content', 'start_time', 'end_time', 'location', 'signup_id', 'signupForm')
depth = 1
def create(self, validated_data):
@@ -73,24 +72,22 @@ class TagSerializer(serializers.ModelSerializer):
class FeedSerializer(serializers.ModelSerializer):
# tags = TagSerializer(many=True, read_only=False)
# tags = serializers.PrimaryKeyRelatedField(
# many=True,
# queryset=Tag.objects.all(),
# read_only=False
# )
tag_id = serializers.PrimaryKeyRelatedField(
many=True,
source="tags",
queryset=Tag.objects.all()
)
class Meta:
model = Feed
fields = ('tags', 'visible', 'title', 'description',
'content', 'publish_time', 'autohide')
fields = ('id', 'tags', 'tag_id', 'visible', 'title', 'description',
'content', 'publish_time', 'autohide', 'autohide_enabled')
depth = 1
def create(self, validated_data):
print("validated data: ", validated_data)
tags_data = validated_data.pop('tags')
feed = Feed.objects.create(**validated_data)
for tag in tags_data:
print(tag)
feed.tags.add(tag)
feed.save()
return feed
+18
View File
@@ -30,6 +30,19 @@ class TagsTestCase(APITestCase):
tag1 = Tag.objects.get(slug="Party")
self.assertEqual(sliced_response, {'id': tag1.id, 'slug': 'Party', 'name': 'Bileet'})
def test_get_single_tag_serializer(self):
response = self.client.get('/api/tags/', format='json')
self.assertTrue(status.is_success(response.status_code))
tags = Tag.objects.all()
serializer = TagSerializer(tags, many=True)
# Icon on serializer is returned without protocol and domain
# Assert these individually
resp_icon = response.data['results'][0].pop('icon')
serial_icon = serializer.data[0].pop('icon')
self.assertEqual(response.data['results'], serializer.data)
self.assertEqual(resp_icon, "http://testserver" + serial_icon)
def test_get_multiple_tags(self):
self.assertEqual(Tag.objects.count(), 1)
Tag.objects.create(slug='Freshmen', name='Fuksit', icon=self.icon)
@@ -88,6 +101,11 @@ class FeedTestCase(APITestCase):
feeds = Feed.objects.all()
serializer = FeedSerializer(feeds, many=True)
# DRF extends path given by serializer with the protocol and domain for icon
# Ignore tag on serializer and response. This is tested on TagTestCase.
# Note that we assume the length here to be 1
response.data['results'][0].pop('tags')
serializer.data[0].pop('tags')
self.assertEqual(response.data['results'], serializer.data)
def test_post_feed(self):
+17 -3
View File
@@ -48,7 +48,11 @@ class EventViewSet(viewsets.ModelViewSet):
search_fields = '__all__'
def get_queryset(self):
return Event.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
since = self.request.query_params.get('since', None)
if since:
return Event.objects.filter(visible=True, end_time__gt=since).order_by('start_time')
return Event.objects.filter(visible=True).order_by('start_time')
class SignupFormViewSet(viewsets.ModelViewSet):
@@ -60,7 +64,7 @@ class SignupFormViewSet(viewsets.ModelViewSet):
search_fields = '__all__'
def get_queryset(self):
return SignupForm.objects.filter(visible=True, end__gt=timezone.now()).order_by('start')
return SignupForm.objects.filter(visible=True, end_time__gt=timezone.now()).order_by('start_time')
class SignupViewSet(viewsets.ModelViewSet):
@@ -90,7 +94,17 @@ class FeedViewSet(viewsets.ModelViewSet):
search_fields = '__all__'
def get_queryset(self):
return Feed.objects.filter(visible=True, autohide__gt=timezone.now()).order_by('publish_time')
objs = Feed.objects.filter(visible=True).order_by('publish_time')
result_ids = []
for obj in objs:
if obj.autohide_enabled:
if obj.autohide > timezone.now():
result_ids.append(obj.id)
else:
result_ids.append(obj.id)
return Feed.objects.filter(id__in=result_ids)
class ContactsViewSet(viewsets.ReadOnlyModelViewSet):
+6 -6
View File
@@ -12,13 +12,13 @@ Make sure to add the python binary directory to PATH. For instructions how to do
Run the following command to install `virtualenv`.
```
```cmd
python -m pip install virtualenv
```
Setup a virtual python environment.
```
```cmd
python -m virtualenv ../virtualenv.sikweb
```
@@ -26,13 +26,13 @@ python -m virtualenv ../virtualenv.sikweb
Activate `virtualenv` (note that this has to be active at all times).
```
```cmd
source ../virtualenv.sikweb/Scripts/activate
```
Run the following command to install python packages.
```
```cmd
pip install -r requirements.txt
```
@@ -40,7 +40,7 @@ pip install -r requirements.txt
Run
```
```cmd
python manage.py migrate
```
@@ -52,4 +52,4 @@ Follow the instructions on [the npm website](https://www.npmjs.com/package/npm).
By default Django uses SQLite, which doesn't need any configuration. If you need PostgreSQL instead, refer to [their website](https://www.postgresql.org/download/windows/).
## Done!
## Done