linting
This commit is contained in:
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class AuthenticationsConfig(AppConfig):
|
||||
name = 'authentications'
|
||||
name = "authentications"
|
||||
|
||||
@@ -11,25 +11,25 @@ def authentication(username, password):
|
||||
return None
|
||||
|
||||
# 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)
|
||||
|
||||
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)
|
||||
|
||||
has_user = False
|
||||
|
||||
try:
|
||||
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):
|
||||
if ("DN: uid=" + str(username.lower())) in str(user):
|
||||
has_user = True
|
||||
except LDAPBindError as e:
|
||||
logger.info('Username does not exist. Error: {}'.format(e))
|
||||
logger.info("Username does not exist. Error: {}".format(e))
|
||||
username = None
|
||||
except Exception as e:
|
||||
logger.info('Connection to server lost. Error: {}'.format(e))
|
||||
logger.info("Connection to server lost. Error: {}".format(e))
|
||||
username = None
|
||||
|
||||
if not has_user:
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.shortcuts import redirect
|
||||
def unauthenticated_user(view_func):
|
||||
def wrapper_func(request, *args, **kwargs):
|
||||
if request.user.is_authenticated:
|
||||
return redirect('home')
|
||||
return redirect("home")
|
||||
else:
|
||||
return view_func(request, *args, **kwargs)
|
||||
|
||||
@@ -16,7 +16,7 @@ def authenticated_user(view_func):
|
||||
if request.user.is_authenticated:
|
||||
return view_func(request, *args, **kwargs)
|
||||
else:
|
||||
return redirect('login')
|
||||
return redirect("login")
|
||||
|
||||
return wrapper_func
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ from django import forms
|
||||
|
||||
class LoginForm(forms.Form):
|
||||
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 = [
|
||||
path('login/', views.loginPage, name="login"),
|
||||
path('logout/', views.logoutUser, name="logout"),
|
||||
path("login/", views.loginPage, name="login"),
|
||||
path("logout/", views.logoutUser, name="logout"),
|
||||
]
|
||||
|
||||
@@ -12,9 +12,9 @@ from .forms import LoginForm
|
||||
|
||||
@unauthenticated_user
|
||||
def loginPage(request):
|
||||
if request.method == 'POST':
|
||||
username = request.POST.get('username')
|
||||
password = request.POST.get('password')
|
||||
if request.method == "POST":
|
||||
username = request.POST.get("username")
|
||||
password = request.POST.get("password")
|
||||
|
||||
auth_user = authentication(username, password)
|
||||
|
||||
@@ -27,25 +27,25 @@ def loginPage(request):
|
||||
login(request, user)
|
||||
|
||||
try:
|
||||
return redirect(request.GET.get('next'))
|
||||
return redirect(request.GET.get("next"))
|
||||
except:
|
||||
return redirect('home')
|
||||
return redirect("home")
|
||||
else:
|
||||
messages.info(request, 'username or password is incorrect')
|
||||
messages.info(request, "username or password is incorrect")
|
||||
|
||||
form = LoginForm()
|
||||
|
||||
context = {
|
||||
"form": form,
|
||||
}
|
||||
return render(request, 'authentications/login.html', context)
|
||||
return render(request, "authentications/login.html", context)
|
||||
|
||||
|
||||
@authenticated_user
|
||||
def logoutUser(request):
|
||||
logout(request)
|
||||
|
||||
response = redirect('home')
|
||||
response = redirect("home")
|
||||
response = del_ep_cookie(request, response)
|
||||
|
||||
return response
|
||||
|
||||
@@ -8,7 +8,7 @@ class JobPostingAdmin(admin.ModelAdmin):
|
||||
form = JobPostingForm
|
||||
model = JobPosting
|
||||
|
||||
list_display = ['companyName', 'jobName', 'salary', 'publishDate']
|
||||
list_display = ["companyName", "jobName", "salary", "publishDate"]
|
||||
|
||||
|
||||
admin.site.register(JobPosting, JobPostingAdmin)
|
||||
|
||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class BlackboardConfig(AppConfig):
|
||||
name = 'blackboard'
|
||||
name = "blackboard"
|
||||
|
||||
@@ -7,19 +7,17 @@ from .models import JobPosting
|
||||
class JobPostingForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = JobPosting
|
||||
fields = ['companyName', 'jobName', 'salary', 'pdfLocation', 'publishDate']
|
||||
fields = ["companyName", "jobName", "salary", "pdfLocation", "publishDate"]
|
||||
|
||||
labels = {
|
||||
'companyName': _("Firmenname"),
|
||||
'jobName': _("Berufsbezeichnung"),
|
||||
'salary': _("Gehalt"),
|
||||
'pdfLocation': _("Stellenausschreibung"),
|
||||
'publishDate': _("Veröffentlichung"),
|
||||
"companyName": _("Firmenname"),
|
||||
"jobName": _("Berufsbezeichnung"),
|
||||
"salary": _("Gehalt"),
|
||||
"pdfLocation": _("Stellenausschreibung"),
|
||||
"publishDate": _("Veröffentlichung"),
|
||||
}
|
||||
|
||||
help_texts = {
|
||||
'pdfLocation': _(
|
||||
"Verwendbare Formate: PDF"
|
||||
),
|
||||
'salary': _("in Euro angeben"),
|
||||
"pdfLocation": _("Verwendbare Formate: PDF"),
|
||||
"salary": _("in Euro angeben"),
|
||||
}
|
||||
|
||||
@@ -11,16 +11,23 @@ from os.path import splitext, basename
|
||||
import ghostscript
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('blackboard')
|
||||
|
||||
logger = logging.getLogger("blackboard")
|
||||
|
||||
|
||||
class JobPosting(models.Model):
|
||||
companyName = models.CharField(verbose_name="Firmenname", max_length=128)
|
||||
jobName = models.CharField(verbose_name="Berufsbezeichnung", max_length=128)
|
||||
salary = models.PositiveSmallIntegerField(verbose_name="Gehalt", )
|
||||
pdfLocation = models.FileField(verbose_name="Stellenausschreibung", upload_to='uploads/blackboard/pdf/')
|
||||
salary = models.PositiveSmallIntegerField(
|
||||
verbose_name="Gehalt",
|
||||
)
|
||||
pdfLocation = models.FileField(
|
||||
verbose_name="Stellenausschreibung", upload_to="uploads/blackboard/pdf/"
|
||||
)
|
||||
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
|
||||
all_jobPosting = models.Manager()
|
||||
@@ -40,7 +47,7 @@ class JobPosting(models.Model):
|
||||
"-dDEVICEWIDTHPOINTS=600",
|
||||
"-dDEVICEHEIGHTPOINTS=800",
|
||||
"-sOutputFile=" + jpeg_output_path,
|
||||
pdf_input_path
|
||||
pdf_input_path,
|
||||
]
|
||||
|
||||
encoding = locale.getpreferredencoding()
|
||||
@@ -54,14 +61,18 @@ class JobPosting(models.Model):
|
||||
if not os.path.exists(settings.MEDIA_ROOT + "uploads/blackboard/thumb/"):
|
||||
os.makedirs(settings.MEDIA_ROOT + "uploads/blackboard/thumb/")
|
||||
|
||||
pdf_thumb_location_full = settings.MEDIA_ROOT \
|
||||
+ "uploads/blackboard/thumb/" \
|
||||
+ splitext(basename(self.pdfLocation.name))[0] \
|
||||
pdf_thumb_location_full = (
|
||||
settings.MEDIA_ROOT
|
||||
+ "uploads/blackboard/thumb/"
|
||||
+ splitext(basename(self.pdfLocation.name))[0]
|
||||
+ ".jpg"
|
||||
)
|
||||
|
||||
self.pdf_thumb_location = "/files/uploads/blackboard/thumb/" \
|
||||
+ splitext(basename(self.pdfLocation.name))[0] \
|
||||
self.pdf_thumb_location = (
|
||||
"/files/uploads/blackboard/thumb/"
|
||||
+ splitext(basename(self.pdfLocation.name))[0]
|
||||
+ ".jpg"
|
||||
)
|
||||
|
||||
self.pdf2jpeg(self.pdfLocation.path, pdf_thumb_location_full)
|
||||
logger.info("SavenThumbAs: " + self.pdf_thumb_location)
|
||||
@@ -70,7 +81,7 @@ class JobPosting(models.Model):
|
||||
def clean(self):
|
||||
count = 0
|
||||
for i in self.pdfLocation.name:
|
||||
if i == '.':
|
||||
if i == ".":
|
||||
count = count + 1
|
||||
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 = [
|
||||
path('', views.index, name='blackboard'),
|
||||
path("", views.index, name="blackboard"),
|
||||
]
|
||||
|
||||
@@ -10,8 +10,8 @@ from posts.models import Post
|
||||
def index(request):
|
||||
job_postings_cutoff = timezone.now().date() - timedelta(30) # 30days from now
|
||||
job_postings = JobPosting.all_jobPosting.filter(publishDate__gt=job_postings_cutoff)
|
||||
bb_info = Post.objects.filter(slug='blackboard').first()
|
||||
bb_empty = Post.objects.filter(slug='blackboard-empty').first()
|
||||
bb_info = Post.objects.filter(slug="blackboard").first()
|
||||
bb_empty = Post.objects.filter(slug="blackboard-empty").first()
|
||||
|
||||
context = {
|
||||
"job_postings": job_postings,
|
||||
@@ -19,4 +19,4 @@ def index(request):
|
||||
"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
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
SERVER_URL = settings.ETHERPAD_CLIENT["exturl"]
|
||||
@@ -20,9 +21,11 @@ def get_ep_client():
|
||||
apikey = f.read()
|
||||
apikey = apikey.rstrip()
|
||||
epc = EtherpadLiteClient(
|
||||
base_params={'apikey': apikey, },
|
||||
base_params={
|
||||
"apikey": apikey,
|
||||
},
|
||||
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")
|
||||
except Exception as e:
|
||||
@@ -62,7 +65,9 @@ def createPadifNotExists(padID):
|
||||
# Pad doesn't exist
|
||||
if not __checkPadExists(padID=padID):
|
||||
try:
|
||||
epc.createGroupPad(groupID=group["groupID"], padName=padID, text="helloworld")
|
||||
epc.createGroupPad(
|
||||
groupID=group["groupID"], padName=padID, text="helloworld"
|
||||
)
|
||||
except EtherpadException as e:
|
||||
logger.info("Can't create Pad '{}'. EtherpadException: {}".format(padID, e))
|
||||
return None
|
||||
@@ -81,7 +86,9 @@ def getPadHTML(padID):
|
||||
try:
|
||||
text = epc.getHTML(padID=group["groupID"] + "$" + padID)["html"]
|
||||
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
|
||||
except Exception as e:
|
||||
raise e
|
||||
@@ -107,4 +114,6 @@ def get_pad_link(padID):
|
||||
if not epc or not group:
|
||||
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.contrib.admin.apps import AdminConfig
|
||||
|
||||
|
||||
class DocumentsConfig(AppConfig):
|
||||
name = 'documents'
|
||||
name = "documents"
|
||||
|
||||
@@ -11,22 +11,21 @@ def __get_ep_sessionid(request):
|
||||
return None, None
|
||||
|
||||
author = epc.createAuthorIfNotExistsFor(
|
||||
name=str(request.user),
|
||||
authorMapper=str(request.user)
|
||||
)['authorID']
|
||||
name=str(request.user), authorMapper=str(request.user)
|
||||
)["authorID"]
|
||||
|
||||
expires = datetime.utcnow() + timedelta(hours=3)
|
||||
try:
|
||||
result = epc.createSession(
|
||||
groupID=str(group['groupID']),
|
||||
groupID=str(group["groupID"]),
|
||||
authorID=str(author),
|
||||
validUntil=str(int(expires.timestamp()))
|
||||
validUntil=str(int(expires.timestamp())),
|
||||
)
|
||||
except Exception as e:
|
||||
raise e
|
||||
return None, None
|
||||
|
||||
return result['sessionID'], expires
|
||||
return result["sessionID"], expires
|
||||
|
||||
|
||||
def add_ep_cookie(request, response):
|
||||
@@ -34,32 +33,19 @@ def add_ep_cookie(request, response):
|
||||
|
||||
if ep_sessid:
|
||||
response.set_cookie(
|
||||
"sessionID",
|
||||
ep_sessid,
|
||||
expires=expires,
|
||||
domain=".2020.fet.at",
|
||||
path="/"
|
||||
)
|
||||
response.set_cookie(
|
||||
"sessionID",
|
||||
ep_sessid,
|
||||
expires=expires,
|
||||
path="/etherpad"
|
||||
"sessionID", ep_sessid, expires=expires, domain=".2020.fet.at", path="/"
|
||||
)
|
||||
response.set_cookie("sessionID", ep_sessid, expires=expires, path="/etherpad")
|
||||
return response
|
||||
|
||||
|
||||
def del_ep_cookie(request, response):
|
||||
|
||||
if 'sessionID' in request.COOKIES:
|
||||
ep_sessionID = request.COOKIES['sessionID']
|
||||
if "sessionID" in request.COOKIES:
|
||||
ep_sessionID = request.COOKIES["sessionID"]
|
||||
|
||||
epc, group = get_ep_client()
|
||||
epc.deleteSession(sessionID=ep_sessionID)
|
||||
|
||||
response.delete_cookie(
|
||||
"sessionID",
|
||||
domain=".2020.fet.at",
|
||||
path="/"
|
||||
)
|
||||
response.delete_cookie("sessionID", domain=".2020.fet.at", path="/")
|
||||
return response
|
||||
|
||||
@@ -2,6 +2,6 @@ import os
|
||||
|
||||
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()
|
||||
|
||||
@@ -11,23 +11,23 @@ env = environ.Env(
|
||||
MYSQL_USER=(str),
|
||||
MYSQL_PASSWORD=(str),
|
||||
HOST_NAME=(str, "localhost"),
|
||||
ETHERPAD_PORT=(str,"9001"),
|
||||
ETHERPAD_HOST=(str,"etherpad2.2020.fet.at")
|
||||
ETHERPAD_PORT=(str, "9001"),
|
||||
ETHERPAD_HOST=(str, "etherpad2.2020.fet.at"),
|
||||
)
|
||||
|
||||
# Prints and logs are written to console
|
||||
# TODO: Change before release
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'handlers': {
|
||||
'console': {
|
||||
'class': 'logging.StreamHandler',
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"handlers": {
|
||||
"console": {
|
||||
"class": "logging.StreamHandler",
|
||||
},
|
||||
},
|
||||
'root': {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
"root": {
|
||||
"handlers": ["console"],
|
||||
"level": "DEBUG",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -41,106 +41,106 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = env('DEBUG')
|
||||
DEBUG = env("DEBUG")
|
||||
if DEBUG:
|
||||
# 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:
|
||||
SECRET_KEY = env('SECRET_KEY')
|
||||
SECRET_KEY = env("SECRET_KEY")
|
||||
|
||||
|
||||
ALLOWED_HOSTS = ["127.0.0.1", env('HOST_NAME')]
|
||||
ALLOWED_HOSTS = ["127.0.0.1", env("HOST_NAME")]
|
||||
|
||||
HOST_NAME = env('HOST_NAME')
|
||||
HOST_NAME = env("HOST_NAME")
|
||||
|
||||
|
||||
DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 1024
|
||||
# Application definition
|
||||
CKEDITOR_UPLOAD_PATH = 'upload'
|
||||
CKEDITOR_UPLOAD_PATH = "upload"
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.admindocs',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'taggit',
|
||||
'ckeditor',
|
||||
'ckeditor_uploader',
|
||||
'easy_thumbnails',
|
||||
'rest_framework',
|
||||
'softhyphen',
|
||||
'django_crontab',
|
||||
'django_filters',
|
||||
'django_static_jquery_ui',
|
||||
'posts.apps.PostsConfig',
|
||||
'members.apps.MembersConfig',
|
||||
'documents.apps.DocumentsConfig',
|
||||
'blackboard.apps.BlackboardConfig',
|
||||
'tasks.apps.TasksConfig',
|
||||
"django.contrib.admin",
|
||||
"django.contrib.admindocs",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"taggit",
|
||||
"ckeditor",
|
||||
"ckeditor_uploader",
|
||||
"easy_thumbnails",
|
||||
"rest_framework",
|
||||
"softhyphen",
|
||||
"django_crontab",
|
||||
"django_filters",
|
||||
"django_static_jquery_ui",
|
||||
"posts.apps.PostsConfig",
|
||||
"members.apps.MembersConfig",
|
||||
"documents.apps.DocumentsConfig",
|
||||
"blackboard.apps.BlackboardConfig",
|
||||
"tasks.apps.TasksConfig",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.locale.LocaleMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'fet2020.urls'
|
||||
ROOT_URLCONF = "fet2020.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [
|
||||
os.path.join(BASE_DIR, 'templates'),
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [
|
||||
os.path.join(BASE_DIR, "templates"),
|
||||
],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
'django.template.context_processors.debug',
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'django.template.context_processors.i18n',
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
"django.template.context_processors.i18n",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = 'fet2020.wsgi.application'
|
||||
WSGI_APPLICATION = "fet2020.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
|
||||
if DEBUG:
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
|
||||
}
|
||||
}
|
||||
else:
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': env('MYSQL_DATABASE'),
|
||||
'USER': env('MYSQL_USER'),
|
||||
'PASSWORD': env('MYSQL_PASSWORD'),
|
||||
'HOST': env('MYSQL_HOST'),
|
||||
'PORT': env('MYSQL_PORT')
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.mysql",
|
||||
"NAME": env("MYSQL_DATABASE"),
|
||||
"USER": env("MYSQL_USER"),
|
||||
"PASSWORD": env("MYSQL_PASSWORD"),
|
||||
"HOST": env("MYSQL_HOST"),
|
||||
"PORT": env("MYSQL_PORT"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
"django.contrib.auth.backends.ModelBackend",
|
||||
]
|
||||
|
||||
# Password validation
|
||||
@@ -148,16 +148,16 @@ AUTHENTICATION_BACKENDS = [
|
||||
|
||||
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",
|
||||
},
|
||||
]
|
||||
|
||||
@@ -165,9 +165,9 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
# Internationalization
|
||||
# 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
|
||||
|
||||
@@ -179,28 +179,26 @@ USE_TZ = True
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||
|
||||
STATIC_URL = '/assets/'
|
||||
STATIC_URL = "/assets/"
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, "static")
|
||||
]
|
||||
STATIC_ROOT = 'assets/'
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'files/')
|
||||
MEDIA_URL = '/files/'
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
|
||||
STATIC_ROOT = "assets/"
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, "files/")
|
||||
MEDIA_URL = "/files/"
|
||||
|
||||
TAGGIT_FORCE_LOWERCASE = True
|
||||
|
||||
CKEDITOR_CONFIGS = {
|
||||
'default': {
|
||||
'stylesSet': [
|
||||
"default": {
|
||||
"stylesSet": [
|
||||
{
|
||||
"name": 'Überschrift 2',
|
||||
"element": 'h2',
|
||||
"name": "Überschrift 2",
|
||||
"element": "h2",
|
||||
"attributes": {},
|
||||
},
|
||||
{
|
||||
"name": 'Code',
|
||||
"element": 'code',
|
||||
"name": "Code",
|
||||
"element": "code",
|
||||
"attributes": {"class": "code-block"},
|
||||
},
|
||||
],
|
||||
@@ -209,41 +207,41 @@ CKEDITOR_CONFIGS = {
|
||||
|
||||
# THUMBNAIL
|
||||
THUMBNAIL_ALIASES = {
|
||||
'': {
|
||||
'avatar': {'size': (50, 50), 'crop': True},
|
||||
'thumb': {'size': (150, 150), 'crop': True},
|
||||
"": {
|
||||
"avatar": {"size": (50, 50), "crop": True},
|
||||
"thumb": {"size": (150, 150), "crop": True},
|
||||
},
|
||||
}
|
||||
|
||||
# ETHERPAD CLIENT
|
||||
if DEBUG:
|
||||
ETHERPAD_CLIENT = {
|
||||
'url': "http://etherpad:"+env('ETHERPAD_PORT'),
|
||||
'exturl': env('ETHERPAD_HOST'),
|
||||
'apikey': "/srv/etherpad/APIKEY.txt"
|
||||
"url": "http://etherpad:" + env("ETHERPAD_PORT"),
|
||||
"exturl": env("ETHERPAD_HOST"),
|
||||
"apikey": "/srv/etherpad/APIKEY.txt",
|
||||
}
|
||||
else:
|
||||
ETHERPAD_CLIENT = {
|
||||
'url': "http://etherpad:"+env('ETHERPAD_PORT'),
|
||||
'exturl': urljoin('https://' + env('HOST_NAME'),"etherpad/"),
|
||||
'apikey': "/app/etherpad/APIKEY.txt"
|
||||
"url": "http://etherpad:" + env("ETHERPAD_PORT"),
|
||||
"exturl": urljoin("https://" + env("HOST_NAME"), "etherpad/"),
|
||||
"apikey": "/app/etherpad/APIKEY.txt",
|
||||
}
|
||||
|
||||
# REST FRAMEWORK
|
||||
REST_FRAMEWORK={
|
||||
'DEFAULT_PERMISSION_CLASSES_CLASSES':[
|
||||
'rest_framework.permissions.AllowAny',
|
||||
REST_FRAMEWORK = {
|
||||
"DEFAULT_PERMISSION_CLASSES_CLASSES": [
|
||||
"rest_framework.permissions.AllowAny",
|
||||
],
|
||||
'DEFAULT_AUTHENTICATION_CLASSES':()
|
||||
"DEFAULT_AUTHENTICATION_CLASSES": (),
|
||||
}
|
||||
|
||||
# DJANGO MAIL
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = 'buran.htu.tuwien.ac.at'
|
||||
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
||||
EMAIL_HOST = "buran.htu.tuwien.ac.at"
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_USE_TLS = True
|
||||
|
||||
# CRON JOBS
|
||||
CRONJOBS = [
|
||||
('0 16 * * *', 'posts.cronjobs.check_to_send_agenda_mail'),
|
||||
("0 16 * * *", "posts.cronjobs.check_to_send_agenda_mail"),
|
||||
]
|
||||
|
||||
@@ -6,29 +6,34 @@ from django.views.generic import RedirectView
|
||||
from . import views
|
||||
from posts.viewsets import PostViewSet
|
||||
from members.urls import member_urlpatterns, jobs_urlpatterns
|
||||
from members.viewsets import MemberViewSet, JobViewSet, JobGroupViewSet, JobMemberViewSet
|
||||
from members.viewsets import (
|
||||
MemberViewSet,
|
||||
JobViewSet,
|
||||
JobGroupViewSet,
|
||||
JobMemberViewSet,
|
||||
)
|
||||
from rest_framework import routers
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'posts', PostViewSet)
|
||||
router.register(r'members', MemberViewSet)
|
||||
router.register(r'jobgroups', JobGroupViewSet)
|
||||
router.register(r'jobs', JobViewSet)
|
||||
router.register(r'jobmembers', JobMemberViewSet)
|
||||
router.register(r"posts", PostViewSet)
|
||||
router.register(r"members", MemberViewSet)
|
||||
router.register(r"jobgroups", JobGroupViewSet)
|
||||
router.register(r"jobs", JobViewSet)
|
||||
router.register(r"jobmembers", JobMemberViewSet)
|
||||
|
||||
urlpatterns = [
|
||||
path('posts/', include('posts.urls')),
|
||||
path('admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
path('admin/login/', RedirectView.as_view(pattern_name='login')),
|
||||
path('admin/', admin.site.urls),
|
||||
path('auth/', include('authentications.urls')),
|
||||
path('', views.index, name='home'),
|
||||
path('index.html', views.index, name='home'),
|
||||
path('ckeditor/', include('ckeditor_uploader.urls')),
|
||||
path('api/', include(router.urls)),
|
||||
path('members/', include('members.urls'), name='members'),
|
||||
path('jobs/', include(jobs_urlpatterns), name='jobs'),
|
||||
path('member/', include(member_urlpatterns), name='member'),
|
||||
path('blackboard/', include('blackboard.urls'), name='blackboard'),
|
||||
path('tasks/', include('tasks.urls'), name='tasks'),
|
||||
path("posts/", include("posts.urls")),
|
||||
path("admin/doc/", include("django.contrib.admindocs.urls")),
|
||||
path("admin/login/", RedirectView.as_view(pattern_name="login")),
|
||||
path("admin/", admin.site.urls),
|
||||
path("auth/", include("authentications.urls")),
|
||||
path("", views.index, name="home"),
|
||||
path("index.html", views.index, name="home"),
|
||||
path("ckeditor/", include("ckeditor_uploader.urls")),
|
||||
path("api/", include(router.urls)),
|
||||
path("members/", include("members.urls"), name="members"),
|
||||
path("jobs/", include(jobs_urlpatterns), name="jobs"),
|
||||
path("member/", include(member_urlpatterns), name="member"),
|
||||
path("blackboard/", include("blackboard.urls"), name="blackboard"),
|
||||
path("tasks/", include("tasks.urls"), name="tasks"),
|
||||
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# from django.http import HttpResponse
|
||||
from collections import deque
|
||||
from posts.models import Post, FetMeeting, Event
|
||||
@@ -34,12 +35,12 @@ def index(request):
|
||||
featured_meeting = FetMeeting.objects.get_meetings()
|
||||
|
||||
context = {
|
||||
'posts': deque(list(posts)[:5]),
|
||||
'events': Event.all_events.get_five_events(),
|
||||
'featured_post': featured_post,
|
||||
'featured_event': featured_event,
|
||||
'featured_meeting': featured_meeting,
|
||||
'tags_list': " ".join(t)
|
||||
"posts": deque(list(posts)[:5]),
|
||||
"events": Event.all_events.get_five_events(),
|
||||
"featured_post": featured_post,
|
||||
"featured_event": featured_event,
|
||||
"featured_meeting": featured_meeting,
|
||||
"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
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'fet2020.settings')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fet2020.settings")
|
||||
|
||||
application = get_wsgi_application()
|
||||
|
||||
@@ -6,13 +6,13 @@ from .forms import MemberForm, JobForm, JobGroupForm
|
||||
|
||||
|
||||
class MemberRoleFilter(admin.SimpleListFilter):
|
||||
title = _('Rolle')
|
||||
parameter_name = 'role'
|
||||
title = _("Rolle")
|
||||
parameter_name = "role"
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
return (
|
||||
('A', _('Aktiv')),
|
||||
('P', _('Pension')),
|
||||
("A", _("Aktiv")),
|
||||
("P", _("Pension")),
|
||||
)
|
||||
|
||||
def queryset(self, request, queryset):
|
||||
@@ -55,40 +55,53 @@ class MemberAdmin(admin.ModelAdmin):
|
||||
form = MemberForm
|
||||
model = Member
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (
|
||||
('firstname', 'surname',),
|
||||
'nickname',
|
||||
'username',
|
||||
'mailaccount',
|
||||
'role',
|
||||
'description',
|
||||
'image',
|
||||
'birthday',
|
||||
'phone',
|
||||
'address',
|
||||
)
|
||||
}),
|
||||
(
|
||||
None,
|
||||
{
|
||||
"fields": (
|
||||
(
|
||||
"firstname",
|
||||
"surname",
|
||||
),
|
||||
"nickname",
|
||||
"username",
|
||||
"mailaccount",
|
||||
"role",
|
||||
"description",
|
||||
"image",
|
||||
"birthday",
|
||||
"phone",
|
||||
"address",
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
inlines = (JobOverviewInline,)
|
||||
|
||||
list_display = ['nickname', 'firstname', 'surname', 'mailaccount', 'role']
|
||||
ordering = ['firstname', ]
|
||||
search_fields = ['firstname', 'surname', 'nickname', 'mailaccount']
|
||||
list_display = ["nickname", "firstname", "surname", "mailaccount", "role"]
|
||||
ordering = [
|
||||
"firstname",
|
||||
]
|
||||
search_fields = ["firstname", "surname", "nickname", "mailaccount"]
|
||||
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['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||
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['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||
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):
|
||||
@@ -101,22 +114,33 @@ class JobAdmin(admin.ModelAdmin):
|
||||
model = Job
|
||||
inlines = (ActiveMemberInline, InactiveMemberInline)
|
||||
|
||||
list_display = ['name', ]
|
||||
ordering = ['name', ]
|
||||
search_fields = ['name', ]
|
||||
list_display = [
|
||||
"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['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||
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['help_text'] = "Fette Schriften sind Pflichfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichfelder."
|
||||
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):
|
||||
@@ -127,24 +151,36 @@ class JobAdmin(admin.ModelAdmin):
|
||||
class JobGroupAdmin(admin.ModelAdmin):
|
||||
form = JobGroupForm
|
||||
model = JobGroup
|
||||
inlines = (JobInline, )
|
||||
inlines = (JobInline,)
|
||||
|
||||
list_display = ['name', 'is_pinned', ]
|
||||
ordering = ['name', ]
|
||||
search_fields = ['name', ]
|
||||
list_display = [
|
||||
"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['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||
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['help_text'] = "Fette Schriften sind Pflichfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichfelder."
|
||||
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):
|
||||
|
||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class MembersConfig(AppConfig):
|
||||
name = 'members'
|
||||
name = "members"
|
||||
|
||||
@@ -10,56 +10,68 @@ class MemberForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Member
|
||||
fields = [
|
||||
'firstname', 'surname', 'nickname', 'username', 'mailaccount', 'role', 'description',
|
||||
'image', 'birthday', 'phone', 'address',
|
||||
"firstname",
|
||||
"surname",
|
||||
"nickname",
|
||||
"username",
|
||||
"mailaccount",
|
||||
"role",
|
||||
"description",
|
||||
"image",
|
||||
"birthday",
|
||||
"phone",
|
||||
"address",
|
||||
]
|
||||
|
||||
widgets = {
|
||||
'description': CKEditorUploadingWidget(config_name='default')
|
||||
}
|
||||
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
||||
|
||||
labels = {
|
||||
'description': _("Beschreibung zu der Person"),
|
||||
'image': _("Porträt"),
|
||||
'birthday': _("Geburtstag"),
|
||||
'phone': _("Telefonnummer"),
|
||||
'address': _("Wohnadresse"),
|
||||
"description": _("Beschreibung zu der Person"),
|
||||
"image": _("Porträt"),
|
||||
"birthday": _("Geburtstag"),
|
||||
"phone": _("Telefonnummer"),
|
||||
"address": _("Wohnadresse"),
|
||||
}
|
||||
|
||||
help_texts = {
|
||||
'image': _(
|
||||
"Mindestgröße: 150*150 px, Verwendbare Formate: ..."
|
||||
),
|
||||
'mailaccount': _(
|
||||
"Die Mailadresse mit '@fet.at' angeben."
|
||||
),
|
||||
"image": _("Mindestgröße: 150*150 px, Verwendbare Formate: ..."),
|
||||
"mailaccount": _("Die Mailadresse mit '@fet.at' angeben."),
|
||||
}
|
||||
|
||||
|
||||
class JobForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Job
|
||||
fields = ['name', 'shortterm', 'slug', 'job_group',]
|
||||
fields = [
|
||||
"name",
|
||||
"shortterm",
|
||||
"slug",
|
||||
"job_group",
|
||||
]
|
||||
|
||||
labels = {
|
||||
'shortterm': _("Kürzel der Tätigkeit"),
|
||||
'job_group': _("Tätigkeitsbereich"),
|
||||
"shortterm": _("Kürzel der Tätigkeit"),
|
||||
"job_group": _("Tätigkeitsbereich"),
|
||||
}
|
||||
|
||||
|
||||
class JobGroupForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = JobGroup
|
||||
fields = ['name', 'shortterm', 'slug', 'description', 'is_pinned',]
|
||||
fields = [
|
||||
"name",
|
||||
"shortterm",
|
||||
"slug",
|
||||
"description",
|
||||
"is_pinned",
|
||||
]
|
||||
|
||||
widgets = {
|
||||
'description': CKEditorUploadingWidget(config_name='default')
|
||||
}
|
||||
widgets = {"description": CKEditorUploadingWidget(config_name="default")}
|
||||
|
||||
labels = {
|
||||
'shortterm': _("Kürzel des Tätigkeitsbereichs"),
|
||||
'description': _("Beschreibung des Tätigkeitsbereichs"),
|
||||
'is_pinned': _(
|
||||
"shortterm": _("Kürzel des Tätigkeitsbereichs"),
|
||||
"description": _("Beschreibung des Tätigkeitsbereichs"),
|
||||
"is_pinned": _(
|
||||
"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):
|
||||
'''
|
||||
"""
|
||||
return a list of active member, and members who are still working
|
||||
'''
|
||||
"""
|
||||
|
||||
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):
|
||||
date_today = timezone.now().date()
|
||||
qs = super().get_queryset().order_by('member__firstname')
|
||||
qs = super().get_queryset().order_by("member__firstname")
|
||||
|
||||
return qs.filter(
|
||||
Q(member__role=Member.MemberRole.ACTIVE)
|
||||
@@ -27,15 +32,20 @@ class ActiveJobMemberManager(models.Manager):
|
||||
|
||||
|
||||
class InactiveJobMemberManager(models.Manager):
|
||||
'''
|
||||
"""
|
||||
return a list of inactive member
|
||||
'''
|
||||
"""
|
||||
|
||||
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):
|
||||
date_today = timezone.now().date()
|
||||
qs = super().get_queryset().order_by('member__firstname')
|
||||
qs = super().get_queryset().order_by("member__firstname")
|
||||
|
||||
return qs.filter(
|
||||
Q(member__role=Member.MemberRole.PENSION)
|
||||
@@ -45,7 +55,7 @@ class InactiveJobMemberManager(models.Manager):
|
||||
|
||||
class JobMemberManager(models.Manager):
|
||||
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))
|
||||
|
||||
@@ -82,19 +92,19 @@ class JobGroupManager(models.Manager):
|
||||
|
||||
class MemberManager(models.Manager):
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().order_by('firstname')
|
||||
return super().get_queryset().order_by("firstname")
|
||||
|
||||
|
||||
class Member(models.Model):
|
||||
firstname = models.CharField("Vorname", max_length=128)
|
||||
surname = models.CharField("Nachname", max_length=128)
|
||||
nickname = models.CharField("Spitzname", max_length=128)
|
||||
nickname = models.CharField("Spitzname", max_length=128)
|
||||
username = models.CharField("Benutzername", blank=True, max_length=128)
|
||||
mailaccount = models.CharField("Mailadresse", unique=True, max_length=128)
|
||||
|
||||
class MemberRole(models.TextChoices):
|
||||
ACTIVE = 'A', _('Active')
|
||||
PENSION = 'P', _('Pension')
|
||||
ACTIVE = "A", _("Active")
|
||||
PENSION = "P", _("Pension")
|
||||
|
||||
role = models.CharField(
|
||||
"Rolle",
|
||||
@@ -104,14 +114,16 @@ class Member(models.Model):
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
phone_error_msg = _((
|
||||
"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_error_msg = _(
|
||||
(
|
||||
"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 = models.CharField(validators=[phone_regex], max_length=17, 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:
|
||||
raise ValidationError(
|
||||
_("Das Bild ist zu klein. (Höhe: {}, Breite: {})").format(
|
||||
self.image.height,
|
||||
self.image.width
|
||||
self.image.height, self.image.width
|
||||
)
|
||||
)
|
||||
|
||||
if not "@fet.at" in self.mailaccount:
|
||||
raise ValidationError(
|
||||
_("In der Mailadresse fehlt die Domäne.")
|
||||
)
|
||||
raise ValidationError(_("In der Mailadresse fehlt die Domäne."))
|
||||
|
||||
def __str__(self):
|
||||
return self.firstname + " " + self.surname
|
||||
@@ -198,7 +207,7 @@ class Job(models.Model):
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
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)
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@@ -218,18 +227,20 @@ class JobMember(models.Model):
|
||||
verbose_name="Tätigkeit",
|
||||
)
|
||||
|
||||
job_start = models.DateField('Job Start')
|
||||
job_end = models.DateField('Job Ende', null=True, blank=True)
|
||||
job_start = models.DateField("Job Start")
|
||||
job_end = models.DateField("Job Ende", null=True, blank=True)
|
||||
|
||||
class JobRole(models.TextChoices):
|
||||
PRESIDENT = ('10', _('VorsitzendeR'))
|
||||
VICE_PRESIDENT = ('20', _('stv VorsitzendeR'))
|
||||
SECOND_VICE_PRESIDENT = ('30', _('2. stv VorsitzendeR'))
|
||||
PERSON_RESPONSIBLE = ('40', _('VerantwortlicheR'))
|
||||
MEMBER = ('50', _('Mitglied'))
|
||||
SUBSTITUTE_MEMBER = ('60', _('Ersatzmitglied'))
|
||||
PRESIDENT = ("10", _("VorsitzendeR"))
|
||||
VICE_PRESIDENT = ("20", _("stv VorsitzendeR"))
|
||||
SECOND_VICE_PRESIDENT = ("30", _("2. stv VorsitzendeR"))
|
||||
PERSON_RESPONSIBLE = ("40", _("VerantwortlicheR"))
|
||||
MEMBER = ("50", _("Mitglied"))
|
||||
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()
|
||||
members = JobMemberManager()
|
||||
|
||||
@@ -4,65 +4,50 @@ from rest_framework import serializers
|
||||
|
||||
|
||||
class MemberSerializer(serializers.HyperlinkedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Member
|
||||
fields = ['id',
|
||||
'firstname',
|
||||
'surname',
|
||||
'nickname',
|
||||
'mailaccount',
|
||||
'role',
|
||||
'description',
|
||||
'image',
|
||||
'birthday',
|
||||
fields = [
|
||||
"id",
|
||||
"firstname",
|
||||
"surname",
|
||||
"nickname",
|
||||
"mailaccount",
|
||||
"role",
|
||||
"description",
|
||||
"image",
|
||||
"birthday",
|
||||
]
|
||||
|
||||
|
||||
class JobGroupSerializer(serializers.HyperlinkedModelSerializer):
|
||||
class Meta:
|
||||
model = JobGroup
|
||||
fields = [
|
||||
'id',
|
||||
'name',
|
||||
'shortterm',
|
||||
'slug'
|
||||
]
|
||||
fields = ["id", "name", "shortterm", "slug"]
|
||||
|
||||
|
||||
class JobSerializer(serializers.HyperlinkedModelSerializer):
|
||||
#job_group = JobGroupSerializer()
|
||||
# job_group = JobGroupSerializer()
|
||||
job_group = serializers.SlugRelatedField(
|
||||
slug_field='slug',queryset = JobGroup.objects
|
||||
)
|
||||
slug_field="slug", queryset=JobGroup.objects
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Job
|
||||
fields = [
|
||||
'id',
|
||||
'name',
|
||||
'shortterm',
|
||||
'job_group',
|
||||
'slug'
|
||||
]
|
||||
fields = ["id", "name", "shortterm", "job_group", "slug"]
|
||||
|
||||
|
||||
class JobMemberSerializer(serializers.HyperlinkedModelSerializer):
|
||||
#member = MemberSerializer()
|
||||
#job = JobSerializer()
|
||||
job = serializers.SlugRelatedField(
|
||||
slug_field='slug',queryset = Job.objects
|
||||
)
|
||||
member= serializers.SlugRelatedField(
|
||||
slug_field='mailaccount',queryset = Member.objects
|
||||
)
|
||||
# member = MemberSerializer()
|
||||
# job = JobSerializer()
|
||||
job = serializers.SlugRelatedField(slug_field="slug", queryset=Job.objects)
|
||||
member = serializers.SlugRelatedField(
|
||||
slug_field="mailaccount", queryset=Member.objects
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = JobMember
|
||||
fields = [
|
||||
'id',
|
||||
'job_start',
|
||||
'job_end',
|
||||
'member',
|
||||
'job',
|
||||
'job_role'
|
||||
]
|
||||
fields = ["id", "job_start", "job_end", "member", "job", "job_role"]
|
||||
|
||||
|
||||
# def create(self, validated_data):
|
||||
# member_data = validated_data.pop('member')
|
||||
|
||||
@@ -4,14 +4,14 @@ from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='members'),
|
||||
path('<str:filter>', views.members_view),
|
||||
path("", views.index, name="members"),
|
||||
path("<str:filter>", views.members_view),
|
||||
]
|
||||
|
||||
member_urlpatterns = [
|
||||
path('<str:member_id>', views.profile_view, name='member'),
|
||||
path("<str:member_id>", views.profile_view, name="member"),
|
||||
]
|
||||
|
||||
jobs_urlpatterns = [
|
||||
path('<str:slug>', views.jobs_view, name='jobs'),
|
||||
path("<str:slug>", views.jobs_view, name="jobs"),
|
||||
]
|
||||
|
||||
@@ -7,6 +7,7 @@ from .models import Member, JobMember, JobGroup, Job
|
||||
from posts.models import Post
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -41,7 +42,7 @@ def index(request):
|
||||
pinned_job_groups, unpinned_job_groups = __get_job_groups()
|
||||
members = deque(Member.all_members.all())
|
||||
|
||||
fs_info = Post.objects.filter(slug='fachschaft-info').first()
|
||||
fs_info = Post.objects.filter(slug="fachschaft-info").first()
|
||||
|
||||
context = {
|
||||
"pinned_job_groups": pinned_job_groups,
|
||||
@@ -50,14 +51,16 @@ def index(request):
|
||||
"fs_info": fs_info,
|
||||
}
|
||||
|
||||
return render(request, 'members/index.html', context)
|
||||
return render(request, "members/index.html", context)
|
||||
|
||||
|
||||
def jobs_view(request, slug=None):
|
||||
pinned_job_groups, unpinned_job_groups = __get_job_groups()
|
||||
|
||||
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:
|
||||
logger.info("Wrong job '{}'".format(slug))
|
||||
raise Http404("wrong job")
|
||||
@@ -71,7 +74,7 @@ def jobs_view(request, slug=None):
|
||||
"job_members": job_members,
|
||||
}
|
||||
|
||||
return render(request, 'members/index.html', context)
|
||||
return render(request, "members/index.html", context)
|
||||
|
||||
|
||||
def members_view(request, filter=None):
|
||||
@@ -83,7 +86,7 @@ def members_view(request, filter=None):
|
||||
logger.info("Wrong member role '{}'".format(filter))
|
||||
raise Http404("no member role")
|
||||
|
||||
fs_info = Post.objects.filter(slug='fachschaft-info').first()
|
||||
fs_info = Post.objects.filter(slug="fachschaft-info").first()
|
||||
|
||||
context = {
|
||||
"pinned_job_groups": pinned_job_groups,
|
||||
@@ -92,7 +95,7 @@ def members_view(request, filter=None):
|
||||
"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):
|
||||
@@ -112,4 +115,4 @@ def profile_view(request, member_id=None):
|
||||
"jobs": jobs,
|
||||
}
|
||||
|
||||
return render(request, 'members/member.html', context)
|
||||
return render(request, "members/member.html", context)
|
||||
|
||||
@@ -2,54 +2,63 @@ 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
|
||||
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')
|
||||
|
||||
queryset = Member.all_members.order_by("nickname")
|
||||
serializer_class = MemberSerializer
|
||||
|
||||
#permission_classes = [permissions.IsAuthenticated]
|
||||
# permission_classes = [permissions.IsAuthenticated]
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = ['nickname','mailaccount']
|
||||
#lookup_field = 'name'
|
||||
filterset_fields = ["nickname", "mailaccount"]
|
||||
# lookup_field = 'name'
|
||||
|
||||
def pre_save(self, obj):
|
||||
obj.image = self.request.FILES.get('image')
|
||||
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'
|
||||
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'
|
||||
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'
|
||||
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):
|
||||
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
|
||||
agenda_key = None
|
||||
@@ -24,7 +24,7 @@ def make_fetmeeting(self, request, queryset):
|
||||
except Exception as e:
|
||||
self.message_user(
|
||||
request,
|
||||
_('Das Agenda konnte nicht erstellt werden. Error: %s') % str(e),
|
||||
_("Das Agenda konnte nicht erstellt werden. Error: %s") % str(e),
|
||||
messages.ERROR,
|
||||
)
|
||||
failed = True
|
||||
@@ -34,14 +34,14 @@ def make_fetmeeting(self, request, queryset):
|
||||
except Exception as e:
|
||||
self.message_user(
|
||||
request,
|
||||
_('Das Protokoll konnte nicht erstellt werden. Error: %s') % str(e),
|
||||
_("Das Protokoll konnte nicht erstellt werden. Error: %s") % str(e),
|
||||
messages.ERROR,
|
||||
)
|
||||
failed = True
|
||||
|
||||
if not failed:
|
||||
queryset.update(
|
||||
post_type='F',
|
||||
post_type="F",
|
||||
has_agenda=True,
|
||||
has_protocol=True,
|
||||
agenda_key=agenda_key,
|
||||
@@ -49,7 +49,8 @@ def make_fetmeeting(self, request, queryset):
|
||||
)
|
||||
self.message_user(
|
||||
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,
|
||||
)
|
||||
|
||||
@@ -60,22 +61,27 @@ make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
|
||||
class PostAdmin(admin.ModelAdmin):
|
||||
form = PostForm
|
||||
model = Post
|
||||
list_filter = ['is_pinned', 'is_hidden']
|
||||
list_display = ['title', 'slug', 'public_date', 'is_pinned', 'is_hidden']
|
||||
ordering = ['is_hidden', '-public_date']
|
||||
list_filter = ["is_pinned", "is_hidden"]
|
||||
list_display = ["title", "slug", "public_date", "is_pinned", "is_hidden"]
|
||||
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['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||
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['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
|
||||
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):
|
||||
@@ -98,9 +104,9 @@ class PostAdmin(admin.ModelAdmin):
|
||||
class EventAdmin(PostAdmin):
|
||||
form = EventForm
|
||||
model = Event
|
||||
list_filter = ['is_pinned']
|
||||
list_display = ['title', 'slug', 'event_start', 'public_date', 'is_pinned']
|
||||
ordering = ['-event_start']
|
||||
list_filter = ["is_pinned"]
|
||||
list_display = ["title", "slug", "event_start", "public_date", "is_pinned"]
|
||||
ordering = ["-event_start"]
|
||||
actions = [make_fetmeeting]
|
||||
|
||||
|
||||
@@ -113,7 +119,7 @@ class FetMeetingAdmin(EventAdmin):
|
||||
form = FetMeetingForm
|
||||
model = FetMeeting
|
||||
list_filter = []
|
||||
list_display = ['title', 'slug', 'event_start', 'public_date']
|
||||
list_display = ["title", "slug", "event_start", "public_date"]
|
||||
actions = []
|
||||
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class PostsConfig(AppConfig):
|
||||
name = 'posts'
|
||||
name = "posts"
|
||||
|
||||
@@ -10,14 +10,23 @@ from .models import Post, Event, News, FetMeeting
|
||||
class PostForm(forms.ModelForm):
|
||||
class Meta:
|
||||
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:
|
||||
js = (
|
||||
'js/auto_slug.js', # automatic slag completion via ajax
|
||||
'js/tag_completion.js', # to get a list for tag autocompletion via ajax
|
||||
"js/auto_slug.js", # automatic slag completion via ajax
|
||||
"js/tag_completion.js", # to get a list for tag autocompletion via ajax
|
||||
)
|
||||
|
||||
|
||||
@@ -25,106 +34,124 @@ class NewsForm(PostForm):
|
||||
class Meta:
|
||||
model = News
|
||||
fields = [
|
||||
'title', 'subtitle', 'tags', 'image', 'body', 'slug', 'author', 'public_date',
|
||||
'is_pinned', 'is_hidden',
|
||||
"title",
|
||||
"subtitle",
|
||||
"tags",
|
||||
"image",
|
||||
"body",
|
||||
"slug",
|
||||
"author",
|
||||
"public_date",
|
||||
"is_pinned",
|
||||
"is_hidden",
|
||||
]
|
||||
|
||||
labels = {
|
||||
'title': _("Titel"),
|
||||
'subtitle': _("Untertitel"),
|
||||
'image': _("Hintergrundbild"),
|
||||
'body': _("Text"),
|
||||
'author': _("Autor"),
|
||||
'public_date': _("Veröffentlichung"),
|
||||
'is_pinned': _("Post anheften"),
|
||||
'is_hidden': _("Post verstecken"),
|
||||
"title": _("Titel"),
|
||||
"subtitle": _("Untertitel"),
|
||||
"image": _("Hintergrundbild"),
|
||||
"body": _("Text"),
|
||||
"author": _("Autor"),
|
||||
"public_date": _("Veröffentlichung"),
|
||||
"is_pinned": _("Post anheften"),
|
||||
"is_hidden": _("Post verstecken"),
|
||||
}
|
||||
|
||||
help_texts = {
|
||||
'tags': _(
|
||||
"tags": _(
|
||||
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||
),
|
||||
'image': _(
|
||||
"Verwendbare Formate: ..."
|
||||
),
|
||||
'is_pinned': _(
|
||||
"image": _("Verwendbare Formate: ..."),
|
||||
"is_pinned": _(
|
||||
"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."
|
||||
),
|
||||
}
|
||||
|
||||
widgets = {'body': CKEditorUploadingWidget(config_name='default')}
|
||||
widgets = {"body": CKEditorUploadingWidget(config_name="default")}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
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 Meta:
|
||||
model = Event
|
||||
fields = [
|
||||
'title', 'subtitle', 'tags', 'image', 'body', 'event_start', 'event_end',
|
||||
'event_place', 'slug', 'author', 'public_date', 'is_pinned',
|
||||
"title",
|
||||
"subtitle",
|
||||
"tags",
|
||||
"image",
|
||||
"body",
|
||||
"event_start",
|
||||
"event_end",
|
||||
"event_place",
|
||||
"slug",
|
||||
"author",
|
||||
"public_date",
|
||||
"is_pinned",
|
||||
]
|
||||
|
||||
labels = {
|
||||
'title': _("Titel"),
|
||||
'subtitle': _("Untertitel"),
|
||||
'image': _("Hintergrundbild"),
|
||||
'body': _("Text"),
|
||||
'event_start': _("Start des Events"),
|
||||
'event_end': _("Ende des Events"),
|
||||
'event_place': _("Ort des Events"),
|
||||
'author': _("Autor"),
|
||||
'public_date': _("Veröffentlichung"),
|
||||
'is_pinned': _("Event anheften"),
|
||||
"title": _("Titel"),
|
||||
"subtitle": _("Untertitel"),
|
||||
"image": _("Hintergrundbild"),
|
||||
"body": _("Text"),
|
||||
"event_start": _("Start des Events"),
|
||||
"event_end": _("Ende des Events"),
|
||||
"event_place": _("Ort des Events"),
|
||||
"author": _("Autor"),
|
||||
"public_date": _("Veröffentlichung"),
|
||||
"is_pinned": _("Event anheften"),
|
||||
}
|
||||
|
||||
help_texts = {
|
||||
'tags': _(
|
||||
"tags": _(
|
||||
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||
),
|
||||
'image': _(
|
||||
"Verwendbare Formate: "
|
||||
),
|
||||
'is_pinned': _(
|
||||
"image": _("Verwendbare Formate: "),
|
||||
"is_pinned": _(
|
||||
"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):
|
||||
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_end'].required = False
|
||||
self.fields["event_start"].required = True
|
||||
self.fields["event_end"].required = False
|
||||
|
||||
if 'event_place' in self.fields:
|
||||
self.fields['event_place'].required = True
|
||||
if "event_place" in self.fields:
|
||||
self.fields["event_place"].required = True
|
||||
|
||||
|
||||
class FetMeetingForm(PostForm):
|
||||
# agenda_html = forms.CharField(widget = forms.TextInput())
|
||||
class Meta:
|
||||
model = FetMeeting
|
||||
fields = ['event_start', 'event_end', 'tags']#, 'has_agenda', 'has_protocol']
|
||||
fields = ["event_start", "event_end", "tags"] # , 'has_agenda', 'has_protocol']
|
||||
|
||||
labels = {
|
||||
'event_start': _("Start der Sitzung"),
|
||||
'event_end': _("Ende der Sitzung")#,
|
||||
# 'has_agenda': _("Agenda"),
|
||||
# 'has_protocol': _("Protokoll"),
|
||||
"event_start": _("Start der Sitzung"),
|
||||
"event_end": _("Ende der Sitzung") # ,
|
||||
# 'has_agenda': _("Agenda"),
|
||||
# 'has_protocol': _("Protokoll"),
|
||||
}
|
||||
|
||||
help_texts = {
|
||||
'tags': _(
|
||||
"tags": _(
|
||||
"Die Hashtags ohne '#' eintragen, und mit Komma kann man mehrere Tags anfügen."
|
||||
)#,
|
||||
) # ,
|
||||
#'has_agenda': _("Agenda zur Sitzung hinzufügen."),
|
||||
#'has_protocol': _("Protokoll zur Sitzung hinzufügen."),
|
||||
}
|
||||
@@ -132,13 +159,13 @@ class FetMeetingForm(PostForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||
|
||||
self.fields['event_start'].required = True
|
||||
self.fields['event_end'].required = False
|
||||
self.fields["event_start"].required = True
|
||||
self.fields["event_end"].required = False
|
||||
|
||||
#self.fields['has_agenda'].initial = True
|
||||
#self.fields['has_protocol'].initial = True
|
||||
# self.fields['has_agenda'].initial = True
|
||||
# self.fields['has_protocol'].initial = True
|
||||
|
||||
tags = []
|
||||
tags.append(Tag())
|
||||
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):
|
||||
msg = "Liebe Alle,\n\n" \
|
||||
"wir haben am " + str(date) + " um " + str(time) + " wieder Sitzung.\n" \
|
||||
"du hast noch bis morgen Zeit, weitere Themen auf die Agenda zu schreiben: " \
|
||||
+ settings.HOST_NAME + '/posts/' + str(slug) + ".\n\n" \
|
||||
msg = (
|
||||
"Liebe Alle,\n\n"
|
||||
"wir haben am " + str(date) + " um " + str(time) + " wieder Sitzung.\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"
|
||||
)
|
||||
|
||||
send_mail(
|
||||
subject = 'Test - Agenda der FET Sitzung von ' + str(date),
|
||||
message = msg,
|
||||
from_email = 'patrick@fet.at',
|
||||
recipient_list = ['all@fet.at', ],
|
||||
subject="Test - Agenda der FET Sitzung von " + str(date),
|
||||
message=msg,
|
||||
from_email="patrick@fet.at",
|
||||
recipient_list=[
|
||||
"all@fet.at",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -5,23 +5,32 @@ from django.utils import timezone
|
||||
|
||||
class PostManager(models.Manager):
|
||||
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):
|
||||
return self.get_queryset().filter(is_hidden=False)
|
||||
|
||||
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):
|
||||
"""
|
||||
Provide a query set only for "Article"
|
||||
regular fet meetings should not be contained in the news stream
|
||||
"""
|
||||
|
||||
def get_queryset(self):
|
||||
return super().get_queryset().filter(
|
||||
Q(post_type='E')
|
||||
| Q(post_type='N')
|
||||
).order_by('-public_date')
|
||||
return (
|
||||
super()
|
||||
.get_queryset()
|
||||
.filter(Q(post_type="E") | Q(post_type="N"))
|
||||
.order_by("-public_date")
|
||||
)
|
||||
|
||||
def get_visible_articles(self):
|
||||
return self.get_queryset().filter(is_hidden=False)
|
||||
@@ -34,8 +43,9 @@ class NewsManager(models.Manager):
|
||||
"""
|
||||
Provide a query set only for "News"
|
||||
"""
|
||||
|
||||
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):
|
||||
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")
|
||||
"""
|
||||
|
||||
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):
|
||||
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):
|
||||
@@ -58,32 +73,50 @@ class EventManager(models.Manager):
|
||||
Provide a query set only for "Events"
|
||||
regular fet meetings should not be contained in the news stream
|
||||
"""
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
"""
|
||||
Provide a query set only for "Fet Meeting"
|
||||
"""
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
meetings = []
|
||||
|
||||
@@ -133,6 +133,7 @@ class Post(models.Model):
|
||||
)
|
||||
html = None
|
||||
return html
|
||||
|
||||
@property
|
||||
def protocol_html(self):
|
||||
"Protocol HTML from Etherpad Pad"
|
||||
@@ -196,7 +197,7 @@ class Post(models.Model):
|
||||
|
||||
def get_agenda_key(self):
|
||||
"""Create a Etherpad Id for the Pad associated to this post.
|
||||
Creates the pad if it doesn't exist"""
|
||||
Creates the pad if it doesn't exist"""
|
||||
if not self.slug:
|
||||
return None
|
||||
return create_pad_for_post(self.slug, typ="agenda")
|
||||
@@ -255,9 +256,10 @@ class Post(models.Model):
|
||||
def clean(self):
|
||||
if self.event_end and self.event_end < self.event_start:
|
||||
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")
|
||||
super().clean()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# save the post with some defaults
|
||||
if not self.public_date:
|
||||
@@ -307,9 +309,9 @@ class Event(Post):
|
||||
verbose_name = "Event"
|
||||
verbose_name_plural = "Events"
|
||||
|
||||
def __init__(self,*args,**kwargs):
|
||||
super().__init__(*args,**kwargs)
|
||||
self.post_type='E'
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.post_type = "E"
|
||||
|
||||
def clean(self):
|
||||
if not self.event_start:
|
||||
@@ -334,9 +336,9 @@ class FetMeeting(Event):
|
||||
verbose_name = "Fet Sitzung"
|
||||
verbose_name_plural = "Fet Sitzungen"
|
||||
|
||||
def __init__(self,*args,**kwargs):
|
||||
super().__init__(*args,**kwargs)
|
||||
self.post_type='F'
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.post_type = "F"
|
||||
|
||||
def __get_slug(self):
|
||||
slug = slugify(self.event_start.date()) + "-" + slugify("Fachschaftssitzung")
|
||||
@@ -349,34 +351,33 @@ class FetMeeting(Event):
|
||||
|
||||
return slug
|
||||
|
||||
# def __get_agenda_key(self):
|
||||
# if not self.slug:
|
||||
# return None##
|
||||
#
|
||||
# try:
|
||||
# agenda_key = createPadifNotExists(self.slug + "-agenda")
|
||||
# except Exception as error:
|
||||
# raise ValidationError(
|
||||
# _("Die Agenda konnte nicht erstellt werden. Error: %(error)s"),
|
||||
# params={"error": str(error)},
|
||||
# ) from error
|
||||
#
|
||||
# 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_agenda_key(self):
|
||||
# if not self.slug:
|
||||
# return None##
|
||||
#
|
||||
# try:
|
||||
# agenda_key = createPadifNotExists(self.slug + "-agenda")
|
||||
# except Exception as error:
|
||||
# raise ValidationError(
|
||||
# _("Die Agenda konnte nicht erstellt werden. Error: %(error)s"),
|
||||
# params={"error": str(error)},
|
||||
# ) from error
|
||||
#
|
||||
# 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 clean(self):
|
||||
super().clean()
|
||||
|
||||
@@ -5,33 +5,34 @@ from rest_framework import serializers
|
||||
|
||||
class PostSerializer(serializers.HyperlinkedModelSerializer):
|
||||
agenda_html = serializers.CharField(required=False)
|
||||
tag_string = serializers.CharField(required=False,read_only=True)
|
||||
imageurl = serializers.CharField(required=False,read_only=True)
|
||||
tag_string = serializers.CharField(required=False, read_only=True)
|
||||
imageurl = serializers.CharField(required=False, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Post
|
||||
fields = [
|
||||
'slug',
|
||||
'title',
|
||||
'subtitle',
|
||||
'body',
|
||||
'url',
|
||||
'post_type',
|
||||
'public_date',
|
||||
'legacy_id',
|
||||
'image',
|
||||
'event_start',
|
||||
'event_end',
|
||||
'is_hidden',
|
||||
'agenda_html',
|
||||
'protocol_html',
|
||||
'has_agenda',
|
||||
'has_protocol',
|
||||
'tag_string',
|
||||
'imageurl'
|
||||
"slug",
|
||||
"title",
|
||||
"subtitle",
|
||||
"body",
|
||||
"url",
|
||||
"post_type",
|
||||
"public_date",
|
||||
"legacy_id",
|
||||
"image",
|
||||
"event_start",
|
||||
"event_end",
|
||||
"is_hidden",
|
||||
"agenda_html",
|
||||
"protocol_html",
|
||||
"has_agenda",
|
||||
"has_protocol",
|
||||
"tag_string",
|
||||
"imageurl"
|
||||
# 'author',
|
||||
]
|
||||
|
||||
extra_kwargs={
|
||||
'agenda_html': {"required": False},
|
||||
'protocol_html': {"required": False}
|
||||
extra_kwargs = {
|
||||
"agenda_html": {"required": False},
|
||||
"protocol_html": {"required": False},
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('func/tag_complete', views.tag_complete),
|
||||
path('func/slug_calc', views.slug_calc),
|
||||
path('t/<str:tag>', views.tags, name='posts.tags'),
|
||||
path('', views.index, name='posts.index'),
|
||||
path('fet_calendar.ics', views.calendar, name='posts.calendar'),
|
||||
path('<str:id>', views.show, name='posts.show'),
|
||||
path("func/tag_complete", views.tag_complete),
|
||||
path("func/slug_calc", views.slug_calc),
|
||||
path("t/<str:tag>", views.tags, name="posts.tags"),
|
||||
path("", views.index, name="posts.index"),
|
||||
path("fet_calendar.ics", views.calendar, name="posts.calendar"),
|
||||
path("<str:id>", views.show, name="posts.show"),
|
||||
]
|
||||
|
||||
@@ -27,7 +27,7 @@ def index(request):
|
||||
"Index von aktuellen Posts"
|
||||
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})
|
||||
|
||||
@@ -48,7 +48,6 @@ def tags(request, tag=""):
|
||||
posts = deque(Post.objects.get_visible_articles().filter(tags__name=tag))
|
||||
featured_post = Post.objects.get_visible_articles().filter(slug=tag).first()
|
||||
|
||||
|
||||
job_members = JobMember.active_member.get_all_by_slug(slug=tag)
|
||||
|
||||
author_image = None
|
||||
@@ -86,25 +85,21 @@ def show(request, id=None):
|
||||
ep_agenda_link = "#"
|
||||
ep_protocol_link = "#"
|
||||
|
||||
if p.has_agenda:# and p.agenda_key:
|
||||
if p.has_agenda: # and p.agenda_key:
|
||||
try:
|
||||
ep_agenda_link = get_pad_link(p.agenda_key)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Can't get the agenda link from '%s'. Error: %s",
|
||||
p.agenda_key,
|
||||
e
|
||||
"Can't get the agenda link from '%s'. Error: %s", p.agenda_key, e
|
||||
)
|
||||
ep_agenda_link = "#"
|
||||
|
||||
if p.has_protocol:# and p.protocol_key:
|
||||
if p.has_protocol: # and p.protocol_key:
|
||||
try:
|
||||
ep_protocol_link = get_pad_link(p.protocol_key)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Can't get the protocol link from '%s. Error: %s",
|
||||
p.protocol_key, e
|
||||
|
||||
"Can't get the protocol link from '%s. Error: %s", p.protocol_key, e
|
||||
)
|
||||
ep_protocol_link = "#"
|
||||
|
||||
@@ -125,8 +120,7 @@ def show(request, id=None):
|
||||
try:
|
||||
response = add_ep_cookie(request, response)
|
||||
except Exception as e:
|
||||
logger.info(
|
||||
"Etherpad Server doesn't work. Error: %s", e)
|
||||
logger.info("Etherpad Server doesn't work. Error: %s", e)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@@ -8,23 +8,33 @@ class TaskAdmin(admin.ModelAdmin):
|
||||
form = TaskAdminForm
|
||||
model = Task
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (
|
||||
'title',
|
||||
'task_list',
|
||||
'assigned_to',
|
||||
'due_date',
|
||||
'completed',
|
||||
'completed_date',
|
||||
'note',
|
||||
'priority',
|
||||
)
|
||||
}),
|
||||
(
|
||||
None,
|
||||
{
|
||||
"fields": (
|
||||
"title",
|
||||
"task_list",
|
||||
"assigned_to",
|
||||
"due_date",
|
||||
"completed",
|
||||
"completed_date",
|
||||
"note",
|
||||
"priority",
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
list_display = ['title', 'task_list', 'assigned_to', 'due_date', 'completed', 'priority']
|
||||
list_filter = ('task_list', )
|
||||
search_fields = ('title', )
|
||||
list_display = [
|
||||
"title",
|
||||
"task_list",
|
||||
"assigned_to",
|
||||
"due_date",
|
||||
"completed",
|
||||
"priority",
|
||||
]
|
||||
list_filter = ("task_list",)
|
||||
search_fields = ("title",)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.created_by = request.user
|
||||
|
||||
@@ -2,4 +2,4 @@ from django.apps import AppConfig
|
||||
|
||||
|
||||
class TasksConfig(AppConfig):
|
||||
name = 'tasks'
|
||||
name = "tasks"
|
||||
|
||||
@@ -7,29 +7,31 @@ from .models import Task, TaskList
|
||||
|
||||
|
||||
class DateInput(forms.DateInput):
|
||||
input_type = 'date'
|
||||
input_type = "date"
|
||||
|
||||
|
||||
class TaskAdminForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Task
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
labels = {
|
||||
'title': _('Titel'),
|
||||
'task_list': _('Aufgabenbereich'),
|
||||
'due_date': _('Fälligkeit'),
|
||||
'completed': _('Abgeschlossen'),
|
||||
'completed_date': _('Datum der Fertigstellung'),
|
||||
'assigned_to': _('Zuweisen an'),
|
||||
'note': _('Notizen'),
|
||||
'priority': _('Priorität'),
|
||||
"title": _("Titel"),
|
||||
"task_list": _("Aufgabenbereich"),
|
||||
"due_date": _("Fälligkeit"),
|
||||
"completed": _("Abgeschlossen"),
|
||||
"completed_date": _("Datum der Fertigstellung"),
|
||||
"assigned_to": _("Zuweisen an"),
|
||||
"note": _("Notizen"),
|
||||
"priority": _("Priorität"),
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||
self.fields['assigned_to'].empty_label = "Alle"
|
||||
self.fields['assigned_to'].queryset = self.fields['assigned_to'].queryset.order_by('username')
|
||||
self.fields["assigned_to"].empty_label = "Alle"
|
||||
self.fields["assigned_to"].queryset = self.fields[
|
||||
"assigned_to"
|
||||
].queryset.order_by("username")
|
||||
|
||||
|
||||
class TaskForm(forms.ModelForm):
|
||||
@@ -37,39 +39,41 @@ class TaskForm(forms.ModelForm):
|
||||
model = Task
|
||||
|
||||
fields = [
|
||||
'title',
|
||||
'task_list',
|
||||
'due_date',
|
||||
'assigned_to',
|
||||
"title",
|
||||
"task_list",
|
||||
"due_date",
|
||||
"assigned_to",
|
||||
]
|
||||
|
||||
labels = {
|
||||
'title': _('Titel des Tasks'),
|
||||
'task_list': _('Task-Gruppe'),
|
||||
'due_date': _('Fälligkeitsdatum'),
|
||||
'assigned_to': _('Zuweisen an'),
|
||||
"title": _("Titel des Tasks"),
|
||||
"task_list": _("Task-Gruppe"),
|
||||
"due_date": _("Fälligkeitsdatum"),
|
||||
"assigned_to": _("Zuweisen an"),
|
||||
}
|
||||
|
||||
widgets = {
|
||||
'due_date': DateInput(
|
||||
format=('%d-%m-%Y'),
|
||||
"due_date": DateInput(
|
||||
format=("%d-%m-%Y"),
|
||||
)
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs) # to get the self.fields set
|
||||
self.fields['assigned_to'].empty_label = "Alle"
|
||||
self.fields['assigned_to'].queryset = self.fields['assigned_to'].queryset.order_by('username')
|
||||
self.fields["assigned_to"].empty_label = "Alle"
|
||||
self.fields["assigned_to"].queryset = self.fields[
|
||||
"assigned_to"
|
||||
].queryset.order_by("username")
|
||||
|
||||
|
||||
class TaskListForm(forms.ModelForm):
|
||||
users = forms.ModelMultipleChoiceField(
|
||||
label="Benutzer",
|
||||
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'),
|
||||
widget=FilteredSelectMultiple("User", is_stacked=False)
|
||||
queryset=User.objects.all().order_by("username"),
|
||||
widget=FilteredSelectMultiple("User", is_stacked=False),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = TaskList
|
||||
fields = '__all__'
|
||||
fields = "__all__"
|
||||
|
||||
@@ -7,7 +7,7 @@ from django.utils import timezone
|
||||
|
||||
class TaskQuerySet(models.QuerySet):
|
||||
def get_ordered(self):
|
||||
return self.order_by('task_list')
|
||||
return self.order_by("task_list")
|
||||
|
||||
|
||||
class TaskManager(models.Manager):
|
||||
@@ -16,7 +16,11 @@ class TaskManager(models.Manager):
|
||||
qs = self.get_queryset().get_ordered().filter(assigned_to__id=user)
|
||||
|
||||
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()
|
||||
|
||||
if not completed:
|
||||
@@ -49,7 +53,9 @@ class TaskList(models.Model):
|
||||
|
||||
class Task(models.Model):
|
||||
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)
|
||||
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)
|
||||
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()
|
||||
taskmanager = TaskManager()
|
||||
|
||||
@@ -4,5 +4,5 @@ from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='tasks'),
|
||||
path("", views.index, name="tasks"),
|
||||
]
|
||||
|
||||
@@ -17,8 +17,8 @@ def index(request):
|
||||
show_tasklist = None
|
||||
show_all_tasks = True
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'btn_input' in request.POST:
|
||||
if request.method == "POST":
|
||||
if "btn_input" in request.POST:
|
||||
form = TaskForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
@@ -29,13 +29,18 @@ def index(request):
|
||||
task.created_by = request.user
|
||||
task.save()
|
||||
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:
|
||||
task.created_by = request.user
|
||||
task.save()
|
||||
|
||||
elif 'btn_checkbox' in request.POST:
|
||||
for task_id in request.POST.getlist('checkbox'):
|
||||
elif "btn_checkbox" in request.POST:
|
||||
for task_id in request.POST.getlist("checkbox"):
|
||||
task = Task.objects.get(id=task_id)
|
||||
|
||||
if not task.completed:
|
||||
@@ -43,27 +48,31 @@ def index(request):
|
||||
task.completed_date = timezone.now().date()
|
||||
task.save()
|
||||
|
||||
elif 'btn_user' in request.POST:
|
||||
if request.POST['action'] == 'show_incompleted':
|
||||
elif "btn_user" in request.POST:
|
||||
if request.POST["action"] == "show_incompleted":
|
||||
current_action = False
|
||||
else:
|
||||
current_action = True
|
||||
|
||||
if request.POST['tasklist'] != 'all':
|
||||
show_tasklist = TaskList.objects.filter(id=request.POST['tasklist']).first()
|
||||
if request.POST["tasklist"] != "all":
|
||||
show_tasklist = TaskList.objects.filter(
|
||||
id=request.POST["tasklist"]
|
||||
).first()
|
||||
|
||||
if request.POST['tasks'] == 'all':
|
||||
if request.POST["tasks"] == "all":
|
||||
show_all_tasks = True
|
||||
else:
|
||||
show_all_tasks = False
|
||||
|
||||
form = TaskForm()
|
||||
tasks = deque(Task.taskmanager.get_tasks(
|
||||
user=current_user,
|
||||
completed=current_action,
|
||||
task_list=show_tasklist,
|
||||
all_tasks=show_all_tasks
|
||||
))
|
||||
tasks = deque(
|
||||
Task.taskmanager.get_tasks(
|
||||
user=current_user,
|
||||
completed=current_action,
|
||||
task_list=show_tasklist,
|
||||
all_tasks=show_all_tasks,
|
||||
)
|
||||
)
|
||||
tasklists = deque(TaskList.objects.all())
|
||||
|
||||
context = {
|
||||
@@ -74,4 +83,4 @@ def index(request):
|
||||
"current_action": current_action,
|
||||
}
|
||||
|
||||
return render(request, 'tasks/index.html', context)
|
||||
return render(request, "tasks/index.html", context)
|
||||
|
||||
Reference in New Issue
Block a user