merge settings.py
This commit is contained in:
2
deployment/dev_nginx/Dockerfile
Normal file
2
deployment/dev_nginx/Dockerfile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from nginx:alpine
|
||||||
|
copy nginxdev.conf /etc/nginx/conf.d/default.conf
|
||||||
3
deployment/dev_nginx/build_and_push
Executable file
3
deployment/dev_nginx/build_and_push
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
cp ../nginxdev.conf .
|
||||||
|
docker build . -t docker.triton2.fet.at/nginxdev-fet2020:latest
|
||||||
|
docker image push docker.triton2.fet.at/nginxdev-fet2020:latest
|
||||||
67
deployment/dev_nginx/nginxdev.conf
Normal file
67
deployment/dev_nginx/nginxdev.conf
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
error_log /var/log/nginx/error.log notice;
|
||||||
|
rewrite_log on;
|
||||||
|
resolver 127.0.0.11 valid=30s;
|
||||||
|
set $theia theia;
|
||||||
|
set $flaskfetfotos "flaskfetfotos:8080";
|
||||||
|
set $etherpad "etherpad:9001";
|
||||||
|
location /fotos {
|
||||||
|
proxy_ssl_server_name on;
|
||||||
|
proxy_ssl_verify off;
|
||||||
|
|
||||||
|
proxy_pass http://$flaskfetfotos;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
# proxy_set_header REMOTE-USER $http_REMOTE_USER;
|
||||||
|
# proxy_set_header X-Forwarded-User $http_REMOTE_USER;
|
||||||
|
# proxy_set_header x-forwarded-user $http_REMOTE_USER;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
location /etherpad {
|
||||||
|
|
||||||
|
rewrite /etherpad/(.*) /$1 break;
|
||||||
|
rewrite ^/etherpad$ /etherpad/ permanent;
|
||||||
|
|
||||||
|
proxy_pass http://$etherpad;
|
||||||
|
proxy_redirect / /etherpad/;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_buffering off;
|
||||||
|
|
||||||
|
}
|
||||||
|
location /dev {
|
||||||
|
rewrite_log on;
|
||||||
|
rewrite /dev/(.*) /$1 break;
|
||||||
|
rewrite ^/dev$ /dev/ permanent;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header Proxy "";
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "Upgrade";
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarde-Proto $scheme;
|
||||||
|
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_pass http://$theia:3000;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header Proxy "";
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "Upgrade";
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarde-Proto $scheme;
|
||||||
|
|
||||||
|
|
||||||
|
proxy_buffering off;
|
||||||
|
|
||||||
|
proxy_pass http://$theia:8000;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
5
deployment/dev_theia/Dockerfile
Normal file
5
deployment/dev_theia/Dockerfile
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from theiaide/theia-python:latest
|
||||||
|
run apt-get update && apt-get -y install libgs-dev
|
||||||
|
COPY ./requirements.txt .
|
||||||
|
run pip3 install --upgrade pip && pip3 install -r requirements.txt && pip3 install pytest pylint bandit flake8 black pytest-django six pytest-mock
|
||||||
|
ENTRYPOINT node /home/theia/src-gen/backend/main.js /home/project/.theia-workspace --hostname=0.0.0.0
|
||||||
3
deployment/dev_theia/build_and_push
Executable file
3
deployment/dev_theia/build_and_push
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
cp ../../fet2020/requirements.txt .
|
||||||
|
docker build . -t docker.triton2.fet.at/theia-fet2020:latest
|
||||||
|
docker image push docker.triton2.fet.at/theia-fet2020:latest
|
||||||
16
deployment/dev_theia/requirements.txt
Normal file
16
deployment/dev_theia/requirements.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
django==3.1.4
|
||||||
|
django-ckeditor==6.0.0
|
||||||
|
django-crontab==0.7.1
|
||||||
|
django-environ==0.4.5
|
||||||
|
django-filter==2.4.0
|
||||||
|
django-static-jquery-ui==1.12.1.1
|
||||||
|
django-softhyphen==1.1.0
|
||||||
|
django-taggit==1.3.0
|
||||||
|
djangorestframework==3.12.2
|
||||||
|
configparser==5.0.1
|
||||||
|
docutils==0.16
|
||||||
|
easy-thumbnails==2.7.1
|
||||||
|
etherpad-lite==0.5
|
||||||
|
ghostscript==0.6
|
||||||
|
ldap3==2.8.1
|
||||||
|
mysqlclient==2.0.1
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
version: "3"
|
version: "2"
|
||||||
services:
|
services:
|
||||||
flaskfetfotos:
|
flaskfetfotos:
|
||||||
image: flask-fet-fotos
|
image: flask-fet-fotos
|
||||||
@@ -7,27 +7,16 @@ services:
|
|||||||
FLASK_APP: main.py
|
FLASK_APP: main.py
|
||||||
pages_root: /app/data
|
pages_root: /app/data
|
||||||
volumes:
|
volumes:
|
||||||
- /mnt/fotos/www:/app/data
|
- foto-data:/app/data
|
||||||
mysql:
|
|
||||||
image: jbergstroem/mariadb-alpine
|
|
||||||
environment:
|
|
||||||
SKIP_INNODB: "yes"
|
|
||||||
MYSQL_DATABASE: fet2020db
|
|
||||||
MYSQL_USER: user
|
|
||||||
MYSQL_PASSWORD: hgu
|
|
||||||
MYSQL_COLLATION: utf8_general_ci
|
|
||||||
MYSQL_CHARSET: utf8
|
|
||||||
volumes:
|
|
||||||
- mysql-volume:/var/lib/mysql
|
|
||||||
etherpadsql:
|
etherpadsql:
|
||||||
image: jbergstroem/mariadb-alpine
|
image: mariadb
|
||||||
environment:
|
environment:
|
||||||
SKIP_INNODB: "no"
|
|
||||||
MYSQL_DATABASE: etherpaddb
|
MYSQL_DATABASE: etherpaddb
|
||||||
MYSQL_USER: user
|
MYSQL_USER: user
|
||||||
MYSQL_PASSWORD: hgu
|
MYSQL_PASSWORD: hgu
|
||||||
MYSQL_COLLATION: utf8_general_ci
|
MYSQL_COLLATION: utf8_general_ci
|
||||||
MYSQL_CHARSET: utf8
|
MYSQL_CHARSET: utf8
|
||||||
|
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
|
||||||
volumes:
|
volumes:
|
||||||
- ep-mysql-volume:/var/lib/mysql
|
- ep-mysql-volume:/var/lib/mysql
|
||||||
etherpad:
|
etherpad:
|
||||||
@@ -40,38 +29,14 @@ services:
|
|||||||
DB_USER: user
|
DB_USER: user
|
||||||
DB_PASS: hgu
|
DB_PASS: hgu
|
||||||
DB_CHARSET: utf8
|
DB_CHARSET: utf8
|
||||||
#ADMIN_PASSWORD: "AndiS"
|
|
||||||
#REQUIRE_AUTHENTICATION: "false"
|
|
||||||
TRUST_PROXY: "true"
|
TRUST_PROXY: "true"
|
||||||
REQUIRE_SESSION: "true"
|
REQUIRE_SESSION: "true"
|
||||||
#LOGLEVEL: "DEBUG"
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- etherpadsql
|
- etherpadsql
|
||||||
volumes:
|
volumes:
|
||||||
- ./etherpad/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt
|
- ./etherpad/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt
|
||||||
# restart: always
|
|
||||||
# fet2020:
|
|
||||||
# image: fet2020django
|
|
||||||
# build: .
|
|
||||||
# environment:
|
|
||||||
# HOST_NAME: andis.2020.fet.at
|
|
||||||
# DEBUG: "False"
|
|
||||||
# SECRET_KEY: arguiq3ebhnjo
|
|
||||||
# MYSQL_USER: user
|
|
||||||
# MYSQL_PASSWORD: hgu
|
|
||||||
# MYSQL_PORT: 3306
|
|
||||||
# depends_on:
|
|
||||||
# - mysql
|
|
||||||
# ports:
|
|
||||||
# - "8106:8080"
|
|
||||||
# volumes:
|
|
||||||
# - ./fet2020:/app
|
|
||||||
# - ./assets:/app/assets
|
|
||||||
# - ./etherpad:/app/etherpad
|
|
||||||
# - ./deployment/nginx.conf:/etc/nginx/conf.d/fet2020.conf
|
|
||||||
# restart: always
|
|
||||||
theia:
|
theia:
|
||||||
image: theiaide/theia-python:latest
|
image: docker.triton2.fet.at/theia-fet2020:latest
|
||||||
volumes:
|
volumes:
|
||||||
- .:/home/project
|
- .:/home/project
|
||||||
- ./etherpad/APIKEY.txt:/srv/etherpad/APIKEY.txt
|
- ./etherpad/APIKEY.txt:/srv/etherpad/APIKEY.txt
|
||||||
@@ -83,4 +48,6 @@ services:
|
|||||||
- "8106:8080"
|
- "8106:8080"
|
||||||
volumes:
|
volumes:
|
||||||
ep-mysql-volume:
|
ep-mysql-volume:
|
||||||
mysql-volume:
|
driver: local
|
||||||
|
foto-data:
|
||||||
|
driver: local
|
||||||
53
docker-compose.dev.yml
Normal file
53
docker-compose.dev.yml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
version: "2"
|
||||||
|
services:
|
||||||
|
flaskfetfotos:
|
||||||
|
image: docker.triton2.fet.at/flask-fet-fotos:latest
|
||||||
|
environment:
|
||||||
|
FLASK_DEBUG: 0
|
||||||
|
FLASK_APP: main.py
|
||||||
|
pages_root: /app/data
|
||||||
|
etherpadsql:
|
||||||
|
image: mariadb
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: etherpaddb
|
||||||
|
MYSQL_USER: user
|
||||||
|
MYSQL_PASSWORD: hgu
|
||||||
|
MYSQL_COLLATION: utf8_general_ci
|
||||||
|
MYSQL_CHARSET: utf8
|
||||||
|
volumes:
|
||||||
|
- ep-mysql:/var/lib/mysql
|
||||||
|
etherpad:
|
||||||
|
image: etherpad/etherpad
|
||||||
|
environment:
|
||||||
|
DB_TYPE: mysql
|
||||||
|
DB_HOST: etherpadsql
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_NAME: etherpaddb
|
||||||
|
DB_USER: user
|
||||||
|
DB_PASS: hgu
|
||||||
|
DB_CHARSET: utf8
|
||||||
|
TRUST_PROXY: "true"
|
||||||
|
REQUIRE_SESSION: "true"
|
||||||
|
depends_on:
|
||||||
|
- etherpadsql
|
||||||
|
volumes:
|
||||||
|
- /srv/etherpad/APIKEY.txt:/opt/etherpad-lite/APIKEY.txt
|
||||||
|
theia:
|
||||||
|
image: docker.triton2.fet.at/theia-fet2020:latest
|
||||||
|
volumes:
|
||||||
|
- dev_data:/home/project
|
||||||
|
- /srv/etherpad/APIKEY.txt:/srv/etherpad/APIKEY.txt
|
||||||
|
- theia_usr:/usr/local
|
||||||
|
environment:
|
||||||
|
HOST_NAME: andis.triton2.fet.at
|
||||||
|
nginx:
|
||||||
|
image: docker.triton2.fet.at/nginxdev-fet2020:latest
|
||||||
|
ports:
|
||||||
|
- "8106:8080"
|
||||||
|
volumes:
|
||||||
|
ep-mysql:
|
||||||
|
driver: local
|
||||||
|
theia_usr:
|
||||||
|
driver: local
|
||||||
|
dev_data:
|
||||||
|
driver: local
|
||||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class AuthenticationsConfig(AppConfig):
|
class AuthenticationsConfig(AppConfig):
|
||||||
name = 'authentications'
|
name = "authentications"
|
||||||
|
|||||||
@@ -11,25 +11,25 @@ def authentication(username, password):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# username format
|
# username format
|
||||||
new_username = 'uid={username},ou=user,dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at'
|
new_username = "uid={username},ou=user,dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at"
|
||||||
userdn = new_username.format(username=username)
|
userdn = new_username.format(username=username)
|
||||||
|
|
||||||
server_uri = 'ldap://gagarin.fet.htu.tuwien.ac.at'
|
server_uri = "ldap://gagarin.fet.htu.tuwien.ac.at"
|
||||||
server = ldap3.Server(server_uri, port=389, use_ssl=True)
|
server = ldap3.Server(server_uri, port=389, use_ssl=True)
|
||||||
|
|
||||||
has_user = False
|
has_user = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = ldap3.Connection(server, user=userdn, password=password, auto_bind=True)
|
conn = ldap3.Connection(server, user=userdn, password=password, auto_bind=True)
|
||||||
conn.search('dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at', '(objectclass=person)')
|
conn.search("dc=fet,dc=htu,dc=tuwien,dc=ac,dc=at", "(objectclass=person)")
|
||||||
for user in sorted(conn.entries):
|
for user in sorted(conn.entries):
|
||||||
if ("DN: uid=" + str(username.lower())) in str(user):
|
if ("DN: uid=" + str(username.lower())) in str(user):
|
||||||
has_user = True
|
has_user = True
|
||||||
except LDAPBindError as e:
|
except LDAPBindError as e:
|
||||||
logger.info('Username does not exist. Error: {}'.format(e))
|
logger.info("Username does not exist. Error: {}".format(e))
|
||||||
username = None
|
username = None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info('Connection to server lost. Error: {}'.format(e))
|
logger.info("Connection to server lost. Error: {}".format(e))
|
||||||
username = None
|
username = None
|
||||||
|
|
||||||
if not has_user:
|
if not has_user:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from django.shortcuts import redirect
|
|||||||
def unauthenticated_user(view_func):
|
def unauthenticated_user(view_func):
|
||||||
def wrapper_func(request, *args, **kwargs):
|
def wrapper_func(request, *args, **kwargs):
|
||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
return redirect('home')
|
return redirect("home")
|
||||||
else:
|
else:
|
||||||
return view_func(request, *args, **kwargs)
|
return view_func(request, *args, **kwargs)
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ def authenticated_user(view_func):
|
|||||||
if request.user.is_authenticated:
|
if request.user.is_authenticated:
|
||||||
return view_func(request, *args, **kwargs)
|
return view_func(request, *args, **kwargs)
|
||||||
else:
|
else:
|
||||||
return redirect('login')
|
return redirect("login")
|
||||||
|
|
||||||
return wrapper_func
|
return wrapper_func
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ from django import forms
|
|||||||
|
|
||||||
class LoginForm(forms.Form):
|
class LoginForm(forms.Form):
|
||||||
username = forms.CharField()
|
username = forms.CharField()
|
||||||
password = forms.CharField(label='Passwort', widget=forms.PasswordInput())
|
password = forms.CharField(label="Passwort", widget=forms.PasswordInput())
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ from . import views
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('login/', views.loginPage, name="login"),
|
path("login/", views.loginPage, name="login"),
|
||||||
path('logout/', views.logoutUser, name="logout"),
|
path("logout/", views.logoutUser, name="logout"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ from .forms import LoginForm
|
|||||||
|
|
||||||
@unauthenticated_user
|
@unauthenticated_user
|
||||||
def loginPage(request):
|
def loginPage(request):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
username = request.POST.get('username')
|
username = request.POST.get("username")
|
||||||
password = request.POST.get('password')
|
password = request.POST.get("password")
|
||||||
|
|
||||||
auth_user = authentication(username, password)
|
auth_user = authentication(username, password)
|
||||||
|
|
||||||
@@ -25,23 +25,27 @@ def loginPage(request):
|
|||||||
user = User.objects.create_user(auth_user.lower())
|
user = User.objects.create_user(auth_user.lower())
|
||||||
|
|
||||||
login(request, user)
|
login(request, user)
|
||||||
return redirect('home')
|
|
||||||
|
try:
|
||||||
|
return redirect(request.GET.get("next"))
|
||||||
|
except:
|
||||||
|
return redirect("home")
|
||||||
else:
|
else:
|
||||||
messages.info(request, 'username or password is incorrect')
|
messages.info(request, "username or password is incorrect")
|
||||||
|
|
||||||
form = LoginForm()
|
form = LoginForm()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"form": form,
|
"form": form,
|
||||||
}
|
}
|
||||||
return render(request, 'authentications/login.html', context)
|
return render(request, "authentications/login.html", context)
|
||||||
|
|
||||||
|
|
||||||
@authenticated_user
|
@authenticated_user
|
||||||
def logoutUser(request):
|
def logoutUser(request):
|
||||||
logout(request)
|
logout(request)
|
||||||
|
|
||||||
response = redirect('home')
|
response = redirect("home")
|
||||||
response = del_ep_cookie(request, response)
|
response = del_ep_cookie(request, response)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ class JobPostingAdmin(admin.ModelAdmin):
|
|||||||
form = JobPostingForm
|
form = JobPostingForm
|
||||||
model = JobPosting
|
model = JobPosting
|
||||||
|
|
||||||
list_display = ['companyName', 'jobName', 'salary', 'publishDate']
|
list_display = ["companyName", "jobName", "salary", "publishDate"]
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(JobPosting, JobPostingAdmin)
|
admin.site.register(JobPosting, JobPostingAdmin)
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class BlackboardConfig(AppConfig):
|
class BlackboardConfig(AppConfig):
|
||||||
name = 'blackboard'
|
name = "blackboard"
|
||||||
|
|||||||
@@ -7,19 +7,17 @@ from .models import JobPosting
|
|||||||
class JobPostingForm(forms.ModelForm):
|
class JobPostingForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = JobPosting
|
model = JobPosting
|
||||||
fields = ['companyName', 'jobName', 'salary', 'pdfLocation', 'publishDate']
|
fields = ["companyName", "jobName", "salary", "pdfLocation", "publishDate"]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'companyName': _("Firmenname"),
|
"companyName": _("Firmenname"),
|
||||||
'jobName': _("Berufsbezeichnung"),
|
"jobName": _("Berufsbezeichnung"),
|
||||||
'salary': _("Gehalt"),
|
"salary": _("Gehalt"),
|
||||||
'pdfLocation': _("Stellenausschreibung"),
|
"pdfLocation": _("Stellenausschreibung"),
|
||||||
'publishDate': _("Veröffentlichung"),
|
"publishDate": _("Veröffentlichung"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'pdfLocation': _(
|
"pdfLocation": _("Verwendbare Formate: PDF"),
|
||||||
"Verwendbare Formate: PDF"
|
"salary": _("in Euro angeben"),
|
||||||
),
|
|
||||||
'salary': _("in Euro angeben"),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,16 +11,23 @@ from os.path import splitext, basename
|
|||||||
import ghostscript
|
import ghostscript
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger('blackboard')
|
|
||||||
|
logger = logging.getLogger("blackboard")
|
||||||
|
|
||||||
|
|
||||||
class JobPosting(models.Model):
|
class JobPosting(models.Model):
|
||||||
companyName = models.CharField(verbose_name="Firmenname", max_length=128)
|
companyName = models.CharField(verbose_name="Firmenname", max_length=128)
|
||||||
jobName = models.CharField(verbose_name="Berufsbezeichnung", max_length=128)
|
jobName = models.CharField(verbose_name="Berufsbezeichnung", max_length=128)
|
||||||
salary = models.PositiveSmallIntegerField(verbose_name="Gehalt", )
|
salary = models.PositiveSmallIntegerField(
|
||||||
pdfLocation = models.FileField(verbose_name="Stellenausschreibung", upload_to='uploads/blackboard/pdf/')
|
verbose_name="Gehalt",
|
||||||
|
)
|
||||||
|
pdfLocation = models.FileField(
|
||||||
|
verbose_name="Stellenausschreibung", upload_to="uploads/blackboard/pdf/"
|
||||||
|
)
|
||||||
pdf_thumb_location = models.CharField(max_length=128)
|
pdf_thumb_location = models.CharField(max_length=128)
|
||||||
publishDate = models.DateField(verbose_name="Veröffentlichung", default=timezone.now)
|
publishDate = models.DateField(
|
||||||
|
verbose_name="Veröffentlichung", default=timezone.now
|
||||||
|
)
|
||||||
|
|
||||||
# Managers
|
# Managers
|
||||||
all_jobPosting = models.Manager()
|
all_jobPosting = models.Manager()
|
||||||
@@ -40,7 +47,7 @@ class JobPosting(models.Model):
|
|||||||
"-dDEVICEWIDTHPOINTS=600",
|
"-dDEVICEWIDTHPOINTS=600",
|
||||||
"-dDEVICEHEIGHTPOINTS=800",
|
"-dDEVICEHEIGHTPOINTS=800",
|
||||||
"-sOutputFile=" + jpeg_output_path,
|
"-sOutputFile=" + jpeg_output_path,
|
||||||
pdf_input_path
|
pdf_input_path,
|
||||||
]
|
]
|
||||||
|
|
||||||
encoding = locale.getpreferredencoding()
|
encoding = locale.getpreferredencoding()
|
||||||
@@ -54,14 +61,18 @@ class JobPosting(models.Model):
|
|||||||
if not os.path.exists(settings.MEDIA_ROOT + "uploads/blackboard/thumb/"):
|
if not os.path.exists(settings.MEDIA_ROOT + "uploads/blackboard/thumb/"):
|
||||||
os.makedirs(settings.MEDIA_ROOT + "uploads/blackboard/thumb/")
|
os.makedirs(settings.MEDIA_ROOT + "uploads/blackboard/thumb/")
|
||||||
|
|
||||||
pdf_thumb_location_full = settings.MEDIA_ROOT \
|
pdf_thumb_location_full = (
|
||||||
+ "uploads/blackboard/thumb/" \
|
settings.MEDIA_ROOT
|
||||||
+ splitext(basename(self.pdfLocation.name))[0] \
|
+ "uploads/blackboard/thumb/"
|
||||||
|
+ splitext(basename(self.pdfLocation.name))[0]
|
||||||
+ ".jpg"
|
+ ".jpg"
|
||||||
|
)
|
||||||
|
|
||||||
self.pdf_thumb_location = "/files/uploads/blackboard/thumb/" \
|
self.pdf_thumb_location = (
|
||||||
+ splitext(basename(self.pdfLocation.name))[0] \
|
"/files/uploads/blackboard/thumb/"
|
||||||
|
+ splitext(basename(self.pdfLocation.name))[0]
|
||||||
+ ".jpg"
|
+ ".jpg"
|
||||||
|
)
|
||||||
|
|
||||||
self.pdf2jpeg(self.pdfLocation.path, pdf_thumb_location_full)
|
self.pdf2jpeg(self.pdfLocation.path, pdf_thumb_location_full)
|
||||||
logger.info("SavenThumbAs: " + self.pdf_thumb_location)
|
logger.info("SavenThumbAs: " + self.pdf_thumb_location)
|
||||||
@@ -70,7 +81,7 @@ class JobPosting(models.Model):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
count = 0
|
count = 0
|
||||||
for i in self.pdfLocation.name:
|
for i in self.pdfLocation.name:
|
||||||
if i == '.':
|
if i == ".":
|
||||||
count = count + 1
|
count = count + 1
|
||||||
if count > 1: # if more than one dot in filename
|
if count > 1: # if more than one dot in filename
|
||||||
raise ValidationError(_('Keine Dateien mit >1 Punkten im Namen erlaubt.'))
|
raise ValidationError(_("Keine Dateien mit >1 Punkten im Namen erlaubt."))
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ from . import views
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name='blackboard'),
|
path("", views.index, name="blackboard"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ from posts.models import Post
|
|||||||
def index(request):
|
def index(request):
|
||||||
job_postings_cutoff = timezone.now().date() - timedelta(30) # 30days from now
|
job_postings_cutoff = timezone.now().date() - timedelta(30) # 30days from now
|
||||||
job_postings = JobPosting.all_jobPosting.filter(publishDate__gt=job_postings_cutoff)
|
job_postings = JobPosting.all_jobPosting.filter(publishDate__gt=job_postings_cutoff)
|
||||||
bb_info = Post.objects.filter(slug='blackboard').first()
|
bb_info = Post.objects.filter(slug="blackboard").first()
|
||||||
bb_empty = Post.objects.filter(slug='blackboard-empty').first()
|
bb_empty = Post.objects.filter(slug="blackboard-empty").first()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"job_postings": job_postings,
|
"job_postings": job_postings,
|
||||||
@@ -19,4 +19,4 @@ def index(request):
|
|||||||
"bb_empty": bb_empty,
|
"bb_empty": bb_empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'blackboard/index.html', context)
|
return render(request, "blackboard/index.html", context)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import urllib.parse
|
|||||||
from etherpad_lite import EtherpadLiteClient, EtherpadException
|
from etherpad_lite import EtherpadLiteClient, EtherpadException
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
SERVER_URL = settings.ETHERPAD_CLIENT["exturl"]
|
SERVER_URL = settings.ETHERPAD_CLIENT["exturl"]
|
||||||
@@ -20,9 +21,11 @@ def get_ep_client():
|
|||||||
apikey = f.read()
|
apikey = f.read()
|
||||||
apikey = apikey.rstrip()
|
apikey = apikey.rstrip()
|
||||||
epc = EtherpadLiteClient(
|
epc = EtherpadLiteClient(
|
||||||
base_params={'apikey': apikey, },
|
base_params={
|
||||||
|
"apikey": apikey,
|
||||||
|
},
|
||||||
base_url=urllib.parse.urljoin(settings.ETHERPAD_CLIENT["url"], "api"),
|
base_url=urllib.parse.urljoin(settings.ETHERPAD_CLIENT["url"], "api"),
|
||||||
api_version='1.2.14',
|
api_version="1.2.14",
|
||||||
)
|
)
|
||||||
group = epc.createGroupIfNotExistsFor(groupMapper="fet")
|
group = epc.createGroupIfNotExistsFor(groupMapper="fet")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -62,7 +65,9 @@ def createPadifNotExists(padID):
|
|||||||
# Pad doesn't exist
|
# Pad doesn't exist
|
||||||
if not __checkPadExists(padID=padID):
|
if not __checkPadExists(padID=padID):
|
||||||
try:
|
try:
|
||||||
epc.createGroupPad(groupID=group["groupID"], padName=padID, text="helloworld")
|
epc.createGroupPad(
|
||||||
|
groupID=group["groupID"], padName=padID, text="helloworld"
|
||||||
|
)
|
||||||
except EtherpadException as e:
|
except EtherpadException as e:
|
||||||
logger.info("Can't create Pad '{}'. EtherpadException: {}".format(padID, e))
|
logger.info("Can't create Pad '{}'. EtherpadException: {}".format(padID, e))
|
||||||
return None
|
return None
|
||||||
@@ -81,7 +86,9 @@ def getPadHTML(padID):
|
|||||||
try:
|
try:
|
||||||
text = epc.getHTML(padID=group["groupID"] + "$" + padID)["html"]
|
text = epc.getHTML(padID=group["groupID"] + "$" + padID)["html"]
|
||||||
except EtherpadException as e:
|
except EtherpadException as e:
|
||||||
logger.info("Can't get HTML from padID '{}'. EtherpadException: {}".format(padID, e))
|
logger.info(
|
||||||
|
"Can't get HTML from padID '{}'. EtherpadException: {}".format(padID, e)
|
||||||
|
)
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
@@ -107,4 +114,6 @@ def get_pad_link(padID):
|
|||||||
if not epc or not group:
|
if not epc or not group:
|
||||||
return "#"
|
return "#"
|
||||||
|
|
||||||
return urllib.parse.urljoin(settings.ETHERPAD_CLIENT["exturl"], 'p/' + group["groupID"] + '$' + str(padID))
|
return urllib.parse.urljoin(
|
||||||
|
settings.ETHERPAD_CLIENT["exturl"], "p/" + group["groupID"] + "$" + str(padID)
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
# from django.contrib.admin.apps import AdminConfig
|
# from django.contrib.admin.apps import AdminConfig
|
||||||
|
|
||||||
|
|
||||||
class DocumentsConfig(AppConfig):
|
class DocumentsConfig(AppConfig):
|
||||||
name = 'documents'
|
name = "documents"
|
||||||
|
|||||||
@@ -11,22 +11,21 @@ def __get_ep_sessionid(request):
|
|||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
author = epc.createAuthorIfNotExistsFor(
|
author = epc.createAuthorIfNotExistsFor(
|
||||||
name=str(request.user),
|
name=str(request.user), authorMapper=str(request.user)
|
||||||
authorMapper=str(request.user)
|
)["authorID"]
|
||||||
)['authorID']
|
|
||||||
|
|
||||||
expires = datetime.utcnow() + timedelta(hours=3)
|
expires = datetime.utcnow() + timedelta(hours=3)
|
||||||
try:
|
try:
|
||||||
result = epc.createSession(
|
result = epc.createSession(
|
||||||
groupID=str(group['groupID']),
|
groupID=str(group["groupID"]),
|
||||||
authorID=str(author),
|
authorID=str(author),
|
||||||
validUntil=str(int(expires.timestamp()))
|
validUntil=str(int(expires.timestamp())),
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
return result['sessionID'], expires
|
return result["sessionID"], expires
|
||||||
|
|
||||||
|
|
||||||
def add_ep_cookie(request, response):
|
def add_ep_cookie(request, response):
|
||||||
@@ -34,32 +33,19 @@ def add_ep_cookie(request, response):
|
|||||||
|
|
||||||
if ep_sessid:
|
if ep_sessid:
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
"sessionID",
|
"sessionID", ep_sessid, expires=expires, domain=".2020.fet.at", path="/"
|
||||||
ep_sessid,
|
|
||||||
expires=expires,
|
|
||||||
domain=".2020.fet.at",
|
|
||||||
path="/"
|
|
||||||
)
|
|
||||||
response.set_cookie(
|
|
||||||
"sessionID",
|
|
||||||
ep_sessid,
|
|
||||||
expires=expires,
|
|
||||||
path="/etherpad"
|
|
||||||
)
|
)
|
||||||
|
response.set_cookie("sessionID", ep_sessid, expires=expires, path="/etherpad")
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def del_ep_cookie(request, response):
|
def del_ep_cookie(request, response):
|
||||||
|
|
||||||
if 'sessionID' in request.COOKIES:
|
if "sessionID" in request.COOKIES:
|
||||||
ep_sessionID = request.COOKIES['sessionID']
|
ep_sessionID = request.COOKIES["sessionID"]
|
||||||
|
|
||||||
epc, group = get_ep_client()
|
epc, group = get_ep_client()
|
||||||
epc.deleteSession(sessionID=ep_sessionID)
|
epc.deleteSession(sessionID=ep_sessionID)
|
||||||
|
|
||||||
response.delete_cookie(
|
response.delete_cookie("sessionID", domain=".2020.fet.at", path="/")
|
||||||
"sessionID",
|
|
||||||
domain=".2020.fet.at",
|
|
||||||
path="/"
|
|
||||||
)
|
|
||||||
return response
|
return response
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ import os
|
|||||||
|
|
||||||
from django.core.asgi import get_asgi_application
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'fet2020.settings')
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fet2020.settings")
|
||||||
|
|
||||||
application = get_asgi_application()
|
application = get_asgi_application()
|
||||||
|
|||||||
@@ -11,23 +11,23 @@ env = environ.Env(
|
|||||||
MYSQL_USER=(str),
|
MYSQL_USER=(str),
|
||||||
MYSQL_PASSWORD=(str),
|
MYSQL_PASSWORD=(str),
|
||||||
HOST_NAME=(str, "localhost"),
|
HOST_NAME=(str, "localhost"),
|
||||||
ETHERPAD_PORT=(str,"9001"),
|
ETHERPAD_PORT=(str, "9001"),
|
||||||
ETHERPAD_HOST=(str,"etherpad2.2020.fet.at")
|
ETHERPAD_HOST=(str, "etherpad2.2020.fet.at"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Prints and logs are written to console
|
# Prints and logs are written to console
|
||||||
# TODO: Change before release
|
# TODO: Change before release
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
"version": 1,
|
||||||
'disable_existing_loggers': False,
|
"disable_existing_loggers": False,
|
||||||
'handlers': {
|
"handlers": {
|
||||||
'console': {
|
"console": {
|
||||||
'class': 'logging.StreamHandler',
|
"class": "logging.StreamHandler",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'root': {
|
"root": {
|
||||||
'handlers': ['console'],
|
"handlers": ["console"],
|
||||||
'level': 'DEBUG',
|
"level": "DEBUG",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,108 +41,107 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = env('DEBUG')
|
DEBUG = env("DEBUG")
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
# SECURITY WARNING: keep the secret key used in production secret!
|
# SECURITY WARNING: keep the secret key used in production secret!
|
||||||
SECRET_KEY = 'r37-i7l)vrduzz2-gira+z#u!p!di9#f+%s*5-bb($hg)55@ns'
|
SECRET_KEY = "r37-i7l)vrduzz2-gira+z#u!p!di9#f+%s*5-bb($hg)55@ns"
|
||||||
else:
|
else:
|
||||||
SECRET_KEY = env('SECRET_KEY')
|
SECRET_KEY = env("SECRET_KEY")
|
||||||
|
|
||||||
|
|
||||||
ALLOWED_HOSTS = ["127.0.0.1", env('HOST_NAME'), "2020.fet.at"]
|
ALLOWED_HOSTS = ["127.0.0.1", env('HOST_NAME'), "2020.fet.at"]
|
||||||
|
|
||||||
HOST_NAME = env('HOST_NAME')
|
HOST_NAME = env("HOST_NAME")
|
||||||
|
|
||||||
|
|
||||||
DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 1024
|
DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 1024
|
||||||
# Application definition
|
# Application definition
|
||||||
CKEDITOR_UPLOAD_PATH = 'upload'
|
CKEDITOR_UPLOAD_PATH = "upload"
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
'django.contrib.admin',
|
"django.contrib.admin",
|
||||||
'django.contrib.admindocs',
|
"django.contrib.admindocs",
|
||||||
'django.contrib.auth',
|
"django.contrib.auth",
|
||||||
'django.contrib.contenttypes',
|
"django.contrib.contenttypes",
|
||||||
'django.contrib.sessions',
|
"django.contrib.sessions",
|
||||||
'django.contrib.messages',
|
"django.contrib.messages",
|
||||||
'django.contrib.staticfiles',
|
"django.contrib.staticfiles",
|
||||||
'taggit',
|
"taggit",
|
||||||
'ckeditor',
|
"ckeditor",
|
||||||
'ckeditor_uploader',
|
"ckeditor_uploader",
|
||||||
'easy_thumbnails',
|
"easy_thumbnails",
|
||||||
'rest_framework',
|
"rest_framework",
|
||||||
'softhyphen',
|
"softhyphen",
|
||||||
'django_crontab',
|
"django_crontab",
|
||||||
'django_filters',
|
"django_filters",
|
||||||
'django_static_jquery_ui',
|
"django_static_jquery_ui",
|
||||||
'posts.apps.PostsConfig',
|
"posts.apps.PostsConfig",
|
||||||
'members.apps.MembersConfig',
|
"members.apps.MembersConfig",
|
||||||
'documents.apps.DocumentsConfig',
|
"documents.apps.DocumentsConfig",
|
||||||
'blackboard.apps.BlackboardConfig',
|
"blackboard.apps.BlackboardConfig",
|
||||||
'tasks.apps.TasksConfig',
|
"tasks.apps.TasksConfig",
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
"django.middleware.security.SecurityMiddleware",
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
"django.middleware.locale.LocaleMiddleware",
|
||||||
'django.middleware.common.CommonMiddleware',
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
'fet2020.middleware.FETHeaderMiddleware',
|
"fet2020.middleware.FETHeaderMiddleware",
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'fet2020.urls'
|
ROOT_URLCONF = "fet2020.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
'DIRS': [
|
"DIRS": [
|
||||||
os.path.join(BASE_DIR, 'templates'),
|
os.path.join(BASE_DIR, "templates"),
|
||||||
],
|
],
|
||||||
'APP_DIRS': True,
|
"APP_DIRS": True,
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'context_processors': [
|
"context_processors": [
|
||||||
'django.template.context_processors.debug',
|
"django.template.context_processors.debug",
|
||||||
'django.template.context_processors.request',
|
"django.template.context_processors.request",
|
||||||
'django.contrib.auth.context_processors.auth',
|
"django.contrib.auth.context_processors.auth",
|
||||||
'django.contrib.messages.context_processors.messages',
|
"django.contrib.messages.context_processors.messages",
|
||||||
'django.template.context_processors.i18n',
|
"django.template.context_processors.i18n",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = 'fet2020.wsgi.application'
|
WSGI_APPLICATION = "fet2020.wsgi.application"
|
||||||
|
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
"default": {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
"ENGINE": "django.db.backends.sqlite3",
|
||||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
"default": {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
"ENGINE": "django.db.backends.mysql",
|
||||||
'NAME': env('MYSQL_DATABASE'),
|
"NAME": env("MYSQL_DATABASE"),
|
||||||
'USER': env('MYSQL_USER'),
|
"USER": env("MYSQL_USER"),
|
||||||
'PASSWORD': env('MYSQL_PASSWORD'),
|
"PASSWORD": env("MYSQL_PASSWORD"),
|
||||||
'HOST': env('MYSQL_HOST'),
|
"HOST": env("MYSQL_HOST"),
|
||||||
'PORT': env('MYSQL_PORT')
|
"PORT": env("MYSQL_PORT"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = [
|
AUTHENTICATION_BACKENDS = [
|
||||||
# 'django.contrib.auth.backends.RemoteUserBackend',
|
"django.contrib.auth.backends.ModelBackend",
|
||||||
'django.contrib.auth.backends.ModelBackend',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
@@ -150,16 +149,16 @@ AUTHENTICATION_BACKENDS = [
|
|||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -167,9 +166,9 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'de-at'
|
LANGUAGE_CODE = "de-at"
|
||||||
|
|
||||||
TIME_ZONE = 'CET'
|
TIME_ZONE = "CET"
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
@@ -177,32 +176,32 @@ USE_L10N = True
|
|||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')]
|
||||||
|
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = '/assets/'
|
STATIC_URL = "/assets/"
|
||||||
|
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
|
||||||
os.path.join(BASE_DIR, "static")
|
STATIC_ROOT = "assets/"
|
||||||
]
|
MEDIA_ROOT = os.path.join(BASE_DIR, "files/")
|
||||||
STATIC_ROOT = 'assets/'
|
MEDIA_URL = "/files/"
|
||||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'files/')
|
|
||||||
MEDIA_URL = '/files/'
|
|
||||||
|
|
||||||
TAGGIT_FORCE_LOWERCASE = True
|
TAGGIT_FORCE_LOWERCASE = True
|
||||||
|
|
||||||
CKEDITOR_CONFIGS = {
|
CKEDITOR_CONFIGS = {
|
||||||
'default': {
|
"default": {
|
||||||
'stylesSet': [
|
"stylesSet": [
|
||||||
{
|
{
|
||||||
"name": 'Überschrift 2',
|
"name": "Überschrift 2",
|
||||||
"element": 'h2',
|
"element": "h2",
|
||||||
"attributes": {},
|
"attributes": {},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": 'Code',
|
"name": "Code",
|
||||||
"element": 'code',
|
"element": "code",
|
||||||
"attributes": {"class": "code-block"},
|
"attributes": {"class": "code-block"},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -211,41 +210,41 @@ CKEDITOR_CONFIGS = {
|
|||||||
|
|
||||||
# THUMBNAIL
|
# THUMBNAIL
|
||||||
THUMBNAIL_ALIASES = {
|
THUMBNAIL_ALIASES = {
|
||||||
'': {
|
"": {
|
||||||
'avatar': {'size': (50, 50), 'crop': True},
|
"avatar": {"size": (50, 50), "crop": True},
|
||||||
'thumb': {'size': (150, 150), 'crop': True},
|
"thumb": {"size": (150, 150), "crop": True},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# ETHERPAD CLIENT
|
# ETHERPAD CLIENT
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
ETHERPAD_CLIENT = {
|
ETHERPAD_CLIENT = {
|
||||||
'url': "http://etherpad:"+env('ETHERPAD_PORT'),
|
"url": "http://etherpad:" + env("ETHERPAD_PORT"),
|
||||||
'exturl': env('ETHERPAD_HOST'),
|
"exturl": env("ETHERPAD_HOST"),
|
||||||
'apikey': "/srv/etherpad/APIKEY.txt"
|
"apikey": "/srv/etherpad/APIKEY.txt",
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
ETHERPAD_CLIENT = {
|
ETHERPAD_CLIENT = {
|
||||||
'url': "http://etherpad:"+env('ETHERPAD_PORT'),
|
"url": "http://etherpad:" + env("ETHERPAD_PORT"),
|
||||||
'exturl': urljoin('https://' + env('HOST_NAME'),"etherpad/"),
|
"exturl": urljoin("https://" + env("HOST_NAME"), "etherpad/"),
|
||||||
'apikey': "/app/etherpad/APIKEY.txt"
|
"apikey": "/app/etherpad/APIKEY.txt",
|
||||||
}
|
}
|
||||||
|
|
||||||
# REST FRAMEWORK
|
# REST FRAMEWORK
|
||||||
REST_FRAMEWORK={
|
REST_FRAMEWORK = {
|
||||||
'DEFAULT_PERMISSION_CLASSES_CLASSES':[
|
"DEFAULT_PERMISSION_CLASSES_CLASSES": [
|
||||||
'rest_framework.permissions.AllowAny',
|
"rest_framework.permissions.AllowAny",
|
||||||
],
|
],
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES':()
|
"DEFAULT_AUTHENTICATION_CLASSES": (),
|
||||||
}
|
}
|
||||||
|
|
||||||
# DJANGO MAIL
|
# DJANGO MAIL
|
||||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
||||||
EMAIL_HOST = 'buran.htu.tuwien.ac.at'
|
EMAIL_HOST = "buran.htu.tuwien.ac.at"
|
||||||
EMAIL_PORT = 587
|
EMAIL_PORT = 587
|
||||||
EMAIL_USE_TLS = True
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
# CRON JOBS
|
# CRON JOBS
|
||||||
CRONJOBS = [
|
CRONJOBS = [
|
||||||
('0 16 * * *', 'posts.cronjobs.check_to_send_agenda_mail'),
|
("0 16 * * *", "posts.cronjobs.check_to_send_agenda_mail"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,31 +4,36 @@ from django.conf.urls.static import static
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.views.generic import RedirectView
|
from django.views.generic import RedirectView
|
||||||
from . import views
|
from . import views
|
||||||
from posts.views import PostViewSet
|
from posts.viewsets import PostViewSet
|
||||||
from members.urls import member_urlpatterns, jobs_urlpatterns
|
from members.urls import member_urlpatterns, jobs_urlpatterns
|
||||||
from members.views import MemberViewSet, JobViewSet, JobGroupViewSet, JobMemberViewSet
|
from members.viewsets import (
|
||||||
|
MemberViewSet,
|
||||||
|
JobViewSet,
|
||||||
|
JobGroupViewSet,
|
||||||
|
JobMemberViewSet,
|
||||||
|
)
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register(r'posts', PostViewSet)
|
router.register(r"posts", PostViewSet)
|
||||||
router.register(r'members', MemberViewSet)
|
router.register(r"members", MemberViewSet)
|
||||||
router.register(r'jobgroups', JobGroupViewSet)
|
router.register(r"jobgroups", JobGroupViewSet)
|
||||||
router.register(r'jobs', JobViewSet)
|
router.register(r"jobs", JobViewSet)
|
||||||
router.register(r'jobmembers', JobMemberViewSet)
|
router.register(r"jobmembers", JobMemberViewSet)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('posts/', include('posts.urls')),
|
path("posts/", include("posts.urls")),
|
||||||
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
path("admin/doc/", include("django.contrib.admindocs.urls")),
|
||||||
path('admin/login/', RedirectView.as_view(pattern_name='login')),
|
path("admin/login/", RedirectView.as_view(pattern_name="login")),
|
||||||
path('admin/', admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path('auth/', include('authentications.urls')),
|
path("auth/", include("authentications.urls")),
|
||||||
path('', views.index, name='home'),
|
path("", views.index, name="home"),
|
||||||
path('index.html', views.index, name='home'),
|
path("index.html", views.index, name="home"),
|
||||||
path('ckeditor/', include('ckeditor_uploader.urls')),
|
path("ckeditor/", include("ckeditor_uploader.urls")),
|
||||||
path('api/', include(router.urls)),
|
path("api/", include(router.urls)),
|
||||||
path('members/', include('members.urls'), name='members'),
|
path("members/", include("members.urls"), name="members"),
|
||||||
path('jobs/', include(jobs_urlpatterns), name='jobs'),
|
path("jobs/", include(jobs_urlpatterns), name="jobs"),
|
||||||
path('member/', include(member_urlpatterns), name='member'),
|
path("member/", include(member_urlpatterns), name="member"),
|
||||||
path('blackboard/', include('blackboard.urls'), name='blackboard'),
|
path("blackboard/", include("blackboard.urls"), name="blackboard"),
|
||||||
path('tasks/', include('tasks.urls'), name='tasks'),
|
path("tasks/", include("tasks.urls"), name="tasks"),
|
||||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
# from django.http import HttpResponse
|
# from django.http import HttpResponse
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from posts.models import Post, FetMeeting, Event
|
from posts.models import Post, FetMeeting, Event
|
||||||
@@ -34,12 +35,12 @@ def index(request):
|
|||||||
featured_meeting = FetMeeting.objects.get_meetings()
|
featured_meeting = FetMeeting.objects.get_meetings()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'posts': deque(list(posts)[:5]),
|
"posts": deque(list(posts)[:5]),
|
||||||
'events': Event.all_events.get_five_events(),
|
"events": Event.all_events.get_five_events(),
|
||||||
'featured_post': featured_post,
|
"featured_post": featured_post,
|
||||||
'featured_event': featured_event,
|
"featured_event": featured_event,
|
||||||
'featured_meeting': featured_meeting,
|
"featured_meeting": featured_meeting,
|
||||||
'tags_list': " ".join(t)
|
"tags_list": " ".join(t),
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'home.html', context)
|
return render(request, "home.html", context)
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ import os
|
|||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'fet2020.settings')
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fet2020.settings")
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
python manage.py makemigrations && python manage.py makemigrations posts members blackboard\
|
python3 manage.py makemigrations && python3 manage.py makemigrations posts members blackboard\
|
||||||
&& python manage.py migrate
|
&& python3 manage.py migrate
|
||||||
|
|||||||
BIN
fet2020/locale/de/LC_MESSAGES/django.mo
Normal file
BIN
fet2020/locale/de/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
346
fet2020/locale/de/LC_MESSAGES/django.po
Normal file
346
fet2020/locale/de/LC_MESSAGES/django.po
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
# Translation for Austrian German 'de_AT'. You have to use 'de' because Django doesn't support 'de_AT'.
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: fet2020\n"
|
||||||
|
"Report-Msgid-Bugs-To: \n"
|
||||||
|
"POT-Creation-Date: 2021-01-17 12:57+0000\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
|
"Last-Translator: FET\n"
|
||||||
|
"Language-Team: German\n"
|
||||||
|
"Language: de_AT\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: blackboard/forms.py:13
|
||||||
|
msgid "Firmenname"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/forms.py:14
|
||||||
|
msgid "Berufsbezeichnung"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/forms.py:15
|
||||||
|
msgid "Gehalt"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/forms.py:16
|
||||||
|
msgid "Stellenausschreibung"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/forms.py:17 posts/forms.py:55 posts/forms.py:109
|
||||||
|
msgid "Veröffentlichung"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/forms.py:21
|
||||||
|
msgid "Verwendbare Formate: PDF"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/forms.py:22
|
||||||
|
msgid "in Euro angeben"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: blackboard/models.py:87
|
||||||
|
msgid "Keine Dateien mit >1 Punkten im Namen erlaubt."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/admin.py:9
|
||||||
|
msgid "Rolle"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/admin.py:14
|
||||||
|
msgid "Aktiv"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/admin.py:15 members/models.py:107
|
||||||
|
msgid "Pension"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:29
|
||||||
|
msgid "Beschreibung zu der Person"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:30
|
||||||
|
msgid "Porträt"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:31
|
||||||
|
msgid "Geburtstag"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:32
|
||||||
|
msgid "Telefonnummer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:33
|
||||||
|
msgid "Wohnadresse"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:37
|
||||||
|
msgid "Mindestgröße: 150*150 px, Verwendbare Formate: ..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:38
|
||||||
|
msgid "Die Mailadresse mit '@fet.at' angeben."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:53
|
||||||
|
msgid "Kürzel der Tätigkeit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:54
|
||||||
|
msgid "Tätigkeitsbereich"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:72
|
||||||
|
msgid "Kürzel des Tätigkeitsbereichs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:73
|
||||||
|
msgid "Beschreibung des Tätigkeitsbereichs"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/forms.py:75
|
||||||
|
msgid ""
|
||||||
|
"Dieser Tätigkeitsbereich soll im Fachschaftsbereich angeheftet werden, damit "
|
||||||
|
"es sofort ersichtlich ist."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:106
|
||||||
|
msgid "Active"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:144
|
||||||
|
msgid "Es fehlt das Profilbild."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:148
|
||||||
|
msgid "Das Bild ist zu klein. (Höhe: {}, Breite: {})"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:154
|
||||||
|
msgid "In der Mailadresse fehlt die Domäne."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:234
|
||||||
|
msgid "VorsitzendeR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:235
|
||||||
|
msgid "stv VorsitzendeR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:236
|
||||||
|
msgid "2. stv VorsitzendeR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:237
|
||||||
|
msgid "VerantwortlicheR"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:238
|
||||||
|
msgid "Mitglied"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: members/models.py:239
|
||||||
|
msgid "Ersatzmitglied"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/admin.py:27
|
||||||
|
#, python-format
|
||||||
|
msgid "Das Agenda konnte nicht erstellt werden. Error: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/admin.py:37
|
||||||
|
#, python-format
|
||||||
|
msgid "Das Protokoll konnte nicht erstellt werden. Error: %s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/admin.py:52
|
||||||
|
#, python-format
|
||||||
|
msgid "Das Event %s wurde erfolgreich in eine FET Sitzung konvertiert."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:50 posts/forms.py:101 tasks/forms.py:19
|
||||||
|
msgid "Titel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:51 posts/forms.py:102
|
||||||
|
msgid "Untertitel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:52 posts/forms.py:103
|
||||||
|
msgid "Hintergrundbild"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:53 posts/forms.py:104
|
||||||
|
msgid "Text"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:54 posts/forms.py:108
|
||||||
|
msgid "Autor"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:56
|
||||||
|
msgid "Post anheften"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:57
|
||||||
|
msgid "Post verstecken"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:62 posts/forms.py:115 posts/forms.py:153
|
||||||
|
msgid ""
|
||||||
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:64
|
||||||
|
msgid "Verwendbare Formate: ..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:66
|
||||||
|
msgid "Dieser Post soll an die Startseite als erster Post angeheftet werden."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:69
|
||||||
|
msgid "Dieser Post soll im News Feed nicht auftauchen, z.B. Impressum."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:105
|
||||||
|
msgid "Start des Events"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:106
|
||||||
|
msgid "Ende des Events"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:107
|
||||||
|
msgid "Ort des Events"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:110
|
||||||
|
msgid "Event anheften"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:117
|
||||||
|
msgid "Verwendbare Formate: "
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:119
|
||||||
|
msgid "Dieses Event soll an die Startseite als erster Post angeheftet werden."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:145
|
||||||
|
msgid "Start der Sitzung"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/forms.py:146
|
||||||
|
msgid "Ende der Sitzung"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/models.py:86
|
||||||
|
msgid "News"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/models.py:86
|
||||||
|
msgid "Event"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/models.py:86
|
||||||
|
msgid "FetMeeting"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/models.py:258
|
||||||
|
msgid "Das Ende des Events liegt vor dem Beginn."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/models.py:318
|
||||||
|
msgid "Das Datum des Events fehlt."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: posts/models.py:349
|
||||||
|
msgid "Es existiert bereits eine Sitzung mit demselben Datum."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:20
|
||||||
|
msgid "Aufgabenbereich"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:21
|
||||||
|
msgid "Fälligkeit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:22
|
||||||
|
msgid "Abgeschlossen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:23
|
||||||
|
msgid "Datum der Fertigstellung"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:24 tasks/forms.py:52
|
||||||
|
msgid "Zuweisen an"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:25
|
||||||
|
msgid "Notizen"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:26
|
||||||
|
msgid "Priorität"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:49
|
||||||
|
msgid "Titel des Tasks"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:50
|
||||||
|
msgid "Task-Gruppe"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tasks/forms.py:51
|
||||||
|
msgid "Fälligkeitsdatum"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/base.html:8
|
||||||
|
msgid "Welcome,"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/base.html:18
|
||||||
|
msgid "Documentation"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/base.html:22
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/base.html:24
|
||||||
|
msgid "Log out"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/admin/submit_line.html:5
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/documents/base.html:17
|
||||||
|
msgid "profile"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: templates/documents/base.html:18
|
||||||
|
msgid "logout"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "January"
|
||||||
|
msgstr "Jänner"
|
||||||
|
|
||||||
|
msgid "jan"
|
||||||
|
msgstr "Jän"
|
||||||
|
|
||||||
|
msgctxt "abbrev. month"
|
||||||
|
msgid "Jan."
|
||||||
|
msgstr "Jän."
|
||||||
|
|
||||||
|
msgctxt "alt. month"
|
||||||
|
msgid "January"
|
||||||
|
msgstr "Jänner"
|
||||||
@@ -6,13 +6,13 @@ from .forms import MemberForm, JobForm, JobGroupForm
|
|||||||
|
|
||||||
|
|
||||||
class MemberRoleFilter(admin.SimpleListFilter):
|
class MemberRoleFilter(admin.SimpleListFilter):
|
||||||
title = _('Rolle')
|
title = _("Rolle")
|
||||||
parameter_name = 'role'
|
parameter_name = "role"
|
||||||
|
|
||||||
def lookups(self, request, model_admin):
|
def lookups(self, request, model_admin):
|
||||||
return (
|
return (
|
||||||
('A', _('Aktiv')),
|
("A", _("Aktiv")),
|
||||||
('P', _('Pension')),
|
("P", _("Pension")),
|
||||||
)
|
)
|
||||||
|
|
||||||
def queryset(self, request, queryset):
|
def queryset(self, request, queryset):
|
||||||
@@ -55,40 +55,53 @@ class MemberAdmin(admin.ModelAdmin):
|
|||||||
form = MemberForm
|
form = MemberForm
|
||||||
model = Member
|
model = Member
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(
|
||||||
'fields': (
|
None,
|
||||||
('firstname', 'surname',),
|
{
|
||||||
'nickname',
|
"fields": (
|
||||||
'username',
|
(
|
||||||
'mailaccount',
|
"firstname",
|
||||||
'role',
|
"surname",
|
||||||
'description',
|
),
|
||||||
'image',
|
"nickname",
|
||||||
'birthday',
|
"username",
|
||||||
'phone',
|
"mailaccount",
|
||||||
'address',
|
"role",
|
||||||
|
"description",
|
||||||
|
"image",
|
||||||
|
"birthday",
|
||||||
|
"phone",
|
||||||
|
"address",
|
||||||
)
|
)
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
inlines = (JobOverviewInline,)
|
inlines = (JobOverviewInline,)
|
||||||
|
|
||||||
list_display = ['nickname', 'firstname', 'surname', 'mailaccount', 'role']
|
list_display = ["nickname", "firstname", "surname", "mailaccount", "role"]
|
||||||
ordering = ['firstname', ]
|
ordering = [
|
||||||
search_fields = ['firstname', 'surname', 'nickname', 'mailaccount']
|
"firstname",
|
||||||
|
]
|
||||||
|
search_fields = ["firstname", "surname", "nickname", "mailaccount"]
|
||||||
list_filter = [MemberRoleFilter]
|
list_filter = [MemberRoleFilter]
|
||||||
|
|
||||||
def add_view(self, request, form_url='', extra_context=None):
|
def add_view(self, request, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||||
return super().add_view(
|
return super().add_view(
|
||||||
request, form_url, extra_context=extra_context,
|
request,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||||
return super().change_view(
|
return super().change_view(
|
||||||
request, object_id, form_url, extra_context=extra_context,
|
request,
|
||||||
|
object_id,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
@@ -101,22 +114,33 @@ class JobAdmin(admin.ModelAdmin):
|
|||||||
model = Job
|
model = Job
|
||||||
inlines = (ActiveMemberInline, InactiveMemberInline)
|
inlines = (ActiveMemberInline, InactiveMemberInline)
|
||||||
|
|
||||||
list_display = ['name', ]
|
list_display = [
|
||||||
ordering = ['name', ]
|
"name",
|
||||||
search_fields = ['name', ]
|
]
|
||||||
|
ordering = [
|
||||||
|
"name",
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
"name",
|
||||||
|
]
|
||||||
|
|
||||||
def add_view(self, request, form_url='', extra_context=None):
|
def add_view(self, request, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||||
return super().add_view(
|
return super().add_view(
|
||||||
request, form_url, extra_context=extra_context,
|
request,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichfelder."
|
||||||
return super().change_view(
|
return super().change_view(
|
||||||
request, object_id, form_url, extra_context=extra_context,
|
request,
|
||||||
|
object_id,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
@@ -127,24 +151,36 @@ class JobAdmin(admin.ModelAdmin):
|
|||||||
class JobGroupAdmin(admin.ModelAdmin):
|
class JobGroupAdmin(admin.ModelAdmin):
|
||||||
form = JobGroupForm
|
form = JobGroupForm
|
||||||
model = JobGroup
|
model = JobGroup
|
||||||
inlines = (JobInline, )
|
inlines = (JobInline,)
|
||||||
|
|
||||||
list_display = ['name', 'is_pinned', ]
|
list_display = [
|
||||||
ordering = ['name', ]
|
"name",
|
||||||
search_fields = ['name', ]
|
"is_pinned",
|
||||||
|
]
|
||||||
|
ordering = [
|
||||||
|
"name",
|
||||||
|
]
|
||||||
|
search_fields = [
|
||||||
|
"name",
|
||||||
|
]
|
||||||
|
|
||||||
def add_view(self, request, form_url='', extra_context=None):
|
def add_view(self, request, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||||
return super().add_view(
|
return super().add_view(
|
||||||
request, form_url, extra_context=extra_context,
|
request,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichfelder."
|
||||||
return super().change_view(
|
return super().change_view(
|
||||||
request, object_id, form_url, extra_context=extra_context,
|
request,
|
||||||
|
object_id,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class MembersConfig(AppConfig):
|
class MembersConfig(AppConfig):
|
||||||
name = 'members'
|
name = "members"
|
||||||
|
|||||||
@@ -10,56 +10,68 @@ class MemberForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Member
|
model = Member
|
||||||
fields = [
|
fields = [
|
||||||
'firstname', 'surname', 'nickname', 'username', 'mailaccount', 'role', 'description',
|
"firstname",
|
||||||
'image', 'birthday', 'phone', 'address',
|
"surname",
|
||||||
|
"nickname",
|
||||||
|
"username",
|
||||||
|
"mailaccount",
|
||||||
|
"role",
|
||||||
|
"description",
|
||||||
|
"image",
|
||||||
|
"birthday",
|
||||||
|
"phone",
|
||||||
|
"address",
|
||||||
]
|
]
|
||||||
|
|
||||||
widgets = {
|
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
||||||
'description': CKEditorUploadingWidget(config_name='default')
|
|
||||||
}
|
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'description': _("Beschreibung zu der Person"),
|
"description": _("Beschreibung zu der Person"),
|
||||||
'image': _("Porträt"),
|
"image": _("Porträt"),
|
||||||
'birthday': _("Geburtstag"),
|
"birthday": _("Geburtstag"),
|
||||||
'phone': _("Telefonnummer"),
|
"phone": _("Telefonnummer"),
|
||||||
'address': _("Wohnadresse"),
|
"address": _("Wohnadresse"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'image': _(
|
"image": _("Mindestgröße: 150*150 px, Verwendbare Formate: ..."),
|
||||||
"Mindestgröße: 150*150 px, Verwendbare Formate: ..."
|
"mailaccount": _("Die Mailadresse mit '@fet.at' angeben."),
|
||||||
),
|
|
||||||
'mailaccount': _(
|
|
||||||
"Die Mailadresse mit '@fet.at' angeben."
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class JobForm(forms.ModelForm):
|
class JobForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Job
|
model = Job
|
||||||
fields = ['name', 'shortterm', 'slug', 'job_group',]
|
fields = [
|
||||||
|
"name",
|
||||||
|
"shortterm",
|
||||||
|
"slug",
|
||||||
|
"job_group",
|
||||||
|
]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'shortterm': _("Kürzel der Tätigkeit"),
|
"shortterm": _("Kürzel der Tätigkeit"),
|
||||||
'job_group': _("Tätigkeitsbereich"),
|
"job_group": _("Tätigkeitsbereich"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class JobGroupForm(forms.ModelForm):
|
class JobGroupForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = JobGroup
|
model = JobGroup
|
||||||
fields = ['name', 'shortterm', 'slug', 'description', 'is_pinned',]
|
fields = [
|
||||||
|
"name",
|
||||||
|
"shortterm",
|
||||||
|
"slug",
|
||||||
|
"description",
|
||||||
|
"is_pinned",
|
||||||
|
]
|
||||||
|
|
||||||
widgets = {
|
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
||||||
'description': CKEditorUploadingWidget(config_name='default')
|
|
||||||
}
|
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'shortterm': _("Kürzel des Tätigkeitsbereichs"),
|
"shortterm": _("Kürzel des Tätigkeitsbereichs"),
|
||||||
'description': _("Beschreibung des Tätigkeitsbereichs"),
|
"description": _("Beschreibung des Tätigkeitsbereichs"),
|
||||||
'is_pinned': _(
|
"is_pinned": _(
|
||||||
"Dieser Tätigkeitsbereich soll im Fachschaftsbereich angeheftet werden, damit es sofort ersichtlich ist."
|
"Dieser Tätigkeitsbereich soll im Fachschaftsbereich angeheftet werden, damit es sofort ersichtlich ist."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,15 +10,20 @@ from easy_thumbnails.fields import ThumbnailerImageField
|
|||||||
|
|
||||||
|
|
||||||
class ActiveJobMemberManager(models.Manager):
|
class ActiveJobMemberManager(models.Manager):
|
||||||
'''
|
"""
|
||||||
return a list of active member, and members who are still working
|
return a list of active member, and members who are still working
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def get_all_by_slug(self, slug):
|
def get_all_by_slug(self, slug):
|
||||||
return self.get_queryset().filter(job__job_group__slug=slug).order_by('job__slug', 'job_role', 'member__firstname')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(job__job_group__slug=slug)
|
||||||
|
.order_by("job__slug", "job_role", "member__firstname")
|
||||||
|
)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
date_today = timezone.now().date()
|
date_today = timezone.now().date()
|
||||||
qs = super().get_queryset().order_by('member__firstname')
|
qs = super().get_queryset().order_by("member__firstname")
|
||||||
|
|
||||||
return qs.filter(
|
return qs.filter(
|
||||||
Q(member__role=Member.MemberRole.ACTIVE)
|
Q(member__role=Member.MemberRole.ACTIVE)
|
||||||
@@ -27,15 +32,20 @@ class ActiveJobMemberManager(models.Manager):
|
|||||||
|
|
||||||
|
|
||||||
class InactiveJobMemberManager(models.Manager):
|
class InactiveJobMemberManager(models.Manager):
|
||||||
'''
|
"""
|
||||||
return a list of inactive member
|
return a list of inactive member
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def get_all_by_slug(self, slug):
|
def get_all_by_slug(self, slug):
|
||||||
return self.get_queryset().filter(job__job_group__slug=slug).order_by('job__slug', 'job_role', 'member__firstname')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(job__job_group__slug=slug)
|
||||||
|
.order_by("job__slug", "job_role", "member__firstname")
|
||||||
|
)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
date_today = timezone.now().date()
|
date_today = timezone.now().date()
|
||||||
qs = super().get_queryset().order_by('member__firstname')
|
qs = super().get_queryset().order_by("member__firstname")
|
||||||
|
|
||||||
return qs.filter(
|
return qs.filter(
|
||||||
Q(member__role=Member.MemberRole.PENSION)
|
Q(member__role=Member.MemberRole.PENSION)
|
||||||
@@ -45,7 +55,7 @@ class InactiveJobMemberManager(models.Manager):
|
|||||||
|
|
||||||
class JobMemberManager(models.Manager):
|
class JobMemberManager(models.Manager):
|
||||||
def get_members(self, role):
|
def get_members(self, role):
|
||||||
qs = self.get_queryset().order_by('member__firstname')
|
qs = self.get_queryset().order_by("member__firstname")
|
||||||
|
|
||||||
return qs.filter(Q(member__role=role))
|
return qs.filter(Q(member__role=role))
|
||||||
|
|
||||||
@@ -82,7 +92,7 @@ class JobGroupManager(models.Manager):
|
|||||||
|
|
||||||
class MemberManager(models.Manager):
|
class MemberManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().order_by('firstname')
|
return super().get_queryset().order_by("firstname")
|
||||||
|
|
||||||
|
|
||||||
class Member(models.Model):
|
class Member(models.Model):
|
||||||
@@ -93,8 +103,8 @@ class Member(models.Model):
|
|||||||
mailaccount = models.CharField("Mailadresse", unique=True, max_length=128)
|
mailaccount = models.CharField("Mailadresse", unique=True, max_length=128)
|
||||||
|
|
||||||
class MemberRole(models.TextChoices):
|
class MemberRole(models.TextChoices):
|
||||||
ACTIVE = 'A', _('Active')
|
ACTIVE = "A", _("Active")
|
||||||
PENSION = 'P', _('Pension')
|
PENSION = "P", _("Pension")
|
||||||
|
|
||||||
role = models.CharField(
|
role = models.CharField(
|
||||||
"Rolle",
|
"Rolle",
|
||||||
@@ -104,14 +114,16 @@ class Member(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
description = models.TextField(null=True, blank=True)
|
description = models.TextField(null=True, blank=True)
|
||||||
image = ThumbnailerImageField(upload_to='uploads/members/image/')
|
image = ThumbnailerImageField(upload_to="uploads/members/image/")
|
||||||
|
|
||||||
birthday = models.DateField(null=True, blank=True)
|
birthday = models.DateField(null=True, blank=True)
|
||||||
|
|
||||||
phone_error_msg = _((
|
phone_error_msg = _(
|
||||||
|
(
|
||||||
"Phone number must be entered in the format: +999999999'. Up to 15 digits allowed."
|
"Phone number must be entered in the format: +999999999'. Up to 15 digits allowed."
|
||||||
))
|
)
|
||||||
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message=phone_error_msg)
|
)
|
||||||
|
phone_regex = RegexValidator(regex=r"^\+?1?\d{9,15}$", message=phone_error_msg)
|
||||||
phone = models.CharField(validators=[phone_regex], max_length=17, blank=True)
|
phone = models.CharField(validators=[phone_regex], max_length=17, blank=True)
|
||||||
|
|
||||||
address = models.TextField(null=True, blank=True)
|
address = models.TextField(null=True, blank=True)
|
||||||
@@ -134,15 +146,12 @@ class Member(models.Model):
|
|||||||
if self.image.height < 150 or self.image.width < 150:
|
if self.image.height < 150 or self.image.width < 150:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
_("Das Bild ist zu klein. (Höhe: {}, Breite: {})").format(
|
_("Das Bild ist zu klein. (Höhe: {}, Breite: {})").format(
|
||||||
self.image.height,
|
self.image.height, self.image.width
|
||||||
self.image.width
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not "@fet.at" in self.mailaccount:
|
if not "@fet.at" in self.mailaccount:
|
||||||
raise ValidationError(
|
raise ValidationError(_("In der Mailadresse fehlt die Domäne."))
|
||||||
_("In der Mailadresse fehlt die Domäne.")
|
|
||||||
)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.firstname + " " + self.surname
|
return self.firstname + " " + self.surname
|
||||||
@@ -198,7 +207,7 @@ class Job(models.Model):
|
|||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.slug:
|
if not self.slug:
|
||||||
self.slug = slugify(self.shortterm)
|
self.slug = slugify(self.shortterm)
|
||||||
#if type(self.job_group) = str:
|
# if type(self.job_group) = str:
|
||||||
# self.job_group=JobGroup.objects.filter(slug=self.job)
|
# self.job_group=JobGroup.objects.filter(slug=self.job)
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
@@ -218,18 +227,20 @@ class JobMember(models.Model):
|
|||||||
verbose_name="Tätigkeit",
|
verbose_name="Tätigkeit",
|
||||||
)
|
)
|
||||||
|
|
||||||
job_start = models.DateField('Job Start')
|
job_start = models.DateField("Job Start")
|
||||||
job_end = models.DateField('Job Ende', null=True, blank=True)
|
job_end = models.DateField("Job Ende", null=True, blank=True)
|
||||||
|
|
||||||
class JobRole(models.TextChoices):
|
class JobRole(models.TextChoices):
|
||||||
PRESIDENT = ('10', _('VorsitzendeR'))
|
PRESIDENT = ("10", _("VorsitzendeR"))
|
||||||
VICE_PRESIDENT = ('20', _('stv VorsitzendeR'))
|
VICE_PRESIDENT = ("20", _("stv VorsitzendeR"))
|
||||||
SECOND_VICE_PRESIDENT = ('30', _('2. stv VorsitzendeR'))
|
SECOND_VICE_PRESIDENT = ("30", _("2. stv VorsitzendeR"))
|
||||||
PERSON_RESPONSIBLE = ('40', _('VerantwortlicheR'))
|
PERSON_RESPONSIBLE = ("40", _("VerantwortlicheR"))
|
||||||
MEMBER = ('50', _('Mitglied'))
|
MEMBER = ("50", _("Mitglied"))
|
||||||
SUBSTITUTE_MEMBER = ('60', _('Ersatzmitglied'))
|
SUBSTITUTE_MEMBER = ("60", _("Ersatzmitglied"))
|
||||||
|
|
||||||
job_role = models.CharField(max_length=2, choices=JobRole.choices, default=JobRole.MEMBER)
|
job_role = models.CharField(
|
||||||
|
max_length=2, choices=JobRole.choices, default=JobRole.MEMBER
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
members = JobMemberManager()
|
members = JobMemberManager()
|
||||||
|
|||||||
@@ -4,65 +4,50 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
|
|
||||||
class MemberSerializer(serializers.HyperlinkedModelSerializer):
|
class MemberSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Member
|
model = Member
|
||||||
fields = ['id',
|
fields = [
|
||||||
'firstname',
|
"id",
|
||||||
'surname',
|
"firstname",
|
||||||
'nickname',
|
"surname",
|
||||||
'mailaccount',
|
"nickname",
|
||||||
'role',
|
"mailaccount",
|
||||||
'description',
|
"role",
|
||||||
'image',
|
"description",
|
||||||
'birthday',
|
"image",
|
||||||
|
"birthday",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class JobGroupSerializer(serializers.HyperlinkedModelSerializer):
|
class JobGroupSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = JobGroup
|
model = JobGroup
|
||||||
fields = [
|
fields = ["id", "name", "shortterm", "slug"]
|
||||||
'id',
|
|
||||||
'name',
|
|
||||||
'shortterm',
|
|
||||||
'slug'
|
|
||||||
]
|
|
||||||
|
|
||||||
class JobSerializer(serializers.HyperlinkedModelSerializer):
|
class JobSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
#job_group = JobGroupSerializer()
|
# job_group = JobGroupSerializer()
|
||||||
job_group = serializers.SlugRelatedField(
|
job_group = serializers.SlugRelatedField(
|
||||||
slug_field='slug',queryset = JobGroup.objects
|
slug_field="slug", queryset=JobGroup.objects
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Job
|
model = Job
|
||||||
fields = [
|
fields = ["id", "name", "shortterm", "job_group", "slug"]
|
||||||
'id',
|
|
||||||
'name',
|
|
||||||
'shortterm',
|
|
||||||
'job_group',
|
|
||||||
'slug'
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class JobMemberSerializer(serializers.HyperlinkedModelSerializer):
|
class JobMemberSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
#member = MemberSerializer()
|
# member = MemberSerializer()
|
||||||
#job = JobSerializer()
|
# job = JobSerializer()
|
||||||
job = serializers.SlugRelatedField(
|
job = serializers.SlugRelatedField(slug_field="slug", queryset=Job.objects)
|
||||||
slug_field='slug',queryset = Job.objects
|
member = serializers.SlugRelatedField(
|
||||||
)
|
slug_field="mailaccount", queryset=Member.objects
|
||||||
member= serializers.SlugRelatedField(
|
|
||||||
slug_field='mailaccount',queryset = Member.objects
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = JobMember
|
model = JobMember
|
||||||
fields = [
|
fields = ["id", "job_start", "job_end", "member", "job", "job_role"]
|
||||||
'id',
|
|
||||||
'job_start',
|
|
||||||
'job_end',
|
|
||||||
'member',
|
|
||||||
'job',
|
|
||||||
'job_role'
|
|
||||||
]
|
|
||||||
|
|
||||||
# def create(self, validated_data):
|
# def create(self, validated_data):
|
||||||
# member_data = validated_data.pop('member')
|
# member_data = validated_data.pop('member')
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ from . import views
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name='members'),
|
path("", views.index, name="members"),
|
||||||
path('<str:filter>', views.members_view),
|
path("<str:filter>", views.members_view),
|
||||||
]
|
]
|
||||||
|
|
||||||
member_urlpatterns = [
|
member_urlpatterns = [
|
||||||
path('<str:member_id>', views.profile_view, name='member'),
|
path("<str:member_id>", views.profile_view, name="member"),
|
||||||
]
|
]
|
||||||
|
|
||||||
jobs_urlpatterns = [
|
jobs_urlpatterns = [
|
||||||
path('<str:slug>', views.jobs_view, name='jobs'),
|
path("<str:slug>", views.jobs_view, name="jobs"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,15 +2,12 @@ from django.http import Http404
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
|
||||||
|
|
||||||
from .models import Member, JobMember, JobGroup, Job
|
from .models import Member, JobMember, JobGroup, Job
|
||||||
from .serializers import MemberSerializer, JobSerializer, JobGroupSerializer, JobMemberSerializer
|
from posts.models import Post
|
||||||
|
|
||||||
from rest_framework import viewsets
|
|
||||||
#from rest_framework import permissions
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -45,20 +42,25 @@ def index(request):
|
|||||||
pinned_job_groups, unpinned_job_groups = __get_job_groups()
|
pinned_job_groups, unpinned_job_groups = __get_job_groups()
|
||||||
members = deque(Member.all_members.all())
|
members = deque(Member.all_members.all())
|
||||||
|
|
||||||
|
fs_info = Post.objects.filter(slug="fachschaft-info").first()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"pinned_job_groups": pinned_job_groups,
|
"pinned_job_groups": pinned_job_groups,
|
||||||
"unpinned_job_groups": unpinned_job_groups,
|
"unpinned_job_groups": unpinned_job_groups,
|
||||||
"members": members,
|
"members": members,
|
||||||
|
"fs_info": fs_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'members/index.html', context)
|
return render(request, "members/index.html", context)
|
||||||
|
|
||||||
|
|
||||||
def jobs_view(request, slug=None):
|
def jobs_view(request, slug=None):
|
||||||
pinned_job_groups, unpinned_job_groups = __get_job_groups()
|
pinned_job_groups, unpinned_job_groups = __get_job_groups()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
description = JobGroup.all_jobgroups.filter(slug=slug).values().first()['description']
|
description = (
|
||||||
|
JobGroup.all_jobgroups.filter(slug=slug).values().first()["description"]
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info("Wrong job '{}'".format(slug))
|
logger.info("Wrong job '{}'".format(slug))
|
||||||
raise Http404("wrong job")
|
raise Http404("wrong job")
|
||||||
@@ -72,7 +74,7 @@ def jobs_view(request, slug=None):
|
|||||||
"job_members": job_members,
|
"job_members": job_members,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'members/index.html', context)
|
return render(request, "members/index.html", context)
|
||||||
|
|
||||||
|
|
||||||
def members_view(request, filter=None):
|
def members_view(request, filter=None):
|
||||||
@@ -84,13 +86,16 @@ def members_view(request, filter=None):
|
|||||||
logger.info("Wrong member role '{}'".format(filter))
|
logger.info("Wrong member role '{}'".format(filter))
|
||||||
raise Http404("no member role")
|
raise Http404("no member role")
|
||||||
|
|
||||||
|
fs_info = Post.objects.filter(slug="fachschaft-info").first()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"pinned_job_groups": pinned_job_groups,
|
"pinned_job_groups": pinned_job_groups,
|
||||||
"unpinned_job_groups": unpinned_job_groups,
|
"unpinned_job_groups": unpinned_job_groups,
|
||||||
"members": members,
|
"members": members,
|
||||||
|
"fs_info": fs_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'members/index.html', context)
|
return render(request, "members/index.html", context)
|
||||||
|
|
||||||
|
|
||||||
def profile_view(request, member_id=None):
|
def profile_view(request, member_id=None):
|
||||||
@@ -110,53 +115,4 @@ def profile_view(request, member_id=None):
|
|||||||
"jobs": jobs,
|
"jobs": jobs,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'members/member.html', context)
|
return render(request, "members/member.html", context)
|
||||||
|
|
||||||
|
|
||||||
class MemberViewSet(viewsets.ModelViewSet):
|
|
||||||
"""
|
|
||||||
API endpoint that allows users to be viewed or edited.
|
|
||||||
"""
|
|
||||||
queryset = Member.all_members.order_by('nickname')
|
|
||||||
serializer_class = MemberSerializer
|
|
||||||
|
|
||||||
#permission_classes = [permissions.IsAuthenticated]
|
|
||||||
filter_backends = [DjangoFilterBackend]
|
|
||||||
filterset_fields = ['nickname','mailaccount']
|
|
||||||
# lookup_field = 'name'
|
|
||||||
|
|
||||||
def pre_save(self, obj):
|
|
||||||
obj.image = self.request.FILES.get('image')
|
|
||||||
|
|
||||||
|
|
||||||
class JobGroupViewSet(viewsets.ModelViewSet):
|
|
||||||
"""
|
|
||||||
API endpoint that allows users to be viewed or edited.
|
|
||||||
"""
|
|
||||||
queryset = JobGroup.all_jobgroups.all()
|
|
||||||
serializer_class = JobGroupSerializer
|
|
||||||
|
|
||||||
filter_backends = [DjangoFilterBackend]
|
|
||||||
filterset_fields = ['name','slug']
|
|
||||||
#lookup_field = 'name'
|
|
||||||
# lookup_field = 'name'
|
|
||||||
|
|
||||||
class JobViewSet(viewsets.ModelViewSet):
|
|
||||||
"""
|
|
||||||
API endpoint that allows users to be viewed or edited.
|
|
||||||
"""
|
|
||||||
queryset = Job.objects.all()
|
|
||||||
serializer_class = JobSerializer
|
|
||||||
filter_backends = [DjangoFilterBackend]
|
|
||||||
filterset_fields = ['name','slug']
|
|
||||||
#lookup_field = 'slug'
|
|
||||||
|
|
||||||
class JobMemberViewSet(viewsets.ModelViewSet):
|
|
||||||
"""
|
|
||||||
API endpoint that allows users to be viewed or edited.
|
|
||||||
"""
|
|
||||||
queryset = JobMember.objects.all()
|
|
||||||
serializer_class = JobMemberSerializer
|
|
||||||
filter_backends = [DjangoFilterBackend]
|
|
||||||
filterset_fields = ['member','job','job_role','job_start']
|
|
||||||
#lookup_field = 'nickname'
|
|
||||||
|
|||||||
64
fet2020/members/viewsets.py
Normal file
64
fet2020/members/viewsets.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from rest_framework import viewsets
|
||||||
|
|
||||||
|
from .models import Member, JobMember, JobGroup, Job
|
||||||
|
from .serializers import (
|
||||||
|
MemberSerializer,
|
||||||
|
JobSerializer,
|
||||||
|
JobGroupSerializer,
|
||||||
|
JobMemberSerializer,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class MemberViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
API endpoint that allows users to be viewed or edited.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queryset = Member.all_members.order_by("nickname")
|
||||||
|
serializer_class = MemberSerializer
|
||||||
|
|
||||||
|
# permission_classes = [permissions.IsAuthenticated]
|
||||||
|
filter_backends = [DjangoFilterBackend]
|
||||||
|
filterset_fields = ["nickname", "mailaccount"]
|
||||||
|
# lookup_field = 'name'
|
||||||
|
|
||||||
|
def pre_save(self, obj):
|
||||||
|
obj.image = self.request.FILES.get("image")
|
||||||
|
|
||||||
|
|
||||||
|
class JobGroupViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
API endpoint that allows users to be viewed or edited.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queryset = JobGroup.all_jobgroups.all()
|
||||||
|
serializer_class = JobGroupSerializer
|
||||||
|
|
||||||
|
filter_backends = [DjangoFilterBackend]
|
||||||
|
filterset_fields = ["name", "slug"]
|
||||||
|
# lookup_field = 'name'
|
||||||
|
|
||||||
|
|
||||||
|
class JobViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
API endpoint that allows users to be viewed or edited.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queryset = Job.objects.all()
|
||||||
|
serializer_class = JobSerializer
|
||||||
|
filter_backends = [DjangoFilterBackend]
|
||||||
|
filterset_fields = ["name", "slug"]
|
||||||
|
# lookup_field = 'slug'
|
||||||
|
|
||||||
|
|
||||||
|
class JobMemberViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
API endpoint that allows users to be viewed or edited.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queryset = JobMember.objects.all()
|
||||||
|
serializer_class = JobMemberSerializer
|
||||||
|
filter_backends = [DjangoFilterBackend]
|
||||||
|
filterset_fields = ["member", "job", "job_role", "job_start"]
|
||||||
|
# lookup_field = 'nickname'
|
||||||
@@ -13,7 +13,7 @@ admin.site.unregister(taggit.models.Tag)
|
|||||||
|
|
||||||
|
|
||||||
def make_fetmeeting(self, request, queryset):
|
def make_fetmeeting(self, request, queryset):
|
||||||
qs = self.get_queryset(request).filter(id=request.POST['_selected_action']).first()
|
qs = self.get_queryset(request).filter(id=request.POST["_selected_action"]).first()
|
||||||
|
|
||||||
failed = False
|
failed = False
|
||||||
agenda_key = None
|
agenda_key = None
|
||||||
@@ -24,7 +24,7 @@ def make_fetmeeting(self, request, queryset):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
_('Das Agenda konnte nicht erstellt werden. Error: %s') % str(e),
|
_("Das Agenda konnte nicht erstellt werden. Error: %s") % str(e),
|
||||||
messages.ERROR,
|
messages.ERROR,
|
||||||
)
|
)
|
||||||
failed = True
|
failed = True
|
||||||
@@ -34,14 +34,14 @@ def make_fetmeeting(self, request, queryset):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
_('Das Protokoll konnte nicht erstellt werden. Error: %s') % str(e),
|
_("Das Protokoll konnte nicht erstellt werden. Error: %s") % str(e),
|
||||||
messages.ERROR,
|
messages.ERROR,
|
||||||
)
|
)
|
||||||
failed = True
|
failed = True
|
||||||
|
|
||||||
if not failed:
|
if not failed:
|
||||||
queryset.update(
|
queryset.update(
|
||||||
post_type='F',
|
post_type="F",
|
||||||
has_agenda=True,
|
has_agenda=True,
|
||||||
has_protocol=True,
|
has_protocol=True,
|
||||||
agenda_key=agenda_key,
|
agenda_key=agenda_key,
|
||||||
@@ -49,7 +49,8 @@ def make_fetmeeting(self, request, queryset):
|
|||||||
)
|
)
|
||||||
self.message_user(
|
self.message_user(
|
||||||
request,
|
request,
|
||||||
_('Das Event %s wurde erfolgreich in eine FET Sitzung konvertiert.') % (qs.title),
|
_("Das Event %s wurde erfolgreich in eine FET Sitzung konvertiert.")
|
||||||
|
% (qs.title),
|
||||||
messages.SUCCESS,
|
messages.SUCCESS,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,22 +61,27 @@ make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
|
|||||||
class PostAdmin(admin.ModelAdmin):
|
class PostAdmin(admin.ModelAdmin):
|
||||||
form = PostForm
|
form = PostForm
|
||||||
model = Post
|
model = Post
|
||||||
list_filter = ['is_pinned', 'is_hidden']
|
list_filter = ["is_pinned", "is_hidden"]
|
||||||
list_display = ['title', 'slug', 'public_date', 'is_pinned', 'is_hidden']
|
list_display = ["title", "slug", "public_date", "is_pinned", "is_hidden"]
|
||||||
ordering = ['is_hidden', '-public_date']
|
ordering = ["is_hidden", "-public_date"]
|
||||||
|
|
||||||
def add_view(self, request, form_url='', extra_context=None):
|
def add_view(self, request, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||||
return super().add_view(
|
return super().add_view(
|
||||||
request, form_url, extra_context=extra_context,
|
request,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
||||||
extra_context = extra_context or {}
|
extra_context = extra_context or {}
|
||||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||||
return super().change_view(
|
return super().change_view(
|
||||||
request, object_id, form_url, extra_context=extra_context,
|
request,
|
||||||
|
object_id,
|
||||||
|
form_url,
|
||||||
|
extra_context=extra_context,
|
||||||
)
|
)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
@@ -98,9 +104,9 @@ class PostAdmin(admin.ModelAdmin):
|
|||||||
class EventAdmin(PostAdmin):
|
class EventAdmin(PostAdmin):
|
||||||
form = EventForm
|
form = EventForm
|
||||||
model = Event
|
model = Event
|
||||||
list_filter = ['is_pinned']
|
list_filter = ["is_pinned"]
|
||||||
list_display = ['title', 'slug', 'event_start', 'public_date', 'is_pinned']
|
list_display = ["title", "slug", "event_start", "public_date", "is_pinned"]
|
||||||
ordering = ['-event_start']
|
ordering = ["-event_start"]
|
||||||
actions = [make_fetmeeting]
|
actions = [make_fetmeeting]
|
||||||
|
|
||||||
|
|
||||||
@@ -113,7 +119,7 @@ class FetMeetingAdmin(EventAdmin):
|
|||||||
form = FetMeetingForm
|
form = FetMeetingForm
|
||||||
model = FetMeeting
|
model = FetMeeting
|
||||||
list_filter = []
|
list_filter = []
|
||||||
list_display = ['title', 'slug', 'event_start', 'public_date']
|
list_display = ["title", "slug", "event_start", "public_date"]
|
||||||
actions = []
|
actions = []
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class PostsConfig(AppConfig):
|
class PostsConfig(AppConfig):
|
||||||
name = 'posts'
|
name = "posts"
|
||||||
|
|||||||
@@ -10,14 +10,23 @@ from .models import Post, Event, News, FetMeeting
|
|||||||
class PostForm(forms.ModelForm):
|
class PostForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Post
|
model = Post
|
||||||
fields = ['title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date']
|
fields = [
|
||||||
|
"title",
|
||||||
|
"subtitle",
|
||||||
|
"tags",
|
||||||
|
"image",
|
||||||
|
"body",
|
||||||
|
"slug",
|
||||||
|
"author",
|
||||||
|
"public_date",
|
||||||
|
]
|
||||||
|
|
||||||
widgets = {'body': CKEditorUploadingWidget(config_name='default')}
|
widgets = {"body": CKEditorUploadingWidget(config_name="default")}
|
||||||
|
|
||||||
class Media:
|
class Media:
|
||||||
js = (
|
js = (
|
||||||
'js/auto_slug.js', # automatic slag completion via ajax
|
"js/auto_slug.js", # automatic slag completion via ajax
|
||||||
'js/tag_completion.js', # to get a list for tag autocompletion via ajax
|
"js/tag_completion.js", # to get a list for tag autocompletion via ajax
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -25,106 +34,124 @@ class NewsForm(PostForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = News
|
model = News
|
||||||
fields = [
|
fields = [
|
||||||
'title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date',
|
"title",
|
||||||
'is_pinned', 'is_hidden',
|
"subtitle",
|
||||||
|
"tags",
|
||||||
|
"image",
|
||||||
|
"body",
|
||||||
|
"slug",
|
||||||
|
"author",
|
||||||
|
"public_date",
|
||||||
|
"is_pinned",
|
||||||
|
"is_hidden",
|
||||||
]
|
]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'title': _("Titel"),
|
"title": _("Titel"),
|
||||||
'subtitle': _("Untertitel"),
|
"subtitle": _("Untertitel"),
|
||||||
'image': _("Hintergrundbild"),
|
"image": _("Hintergrundbild"),
|
||||||
'body': _("Text"),
|
"body": _("Text"),
|
||||||
'author': _("Autor"),
|
"author": _("Autor"),
|
||||||
'public_date': _("Veröffentlichung"),
|
"public_date": _("Veröffentlichung"),
|
||||||
'is_pinned': _("Post anheften"),
|
"is_pinned": _("Post anheften"),
|
||||||
'is_hidden': _("Post verstecken"),
|
"is_hidden": _("Post verstecken"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'tags': _(
|
"tags": _(
|
||||||
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
),
|
),
|
||||||
'image': _(
|
"image": _("Verwendbare Formate: ..."),
|
||||||
"Verwendbare Formate: ..."
|
"is_pinned": _(
|
||||||
),
|
|
||||||
'is_pinned': _(
|
|
||||||
"Dieser Post soll an die Startseite als erster Post angeheftet werden."
|
"Dieser Post soll an die Startseite als erster Post angeheftet werden."
|
||||||
),
|
),
|
||||||
'is_hidden': _(
|
"is_hidden": _(
|
||||||
"Dieser Post soll im News Feed nicht auftauchen, z.B. Impressum."
|
"Dieser Post soll im News Feed nicht auftauchen, z.B. Impressum."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
widgets = {'body': CKEditorUploadingWidget(config_name='default')}
|
widgets = {"body": CKEditorUploadingWidget(config_name="default")}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
self.fields['author'].queryset = self.fields['author'].queryset.order_by('username')
|
self.fields["author"].queryset = self.fields["author"].queryset.order_by(
|
||||||
|
"username"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventForm(PostForm):
|
class EventForm(PostForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Event
|
model = Event
|
||||||
fields = [
|
fields = [
|
||||||
'title', 'subtitle', 'tags', 'image', 'body', 'event_start', 'event_end',
|
"title",
|
||||||
'event_place', 'slug', 'author', 'public_date', 'is_pinned',
|
"subtitle",
|
||||||
|
"tags",
|
||||||
|
"image",
|
||||||
|
"body",
|
||||||
|
"event_start",
|
||||||
|
"event_end",
|
||||||
|
"event_place",
|
||||||
|
"slug",
|
||||||
|
"author",
|
||||||
|
"public_date",
|
||||||
|
"is_pinned",
|
||||||
]
|
]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'title': _("Titel"),
|
"title": _("Titel"),
|
||||||
'subtitle': _("Untertitel"),
|
"subtitle": _("Untertitel"),
|
||||||
'image': _("Hintergrundbild"),
|
"image": _("Hintergrundbild"),
|
||||||
'body': _("Text"),
|
"body": _("Text"),
|
||||||
'event_start': _("Start des Events"),
|
"event_start": _("Start des Events"),
|
||||||
'event_end': _("Ende des Events"),
|
"event_end": _("Ende des Events"),
|
||||||
'event_place': _("Ort des Events"),
|
"event_place": _("Ort des Events"),
|
||||||
'author': _("Autor"),
|
"author": _("Autor"),
|
||||||
'public_date': _("Veröffentlichung"),
|
"public_date": _("Veröffentlichung"),
|
||||||
'is_pinned': _("Event anheften"),
|
"is_pinned": _("Event anheften"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'tags': _(
|
"tags": _(
|
||||||
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
),
|
),
|
||||||
'image': _(
|
"image": _("Verwendbare Formate: "),
|
||||||
"Verwendbare Formate: "
|
"is_pinned": _(
|
||||||
),
|
|
||||||
'is_pinned': _(
|
|
||||||
"Dieses Event soll an die Startseite als erster Post angeheftet werden."
|
"Dieses Event soll an die Startseite als erster Post angeheftet werden."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
widgets = {'body': CKEditorUploadingWidget(config_name='default')}
|
widgets = {"body": CKEditorUploadingWidget(config_name="default")}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
self.fields['author'].queryset = self.fields['author'].queryset.order_by('username')
|
self.fields["author"].queryset = self.fields["author"].queryset.order_by(
|
||||||
|
"username"
|
||||||
|
)
|
||||||
|
|
||||||
self.fields['event_start'].required = True
|
self.fields["event_start"].required = True
|
||||||
self.fields['event_end'].required = False
|
self.fields["event_end"].required = False
|
||||||
|
|
||||||
if 'event_place' in self.fields:
|
if "event_place" in self.fields:
|
||||||
self.fields['event_place'].required = True
|
self.fields["event_place"].required = True
|
||||||
|
|
||||||
|
|
||||||
class FetMeetingForm(PostForm):
|
class FetMeetingForm(PostForm):
|
||||||
# agenda_html = forms.CharField(widget = forms.TextInput())
|
# agenda_html = forms.CharField(widget = forms.TextInput())
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FetMeeting
|
model = FetMeeting
|
||||||
fields = ['event_start', 'event_end', 'tags']#, 'has_agenda', 'has_protocol']
|
fields = ["event_start", "event_end", "tags"] # , 'has_agenda', 'has_protocol']
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'event_start': _("Start der Sitzung"),
|
"event_start": _("Start der Sitzung"),
|
||||||
'event_end': _("Ende der Sitzung")#,
|
"event_end": _("Ende der Sitzung") # ,
|
||||||
# 'has_agenda': _("Agenda"),
|
# 'has_agenda': _("Agenda"),
|
||||||
# 'has_protocol': _("Protokoll"),
|
# 'has_protocol': _("Protokoll"),
|
||||||
}
|
}
|
||||||
|
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'tags': _(
|
"tags": _(
|
||||||
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||||
)#,
|
) # ,
|
||||||
#'has_agenda': _("Agenda zur Sitzung hinzufügen."),
|
#'has_agenda': _("Agenda zur Sitzung hinzufügen."),
|
||||||
#'has_protocol': _("Protokoll zur Sitzung hinzufügen."),
|
#'has_protocol': _("Protokoll zur Sitzung hinzufügen."),
|
||||||
}
|
}
|
||||||
@@ -132,13 +159,13 @@ class FetMeetingForm(PostForm):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
|
|
||||||
self.fields['event_start'].required = True
|
self.fields["event_start"].required = True
|
||||||
self.fields['event_end'].required = False
|
self.fields["event_end"].required = False
|
||||||
|
|
||||||
#self.fields['has_agenda'].initial = True
|
# self.fields['has_agenda'].initial = True
|
||||||
#self.fields['has_protocol'].initial = True
|
# self.fields['has_protocol'].initial = True
|
||||||
|
|
||||||
tags = []
|
tags = []
|
||||||
tags.append(Tag())
|
tags.append(Tag())
|
||||||
tags[0].name = "fachschaft"
|
tags[0].name = "fachschaft"
|
||||||
self.fields['tags'].initial = tags
|
self.fields["tags"].initial = tags
|
||||||
|
|||||||
@@ -3,15 +3,22 @@ from django.core.mail import send_mail
|
|||||||
|
|
||||||
|
|
||||||
def send_agenda_mail(date, time, slug):
|
def send_agenda_mail(date, time, slug):
|
||||||
msg = "Liebe Alle,\n\n" \
|
msg = (
|
||||||
"wir haben am " + str(date) + " um " + str(time) + " wieder Sitzung.\n" \
|
"Liebe Alle,\n\n"
|
||||||
"du hast noch bis morgen Zeit, weitere Themen auf die Agenda zu schreiben: " \
|
"wir haben am " + str(date) + " um " + str(time) + " wieder Sitzung.\n"
|
||||||
+ settings.HOST_NAME + '/posts/' + str(slug) + ".\n\n" \
|
"du hast noch bis morgen Zeit, weitere Themen auf die Agenda zu schreiben: "
|
||||||
|
+ settings.HOST_NAME
|
||||||
|
+ "/posts/"
|
||||||
|
+ str(slug)
|
||||||
|
+ ".\n\n"
|
||||||
"LG deine FET"
|
"LG deine FET"
|
||||||
|
)
|
||||||
|
|
||||||
send_mail(
|
send_mail(
|
||||||
subject = 'Test - Agenda der FET Sitzung von ' + str(date),
|
subject="Test - Agenda der FET Sitzung von " + str(date),
|
||||||
message = msg,
|
message=msg,
|
||||||
from_email = 'patrick@fet.at',
|
from_email="patrick@fet.at",
|
||||||
recipient_list = ['all@fet.at', ],
|
recipient_list=[
|
||||||
|
"all@fet.at",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,23 +5,32 @@ from django.utils import timezone
|
|||||||
|
|
||||||
class PostManager(models.Manager):
|
class PostManager(models.Manager):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().order_by('-public_date')
|
return super().get_queryset().order_by("-public_date")
|
||||||
|
|
||||||
def get_visible_articles(self):
|
def get_visible_articles(self):
|
||||||
return self.get_queryset().filter(is_hidden=False)
|
return self.get_queryset().filter(is_hidden=False)
|
||||||
|
|
||||||
def all_post_with_date(self):
|
def all_post_with_date(self):
|
||||||
return self.get_queryset().filter(Q(event_start__isnull=False) & Q(event_end__isnull=False)).order_by('-event_start')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(Q(event_start__isnull=False) & Q(event_end__isnull=False))
|
||||||
|
.order_by("-event_start")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ArticleManager(models.Manager):
|
class ArticleManager(models.Manager):
|
||||||
"""
|
"""
|
||||||
Provide a query set only for "Article"
|
Provide a query set only for "Article"
|
||||||
regular fet meetings should not be contained in the news stream
|
regular fet meetings should not be contained in the news stream
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().filter(
|
return (
|
||||||
Q(post_type='E')
|
super()
|
||||||
| Q(post_type='N')
|
.get_queryset()
|
||||||
).order_by('-public_date')
|
.filter(Q(post_type="E") | Q(post_type="N"))
|
||||||
|
.order_by("-public_date")
|
||||||
|
)
|
||||||
|
|
||||||
def get_visible_articles(self):
|
def get_visible_articles(self):
|
||||||
return self.get_queryset().filter(is_hidden=False)
|
return self.get_queryset().filter(is_hidden=False)
|
||||||
@@ -34,8 +43,9 @@ class NewsManager(models.Manager):
|
|||||||
"""
|
"""
|
||||||
Provide a query set only for "News"
|
Provide a query set only for "News"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().filter(post_type='N').order_by('-public_date')
|
return super().get_queryset().filter(post_type="N").order_by("-public_date")
|
||||||
|
|
||||||
def get_visible_articles(self):
|
def get_visible_articles(self):
|
||||||
return self.get_queryset().filter(is_hidden=False)
|
return self.get_queryset().filter(is_hidden=False)
|
||||||
@@ -45,12 +55,17 @@ class AllEventManager(models.Manager):
|
|||||||
"""
|
"""
|
||||||
Provide a query set for all events ("Event" and "Fet Meeting")
|
Provide a query set for all events ("Event" and "Fet Meeting")
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().filter(Q(post_type='E') | Q(post_type='F'))
|
return super().get_queryset().filter(Q(post_type="E") | Q(post_type="F"))
|
||||||
|
|
||||||
def get_five_events(self):
|
def get_five_events(self):
|
||||||
date_today = timezone.now()
|
date_today = timezone.now()
|
||||||
return self.get_queryset().filter(event_start__gt=date_today).order_by('event_start')[:5]
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(event_start__gt=date_today)
|
||||||
|
.order_by("event_start")[:5]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventManager(models.Manager):
|
class EventManager(models.Manager):
|
||||||
@@ -58,32 +73,50 @@ class EventManager(models.Manager):
|
|||||||
Provide a query set only for "Events"
|
Provide a query set only for "Events"
|
||||||
regular fet meetings should not be contained in the news stream
|
regular fet meetings should not be contained in the news stream
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().filter(post_type='E')
|
return super().get_queryset().filter(post_type="E")
|
||||||
|
|
||||||
def get_future_events(self):
|
def get_future_events(self):
|
||||||
date_today = timezone.now()
|
date_today = timezone.now()
|
||||||
return self.get_queryset().filter(event_start__gt=date_today).order_by('event_start')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(event_start__gt=date_today)
|
||||||
|
.order_by("event_start")
|
||||||
|
)
|
||||||
|
|
||||||
def get_past_events(self):
|
def get_past_events(self):
|
||||||
date_today = timezone.now()
|
date_today = timezone.now()
|
||||||
return self.get_queryset().filter(event_start__lt=date_today).order_by('-event_start')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(event_start__lt=date_today)
|
||||||
|
.order_by("-event_start")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FetMeetingManager(models.Manager):
|
class FetMeetingManager(models.Manager):
|
||||||
"""
|
"""
|
||||||
Provide a query set only for "Fet Meeting"
|
Provide a query set only for "Fet Meeting"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return super().get_queryset().filter(post_type='F')
|
return super().get_queryset().filter(post_type="F")
|
||||||
|
|
||||||
def _get_future_events(self):
|
def _get_future_events(self):
|
||||||
date_today = timezone.now()
|
date_today = timezone.now()
|
||||||
return self.get_queryset().filter(event_start__gt=date_today).order_by('event_start')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(event_start__gt=date_today)
|
||||||
|
.order_by("event_start")
|
||||||
|
)
|
||||||
|
|
||||||
def _get_past_events(self):
|
def _get_past_events(self):
|
||||||
date_today = timezone.now()
|
date_today = timezone.now()
|
||||||
return self.get_queryset().filter(event_start__lt=date_today).order_by('-event_start')
|
return (
|
||||||
|
self.get_queryset()
|
||||||
|
.filter(event_start__lt=date_today)
|
||||||
|
.order_by("-event_start")
|
||||||
|
)
|
||||||
|
|
||||||
def get_meetings(self):
|
def get_meetings(self):
|
||||||
meetings = []
|
meetings = []
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ class Post(models.Model):
|
|||||||
)
|
)
|
||||||
html = None
|
html = None
|
||||||
return html
|
return html
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def protocol_html(self):
|
def protocol_html(self):
|
||||||
"Protocol HTML from Etherpad Pad"
|
"Protocol HTML from Etherpad Pad"
|
||||||
@@ -255,9 +256,10 @@ class Post(models.Model):
|
|||||||
def clean(self):
|
def clean(self):
|
||||||
if self.event_end and self.event_end < self.event_start:
|
if self.event_end and self.event_end < self.event_start:
|
||||||
raise ValidationError(_("Das Ende des Events liegt vor dem Beginn."))
|
raise ValidationError(_("Das Ende des Events liegt vor dem Beginn."))
|
||||||
if self.event_start and self.post_type not in ['E','F']:
|
if self.event_start and self.post_type not in ["E", "F"]:
|
||||||
raise ValidationError("Für diesen Post Typ ist kein Event Start zulässig")
|
raise ValidationError("Für diesen Post Typ ist kein Event Start zulässig")
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
# save the post with some defaults
|
# save the post with some defaults
|
||||||
if not self.public_date:
|
if not self.public_date:
|
||||||
@@ -307,9 +309,9 @@ class Event(Post):
|
|||||||
verbose_name = "Event"
|
verbose_name = "Event"
|
||||||
verbose_name_plural = "Events"
|
verbose_name_plural = "Events"
|
||||||
|
|
||||||
def __init__(self,*args,**kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args,**kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.post_type='E'
|
self.post_type = "E"
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
if not self.event_start:
|
if not self.event_start:
|
||||||
@@ -334,9 +336,9 @@ class FetMeeting(Event):
|
|||||||
verbose_name = "Fet Sitzung"
|
verbose_name = "Fet Sitzung"
|
||||||
verbose_name_plural = "Fet Sitzungen"
|
verbose_name_plural = "Fet Sitzungen"
|
||||||
|
|
||||||
def __init__(self,*args,**kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args,**kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.post_type='F'
|
self.post_type = "F"
|
||||||
|
|
||||||
def __get_slug(self):
|
def __get_slug(self):
|
||||||
slug = slugify(self.event_start.date()) + "-" + slugify("Fachschaftssitzung")
|
slug = slugify(self.event_start.date()) + "-" + slugify("Fachschaftssitzung")
|
||||||
@@ -349,34 +351,33 @@ class FetMeeting(Event):
|
|||||||
|
|
||||||
return slug
|
return slug
|
||||||
|
|
||||||
# def __get_agenda_key(self):
|
# def __get_agenda_key(self):
|
||||||
# if not self.slug:
|
# if not self.slug:
|
||||||
# return None##
|
# return None##
|
||||||
#
|
#
|
||||||
# try:
|
# try:
|
||||||
# agenda_key = createPadifNotExists(self.slug + "-agenda")
|
# agenda_key = createPadifNotExists(self.slug + "-agenda")
|
||||||
# except Exception as error:
|
# except Exception as error:
|
||||||
# raise ValidationError(
|
# raise ValidationError(
|
||||||
# _("Die Agenda konnte nicht erstellt werden. Error: %(error)s"),
|
# _("Die Agenda konnte nicht erstellt werden. Error: %(error)s"),
|
||||||
# params={"error": str(error)},
|
# params={"error": str(error)},
|
||||||
# ) from error
|
# ) from error
|
||||||
#
|
#
|
||||||
# return agenda_key
|
# return agenda_key
|
||||||
|
|
||||||
# def __get_protocol_key(self):
|
|
||||||
# if not self.slug:
|
|
||||||
# return None#
|
|
||||||
#
|
|
||||||
# try:
|
|
||||||
# protocol_key = createPadifNotExists(self.slug + "-protocol")
|
|
||||||
# except URLError as error:
|
|
||||||
# raise ValidationError(
|
|
||||||
# _("Das Protokoll konnte nicht erstellt werden. Error: %(error)s"),
|
|
||||||
# params={"error": str(error)},
|
|
||||||
# ) from error#
|
|
||||||
#
|
|
||||||
# return protocol_key
|
|
||||||
|
|
||||||
|
# def __get_protocol_key(self):
|
||||||
|
# if not self.slug:
|
||||||
|
# return None#
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# protocol_key = createPadifNotExists(self.slug + "-protocol")
|
||||||
|
# except URLError as error:
|
||||||
|
# raise ValidationError(
|
||||||
|
# _("Das Protokoll konnte nicht erstellt werden. Error: %(error)s"),
|
||||||
|
# params={"error": str(error)},
|
||||||
|
# ) from error#
|
||||||
|
#
|
||||||
|
# return protocol_key
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|||||||
@@ -5,33 +5,34 @@ from rest_framework import serializers
|
|||||||
|
|
||||||
class PostSerializer(serializers.HyperlinkedModelSerializer):
|
class PostSerializer(serializers.HyperlinkedModelSerializer):
|
||||||
agenda_html = serializers.CharField(required=False)
|
agenda_html = serializers.CharField(required=False)
|
||||||
tag_string = serializers.CharField(required=False,read_only=True)
|
tag_string = serializers.CharField(required=False, read_only=True)
|
||||||
imageurl = serializers.CharField(required=False,read_only=True)
|
imageurl = serializers.CharField(required=False, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Post
|
model = Post
|
||||||
fields = [
|
fields = [
|
||||||
'slug',
|
"slug",
|
||||||
'title',
|
"title",
|
||||||
'subtitle',
|
"subtitle",
|
||||||
'body',
|
"body",
|
||||||
'url',
|
"url",
|
||||||
'post_type',
|
"post_type",
|
||||||
'public_date',
|
"public_date",
|
||||||
'legacy_id',
|
"legacy_id",
|
||||||
'image',
|
"image",
|
||||||
'event_start',
|
"event_start",
|
||||||
'event_end',
|
"event_end",
|
||||||
'is_hidden',
|
"is_hidden",
|
||||||
'agenda_html',
|
"agenda_html",
|
||||||
'protocol_html',
|
"protocol_html",
|
||||||
'has_agenda',
|
"has_agenda",
|
||||||
'has_protocol',
|
"has_protocol",
|
||||||
'tag_string',
|
"tag_string",
|
||||||
'imageurl'
|
"imageurl"
|
||||||
# 'author',
|
# 'author',
|
||||||
]
|
]
|
||||||
|
|
||||||
extra_kwargs={
|
extra_kwargs = {
|
||||||
'agenda_html': {"required": False},
|
"agenda_html": {"required": False},
|
||||||
'protocol_html': {"required": False}
|
"protocol_html": {"required": False},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ from . import views
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('func/tag_complete', views.tag_complete),
|
path("func/tag_complete", views.tag_complete),
|
||||||
path('func/slug_calc', views.slug_calc),
|
path("func/slug_calc", views.slug_calc),
|
||||||
path('t/<str:tag>', views.tags, name='posts.tags'),
|
path("t/<str:tag>", views.tags, name="posts.tags"),
|
||||||
path('', views.index, name='posts.index'),
|
path("", views.index, name="posts.index"),
|
||||||
path('fet_calendar.ics', views.calendar, name='posts.calendar'),
|
path("fet_calendar.ics", views.calendar, name="posts.calendar"),
|
||||||
path('<str:id>', views.show, name='posts.show'),
|
path("<str:id>", views.show, name="posts.show"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
from collections import deque
|
from collections import deque
|
||||||
import logging
|
import logging
|
||||||
from rest_framework import viewsets
|
|
||||||
from taggit.models import Tag
|
from taggit.models import Tag
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.http import HttpResponse, JsonResponse, HttpResponseServerError
|
from django.http import HttpResponse, JsonResponse, HttpResponseServerError
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
|
||||||
|
|
||||||
from documents.api import get_pad_link
|
from documents.api import get_pad_link
|
||||||
from documents.etherpadlib import add_ep_cookie
|
from documents.etherpadlib import add_ep_cookie
|
||||||
@@ -15,7 +13,8 @@ from members.models import Member, JobMember
|
|||||||
|
|
||||||
|
|
||||||
from .models import Post, FetMeeting
|
from .models import Post, FetMeeting
|
||||||
from .serializers import PostSerializer
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ def index(request):
|
|||||||
"Index von aktuellen Posts"
|
"Index von aktuellen Posts"
|
||||||
posts = deque(Post.objects.get_visible_articles().order_by("-public_date"))
|
posts = deque(Post.objects.get_visible_articles().order_by("-public_date"))
|
||||||
|
|
||||||
taglist = map(lambda post : post.tags, posts)
|
taglist = map(lambda post: post.tags, posts)
|
||||||
|
|
||||||
return render(request, "posts/index.html", {"posts": posts, "tags_list": taglist})
|
return render(request, "posts/index.html", {"posts": posts, "tags_list": taglist})
|
||||||
|
|
||||||
@@ -49,7 +48,6 @@ def tags(request, tag=""):
|
|||||||
posts = deque(Post.objects.get_visible_articles().filter(tags__name=tag))
|
posts = deque(Post.objects.get_visible_articles().filter(tags__name=tag))
|
||||||
featured_post = Post.objects.get_visible_articles().filter(slug=tag).first()
|
featured_post = Post.objects.get_visible_articles().filter(slug=tag).first()
|
||||||
|
|
||||||
|
|
||||||
job_members = JobMember.active_member.get_all_by_slug(slug=tag)
|
job_members = JobMember.active_member.get_all_by_slug(slug=tag)
|
||||||
|
|
||||||
author_image = None
|
author_image = None
|
||||||
@@ -87,25 +85,21 @@ def show(request, id=None):
|
|||||||
ep_agenda_link = "#"
|
ep_agenda_link = "#"
|
||||||
ep_protocol_link = "#"
|
ep_protocol_link = "#"
|
||||||
|
|
||||||
if p.has_agenda:# and p.agenda_key:
|
if p.has_agenda: # and p.agenda_key:
|
||||||
try:
|
try:
|
||||||
ep_agenda_link = get_pad_link(p.agenda_key)
|
ep_agenda_link = get_pad_link(p.agenda_key)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Can't get the agenda link from '%s'. Error: %s",
|
"Can't get the agenda link from '%s'. Error: %s", p.agenda_key, e
|
||||||
p.agenda_key,
|
|
||||||
e
|
|
||||||
)
|
)
|
||||||
ep_agenda_link = "#"
|
ep_agenda_link = "#"
|
||||||
|
|
||||||
if p.has_protocol:# and p.protocol_key:
|
if p.has_protocol: # and p.protocol_key:
|
||||||
try:
|
try:
|
||||||
ep_protocol_link = get_pad_link(p.protocol_key)
|
ep_protocol_link = get_pad_link(p.protocol_key)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(
|
logger.error(
|
||||||
"Can't get the protocol link from '%s. Error: %s",
|
"Can't get the protocol link from '%s. Error: %s", p.protocol_key, e
|
||||||
p.protocol_key, e
|
|
||||||
|
|
||||||
)
|
)
|
||||||
ep_protocol_link = "#"
|
ep_protocol_link = "#"
|
||||||
|
|
||||||
@@ -126,8 +120,7 @@ def show(request, id=None):
|
|||||||
try:
|
try:
|
||||||
response = add_ep_cookie(request, response)
|
response = add_ep_cookie(request, response)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(
|
logger.info("Etherpad Server doesn't work. Error: %s", e)
|
||||||
"Etherpad Server doesn't work. Error: %s", e)
|
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@@ -196,19 +189,3 @@ def get_next_dict(post=None):
|
|||||||
break
|
break
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
class PostViewSet(viewsets.ModelViewSet):
|
|
||||||
"""
|
|
||||||
API endpoint that allows users to be viewed or edited.
|
|
||||||
"""
|
|
||||||
|
|
||||||
queryset = Post.objects.all().order_by("-public_date")
|
|
||||||
serializer_class = PostSerializer
|
|
||||||
# permission_classes = [permissions.IsAuthenticated]
|
|
||||||
filter_backends = [DjangoFilterBackend]
|
|
||||||
filterset_fields = ["legacy_id", "slug", "legacy_rubrik_id"]
|
|
||||||
lookup_field = "slug"
|
|
||||||
|
|
||||||
def pre_save(self, obj):
|
|
||||||
obj.image = self.request.FILES.get("image")
|
|
||||||
|
|||||||
21
fet2020/posts/viewsets.py
Normal file
21
fet2020/posts/viewsets.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
|
from rest_framework import viewsets
|
||||||
|
|
||||||
|
from .models import Post, FetMeeting
|
||||||
|
from .serializers import PostSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class PostViewSet(viewsets.ModelViewSet):
|
||||||
|
"""
|
||||||
|
API endpoint that allows users to be viewed or edited.
|
||||||
|
"""
|
||||||
|
|
||||||
|
queryset = Post.objects.all().order_by("-public_date")
|
||||||
|
serializer_class = PostSerializer
|
||||||
|
# permission_classes = [permissions.IsAuthenticated]
|
||||||
|
filter_backends = [DjangoFilterBackend]
|
||||||
|
filterset_fields = ["legacy_id", "slug", "legacy_rubrik_id"]
|
||||||
|
lookup_field = "slug"
|
||||||
|
|
||||||
|
def pre_save(self, obj):
|
||||||
|
obj.image = self.request.FILES.get("image")
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
django==3.1.4
|
django==3.1.5
|
||||||
django-ckeditor==6.0.0
|
django-ckeditor==6.0.0
|
||||||
django-crontab==0.7.1
|
django-crontab==0.7.1
|
||||||
django-environ==0.4.5
|
django-environ==0.4.5
|
||||||
|
|||||||
18
fet2020/static/fet.css
Normal file
18
fet2020/static/fet.css
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
body {
|
||||||
|
min-height:100%;
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
img.logo {
|
||||||
|
height:40px;
|
||||||
|
width:40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.footer {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.footer a i {
|
||||||
|
font-size:30px;
|
||||||
|
}
|
||||||
@@ -8,23 +8,33 @@ class TaskAdmin(admin.ModelAdmin):
|
|||||||
form = TaskAdminForm
|
form = TaskAdminForm
|
||||||
model = Task
|
model = Task
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, {
|
(
|
||||||
'fields': (
|
None,
|
||||||
'title',
|
{
|
||||||
'task_list',
|
"fields": (
|
||||||
'assigned_to',
|
"title",
|
||||||
'due_date',
|
"task_list",
|
||||||
'completed',
|
"assigned_to",
|
||||||
'completed_date',
|
"due_date",
|
||||||
'note',
|
"completed",
|
||||||
'priority',
|
"completed_date",
|
||||||
|
"note",
|
||||||
|
"priority",
|
||||||
)
|
)
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
list_display = ['title', 'task_list', 'assigned_to', 'due_date', 'completed', 'priority']
|
list_display = [
|
||||||
list_filter = ('task_list', )
|
"title",
|
||||||
search_fields = ('title', )
|
"task_list",
|
||||||
|
"assigned_to",
|
||||||
|
"due_date",
|
||||||
|
"completed",
|
||||||
|
"priority",
|
||||||
|
]
|
||||||
|
list_filter = ("task_list",)
|
||||||
|
search_fields = ("title",)
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
obj.created_by = request.user
|
obj.created_by = request.user
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
|||||||
|
|
||||||
|
|
||||||
class TasksConfig(AppConfig):
|
class TasksConfig(AppConfig):
|
||||||
name = 'tasks'
|
name = "tasks"
|
||||||
|
|||||||
@@ -7,29 +7,31 @@ from .models import Task, TaskList
|
|||||||
|
|
||||||
|
|
||||||
class DateInput(forms.DateInput):
|
class DateInput(forms.DateInput):
|
||||||
input_type = 'date'
|
input_type = "date"
|
||||||
|
|
||||||
|
|
||||||
class TaskAdminForm(forms.ModelForm):
|
class TaskAdminForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Task
|
model = Task
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'title': _('Titel'),
|
"title": _("Titel"),
|
||||||
'task_list': _('Aufgabenbereich'),
|
"task_list": _("Aufgabenbereich"),
|
||||||
'due_date': _('Fälligkeit'),
|
"due_date": _("Fälligkeit"),
|
||||||
'completed': _('Abgeschlossen'),
|
"completed": _("Abgeschlossen"),
|
||||||
'completed_date': _('Datum der Fertigstellung'),
|
"completed_date": _("Datum der Fertigstellung"),
|
||||||
'assigned_to': _('Zuweisen an'),
|
"assigned_to": _("Zuweisen an"),
|
||||||
'note': _('Notizen'),
|
"note": _("Notizen"),
|
||||||
'priority': _('Priorität'),
|
"priority": _("Priorität"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
self.fields['assigned_to'].empty_label = "Alle"
|
self.fields["assigned_to"].empty_label = "Alle"
|
||||||
self.fields['assigned_to'].queryset = self.fields['assigned_to'].queryset.order_by('username')
|
self.fields["assigned_to"].queryset = self.fields[
|
||||||
|
"assigned_to"
|
||||||
|
].queryset.order_by("username")
|
||||||
|
|
||||||
|
|
||||||
class TaskForm(forms.ModelForm):
|
class TaskForm(forms.ModelForm):
|
||||||
@@ -37,39 +39,41 @@ class TaskForm(forms.ModelForm):
|
|||||||
model = Task
|
model = Task
|
||||||
|
|
||||||
fields = [
|
fields = [
|
||||||
'title',
|
"title",
|
||||||
'task_list',
|
"task_list",
|
||||||
'due_date',
|
"due_date",
|
||||||
'assigned_to',
|
"assigned_to",
|
||||||
]
|
]
|
||||||
|
|
||||||
labels = {
|
labels = {
|
||||||
'title': _('Titel des Tasks'),
|
"title": _("Titel des Tasks"),
|
||||||
'task_list': _('Task-Gruppe'),
|
"task_list": _("Task-Gruppe"),
|
||||||
'due_date': _('Fälligkeitsdatum'),
|
"due_date": _("Fälligkeitsdatum"),
|
||||||
'assigned_to': _('Zuweisen an'),
|
"assigned_to": _("Zuweisen an"),
|
||||||
}
|
}
|
||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
'due_date': DateInput(
|
"due_date": DateInput(
|
||||||
format=('%d-%m-%Y'),
|
format=("%d-%m-%Y"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||||
self.fields['assigned_to'].empty_label = "Alle"
|
self.fields["assigned_to"].empty_label = "Alle"
|
||||||
self.fields['assigned_to'].queryset = self.fields['assigned_to'].queryset.order_by('username')
|
self.fields["assigned_to"].queryset = self.fields[
|
||||||
|
"assigned_to"
|
||||||
|
].queryset.order_by("username")
|
||||||
|
|
||||||
|
|
||||||
class TaskListForm(forms.ModelForm):
|
class TaskListForm(forms.ModelForm):
|
||||||
users = forms.ModelMultipleChoiceField(
|
users = forms.ModelMultipleChoiceField(
|
||||||
label="Benutzer",
|
label="Benutzer",
|
||||||
help_text="Es können nur die Benutzer ausgewählt werden, die sich auf der Homepage angemeldet haben.",
|
help_text="Es können nur die Benutzer ausgewählt werden, die sich auf der Homepage angemeldet haben.",
|
||||||
queryset=User.objects.all().order_by('username'),
|
queryset=User.objects.all().order_by("username"),
|
||||||
widget=FilteredSelectMultiple("User", is_stacked=False)
|
widget=FilteredSelectMultiple("User", is_stacked=False),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TaskList
|
model = TaskList
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from django.utils import timezone
|
|||||||
|
|
||||||
class TaskQuerySet(models.QuerySet):
|
class TaskQuerySet(models.QuerySet):
|
||||||
def get_ordered(self):
|
def get_ordered(self):
|
||||||
return self.order_by('task_list')
|
return self.order_by("task_list")
|
||||||
|
|
||||||
|
|
||||||
class TaskManager(models.Manager):
|
class TaskManager(models.Manager):
|
||||||
@@ -16,7 +16,11 @@ class TaskManager(models.Manager):
|
|||||||
qs = self.get_queryset().get_ordered().filter(assigned_to__id=user)
|
qs = self.get_queryset().get_ordered().filter(assigned_to__id=user)
|
||||||
|
|
||||||
if all_tasks:
|
if all_tasks:
|
||||||
qs_tmp = self.get_queryset().get_ordered().filter(Q(assigned_to=None) & Q(task_list__users__id__exact=user))
|
qs_tmp = (
|
||||||
|
self.get_queryset()
|
||||||
|
.get_ordered()
|
||||||
|
.filter(Q(assigned_to=None) & Q(task_list__users__id__exact=user))
|
||||||
|
)
|
||||||
qs = (qs | qs_tmp).distinct()
|
qs = (qs | qs_tmp).distinct()
|
||||||
|
|
||||||
if not completed:
|
if not completed:
|
||||||
@@ -49,7 +53,9 @@ class TaskList(models.Model):
|
|||||||
|
|
||||||
class Task(models.Model):
|
class Task(models.Model):
|
||||||
title = models.CharField(verbose_name="Titel", max_length=140)
|
title = models.CharField(verbose_name="Titel", max_length=140)
|
||||||
task_list = models.ForeignKey(TaskList, verbose_name="Aufgabenbereich", on_delete=models.CASCADE, null=True)
|
task_list = models.ForeignKey(
|
||||||
|
TaskList, verbose_name="Aufgabenbereich", on_delete=models.CASCADE, null=True
|
||||||
|
)
|
||||||
|
|
||||||
created_date = models.DateTimeField(auto_now_add=True)
|
created_date = models.DateTimeField(auto_now_add=True)
|
||||||
due_date = models.DateField(verbose_name="Fälligkeit", blank=True, null=True)
|
due_date = models.DateField(verbose_name="Fälligkeit", blank=True, null=True)
|
||||||
@@ -72,7 +78,9 @@ class Task(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
note = models.TextField(verbose_name="Notizen", blank=True, null=True)
|
note = models.TextField(verbose_name="Notizen", blank=True, null=True)
|
||||||
priority = models.PositiveIntegerField(verbose_name="Priorität", blank=True, null=True)
|
priority = models.PositiveIntegerField(
|
||||||
|
verbose_name="Priorität", blank=True, null=True
|
||||||
|
)
|
||||||
|
|
||||||
objects = models.Manager()
|
objects = models.Manager()
|
||||||
taskmanager = TaskManager()
|
taskmanager = TaskManager()
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ from . import views
|
|||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name='tasks'),
|
path("", views.index, name="tasks"),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ def index(request):
|
|||||||
show_tasklist = None
|
show_tasklist = None
|
||||||
show_all_tasks = True
|
show_all_tasks = True
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
if 'btn_input' in request.POST:
|
if "btn_input" in request.POST:
|
||||||
form = TaskForm(request.POST)
|
form = TaskForm(request.POST)
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@@ -29,13 +29,18 @@ def index(request):
|
|||||||
task.created_by = request.user
|
task.created_by = request.user
|
||||||
task.save()
|
task.save()
|
||||||
else:
|
else:
|
||||||
messages.info(request, "User '{}' ist nicht in der Liste von Task-Gruppe '{}'.".format(task.assigned_to, task.task_list.name))
|
messages.info(
|
||||||
|
request,
|
||||||
|
"User '{}' ist nicht in der Liste von Task-Gruppe '{}'.".format(
|
||||||
|
task.assigned_to, task.task_list.name
|
||||||
|
),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
task.created_by = request.user
|
task.created_by = request.user
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
elif 'btn_checkbox' in request.POST:
|
elif "btn_checkbox" in request.POST:
|
||||||
for task_id in request.POST.getlist('checkbox'):
|
for task_id in request.POST.getlist("checkbox"):
|
||||||
task = Task.objects.get(id=task_id)
|
task = Task.objects.get(id=task_id)
|
||||||
|
|
||||||
if not task.completed:
|
if not task.completed:
|
||||||
@@ -43,27 +48,31 @@ def index(request):
|
|||||||
task.completed_date = timezone.now().date()
|
task.completed_date = timezone.now().date()
|
||||||
task.save()
|
task.save()
|
||||||
|
|
||||||
elif 'btn_user' in request.POST:
|
elif "btn_user" in request.POST:
|
||||||
if request.POST['action'] == 'show_incompleted':
|
if request.POST["action"] == "show_incompleted":
|
||||||
current_action = False
|
current_action = False
|
||||||
else:
|
else:
|
||||||
current_action = True
|
current_action = True
|
||||||
|
|
||||||
if request.POST['tasklist'] != 'all':
|
if request.POST["tasklist"] != "all":
|
||||||
show_tasklist = TaskList.objects.filter(id=request.POST['tasklist']).first()
|
show_tasklist = TaskList.objects.filter(
|
||||||
|
id=request.POST["tasklist"]
|
||||||
|
).first()
|
||||||
|
|
||||||
if request.POST['tasks'] == 'all':
|
if request.POST["tasks"] == "all":
|
||||||
show_all_tasks = True
|
show_all_tasks = True
|
||||||
else:
|
else:
|
||||||
show_all_tasks = False
|
show_all_tasks = False
|
||||||
|
|
||||||
form = TaskForm()
|
form = TaskForm()
|
||||||
tasks = deque(Task.taskmanager.get_tasks(
|
tasks = deque(
|
||||||
|
Task.taskmanager.get_tasks(
|
||||||
user=current_user,
|
user=current_user,
|
||||||
completed=current_action,
|
completed=current_action,
|
||||||
task_list=show_tasklist,
|
task_list=show_tasklist,
|
||||||
all_tasks=show_all_tasks
|
all_tasks=show_all_tasks,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
tasklists = deque(TaskList.objects.all())
|
tasklists = deque(TaskList.objects.all())
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
@@ -74,4 +83,4 @@ def index(request):
|
|||||||
"current_action": current_action,
|
"current_action": current_action,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'tasks/index.html', context)
|
return render(request, "tasks/index.html", context)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
{% for post in events %}
|
{% for post in events %}
|
||||||
{% include 'posts/partials/_date_box.html' %}
|
{% include 'posts/partials/_date_box.html' %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<a href="{% url 'posts.calendar' %}">ICS Kalendar</a>
|
FET-Kalender abonnieren: <a href="{% url 'posts.calendar' %}">ICS Kalender</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,11 +8,12 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>FET</title>
|
<title>FET</title>
|
||||||
<link rel="stylesheet" href="{% static 'app.css' %}">
|
<link rel="stylesheet" href="{% static 'app.css' %}">
|
||||||
|
<link rel="stylesheet" href="{% static 'fet.css' %}">
|
||||||
<script src="https://kit.fontawesome.com/dbe3c89a9d.js" crossorigin="anonymous"></script>
|
<script src="https://kit.fontawesome.com/dbe3c89a9d.js" crossorigin="anonymous"></script>
|
||||||
{% block extraheader %}
|
{% block extraheader %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body style="min-height:100%; position:relative">
|
<body style="">
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
footer {
|
footer {
|
||||||
@@ -28,7 +29,7 @@ footer {
|
|||||||
|
|
||||||
<div class="title-bar-left">
|
<div class="title-bar-left">
|
||||||
<a href="{% url 'home' %}">
|
<a href="{% url 'home' %}">
|
||||||
<img style="height:40px; width:40px" src="/assets/img/logo2014_64.png"/>
|
<img class="logo" src="/assets/img/logo2014_64.png"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -43,26 +44,26 @@ footer {
|
|||||||
|
|
||||||
<div class="top-bar-left show-for-large">
|
<div class="top-bar-left show-for-large">
|
||||||
<a href="{% url 'home' %}">
|
<a href="{% url 'home' %}">
|
||||||
<img style="height:40px; width:40px" src="/assets/img/logo2014_64.png"/>
|
<img class="logo" src="/assets/img/logo2014_64.png"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="top-bar-right">
|
<div class="top-bar-right">
|
||||||
<ul class="dropdown vertical medium-horizontal menu" data-responsive-menu="drilldown medium-dropdown" data-animate-heigt="true">
|
<ul class="dropdown vertical medium-horizontal menu" data-responsive-menu="drilldown medium-dropdown" data-animate-heigt="true">
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li><a role="menuitem" style="color: black; background: lightgrey">Hallo {{request.user.username}}</a></li>
|
<li><a role="menuitem" style="color: black; background: lightgrey">Hallo {{ request.user.username }}</a></li>
|
||||||
<li><a href="/admin" style="background: lightgrey;">Admin</a></li>
|
<li><a href="/admin" style="background: lightgrey;">Admin</a></li>
|
||||||
<li><a href="{%url 'tasks'%}" style="background: lightgrey;">Tasks</a></li>
|
<li><a href="{% url 'tasks' %}" style="background: lightgrey;">Tasks</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li><a href="{% url 'posts.index' %}">Aktuelles</a></li>
|
<li><a href="{% url 'posts.index' %}">Aktuelles</a></li>
|
||||||
<!-- show active members first -->
|
<!-- show active members first -->
|
||||||
<li><a href="{% url 'members'%}A">Fachschaft</a></li>
|
<li><a href="{% url 'members' %}A">Fachschaft</a></li>
|
||||||
<li><a href="/fotos/">Fotos</a></li>
|
<li><a href="/fotos/">Fotos</a></li>
|
||||||
<li><a href="/blackboard">Blackboard</a></li>
|
<li><a href="/blackboard">Blackboard</a></li>
|
||||||
{% if request.user.is_authenticated %}
|
{% if request.user.is_authenticated %}
|
||||||
<li><a href="{%url 'logout'%}">Logout</a></li>
|
<li><a href="{% url 'logout' %}">Logout</a></li>
|
||||||
{% else %}
|
{% else %}
|
||||||
<li><a href="{%url 'login'%}">Login</a></li>
|
<li><a href="{% url 'login' %}?next={{ request.path }}">Login</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -76,17 +77,17 @@ footer {
|
|||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div class="grid-x padding-top-1 padding-bottom-1">
|
<div class="grid-x padding-top-1 padding-bottom-1">
|
||||||
<div class="cell medium-6 large-9">
|
<div class="cell medium-6 large-9">
|
||||||
<div class="grid-y" style="height: 100%;">
|
<div class="grid-y" style="height: 100%;" class="footer">
|
||||||
|
|
||||||
<div class="cell small-6 medium-9 large-9">
|
<div class="cell small-6 medium-9 large-9">
|
||||||
<a href="{% url 'posts.show' 'impressum' %}" style="color: white">Impressum</a>
|
<a href="{% url 'posts.show' 'impressum' %}" >Impressum</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell small-6 medium-3 large-3 padding-bottom-2">
|
<div class="cell small-6 medium-3 large-3 padding-bottom-2">
|
||||||
<a href="https://www.facebook.com/FachschaftET"><i class="fab fa-facebook-square" style="font-size:30px; color: white;"></i></a>
|
<a href="https://www.facebook.com/FachschaftET"><i class="fab fa-facebook-square" style="font-size:30px; color: white;"></i>Facebook</a>
|
||||||
<a href="https://www.instagram.com/fet_tuwien/"><i class="fab fa-instagram-square" style="font-size:30px; color: white;"></i></a>
|
<a href="https://www.instagram.com/fet_tuwien/"><i class="fab fa-instagram-square" style="font-size:30px; color: white;"></i>Instagram</a>
|
||||||
<a href="https://discord.gg/7qRuuMA"><i class="fab fa-discord" style="font-size:30px; color: white;"></i></a>
|
<a href="https://discord.gg/7qRuuMA"><i class="fab fa-discord" style="font-size:30px; color: white;"></i>Discord</a>
|
||||||
<a href="https://t.me/FETInfo"><i class="fab fa-telegram" style="font-size:30px; color: white;"></i></a>
|
<a href="https://t.me/FETInfo"><i class="fab fa-telegram" style="font-size:30px; color: white;"></i>Telegram</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -62,7 +62,9 @@
|
|||||||
{% if members %}
|
{% if members %}
|
||||||
<div class="grid-x">
|
<div class="grid-x">
|
||||||
<div class="cell padding-top-1 padding-left-1 padding-right-1" style="background-color: white; text-align: justify;">
|
<div class="cell padding-top-1 padding-left-1 padding-right-1" style="background-color: white; text-align: justify;">
|
||||||
Die Fachschaft Elektrotechnik (kurz: FET), ist die offizielle Vertretung aller Studierenden auf der Fakultät für Elektrotechnik und Informationstechnik. Ehrenamtliche engagierte Studierende unterstützen dich in Anliegen und Fragen zum und rund ums Studium. Wir vertreten eure Interessen in den offiziellen Gremien der Universität und arbeiten an Studienplänen mit. Außerdem bieten wir ein Rahmenprogramm zum Studium in Form von Veranstaltungen und Festln. Wir freuen uns über Feedback und Anregungen, insbesondere von jenen, die gleich Nägel mit Köpfen machen und unser Team verstärken wollen oder ihre Themen und Meinungen in eine unserer Sitzungen einbringen möchten.
|
{% if fs_info %}
|
||||||
|
{{ fs_info.body|safe }}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ UID:{{event.id}}
|
|||||||
ORGANIZER;CN="Fachschaft Elektrotechnik":MAILTO:service@fet.at
|
ORGANIZER;CN="Fachschaft Elektrotechnik":MAILTO:service@fet.at
|
||||||
LOCATION:Vienna
|
LOCATION:Vienna
|
||||||
SUMMARY:{{ event.title }}
|
SUMMARY:{{ event.title }}
|
||||||
DESCRIPTION: {{ request.scheme }}://{{ request.get_host }}{{ event.url }} {{ even.title }}</a>
|
DESCRIPTION:{{ request.scheme }}://{{ request.get_host }}{{ event.url }} {{ even.title }}
|
||||||
CLASS:PUBLIC
|
CLASS:PUBLIC
|
||||||
DTSTART;TZID=Europe/Vienna:{{ event.event_start|date:'Ymd' }}T{{ event.event_start|time:'His' }}
|
DTSTART;TZID=Europe/Vienna:{{ event.event_start|date:'Ymd' }}T{{ event.event_start|time:'His' }}
|
||||||
DTEND;TZID=Europe/Vienna:{{ event.event_end|date:'Ymd' }}T{{ event.event_end|time:'His' }}
|
DTEND;TZID=Europe/Vienna:{{ event.event_end|date:'Ymd' }}T{{ event.event_end|time:'His' }}
|
||||||
|
|||||||
Reference in New Issue
Block a user