We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix time representation in event form
Currently, an event is seen as all day long if and only if `start_time` equals 00:00 and `end_time` equals 23:59.
This results in an interesting bug: in the case where `start_time` and `end_time` of an event are manually set to these values, the fields in the form are not displayed upon reload but the corresponding checkbox also isn't checked.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `backend/cms/models/events/event_translation.py`
Content:
```
1 """Class defining event-related database models
2 
3 Raises:
4     ValidationError: Raised when an value does not match the requirements
5 """
6 from django.conf import settings
7 from django.db import models
8 from django.utils import timezone
9 
10 from .event import Event
11 from ..languages.language import Language
12 from ...constants import status
13 
14 
15 class EventTranslation(models.Model):
16     """
17     Database object representing an event translation
18     """
19 
20     event = models.ForeignKey(Event, related_name='translations', on_delete=models.CASCADE)
21     slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)
22     status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)
23     title = models.CharField(max_length=250)
24     description = models.TextField()
25     language = models.ForeignKey(
26         Language,
27         related_name='event_translations',
28         on_delete=models.CASCADE
29     )
30     currently_in_translation = models.BooleanField(default=False)
31     version = models.PositiveIntegerField(default=0)
32     minor_edit = models.BooleanField(default=False)
33     creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)
34     created_date = models.DateTimeField(default=timezone.now)
35     last_updated = models.DateTimeField(auto_now=True)
36 
37     @property
38     def foreign_object(self):
39         return self.event
40 
41     @property
42     def permalink(self):
43         return '/'.join([
44             self.event.region.slug,
45             self.language.code,
46             'events',
47             self.slug
48         ])
49 
50     def __str__(self):
51         return self.title
52 
53     class Meta:
54         ordering = ['event', '-version']
55         default_permissions = ()
56
```

Path: `setup.py`
Content:
```
1 #!/usr/bin/env python3
2 
3 import os
4 
5 from setuptools import find_packages, setup
6 
7 setup(
8     name="integreat_cms",
9     version="0.0.13",
10     packages=find_packages("backend"),
11     package_dir={'':'backend'},
12     include_package_data=True,
13     scripts=['backend/integreat-cms'],
14     data_files= [("lib/integreat-{}".format(root), [os.path.join(root, f) for f in files])
15                  for root, dirs, files in os.walk('backend/cms/templates/')] +
16                 [("lib/integreat-{}".format(root), [os.path.join(root, f) for f in files])
17                  for root, dirs, files in os.walk('backend/cms/static/')] +
18                 [('usr/lib/systemd/system/', ['systemd/integreat-cms@.service'])],
19     install_requires=[
20         "beautifulsoup4",
21         "cffi",
22         "Django==2.2.8",
23         "django-filer",
24         "django-mptt",
25         "django-widget-tweaks",
26         "idna",
27         "lxml",
28         "psycopg2-binary",
29         "python-dateutil",
30         "requests",
31         "rules",
32         "six",
33         "webauthn",
34     ],
35     extras_require={
36         "dev": [
37             "django-compressor",
38             "django-compressor-toolkit",
39             "packaging",
40             "pylint",
41             "pylint-django",
42             "pylint_runner",
43         ]
44     },
45     author="Integreat App Project",
46     author_email="info@integreat-app.de",
47     description="Content Management System for the Integreat App",
48     license="GPL-2.0-or-later",
49     keywords="Django Integreat CMS",
50     url="http://github.com/Integreat/",
51     classifiers=[
52         'Development Status :: 5 - Production/Stable',
53         'Intended Audience :: Developers',
54         'Programming Language :: Python :: 3.4',
55         'Programming Language :: Python :: 3.5',
56         'Programming Language :: Python :: 3.6',
57     ]
58 )
59
```

Path: `backend/cms/forms/events/event_form.py`
Content:
```
1 """
2 Form for creating or saving event objects and their corresponding event translation objects
3 """
4 import logging
5 
6 from datetime import time
7 
8 from django import forms
9 from django.utils.translation import ugettext as _
10 
11 from ...models import Event
12 
13 logger = logging.getLogger(__name__)
14 
15 
16 class EventForm(forms.ModelForm):
17     is_all_day = forms.BooleanField(required=False)
18     is_recurring = forms.BooleanField(required=False)
19 
20     class Meta:
21         model = Event
22         fields = [
23             'start_date',
24             'start_time',
25             'end_date',
26             'end_time',
27             'picture'
28         ]
29         widgets = {
30             'start_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}),
31             'end_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}),
32             'start_time': forms.TimeInput(format='%H:%M', attrs={'type': 'time'}),
33             'end_time': forms.TimeInput(format='%H:%M', attrs={'type': 'time'}),
34         }
35 
36     def __init__(self, data=None, instance=None, disabled=False):
37         logger.info('EventForm instantiated with data %s and instance %s', data, instance)
38 
39         # Instantiate ModelForm
40         super(EventForm, self).__init__(data=data, instance=instance)
41 
42         if self.instance.id:
43             # Initialize BooleanFields based on Event properties
44             self.fields['is_all_day'].initial = self.instance.is_all_day
45             self.fields['is_recurring'].initial = self.instance.is_recurring
46 
47         # If form is disabled because the user has no permissions to edit the page, disable all form fields
48         if disabled:
49             for _, field in self.fields.items():
50                 field.disabled = True
51 
52     #pylint: disable=arguments-differ
53     def save(self, region=None, recurrence_rule=None):
54         logger.info('EventForm saved with cleaned data %s and changed data %s', self.cleaned_data, self.changed_data)
55 
56         # Disable instant commit on saving because missing information would cause errors
57         event = super(EventForm, self).save(commit=False)
58 
59         if not self.instance.id:
60             # Set initial values on event creation
61             event.region = region
62 
63         if event.recurrence_rule and not recurrence_rule:
64             # Delete old recurrence rule from database in order to not spam the database with unused objects
65             event.recurrence_rule.delete()
66         event.recurrence_rule = recurrence_rule
67 
68         event.save()
69         return event
70 
71     def clean(self):
72         cleaned_data = super(EventForm, self).clean()
73 
74         # If at least one of the time fields are missing, check if is_all_day is set
75         if not cleaned_data.get('start_time'):
76             if cleaned_data.get('is_all_day'):
77                 cleaned_data['start_time'] = time.min
78             else:
79                 self.add_error('start_time', forms.ValidationError(_('If the event is not all-day, the start time is required'), code='required'))
80         if not cleaned_data.get('end_time'):
81             if cleaned_data.get('is_all_day'):
82                 # Strip seconds and microseconds because our time fields only has hours and minutes
83                 cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)
84             else:
85                 self.add_error('end_time', forms.ValidationError(_('If the event is not all-day, the end time is required'), code='required'))
86 
87         if cleaned_data.get('end_date') and cleaned_data.get('start_date'):
88             if cleaned_data.get('end_date') < cleaned_data.get('start_date'):
89                 # If both dates are given, check if they are valid
90                 self.add_error('end_date', forms.ValidationError(_('The end of the event can\'t be before the start of the event'), code='invalid'))
91             elif cleaned_data.get('end_date') == cleaned_data.get('start_date'):
92                 # If both dates are identical, check the times
93                 if cleaned_data.get('end_time') and cleaned_data.get('start_time'):
94                     # If both times are given, check if they are valid
95                     if cleaned_data.get('end_time') < cleaned_data.get('start_time'):
96                         self.add_error('end_time', forms.ValidationError(_('The end of the event can\'t be before the start of the event'), code='invalid'))
97 
98         return cleaned_data
99 
100     def has_changed(self):
101         # The change of all-day does not represent anything in the model
102         try:
103             self.changed_data.remove('is_all_day')
104         except ValueError:
105             pass
106         return super(EventForm, self).has_changed()
107
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/backend/cms/forms/events/event_form.py b/backend/cms/forms/events/event_form.py
--- a/backend/cms/forms/events/event_form.py
+++ b/backend/cms/forms/events/event_form.py
@@ -70,19 +70,25 @@
 
     def clean(self):
         cleaned_data = super(EventForm, self).clean()
-
-        # If at least one of the time fields are missing, check if is_all_day is set
-        if not cleaned_data.get('start_time'):
-            if cleaned_data.get('is_all_day'):
-                cleaned_data['start_time'] = time.min
-            else:
+        logger.info('EventForm cleaned [1/2] with cleaned data %s', cleaned_data)
+
+        # make self.data mutable to allow values to be changed manually
+        self.data = self.data.copy()
+
+        if cleaned_data.get('is_all_day'):
+            cleaned_data['start_time'] = time.min
+            self.data['start_time'] = time.min
+            # Strip seconds and microseconds because our time fields only has hours and minutes
+            cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)
+            self.data['end_time'] = time.max.replace(second=0, microsecond=0)
+        else:
+            # If at least one of the time fields are missing, show an error
+            if not cleaned_data.get('start_time'):
                 self.add_error('start_time', forms.ValidationError(_('If the event is not all-day, the start time is required'), code='required'))
-        if not cleaned_data.get('end_time'):
-            if cleaned_data.get('is_all_day'):
-                # Strip seconds and microseconds because our time fields only has hours and minutes
-                cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)
-            else:
+            if not cleaned_data.get('end_time'):
                 self.add_error('end_time', forms.ValidationError(_('If the event is not all-day, the end time is required'), code='required'))
+            elif cleaned_data['start_time'] == time.min and cleaned_data['end_time'] == time.max.replace(second=0, microsecond=0):
+                self.data['is_all_day'] = True
 
         if cleaned_data.get('end_date') and cleaned_data.get('start_date'):
             if cleaned_data.get('end_date') < cleaned_data.get('start_date'):
@@ -95,12 +101,6 @@
                     if cleaned_data.get('end_time') < cleaned_data.get('start_time'):
                         self.add_error('end_time', forms.ValidationError(_('The end of the event can\'t be before the start of the event'), code='invalid'))
 
-        return cleaned_data
+        logger.info('EventForm cleaned [2/2] with cleaned data %s', cleaned_data)
 
-    def has_changed(self):
-        # The change of all-day does not represent anything in the model
-        try:
-            self.changed_data.remove('is_all_day')
-        except ValueError:
-            pass
-        return super(EventForm, self).has_changed()
+        return cleaned_data
diff --git a/backend/cms/models/events/event_translation.py b/backend/cms/models/events/event_translation.py
--- a/backend/cms/models/events/event_translation.py
+++ b/backend/cms/models/events/event_translation.py
@@ -21,7 +21,7 @@
     slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)
     status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)
     title = models.CharField(max_length=250)
-    description = models.TextField()
+    description = models.TextField(blank=True)
     language = models.ForeignKey(
         Language,
         related_name='event_translations',
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@
     install_requires=[
         "beautifulsoup4",
         "cffi",
-        "Django==2.2.8",
+        "Django==2.2.9",
         "django-filer",
         "django-mptt",
         "django-widget-tweaks",

{"golden_diff": "diff --git a/backend/cms/forms/events/event_form.py b/backend/cms/forms/events/event_form.py\n--- a/backend/cms/forms/events/event_form.py\n+++ b/backend/cms/forms/events/event_form.py\n@@ -70,19 +70,25 @@\n \n     def clean(self):\n         cleaned_data = super(EventForm, self).clean()\n-\n-        # If at least one of the time fields are missing, check if is_all_day is set\n-        if not cleaned_data.get('start_time'):\n-            if cleaned_data.get('is_all_day'):\n-                cleaned_data['start_time'] = time.min\n-            else:\n+        logger.info('EventForm cleaned [1/2] with cleaned data %s', cleaned_data)\n+\n+        # make self.data mutable to allow values to be changed manually\n+        self.data = self.data.copy()\n+\n+        if cleaned_data.get('is_all_day'):\n+            cleaned_data['start_time'] = time.min\n+            self.data['start_time'] = time.min\n+            # Strip seconds and microseconds because our time fields only has hours and minutes\n+            cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)\n+            self.data['end_time'] = time.max.replace(second=0, microsecond=0)\n+        else:\n+            # If at least one of the time fields are missing, show an error\n+            if not cleaned_data.get('start_time'):\n                 self.add_error('start_time', forms.ValidationError(_('If the event is not all-day, the start time is required'), code='required'))\n-        if not cleaned_data.get('end_time'):\n-            if cleaned_data.get('is_all_day'):\n-                # Strip seconds and microseconds because our time fields only has hours and minutes\n-                cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)\n-            else:\n+            if not cleaned_data.get('end_time'):\n                 self.add_error('end_time', forms.ValidationError(_('If the event is not all-day, the end time is required'), code='required'))\n+            elif cleaned_data['start_time'] == time.min and cleaned_data['end_time'] == time.max.replace(second=0, microsecond=0):\n+                self.data['is_all_day'] = True\n \n         if cleaned_data.get('end_date') and cleaned_data.get('start_date'):\n             if cleaned_data.get('end_date') < cleaned_data.get('start_date'):\n@@ -95,12 +101,6 @@\n                     if cleaned_data.get('end_time') < cleaned_data.get('start_time'):\n                         self.add_error('end_time', forms.ValidationError(_('The end of the event can\\'t be before the start of the event'), code='invalid'))\n \n-        return cleaned_data\n+        logger.info('EventForm cleaned [2/2] with cleaned data %s', cleaned_data)\n \n-    def has_changed(self):\n-        # The change of all-day does not represent anything in the model\n-        try:\n-            self.changed_data.remove('is_all_day')\n-        except ValueError:\n-            pass\n-        return super(EventForm, self).has_changed()\n+        return cleaned_data\ndiff --git a/backend/cms/models/events/event_translation.py b/backend/cms/models/events/event_translation.py\n--- a/backend/cms/models/events/event_translation.py\n+++ b/backend/cms/models/events/event_translation.py\n@@ -21,7 +21,7 @@\n     slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)\n     status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)\n     title = models.CharField(max_length=250)\n-    description = models.TextField()\n+    description = models.TextField(blank=True)\n     language = models.ForeignKey(\n         Language,\n         related_name='event_translations',\ndiff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -19,7 +19,7 @@\n     install_requires=[\n         \"beautifulsoup4\",\n         \"cffi\",\n-        \"Django==2.2.8\",\n+        \"Django==2.2.9\",\n         \"django-filer\",\n         \"django-mptt\",\n         \"django-widget-tweaks\",\n", "issue": "Fix time representation in event form\nCurrently, an event is seen as all day long if and only if `start_time` equals 00:00 and `end_time` equals 23:59.\r\nThis results in an interesting bug: in the case where `start_time` and `end_time` of an event are manually set to these values, the fields in the form are not displayed upon reload but the corresponding checkbox also isn't checked.\n", "before_files": [{"content": "\"\"\"Class defining event-related database models\n\nRaises:\n    ValidationError: Raised when an value does not match the requirements\n\"\"\"\nfrom django.conf import settings\nfrom django.db import models\nfrom django.utils import timezone\n\nfrom .event import Event\nfrom ..languages.language import Language\nfrom ...constants import status\n\n\nclass EventTranslation(models.Model):\n    \"\"\"\n    Database object representing an event translation\n    \"\"\"\n\n    event = models.ForeignKey(Event, related_name='translations', on_delete=models.CASCADE)\n    slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)\n    status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)\n    title = models.CharField(max_length=250)\n    description = models.TextField()\n    language = models.ForeignKey(\n        Language,\n        related_name='event_translations',\n        on_delete=models.CASCADE\n    )\n    currently_in_translation = models.BooleanField(default=False)\n    version = models.PositiveIntegerField(default=0)\n    minor_edit = models.BooleanField(default=False)\n    creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)\n    created_date = models.DateTimeField(default=timezone.now)\n    last_updated = models.DateTimeField(auto_now=True)\n\n    @property\n    def foreign_object(self):\n        return self.event\n\n    @property\n    def permalink(self):\n        return '/'.join([\n            self.event.region.slug,\n            self.language.code,\n            'events',\n            self.slug\n        ])\n\n    def __str__(self):\n        return self.title\n\n    class Meta:\n        ordering = ['event', '-version']\n        default_permissions = ()\n", "path": "backend/cms/models/events/event_translation.py"}, {"content": "#!/usr/bin/env python3\n\nimport os\n\nfrom setuptools import find_packages, setup\n\nsetup(\n    name=\"integreat_cms\",\n    version=\"0.0.13\",\n    packages=find_packages(\"backend\"),\n    package_dir={'':'backend'},\n    include_package_data=True,\n    scripts=['backend/integreat-cms'],\n    data_files= [(\"lib/integreat-{}\".format(root), [os.path.join(root, f) for f in files])\n                 for root, dirs, files in os.walk('backend/cms/templates/')] +\n                [(\"lib/integreat-{}\".format(root), [os.path.join(root, f) for f in files])\n                 for root, dirs, files in os.walk('backend/cms/static/')] +\n                [('usr/lib/systemd/system/', ['systemd/integreat-cms@.service'])],\n    install_requires=[\n        \"beautifulsoup4\",\n        \"cffi\",\n        \"Django==2.2.8\",\n        \"django-filer\",\n        \"django-mptt\",\n        \"django-widget-tweaks\",\n        \"idna\",\n        \"lxml\",\n        \"psycopg2-binary\",\n        \"python-dateutil\",\n        \"requests\",\n        \"rules\",\n        \"six\",\n        \"webauthn\",\n    ],\n    extras_require={\n        \"dev\": [\n            \"django-compressor\",\n            \"django-compressor-toolkit\",\n            \"packaging\",\n            \"pylint\",\n            \"pylint-django\",\n            \"pylint_runner\",\n        ]\n    },\n    author=\"Integreat App Project\",\n    author_email=\"info@integreat-app.de\",\n    description=\"Content Management System for the Integreat App\",\n    license=\"GPL-2.0-or-later\",\n    keywords=\"Django Integreat CMS\",\n    url=\"http://github.com/Integreat/\",\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'Intended Audience :: Developers',\n        'Programming Language :: Python :: 3.4',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n    ]\n)\n", "path": "setup.py"}, {"content": "\"\"\"\nForm for creating or saving event objects and their corresponding event translation objects\n\"\"\"\nimport logging\n\nfrom datetime import time\n\nfrom django import forms\nfrom django.utils.translation import ugettext as _\n\nfrom ...models import Event\n\nlogger = logging.getLogger(__name__)\n\n\nclass EventForm(forms.ModelForm):\n    is_all_day = forms.BooleanField(required=False)\n    is_recurring = forms.BooleanField(required=False)\n\n    class Meta:\n        model = Event\n        fields = [\n            'start_date',\n            'start_time',\n            'end_date',\n            'end_time',\n            'picture'\n        ]\n        widgets = {\n            'start_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}),\n            'end_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}),\n            'start_time': forms.TimeInput(format='%H:%M', attrs={'type': 'time'}),\n            'end_time': forms.TimeInput(format='%H:%M', attrs={'type': 'time'}),\n        }\n\n    def __init__(self, data=None, instance=None, disabled=False):\n        logger.info('EventForm instantiated with data %s and instance %s', data, instance)\n\n        # Instantiate ModelForm\n        super(EventForm, self).__init__(data=data, instance=instance)\n\n        if self.instance.id:\n            # Initialize BooleanFields based on Event properties\n            self.fields['is_all_day'].initial = self.instance.is_all_day\n            self.fields['is_recurring'].initial = self.instance.is_recurring\n\n        # If form is disabled because the user has no permissions to edit the page, disable all form fields\n        if disabled:\n            for _, field in self.fields.items():\n                field.disabled = True\n\n    #pylint: disable=arguments-differ\n    def save(self, region=None, recurrence_rule=None):\n        logger.info('EventForm saved with cleaned data %s and changed data %s', self.cleaned_data, self.changed_data)\n\n        # Disable instant commit on saving because missing information would cause errors\n        event = super(EventForm, self).save(commit=False)\n\n        if not self.instance.id:\n            # Set initial values on event creation\n            event.region = region\n\n        if event.recurrence_rule and not recurrence_rule:\n            # Delete old recurrence rule from database in order to not spam the database with unused objects\n            event.recurrence_rule.delete()\n        event.recurrence_rule = recurrence_rule\n\n        event.save()\n        return event\n\n    def clean(self):\n        cleaned_data = super(EventForm, self).clean()\n\n        # If at least one of the time fields are missing, check if is_all_day is set\n        if not cleaned_data.get('start_time'):\n            if cleaned_data.get('is_all_day'):\n                cleaned_data['start_time'] = time.min\n            else:\n                self.add_error('start_time', forms.ValidationError(_('If the event is not all-day, the start time is required'), code='required'))\n        if not cleaned_data.get('end_time'):\n            if cleaned_data.get('is_all_day'):\n                # Strip seconds and microseconds because our time fields only has hours and minutes\n                cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)\n            else:\n                self.add_error('end_time', forms.ValidationError(_('If the event is not all-day, the end time is required'), code='required'))\n\n        if cleaned_data.get('end_date') and cleaned_data.get('start_date'):\n            if cleaned_data.get('end_date') < cleaned_data.get('start_date'):\n                # If both dates are given, check if they are valid\n                self.add_error('end_date', forms.ValidationError(_('The end of the event can\\'t be before the start of the event'), code='invalid'))\n            elif cleaned_data.get('end_date') == cleaned_data.get('start_date'):\n                # If both dates are identical, check the times\n                if cleaned_data.get('end_time') and cleaned_data.get('start_time'):\n                    # If both times are given, check if they are valid\n                    if cleaned_data.get('end_time') < cleaned_data.get('start_time'):\n                        self.add_error('end_time', forms.ValidationError(_('The end of the event can\\'t be before the start of the event'), code='invalid'))\n\n        return cleaned_data\n\n    def has_changed(self):\n        # The change of all-day does not represent anything in the model\n        try:\n            self.changed_data.remove('is_all_day')\n        except ValueError:\n            pass\n        return super(EventForm, self).has_changed()\n", "path": "backend/cms/forms/events/event_form.py"}], "after_files": [{"content": "\"\"\"Class defining event-related database models\n\nRaises:\n    ValidationError: Raised when an value does not match the requirements\n\"\"\"\nfrom django.conf import settings\nfrom django.db import models\nfrom django.utils import timezone\n\nfrom .event import Event\nfrom ..languages.language import Language\nfrom ...constants import status\n\n\nclass EventTranslation(models.Model):\n    \"\"\"\n    Database object representing an event translation\n    \"\"\"\n\n    event = models.ForeignKey(Event, related_name='translations', on_delete=models.CASCADE)\n    slug = models.SlugField(max_length=200, blank=True, allow_unicode=True)\n    status = models.CharField(max_length=6, choices=status.CHOICES, default=status.DRAFT)\n    title = models.CharField(max_length=250)\n    description = models.TextField(blank=True)\n    language = models.ForeignKey(\n        Language,\n        related_name='event_translations',\n        on_delete=models.CASCADE\n    )\n    currently_in_translation = models.BooleanField(default=False)\n    version = models.PositiveIntegerField(default=0)\n    minor_edit = models.BooleanField(default=False)\n    creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL)\n    created_date = models.DateTimeField(default=timezone.now)\n    last_updated = models.DateTimeField(auto_now=True)\n\n    @property\n    def foreign_object(self):\n        return self.event\n\n    @property\n    def permalink(self):\n        return '/'.join([\n            self.event.region.slug,\n            self.language.code,\n            'events',\n            self.slug\n        ])\n\n    def __str__(self):\n        return self.title\n\n    class Meta:\n        ordering = ['event', '-version']\n        default_permissions = ()\n", "path": "backend/cms/models/events/event_translation.py"}, {"content": "#!/usr/bin/env python3\n\nimport os\n\nfrom setuptools import find_packages, setup\n\nsetup(\n    name=\"integreat_cms\",\n    version=\"0.0.13\",\n    packages=find_packages(\"backend\"),\n    package_dir={'':'backend'},\n    include_package_data=True,\n    scripts=['backend/integreat-cms'],\n    data_files= [(\"lib/integreat-{}\".format(root), [os.path.join(root, f) for f in files])\n                 for root, dirs, files in os.walk('backend/cms/templates/')] +\n                [(\"lib/integreat-{}\".format(root), [os.path.join(root, f) for f in files])\n                 for root, dirs, files in os.walk('backend/cms/static/')] +\n                [('usr/lib/systemd/system/', ['systemd/integreat-cms@.service'])],\n    install_requires=[\n        \"beautifulsoup4\",\n        \"cffi\",\n        \"Django==2.2.9\",\n        \"django-filer\",\n        \"django-mptt\",\n        \"django-widget-tweaks\",\n        \"idna\",\n        \"lxml\",\n        \"psycopg2-binary\",\n        \"python-dateutil\",\n        \"requests\",\n        \"rules\",\n        \"six\",\n        \"webauthn\",\n    ],\n    extras_require={\n        \"dev\": [\n            \"django-compressor\",\n            \"django-compressor-toolkit\",\n            \"packaging\",\n            \"pylint\",\n            \"pylint-django\",\n            \"pylint_runner\",\n        ]\n    },\n    author=\"Integreat App Project\",\n    author_email=\"info@integreat-app.de\",\n    description=\"Content Management System for the Integreat App\",\n    license=\"GPL-2.0-or-later\",\n    keywords=\"Django Integreat CMS\",\n    url=\"http://github.com/Integreat/\",\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'Intended Audience :: Developers',\n        'Programming Language :: Python :: 3.4',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n    ]\n)\n", "path": "setup.py"}, {"content": "\"\"\"\nForm for creating or saving event objects and their corresponding event translation objects\n\"\"\"\nimport logging\n\nfrom datetime import time\n\nfrom django import forms\nfrom django.utils.translation import ugettext as _\n\nfrom ...models import Event\n\nlogger = logging.getLogger(__name__)\n\n\nclass EventForm(forms.ModelForm):\n    is_all_day = forms.BooleanField(required=False)\n    is_recurring = forms.BooleanField(required=False)\n\n    class Meta:\n        model = Event\n        fields = [\n            'start_date',\n            'start_time',\n            'end_date',\n            'end_time',\n            'picture'\n        ]\n        widgets = {\n            'start_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}),\n            'end_date': forms.DateInput(format='%Y-%m-%d', attrs={'type': 'date'}),\n            'start_time': forms.TimeInput(format='%H:%M', attrs={'type': 'time'}),\n            'end_time': forms.TimeInput(format='%H:%M', attrs={'type': 'time'}),\n        }\n\n    def __init__(self, data=None, instance=None, disabled=False):\n        logger.info('EventForm instantiated with data %s and instance %s', data, instance)\n\n        # Instantiate ModelForm\n        super(EventForm, self).__init__(data=data, instance=instance)\n\n        if self.instance.id:\n            # Initialize BooleanFields based on Event properties\n            self.fields['is_all_day'].initial = self.instance.is_all_day\n            self.fields['is_recurring'].initial = self.instance.is_recurring\n\n        # If form is disabled because the user has no permissions to edit the page, disable all form fields\n        if disabled:\n            for _, field in self.fields.items():\n                field.disabled = True\n\n    #pylint: disable=arguments-differ\n    def save(self, region=None, recurrence_rule=None):\n        logger.info('EventForm saved with cleaned data %s and changed data %s', self.cleaned_data, self.changed_data)\n\n        # Disable instant commit on saving because missing information would cause errors\n        event = super(EventForm, self).save(commit=False)\n\n        if not self.instance.id:\n            # Set initial values on event creation\n            event.region = region\n\n        if event.recurrence_rule and not recurrence_rule:\n            # Delete old recurrence rule from database in order to not spam the database with unused objects\n            event.recurrence_rule.delete()\n        event.recurrence_rule = recurrence_rule\n\n        event.save()\n        return event\n\n    def clean(self):\n        cleaned_data = super(EventForm, self).clean()\n        logger.info('EventForm cleaned [1/2] with cleaned data %s', cleaned_data)\n\n        # make self.data mutable to allow values to be changed manually\n        self.data = self.data.copy()\n\n        if cleaned_data.get('is_all_day'):\n            cleaned_data['start_time'] = time.min\n            self.data['start_time'] = time.min\n            # Strip seconds and microseconds because our time fields only has hours and minutes\n            cleaned_data['end_time'] = time.max.replace(second=0, microsecond=0)\n            self.data['end_time'] = time.max.replace(second=0, microsecond=0)\n        else:\n            # If at least one of the time fields are missing, show an error\n            if not cleaned_data.get('start_time'):\n                self.add_error('start_time', forms.ValidationError(_('If the event is not all-day, the start time is required'), code='required'))\n            if not cleaned_data.get('end_time'):\n                self.add_error('end_time', forms.ValidationError(_('If the event is not all-day, the end time is required'), code='required'))\n            elif cleaned_data['start_time'] == time.min and cleaned_data['end_time'] == time.max.replace(second=0, microsecond=0):\n                self.data['is_all_day'] = True\n\n        if cleaned_data.get('end_date') and cleaned_data.get('start_date'):\n            if cleaned_data.get('end_date') < cleaned_data.get('start_date'):\n                # If both dates are given, check if they are valid\n                self.add_error('end_date', forms.ValidationError(_('The end of the event can\\'t be before the start of the event'), code='invalid'))\n            elif cleaned_data.get('end_date') == cleaned_data.get('start_date'):\n                # If both dates are identical, check the times\n                if cleaned_data.get('end_time') and cleaned_data.get('start_time'):\n                    # If both times are given, check if they are valid\n                    if cleaned_data.get('end_time') < cleaned_data.get('start_time'):\n                        self.add_error('end_time', forms.ValidationError(_('The end of the event can\\'t be before the start of the event'), code='invalid'))\n\n        logger.info('EventForm cleaned [2/2] with cleaned data %s', cleaned_data)\n\n        return cleaned_data\n", "path": "backend/cms/forms/events/event_form.py"}]}