diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 34aca70fe5e6276d60749bf11cf73d974a1c90eb..809f80719cce1542d5f9d3e833c01218e463494a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,5 @@
 linter:
-  image: registry.git.fsmpi.rwth-aachen.de/videoaginfra/testenvs/stretch
+  image: registry.git.fsmpi.rwth-aachen.de/videoaginfra/testenvs/bullseye
   stage: test
   script:
   - uname -a
@@ -11,7 +11,7 @@ linter:
       - pylint.txt
 
 unittest: &unittest
-  image: registry.git.fsmpi.rwth-aachen.de/videoaginfra/testenvs/stretch
+  image: registry.git.fsmpi.rwth-aachen.de/videoaginfra/testenvs/bullseye
   stage: test
   script:
   - uname -a
@@ -25,27 +25,3 @@ unittest: &unittest
       - htmlcov/*
       - .coverage
       - report.txt
-
-# Buster is not supported for now
-#
-#unittest_buster:
-#  <<: *unittest
-#  image: debian:buster
-#
-#livetest:
-#  image: debian:stretch
-#  stage: test
-#  script:
-#  - apt update
-#  - apt install -y python3
-#  - python3 -V
-#  - uname -a
-#  - apt install -y python3-requests
-#    - ./tests/urlcheck_sinf.py
-#
-#deploy_staging:
-#  image: archlinux/base
-#  stage: deploy
-#  script:
-#  - pacman --noconfirm -Sy ansible git
-#
diff --git a/.pylintrc b/.pylintrc
index 836f4d0e9e8555ca2c4b3f7b06d9443f76ea17f7..243cf271f16c69bd4cce874bdeb3261ea1e7492c 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -60,97 +60,29 @@ confidence=
 # --enable=similarities". If you want to run only the classes checker, but have
 # no Warning level messages displayed, use "--disable=all --enable=classes
 # --disable=W".
-disable=missing-module-docstring,
-        missing-class-docstring,
+disable=consider-using-dict-items,
+        consider-using-f-string,
+        consider-using-with,
+        cyclic-import, # remove me later, should be fixed but needs major refactoring
+        function-redefined, # remove me later
+        implicit-str-concat,
+        invalid-name,
+        line-too-long,
         missing-function-docstring,
+        missing-module-docstring,
+        no-else-return,
         pointless-string-statement, # docstrings were misdetected
-        print-statement,
-        parameter-unpacking,
-        unpacking-in-except,
-        old-raise-syntax,
-        backtick,
-        long-suffix,
-        old-ne-operator,
-        old-octal-literal,
-        import-star-module-level,
-        non-ascii-bytes-literal,
-        raw-checker-failed,
-        bad-inline-option,
-        locally-disabled,
-        file-ignored,
-        suppressed-message,
-        useless-suppression,
-        deprecated-pragma,
-        use-symbolic-message-instead,
-        unused-wildcard-import,
-        apply-builtin,
-        basestring-builtin,
-        buffer-builtin,
-        cmp-builtin,
-        coerce-builtin,
-        execfile-builtin,
-        file-builtin,
-        long-builtin,
-        raw_input-builtin,
-        reduce-builtin,
-        standarderror-builtin,
-        unicode-builtin,
-        xrange-builtin,
-        coerce-method,
-        delslice-method,
-        getslice-method,
-        setslice-method,
-        no-absolute-import,
-        old-division,
-        dict-iter-method,
-        dict-view-method,
-        next-method-called,
-        metaclass-assignment,
-        indexing-exception,
-        raising-string,
-        reload-builtin,
-        oct-method,
-        hex-method,
-        nonzero-method,
-        cmp-method,
-        input-builtin,
-        round-builtin,
-        intern-builtin,
-        unichr-builtin,
-        map-builtin-not-iterating,
-        zip-builtin-not-iterating,
-        range-builtin-not-iterating,
-        filter-builtin-not-iterating,
-        using-cmp-argument,
-        eq-without-hash,
-        div-method,
-        idiv-method,
-        rdiv-method,
-        exception-message-attribute,
-        invalid-str-codec,
-        sys-max-int,
-        bad-python3-import,
-        deprecated-string-function,
-        deprecated-str-translate-call,
-        deprecated-itertools-function,
-        deprecated-types-field,
-        next-method-defined,
-        dict-items-not-iterating,
-        dict-keys-not-iterating,
-        dict-values-not-iterating,
-        deprecated-operator-function,
-        deprecated-urllib-function,
-        xreadlines-attribute,
-        deprecated-sys-function,
-        exception-escape,
-        comprehension-escape,
-        wildcard-import,
-        bad-continuation, # remove me later
         redefined-builtin,
         redefined-outer-name, # remove me later
-        function-redefined,  # remove me later
-        cyclic-import, # remove me later, should be fixed but needs major refactoring
-        no-else-return
+        too-many-return-statements,
+        trailing-whitespace,
+        unneeded-not,
+        unspecified-encoding,
+        unused-variable,
+        unused-wildcard-import,
+        use-implicit-booleaness-not-comparison,
+        use-maxsplit-arg,
+        wildcard-import
 
 # Enable the message, report, category or checker with the given id(s). You can
 # either give multiple identifier separated by comma (,) or put this option
@@ -471,13 +403,6 @@ max-line-length=160
 # Maximum number of lines in a module.
 max-module-lines=1000
 
-# List of optional constructs for which whitespace checking is disabled. `dict-
-# separator` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}.
-# `trailing-comma` allows a space between comma and closing bracket: (a, ).
-# `empty-line` allows space-only lines.
-no-space-check=trailing-comma,
-               dict-separator
-
 # Allow the body of a class to be on the same line as the declaration if body
 # contains single statement.
 single-line-class-stmt=no
diff --git a/db_schema.sql b/db_schema.sql
index 71b31287516a33622eab6d97ed0ac78d83000b15..eb3f8f059feddad5ad27ab9f7df2a3bee51f46cb 100644
--- a/db_schema.sql
+++ b/db_schema.sql
@@ -47,7 +47,7 @@ CREATE TABLE IF NOT EXISTS `courses_data` (
   `deleted` INTEGER NOT NULL DEFAULT '0',
   `title` text NOT NULL DEFAULT '',
   `short` varchar(32) NOT NULL DEFAULT '',
-  `handle` varchar(32) NOT NULL DEFAULT '',
+  `handle` varchar(32) NOT NULL,
   `organizer` text NOT NULL DEFAULT '',
   `subject` varchar(32) NOT NULL DEFAULT '',
   `credits` INTEGER NOT NULL DEFAULT '0',
@@ -260,8 +260,8 @@ CREATE TABLE IF NOT EXISTS `announcements` (
 	`level` INTEGER NOT NULL DEFAULT 0,
 	`visible` INTEGER NOT NULL DEFAULT 0,
 	`deleted` INTEGER NOT NULL DEFAULT 0,
-  `time_publish` datetime DEFAULT '',
-  `time_expire` datetime DEFAULT '',
+  `time_publish` datetime,
+  `time_expire` datetime,
   `time_created` datetime NOT NULL,
   `time_updated` datetime NOT NULL,
   `created_by` INTEGER NOT NULL
@@ -271,7 +271,7 @@ CREATE TABLE IF NOT EXISTS `featured` (
 	`title` text NOT NULL DEFAULT '',
 	`text` text NOT NULL DEFAULT '',
 	`internal` text NOT NULL DEFAULT '',
-	`type` varchar(32) NOT NULL DEFAULT '',
+	`type` varchar(32) NOT NULL,
 	`param` text NOT NULL DEFAULT '',
 	`param2` text NOT NULL DEFAULT '',
 	`order` INTEGER DEFAULT NULL,
diff --git a/server.py b/server.py
index 8600c2b78d02ef6287aeb5c3ef069504e104396a..36ebc5a60ab56016d15672b756c522b7f2cc1fd1 100644
--- a/server.py
+++ b/server.py
@@ -104,11 +104,19 @@ def handle_errors(endpoint, text, code, *errors, **epargs):
 		return decorator
 	return wrapper
 
+@app.errorhandler(400)
+def handle_bad_request(e=None): #pylint: disable=unused-argument
+	return render_endpoint('index', 'Diese Seite existiert nicht!'), 400
+
 @app.errorhandler(404)
 @app.route('/invalidpath')
 def handle_not_found(e=None): #pylint: disable=unused-argument
 	return render_endpoint('index', 'Diese Seite existiert nicht!'), 404
 
+@app.errorhandler(405)
+def handle_method_not_allowed(e=None): #pylint: disable=unused-argument
+	return render_endpoint('index', 'Diese Seite existiert nicht!'), 405
+
 @app.errorhandler(500)
 @app.errorhandler(Exception)
 def handle_internal_error(e): #pylint: disable=unused-argument