Merge branch 'develop' into 'master'
New Sika & Membership application See merge request sahkoinsinoorikilta/vtmk/web2.0-backend!3
@@ -3,3 +3,4 @@ infoscreen/static/js/lib
|
||||
webapp/static/js/lib
|
||||
static/js/lib
|
||||
collected_static
|
||||
venv
|
||||
|
||||
@@ -5,7 +5,6 @@ sikweb/settings.py
|
||||
*.sqlite3
|
||||
uwsgi.ini
|
||||
uwsgi.log
|
||||
infoscreen/static/js/hsl.json
|
||||
members/logs/*
|
||||
.idea/
|
||||
logs/
|
||||
|
||||
@@ -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"
|
||||
@@ -0,0 +1 @@
|
||||
3.6.8
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -1,5 +0,0 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class IlmotunkkiConfig(AppConfig):
|
||||
name = 'ilmotunkki'
|
||||
@@ -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)
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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"]
|
||||
}
|
||||
@@ -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',
|
||||
),
|
||||
]
|
||||
|
||||
@@ -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',),
|
||||
),
|
||||
]
|
||||
@@ -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."""
|
||||
|
||||
|
||||
@@ -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ä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>
|
||||
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 736 KiB |
|
Before Width: | Height: | Size: 1.8 MiB |
|
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();
|
||||
}
|
||||
);
|
||||
|
||||
@@ -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),
|
||||
]
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'),
|
||||
),
|
||||
]
|
||||
@@ -23,7 +23,7 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: #052f5f;
|
||||
background-color: #0c2938;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 74 KiB |
@@ -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>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
@@ -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 /
|
||||
```
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 €
|
||||
@@ -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)
|
||||
|
||||
@@ -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 }}
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
[pycodestyle]
|
||||
max-line-length = 120
|
||||
ignore = E501,E722
|
||||
exclude = '*/migrations/*'
|
||||
exclude = '*/migrations/*', venv/*
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
version: '3.2'
|
||||
services:
|
||||
web20_backend:
|
||||
image: registry.gitlab.com/sahkoinsinoorikilta/vtmk/web2.0-backend:latest
|
||||
ports:
|
||||
- 8000:8000
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 74 KiB |
@@ -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>
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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='[]'),
|
||||
),
|
||||
]
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||