From 62c65610e1940c77a338e31ad8faff03259e3ce2 Mon Sep 17 00:00:00 2001 From: Santtu Pajukanta Date: Fri, 12 May 2023 22:07:08 +0300 Subject: [PATCH] chore(cosvision2023): new event --- .vscode/settings.json | 10 - events/cosvision2023/__init__.py | 0 events/cosvision2023/admin.py | 3 + events/cosvision2023/forms.py | 201 +++++++++++ events/cosvision2023/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../commands/setup_cosvision2023.py | 316 ++++++++++++++++++ .../cosvision2023/migrations/0001_initial.py | 102 ++++++ events/cosvision2023/migrations/__init__.py | 0 events/cosvision2023/models.py | 77 +++++ kompassi/settings.py | 9 +- 11 files changed, 706 insertions(+), 12 deletions(-) delete mode 100644 .vscode/settings.json create mode 100644 events/cosvision2023/__init__.py create mode 100644 events/cosvision2023/admin.py create mode 100644 events/cosvision2023/forms.py create mode 100644 events/cosvision2023/management/__init__.py create mode 100644 events/cosvision2023/management/commands/__init__.py create mode 100644 events/cosvision2023/management/commands/setup_cosvision2023.py create mode 100644 events/cosvision2023/migrations/0001_initial.py create mode 100644 events/cosvision2023/migrations/__init__.py create mode 100644 events/cosvision2023/models.py diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index d4e750859..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "editor.insertSpaces": true, - "editor.tabSize": 4, - "files.insertFinalNewline": true, - "files.trimTrailingWhitespace": true, - "python.linting.flake8Enabled": true, - "python.linting.pylintEnabled": false, - "python.linting.enabled": false, - "python.pythonPath": "/home/japsu/Hobby/venv3.9-kompassi/bin/python" -} diff --git a/events/cosvision2023/__init__.py b/events/cosvision2023/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/events/cosvision2023/admin.py b/events/cosvision2023/admin.py new file mode 100644 index 000000000..8c38f3f3d --- /dev/null +++ b/events/cosvision2023/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/events/cosvision2023/forms.py b/events/cosvision2023/forms.py new file mode 100644 index 000000000..f043fb2fc --- /dev/null +++ b/events/cosvision2023/forms.py @@ -0,0 +1,201 @@ +from django import forms + +from crispy_forms.layout import Layout, Fieldset + +from core.utils import horizontal_form_helper +from labour.forms import AlternativeFormMixin +from labour.models import Signup, JobCategory +from programme.models import Category, Programme +from programme.forms import AlternativeProgrammeFormMixin + +from .models import SignupExtra + + +class SignupExtraForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = horizontal_form_helper() + self.helper.form_tag = False + self.helper.layout = Layout( + "shift_type", + "total_work", + Fieldset( + "Lisätiedot", + "special_diet", + "special_diet_other", + "prior_experience", + "free_text", + ), + ) + + class Meta: + model = SignupExtra + fields = ( + "shift_type", + "total_work", + "special_diet", + "special_diet_other", + "prior_experience", + "free_text", + ) + + widgets = dict( + special_diet=forms.CheckboxSelectMultiple, + ) + + +class OrganizerSignupForm(forms.ModelForm, AlternativeFormMixin): + def __init__(self, *args, **kwargs): + event = kwargs.pop("event") + admin = kwargs.pop("admin") + + assert not admin + + super().__init__(*args, **kwargs) + + self.helper = horizontal_form_helper() + self.helper.form_tag = False + self.helper.layout = Layout( + Fieldset( + "Tehtävän tiedot", + "job_title", + ), + ) + + self.fields["job_title"].help_text = "Mikä on vastaavatehtäväsi? Printataan badgeen." + # self.fields['job_title'].required = True + + class Meta: + model = Signup + fields = ("job_title",) + + widgets = dict( + job_categories=forms.CheckboxSelectMultiple, + ) + + def get_excluded_m2m_field_defaults(self): + return dict(job_categories=JobCategory.objects.filter(event__slug="cosvision2023", name="Vastaava")) + + +class OrganizerSignupExtraForm(forms.ModelForm, AlternativeFormMixin): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = horizontal_form_helper() + self.helper.form_tag = False + self.helper.layout = Layout( + Fieldset( + "Lisätiedot", + "special_diet", + "special_diet_other", + ), + ) + + class Meta: + model = SignupExtra + fields = ( + "special_diet", + "special_diet_other", + ) + + widgets = dict( + special_diet=forms.CheckboxSelectMultiple, + ) + + def get_excluded_field_defaults(self): + return dict( + shift_type="yli4h", + total_work="yli8h", + prior_experience="", + free_text="Syötetty käyttäen vastaavan ilmoittautumislomaketta", + ) + + def get_excluded_m2m_field_defaults(self): + return dict() + + +class ProgrammeForm(forms.ModelForm, AlternativeProgrammeFormMixin): + def __init__(self, *args, **kwargs): + event = kwargs.pop("event") + if "admin" in kwargs: + admin = kwargs.pop("admin") + else: + admin = False + + super().__init__(*args, **kwargs) + + self.helper = horizontal_form_helper() + self.helper.form_tag = False + + for field_name in [ + "title", + ]: + self.fields[field_name].required = True + + if not admin: + for field_name in [ + "description", + # "video_permission", + # "stream_permission", + "photography", + "rerun", + # "encumbered_content", + ]: + self.fields[field_name].required = True + + self.fields["category"].queryset = Category.objects.filter(event=event, public=True) + self.fields["approximate_length"].initial = 60 + self.fields[ + "approximate_length" + ].help_text = "Arvio ohjelman pituudesta minuutteina. Huomaathan, että lopullinen ohjelmapaikan pituus voi poiketa tästä." + + def get_excluded_field_defaults(self): + return dict() + + class Meta: + model = Programme + fields = ( + "title", + "description", + "approximate_length", + "category", + "computer", + "use_audio", + "use_video", + "number_of_microphones", + "tech_requirements", + # "video_permission", + # "stream_permission", + # "encumbered_content", + "photography", + "rerun", + "room_requirements", + "requested_time_slot", + "notes_from_host", + ) + + +class ProgrammeSignupExtraForm(forms.ModelForm, AlternativeFormMixin): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.helper = horizontal_form_helper() + self.helper.form_tag = False + self.helper.layout = Layout( + "special_diet", + "special_diet_other", + ) + + class Meta: + model = SignupExtra + fields = ( + "special_diet", + "special_diet_other", + ) + + widgets = dict( + special_diet=forms.CheckboxSelectMultiple, + ) + + def get_excluded_field_defaults(self): + return dict( + free_text="Syötetty käyttäen ohjelmanjärjestäjän ilmoittautumislomaketta", + ) diff --git a/events/cosvision2023/management/__init__.py b/events/cosvision2023/management/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/events/cosvision2023/management/commands/__init__.py b/events/cosvision2023/management/commands/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/events/cosvision2023/management/commands/setup_cosvision2023.py b/events/cosvision2023/management/commands/setup_cosvision2023.py new file mode 100644 index 000000000..d43e408e0 --- /dev/null +++ b/events/cosvision2023/management/commands/setup_cosvision2023.py @@ -0,0 +1,316 @@ +from datetime import datetime, timedelta + +from django.conf import settings +from django.core.management.base import BaseCommand +from django.utils.timezone import now + +from dateutil.tz import tzlocal + +from core.utils import full_hours_between + + +class Setup: + def __init__(self): + self._ordering = 0 + + def get_ordering_number(self): + self._ordering += 10 + return self._ordering + + def setup(self, test=False): + self.test = test + self.tz = tzlocal() + self.setup_core() + self.setup_labour() + self.setup_programme() + self.setup_badges() + self.setup_intra() + + def setup_core(self): + from core.models import Venue, Event, Organization + + self.venue, unused = Venue.objects.get_or_create( + name="Espoon kulttuurikeskus", + defaults=dict( + name_inessive="Espoon kulttuurikeskuksessa", + ), + ) + self.organization, unused = Organization.objects.get_or_create( + slug="cosvision-ry", + defaults=dict( + name="Cosvision ry", + homepage_url="https://www.cosvision.fi", + ), + ) + self.event, unused = Event.objects.get_or_create( + slug="cosvision2023", + defaults=dict( + name="Cosvision (2023)", + name_genitive="Cosvisionissa", + name_illative="Cosvisioniin", + name_inessive="Cosvisionissa", + homepage_url="http://www.cosvision.fi", + organization=self.organization, + start_time=datetime(2023, 11, 25, 10, 0, tzinfo=self.tz), + end_time=datetime(2023, 11, 25, 19, 0, tzinfo=self.tz), + venue=self.venue, + ), + ) + + def setup_labour(self): + from core.models import Person, Event + from core.utils import slugify + from labour.models import ( + AlternativeSignupForm, + InfoLink, + JobCategory, + LabourEventMeta, + PersonnelClass, + Qualification, + ) + from ...models import SignupExtra, SpecialDiet + from django.contrib.contenttypes.models import ContentType + + (labour_admin_group,) = LabourEventMeta.get_or_create_groups(self.event, ["admins"]) + + if self.test: + person, unused = Person.get_or_create_dummy() + labour_admin_group.user_set.add(person.user) + + content_type = ContentType.objects.get_for_model(SignupExtra) + + labour_event_meta_defaults = dict( + signup_extra_content_type=content_type, + work_begins=self.event.start_time.replace(hour=8, minute=0, tzinfo=self.tz), + work_ends=self.event.end_time.replace(hour=20, minute=0, tzinfo=self.tz), + admin_group=labour_admin_group, + contact_email="Cosvision ", + ) + + if self.test: + t = now() + labour_event_meta_defaults.update( + registration_opens=t - timedelta(days=60), + registration_closes=t + timedelta(days=60), + ) + else: + pass + + labour_event_meta, unused = LabourEventMeta.objects.get_or_create( + event=self.event, + defaults=labour_event_meta_defaults, + ) + + for pc_name, pc_slug, pc_app_label in [ + ("Vastaavat", "vastaava", "labour"), + ("Työvoima", "tyovoima", "labour"), + ("Ohjelmanjärjestäjä", "ohjelma", "programme"), + ("Guest of Honour", "goh", "programme"), + ("Media", "media", "badges"), + ("Myyjä", "myyja", "badges"), + ("Vieras", "vieras", "badges"), + ]: + personnel_class, created = PersonnelClass.objects.get_or_create( + event=self.event, + slug=pc_slug, + defaults=dict( + name=pc_name, + app_label=pc_app_label, + priority=self.get_ordering_number(), + ), + ) + + tyovoima = PersonnelClass.objects.get(event=self.event, slug="tyovoima") + vastaava = PersonnelClass.objects.get(event=self.event, slug="vastaava") + + # if not JobCategory.objects.filter(event=self.event).exists(): + # JobCategory.copy_from_event( + # source_event=Event.objects.get(slug="cosvision2022"), + # target_event=self.event, + # ) + + # for name in ["Vastaava"]: + # JobCategory.objects.filter(event=self.event, name=name).update(public=False) + + # for jc_name, qualification_name in [ + # # ("Järjestyksenvalvoja", "JV-kortti"), + # ]: + # jc = JobCategory.objects.get(event=self.event, name=jc_name) + # qual = Qualification.objects.get(name=qualification_name) + + # jc.required_qualifications.set([qual]) + + labour_event_meta.create_groups() + + for diet_name in [ + "Gluteeniton", + "Laktoositon", + "Maidoton", + "Vegaaninen", + "Lakto-ovo-vegetaristinen", + ]: + SpecialDiet.objects.get_or_create(name=diet_name) + + AlternativeSignupForm.objects.get_or_create( + event=self.event, + slug="vastaava", + defaults=dict( + title="Vastaavien ilmoittautumislomake", + signup_form_class_path="events.cosvision2023.forms:OrganizerSignupForm", + signup_extra_form_class_path="events.cosvision2023.forms:OrganizerSignupExtraForm", + active_from=now(), + active_until=self.event.end_time, + ), + ) + + def setup_programme(self): + from labour.models import PersonnelClass + from programme.models import ( + AlternativeProgrammeForm, + Category, + ProgrammeEventMeta, + Role, + SpecialStartTime, + Tag, + TimeBlock, + ) + + programme_admin_group, hosts_group = ProgrammeEventMeta.get_or_create_groups( + self.event, ["admins", "hosts"] + ) + programme_event_meta, unused = ProgrammeEventMeta.objects.get_or_create( + event=self.event, + defaults=dict( + public=False, + admin_group=programme_admin_group, + contact_email="Cosvision ", + schedule_layout="reasonable", + ), + ) + + if settings.DEBUG: + programme_event_meta.accepting_cold_offers_from = now() - timedelta(days=60) + programme_event_meta.accepting_cold_offers_until = now() + timedelta(days=60) + programme_event_meta.save() + + for pc_slug, role_title, role_is_default in [ + ("ohjelma", "Ohjelmanjärjestäjä", True), + ]: + personnel_class = PersonnelClass.objects.get(event=self.event, slug=pc_slug) + role, unused = Role.objects.get_or_create( + personnel_class=personnel_class, + title=role_title, + defaults=dict( + is_default=role_is_default, + ), + ) + + have_categories = Category.objects.filter(event=self.event).exists() + if not have_categories: + for title, style in [ + ("Esitys", "color1"), + ("Jatkuva ohjelma", "color2"), + ("Osallistava ohjelma", "color3"), + ("Työpaja", "color4"), + ]: + Category.objects.get_or_create( + event=self.event, + style=style, + defaults=dict( + title=title, + ), + ) + + saturday_start = (self.event.end_time - timedelta(days=1)).replace(hour=10, minute=0, tzinfo=self.tz) + saturday_end = saturday_start.replace(hour=18, minute=0, tzinfo=self.tz) + sunday_start = self.event.end_time.replace(hour=10, minute=0, tzinfo=self.tz) + sunday_end = self.event.end_time.replace(hour=18, minute=0, tzinfo=self.tz) + + for start_time, end_time in [ + (saturday_start, saturday_end), + (sunday_start, sunday_end), + ]: + TimeBlock.objects.get_or_create( + event=self.event, start_time=start_time, defaults=dict(end_time=end_time) + ) + + for time_block in TimeBlock.objects.filter(event=self.event): + # Half hours + # [:-1] – discard 18:30 + for hour_start_time in full_hours_between(time_block.start_time, time_block.end_time)[:-1]: + SpecialStartTime.objects.get_or_create( + event=self.event, start_time=hour_start_time.replace(minute=30) # look, no tz + ) + + for tag_title, tag_class in [ + ("Suositeltu", "hilight"), + ("In English", "label-success"), + ("Paikkaliput", "label-warning"), + ]: + Tag.objects.get_or_create( + event=self.event, + title=tag_title, + defaults=dict( + style=tag_class, + ), + ) + + default_form, created = AlternativeProgrammeForm.objects.get_or_create( + event=self.event, + slug="default", + defaults=dict( + title="Tarjoa ohjelmaa", + short_description="Tämän ohjetekstin ei pitäisi näkyä kenellekään.", + programme_form_code="events.cosvision2023.forms:ProgrammeForm", + num_extra_invites=3, + order=30, + ), + ) + + def setup_badges(self): + from badges.models import BadgesEventMeta + + (badge_admin_group,) = BadgesEventMeta.get_or_create_groups(self.event, ["admins"]) + meta, unused = BadgesEventMeta.objects.get_or_create( + event=self.event, + defaults=dict( + admin_group=badge_admin_group, + badge_layout="nick", + ), + ) + + def setup_intra(self): + from intra.models import IntraEventMeta, Team + + (admin_group,) = IntraEventMeta.get_or_create_groups(self.event, ["admins"]) + organizer_group = self.event.labour_event_meta.get_group("vastaava") + meta, unused = IntraEventMeta.objects.get_or_create( + event=self.event, + defaults=dict( + admin_group=admin_group, + organizer_group=organizer_group, + ), + ) + + for team_slug, team_name in [ + ("vastaavat", "Vastaavat"), + ]: + (team_group,) = IntraEventMeta.get_or_create_groups(self.event, [team_slug]) + + team, created = Team.objects.get_or_create( + event=self.event, + slug=team_slug, + defaults=dict( + name=team_name, + order=self.get_ordering_number(), + group=team_group, + ), + ) + + +class Command(BaseCommand): + args = "" + help = "Setup cosvision2023 specific stuff" + + def handle(self, *args, **opts): + Setup().setup(test=settings.DEBUG) diff --git a/events/cosvision2023/migrations/0001_initial.py b/events/cosvision2023/migrations/0001_initial.py new file mode 100644 index 000000000..466c72383 --- /dev/null +++ b/events/cosvision2023/migrations/0001_initial.py @@ -0,0 +1,102 @@ +# Generated by Django 4.2 on 2023-05-12 18:59 + +from django.db import migrations, models +import django.db.models.deletion +import labour.models.signup_extras + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("core", "0037_alter_organization_panel_css_class"), + ] + + operations = [ + migrations.CreateModel( + name="SpecialDiet", + fields=[ + ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("name", models.CharField(max_length=63)), + ], + ), + migrations.CreateModel( + name="SignupExtra", + fields=[ + ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("is_active", models.BooleanField(default=True)), + ( + "shift_type", + models.CharField( + choices=[ + ("2h", "2 tunnin vuoroja"), + ("4h", "4 tunnin vuoroja"), + ("yli4h", "Yli 4 tunnin vuoroja"), + ], + help_text="Haluatko tehdä yhden pitkän työvuoron vaiko monta lyhyempää vuoroa?", + max_length=15, + verbose_name="Toivottu työvuoron pituus", + ), + ), + ( + "total_work", + models.CharField( + choices=[("8h", "8 tuntia"), ("yli8h", "Yli 8 tuntia")], + help_text="Kuinka paljon haluat tehdä töitä yhteensä tapahtuman aikana? Useimmissa tehtävistä minimi on kahdeksan tuntia, mutta joissain tehtävissä se voi olla myös vähemmän (esim. majoitusvalvonta 6 h).", + max_length=15, + verbose_name="Toivottu kokonaistyömäärä", + ), + ), + ( + "special_diet_other", + models.TextField( + blank=True, + help_text="Jos noudatat erikoisruokavaliota, jota ei ole yllä olevassa listassa, ilmoita se tässä. Tapahtuman järjestäjä pyrkii ottamaan erikoisruokavaliot huomioon, mutta kaikkia erikoisruokavalioita ei välttämättä pystytä järjestämään.", + verbose_name="Muu erikoisruokavalio", + ), + ), + ( + "prior_experience", + models.TextField( + blank=True, + help_text="Kerro tässä kentässä, jos sinulla on aiempaa kokemusta vastaavista tehtävistä tai muuta sellaista työkokemusta, josta arvioit olevan hyötyä hakemassasi tehtävässä.", + verbose_name="Työkokemus", + ), + ), + ( + "free_text", + models.TextField( + blank=True, + help_text="Jos haluat sanoa hakemuksesi käsittelijöille jotain sellaista, jolle ei ole omaa kenttää yllä, käytä tätä kenttää.", + verbose_name="Vapaa alue", + ), + ), + ( + "event", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="%(app_label)s_signup_extras", + to="core.event", + ), + ), + ( + "person", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="%(app_label)s_signup_extra", + to="core.person", + ), + ), + ( + "special_diet", + models.ManyToManyField( + blank=True, to="cosvision2023.specialdiet", verbose_name="Erikoisruokavalio" + ), + ), + ], + options={ + "abstract": False, + }, + bases=(labour.models.signup_extras.SignupExtraMixin, models.Model), + ), + ] diff --git a/events/cosvision2023/migrations/__init__.py b/events/cosvision2023/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/events/cosvision2023/models.py b/events/cosvision2023/models.py new file mode 100644 index 000000000..20c4a8532 --- /dev/null +++ b/events/cosvision2023/models.py @@ -0,0 +1,77 @@ +from django.db import models + +from core.utils import validate_slug +from labour.models import SignupExtraBase + + +SHIFT_TYPE_CHOICES = [ + ("2h", "2 tunnin vuoroja"), + ("4h", "4 tunnin vuoroja"), + ("yli4h", "Yli 4 tunnin vuoroja"), +] + + +TOTAL_WORK_CHOICES = [ + ("8h", "8 tuntia"), + ("yli8h", "Yli 8 tuntia"), +] + + +class SpecialDiet(models.Model): + name = models.CharField(max_length=63) + + def __str__(self): + return self.name + + +class SignupExtra(SignupExtraBase): + shift_type = models.CharField( + max_length=15, + verbose_name="Toivottu työvuoron pituus", + help_text="Haluatko tehdä yhden pitkän työvuoron vaiko monta lyhyempää vuoroa?", + choices=SHIFT_TYPE_CHOICES, + ) + + total_work = models.CharField( + max_length=15, + verbose_name="Toivottu kokonaistyömäärä", + help_text="Kuinka paljon haluat tehdä töitä yhteensä tapahtuman aikana? Useimmissa tehtävistä minimi on kahdeksan tuntia, mutta joissain tehtävissä se voi olla myös vähemmän (esim. majoitusvalvonta 6 h).", + choices=TOTAL_WORK_CHOICES, + ) + + special_diet = models.ManyToManyField(SpecialDiet, blank=True, verbose_name="Erikoisruokavalio") + + special_diet_other = models.TextField( + blank=True, + verbose_name="Muu erikoisruokavalio", + help_text="Jos noudatat erikoisruokavaliota, jota ei ole yllä olevassa listassa, " + "ilmoita se tässä. Tapahtuman järjestäjä pyrkii ottamaan erikoisruokavaliot " + "huomioon, mutta kaikkia erikoisruokavalioita ei välttämättä pystytä järjestämään.", + ) + + prior_experience = models.TextField( + blank=True, + verbose_name="Työkokemus", + help_text="Kerro tässä kentässä, jos sinulla on aiempaa kokemusta vastaavista " + "tehtävistä tai muuta sellaista työkokemusta, josta arvioit olevan hyötyä " + "hakemassasi tehtävässä.", + ) + + free_text = models.TextField( + blank=True, + verbose_name="Vapaa alue", + help_text="Jos haluat sanoa hakemuksesi käsittelijöille jotain sellaista, jolle ei ole " + "omaa kenttää yllä, käytä tätä kenttää.", + ) + + @classmethod + def get_form_class(cls): + from .forms import SignupExtraForm + + return SignupExtraForm + + @classmethod + def get_programme_form_class(cls): + from .forms import ProgrammeSignupExtraForm + + return ProgrammeSignupExtraForm diff --git a/kompassi/settings.py b/kompassi/settings.py index 8bf9e8a74..62c3cc37d 100644 --- a/kompassi/settings.py +++ b/kompassi/settings.py @@ -273,6 +273,7 @@ def mkpath(*parts): "events.nekocon2023", "events.finncon2023", "events.tracon2023paidat", + "events.cosvision2023", ) LOGGING = { @@ -485,8 +486,12 @@ def mkpath(*parts): # Used by access.SMTPServer. Must be created with ssh-keygen -t rsa -m pem (will not work without -m pem). -KOMPASSI_SSH_PRIVATE_KEY_FILE = env("KOMPASSI_SSH_PRIVATE_KEY_FILE", default="/mnt/secrets/kompassi/sshPrivateKey") -KOMPASSI_SSH_KNOWN_HOSTS_FILE = env("KOMPASSI_SSH_KNOWN_HOSTS_FILE", default="/mnt/secrets/kompassi/sshKnownHosts") +KOMPASSI_SSH_PRIVATE_KEY_FILE = env( + "KOMPASSI_SSH_PRIVATE_KEY_FILE", default="/mnt/secrets/kompassi/sshPrivateKey" +) +KOMPASSI_SSH_KNOWN_HOSTS_FILE = env( + "KOMPASSI_SSH_KNOWN_HOSTS_FILE", default="/mnt/secrets/kompassi/sshKnownHosts" +) # used by manage.py setup to noop if already run for this deploy KOMPASSI_SETUP_RUN_ID = env("KOMPASSI_SETUP_RUN_ID", default="")