Changeset - 630bf4086135
[Not reviewed]
11 29 11
Joel Addison - 18 months ago 2022-12-07 14:08:54
joel@addison.net.au
Everything Open 2023 - Initial Setup
47 files changed with 406 insertions and 512 deletions:
0 comments (0 inline, 0 general)
.gitlab-ci.yml
Show inline comments
 
stages:
 
  - build
 
  - deploy
 

	
 
variables:
 
  DOCKER_TLS_CERTDIR: "/certs"
 
  CONTAINER_PREFIX: 2022
 
  CONTAINER_PREFIX: 2023
 
  CONTAINER_IMAGE: $CI_REGISTRY_IMAGE/$CONTAINER_PREFIX:$CI_COMMIT_SHA
 

	
 
build-image:
 
  image: docker:git
 
  stage: build
 
  services:
 
  - docker:dind
 
  script:
 
    - apk update && apk add git
 
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
 
    - docker build --pull -f docker/Dockerfile -t $CONTAINER_IMAGE .
 
    - docker push $CONTAINER_IMAGE
 
  only:
 
    - "2022"
 
    - conf/2023
 

	
 
k8s-deploy-staging:
 
  image: google/cloud-sdk
 
  stage: deploy
 
  script:
 
  - echo "${CA_CERT}" > cert.crt
 
  - kubectl config set-cluster cluster --server="${KUBE_SERVER}" --embed-certs=true --certificate-authority=cert.crt
 
  - kubectl config set-context cluster --cluster=cluster --namespace=lca2022-staging --user=gitlab-ci
 
  - kubectl config set-context cluster --cluster=cluster --namespace=eo2023-staging --user=gitlab-ci
 
  - kubectl config use-context cluster
 
  - kubectl --token "${KUBE_TOKEN}" set image deployment/symposion-app symposion-app=$CONTAINER_IMAGE
 
  when: manual
 
  only:
 
  - dev/2022
 
  - dev/2023
 
  environment:
 
    name: 2022/staging
 
    url: https://staging-lca2022.gc2020.org/
 
    name: 2023/staging
 
    url: https://staging-eo2023.osaconftools.net/
 

	
 
k8s-deploy-prod:
 
  image: google/cloud-sdk
 
  stage: deploy
 
  script:
 
  - echo "${CA_CERT}" > cert.crt
 
  - kubectl config set-cluster cluster --server="${KUBE_SERVER}" --embed-certs=true --certificate-authority=cert.crt
 
  - kubectl config set-context cluster --cluster=cluster --namespace=lca2022-prod --user=gitlab-ci
 
  - kubectl config set-context cluster --cluster=cluster --namespace=eo2023-prod --user=gitlab-ci
 
  - kubectl config use-context cluster
 
  - kubectl --token "${KUBE_TOKEN}" set image deployment/symposion-app symposion-app=$CONTAINER_IMAGE
 
  when: manual
 
  only:
 
  - "2022"
 
  - conf/2023
 
  environment:
 
    name: 2022/prod
 
    url: https://lca2022.linux.org.au
 
    name: 2023/prod
 
    url: https://2023.everythingopen.au/
 

	
 
.docs_template: &sphinx
 
  image: alpine
 
  script:
 
  - apk --no-cache add py3-pip python3-dev make
 
  - pip install sphinx
 
  - cd docs
 
  - make html
 
  - cd ..
 
  - mv docs/_build/html public
 
  artifacts:
 
    paths:
 
    - public
 

	
 
pages:
 
  <<: *sphinx
 
  stage: build
 
  only:
 
  - master
 
  - "2022"
 
  - conf/2023
 
  environment:
 
    name: docs
 
    url: https://laconfdev.gitlab.io/symposion_app/
 

	
 
build-sphinx:
 
  <<: *sphinx
 
  stage: build
 
  except:
 
  - master
 
  - "2022"
 
  - conf/2023
fixtures/2022/auth.permission.json
Show inline comments
 
deleted file
fixtures/2022/conference.section.json
Show inline comments
 
deleted file
fixtures/2022/proposals.proposalsection.json
Show inline comments
 
deleted file
fixtures/conference.json
Show inline comments
 
[
 
{
 
  "model": "symposion_conference.conference",
 
  "pk": 1,
 
  "fields": {
 
    "title": "linux.conf.au 2022",
 
    "start_date": "2022-01-14",
 
    "end_date": "2022-01-16",
 
    "timezone": "Australia/Canberra"
 
    "title": "Everything Open 2023",
 
    "start_date": "2023-03-14",
 
    "end_date": "2023-03-16",
 
    "timezone": "Australia/Melbourne"
 
  }
 
}
 
]
fixtures/flatpages.json
Show inline comments
 
[
 
{
 
  "model": "flatpages.flatpage",
 
  "pk": 1,
 
  "fields": {
 
    "url": "/",
 
    "title": "Home Page",
 
    "content": "Here is the home page for LCA.\r\n\r\nOther pages to come.",
 
    "content": "Here is the home page.\r\n\r\nOther pages to come.",
 
    "enable_comments": false,
 
    "template_name": "",
 
    "registration_required": false,
 
    "sites": [
 
      1
 
    ]
 
  }
 
}
 
]
fixtures/sessions/auth.group.json
Show inline comments
 
file renamed from fixtures/2022/auth.group.json to fixtures/sessions/auth.group.json
fixtures/sessions/auth.permission.json
Show inline comments
 
new file 100644
 
[
 
{
 
  "model": "auth.permission",
 
  "fields": {
 
    "name": "Can review Main Conference",
 
    "content_type": [
 
      "reviews",
 
      ""
 
    ],
 
    "codename": "can_review_main"
 
  }
 
},
 
{
 
  "model": "auth.permission",
 
  "fields": {
 
    "name": "Can manage Main Conference",
 
    "content_type": [
 
      "reviews",
 
      ""
 
    ],
 
    "codename": "can_manage_main"
 
  }
 
}
 
]
fixtures/sessions/conference.section.json
Show inline comments
 
new file 100644
 
[
 
{
 
  "model": "symposion_conference.section",
 
  "pk": 1,
 
  "fields": {
 
    "conference": 1,
 
    "name": "Main Conference",
 
    "slug": "main",
 
    "start_date": "2023-03-14",
 
    "end_date": "2023-03-16"
 
  }
 
}
 
]
fixtures/sessions/proposals.proposalkind.json
Show inline comments
 
file renamed from fixtures/2022/proposals.proposalkind.json to fixtures/sessions/proposals.proposalkind.json
 
[
 
{
 
  "model": "symposion_proposals.proposalkind",
 
  "pk": 1,
 
  "fields": {
 
    "section": 1,
 
    "name": "Talk",
 
    "slug": "talk"
 
  }
 
},
 
{
 
  "model": "symposion_proposals.proposalkind",
 
  "pk": 3,
 
  "pk": 2,
 
  "fields": {
 
    "section": 2,
 
    "name": "Miniconf",
 
    "slug": "miniconf"
 
    "section": 1,
 
    "name": "Tutorial",
 
    "slug": "tutorial"
 
  }
 
}
 
]
fixtures/sessions/proposals.proposalsection.json
Show inline comments
 
new file 100644
 
[
 
{
 
  "model": "symposion_proposals.proposalsection",
 
  "pk": 1,
 
  "fields": {
 
    "section": 1,
 
    "start": "2022-12-07T12:00:00Z",
 
    "end": "2023-01-09T12:00:00Z",
 
    "closed": false,
 
    "published": true
 
  }
 
}
 
]
fixtures/sessions/teams.team.json
Show inline comments
 
file renamed from fixtures/2022/teams.team.json to fixtures/sessions/teams.team.json
 
[
 
{
 
  "model": "teams.team",
 
  "pk": 1,
 
  "fields": {
 
    "slug": "main-proposals",
 
    "name": "linux.conf.au Sessions Team",
 
    "description": "Team looking after the linux.conf.au Call for Sessions",
 
    "name": "Sessions Team",
 
    "description": "Team looking after the Call for Sessions",
 
    "access": "invitation",
 
    "created": "2019-06-23T08:16:34.032Z",
 
    "permissions": [
 
      [
 
        "can_review_main",
 
        "reviews",
 
        ""
 
      ],
 
      [
 
        "can_review_miniconf",
 
        "reviews",
 
        ""
 
      ]
 
    ],
 
    "manager_permissions": [
 
      [
 
        "can_manage_main",
 
        "reviews",
 
        ""
 
      ],
 
      [
 
        "can_review_main",
 
        "reviews",
 
        ""
 
      ]
 
    ]
 
  }
 
},
 
{
 
  "model": "teams.team",
 
  "pk": 2,
 
  "fields": {
 
    "slug": "organising-team",
 
    "name": "linux.conf.au Organising Team",
 
    "description": "The organising team for linux.conf.au",
 
    "name": "Organising Team",
 
    "description": "The conference organising team",
 
    "access": "invitation",
 
    "created": "2019-08-26T22:59:09.265Z",
 
    "permissions": [
 
      [
 
        "can_review_main",
 
        "reviews",
 
        ""
 
      ],
 
      [
 
        "can_review_miniconf",
 
        "reviews",
 
        ""
 
      ]
 
    ],
 
    "manager_permissions": []
 
  }
 
}
 
]
fixtures/sites.json
Show inline comments
 
[
 
{
 
  "model": "sites.site",
 
  "pk": 1,
 
  "fields": {
 
    "domain": "lca2022.linux.org.au",
 
    "name": "linux.conf.au 2022"
 
    "domain": "2023.everythingopen.au",
 
    "name": "Everything Open 2023"
 
  }
 
}
 
]
fixtures/sitetree.json
Show inline comments
...
 
@@ -122,25 +122,25 @@
 
    "access_guest": false,
 
    "access_restricted": false,
 
    "access_perm_type": 1,
 
    "parent": null,
 
    "sort_order": 3,
 
    "access_permissions": []
 
  }
 
},
 
{
 
  "model": "sitetree.treeitem",
 
  "pk": 6,
 
  "fields": {
 
    "title": "About LCA2022",
 
    "title": "About Everything Open",
 
    "hint": "",
 
    "url": "/about/",
 
    "urlaspattern": false,
 
    "tree": 1,
 
    "hidden": false,
 
    "alias": null,
 
    "description": "",
 
    "inmenu": true,
 
    "inbreadcrumbs": true,
 
    "insitetree": true,
 
    "access_loggedin": false,
 
    "access_guest": false,
k8s/deployment_template.jsonnet
Show inline comments
...
 
@@ -112,25 +112,25 @@ function (slug, sha) {
 
                          }
 
                        }
 
                      },
 
                      {
 
                        "name": "SYMPOSION_DEV_MODE",
 
                        "value": "LAPTOP"
 
                      },
 
                      {
 
                        "name": "ANALYTICS_KEY",
 
                        "value": "UA-000000000-1"
 
                      }
 
                    ],
 
                    "image": "asia.gcr.io/linuxconfsydney/symposion_app_2022_dev:" + sha,
 
                    "image": "registry.gitlab.com/laconfdev/symposion_app/2023:" + sha,
 
                    "imagePullPolicy": "Always",
 
                    "livenessProbe": {
 
                      "failureThreshold": 3,
 
                      "httpGet": {
 
                        "path": "/admin/login/",
 
                        "port": 8000,
 
                        "scheme": "HTTP"
 
                      },
 
                      "initialDelaySeconds": 180,
 
                      "periodSeconds": 10,
 
                      "successThreshold": 1,
 
                      "timeoutSeconds": 5
make_dev_container.sh
Show inline comments
...
 
@@ -17,25 +17,25 @@ fi
 
docker image build -f docker/Dockerfile -t ${IMAGE_NAME} --target symposion_dev .
 
docker container stop symposion
 
docker container rm symposion
 
docker container create --env-file docker/laptop-mode-env -p 28000:8000 -v $(pwd):/app/symposion_app --name symposion ${IMAGE_NAME}
 
docker container start symposion
 
## When we started the container and mounted . into /app/symposion_app, it hides the static/build directory
 
## As a kludge, re-run collectstatic to recreate it
 
## Possible alternative here: don't mount all of ., just mount the bits that we'd live to have update live
 
docker exec symposion ./manage.py collectstatic --noinput -v 0
 
docker exec symposion ./manage.py migrate
 
docker exec symposion ./manage.py loaddata ./fixtures/{conference,sites,sitetree,flatpages}.json
 
docker exec symposion ./manage.py create_review_permissions
 
docker exec symposion ./manage.py loaddata ./fixtures/????/*.json
 
docker exec symposion ./manage.py loaddata ./fixtures/sessions/*.json
 
docker exec symposion ./manage.py populate_inventory
 

	
 
if [ -e ./symposion-tools ]; then
 
    pushd ./symposion-tools
 
    ./fixture_to_docker.sh fixtures/dev_dummy_superuser.json
 
    ./fixture_to_docker.sh fixtures/????_*.json
 
    popd
 
else
 
    echo Now creating a Django superuser. Please enter a
 
    docker exec -it symposion ./manage.py createsuperuser --username admin1 --email root@example.com
 
fi
 

	
pinaxcon/proposals/admin.py
Show inline comments
...
 
@@ -14,30 +14,24 @@ class CategoryAdmin(admin.ModelAdmin):
 
        readonly_fields = ["score"]
 
        fields = ["status"]
 

	
 
    inlines = [
 
        AdditionalSpeakerInline,
 
        ProposalResultInline,
 
    ]
 

	
 

	
 
models_to_register = [
 
    models.TalkProposal,
 
    models.TutorialProposal,
 
    models.MiniconfProposal,
 
    ### LCA2022 Miniconfs
 
    models.GlamCommunityProposal,
 
    models.KernelProposal,
 
    models.OpenHardwareProposal,
 
    models.SysAdminProposal,
 
]
 

	
 
for model in models_to_register:
 
    admin.site.register(model, CategoryAdmin,
 
                        list_display = [
 
                            "id",
 
                            "title",
 
                            "speaker",
 
                            "speaker_email",
 
                            "kind",
 
                            "target_audience",
 
                            "status",
pinaxcon/proposals/forms.py
Show inline comments
...
 
@@ -4,35 +4,34 @@ from django import forms
 

	
 
from pinaxcon.proposals.fields import HelpTextField
 
from pinaxcon.proposals import models
 

	
 

	
 
DEFAULT_FIELDS =  [
 
    "title",
 
    "primary_topic",
 
    "target_audience",
 
    "experience_level",
 
    "abstract",
 
    "private_abstract",
 
    "content_warning",
 
    "technical_requirements",
 
    "project",
 
    "project_url",
 
    "video_url",
 
    "require_approval",
 
    "recording_release",
 
    "materials_release",
 
]
 

	
 
MINICONF_SESSION_FORMAT_FIELDS = copy.copy(DEFAULT_FIELDS)
 

	
 
class ProposalForm(forms.ModelForm):
 

	
 
    required_css_class = 'label-required'
 

	
 
    def clean_description(self):
 
        value = self.cleaned_data["description"]
 
        if len(value) > 400:
 
            raise forms.ValidationError(
 
                u"The description must be less than 400 characters"
 
            )
 
        return value
 

	
...
 
@@ -40,66 +39,12 @@ class ProposalForm(forms.ModelForm):
 
class TalkProposalForm(ProposalForm):
 

	
 
    class Meta:
 
        model = models.TalkProposal
 
        fields = copy.copy(DEFAULT_FIELDS)
 

	
 

	
 
class TutorialProposalForm(ProposalForm):
 

	
 
    class Meta:
 
        model = models.TutorialProposal
 
        fields = copy.copy(DEFAULT_FIELDS)
 

	
 

	
 
class MiniconfProposalForm(ProposalForm):
 

	
 
    class Meta:
 
        model = models.MiniconfProposal
 
        fields = [
 
            "title",
 
            "abstract",
 
            "private_abstract",
 
            "technical_requirements",
 
            "recording_release",
 
            "materials_release",
 
        ]
 

	
 
### LCA2022 Miniconfs
 

	
 
class MiniconfSessionProposalForm(ProposalForm):
 
    pass
 

	
 

	
 
class GlamCommunityProposalForm(MiniconfSessionProposalForm):
 

	
 
    class Meta:
 
        model = models.GlamCommunityProposal
 
        fields = MINICONF_SESSION_FORMAT_FIELDS
 

	
 

	
 
class KernelProposalForm(MiniconfSessionProposalForm):
 

	
 
    class Meta:
 
        model = models.KernelProposal
 
        fields = MINICONF_SESSION_FORMAT_FIELDS
 

	
 

	
 
HARDWARE_FIELDS = copy.copy(MINICONF_SESSION_FORMAT_FIELDS)
 
HARDWARE_FIELDS.insert(4, "talk_format")
 

	
 
class OpenHardwareProposalForm(MiniconfSessionProposalForm):
 

	
 
    def __init__(self, *a, **k):
 
        super(OpenHardwareProposalForm, self).__init__(*a, **k)
 
        self.fields['talk_format'].required = True
 

	
 
    class Meta:
 
        model = models.OpenHardwareProposal
 
        fields = HARDWARE_FIELDS
 

	
 

	
 
class SysAdminProposalForm(MiniconfSessionProposalForm):
 

	
 
    class Meta:
 
        model = models.SysAdminProposal
 
        fields = MINICONF_SESSION_FORMAT_FIELDS
pinaxcon/proposals/migrations/0004_auto_20210809_2026.py
Show inline comments
 
deleted file
pinaxcon/proposals/migrations/0004_auto_20221208_0102.py
Show inline comments
 
new file 100644
 
# Generated by Django 2.2.28 on 2022-12-07 14:02
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('symposion_schedule', '0008_auto_20190122_0815'),
 
        ('symposion_reviews', '0001_initial'),
 
        ('symposion_proposals', '0003_auto_20170702_2250'),
 
        ('proposals', '0003_auto_20170702_2227'),
 
    ]
 

	
 
    operations = [
 
        migrations.AddField(
 
            model_name='talkproposal',
 
            name='content_warning',
 
            field=models.TextField(blank=True, help_text='This will be shown on the schedule to give attendees advanced warning of topics covered in the session. ', verbose_name='Content Warning'),
 
        ),
 
        migrations.AddField(
 
            model_name='talkproposal',
 
            name='content_warning_html',
 
            field=models.TextField(blank=True),
 
        ),
 
        migrations.AddField(
 
            model_name='talkproposal',
 
            name='experience_level',
 
            field=models.IntegerField(choices=[(1, 'Beginner'), (2, 'Intermediate'), (3, 'Advanced')], help_text='What level of experience will your session be pitched at?'),
 
        ),
 
        migrations.AddField(
 
            model_name='talkproposal',
 
            name='primary_topic',
 
            field=models.IntegerField(choices=[(1, 'Linux'), (2, 'Software'), (3, 'Hardware'), (4, 'Firmware'), (5, 'System Administration / Operations'), (6, 'Security'), (7, 'Documentation'), (8, 'Community'), (9, 'Science & Data'), (10, 'Galleries, Libraries, Archives & Museums (GLAM)'), (11, 'Multimedia'), (12, 'Aerospace / UAV'), (13, 'Agriculture'), (14, 'Other')], help_text='What is the primary topic area for your session?'),
 
        ),
 
        migrations.AddField(
 
            model_name='talkproposal',
 
            name='require_approval',
 
            field=models.BooleanField(default=False, help_text='Do you require further approval from your employer or institution before you can confirm your availability to present?'),
 
        ),
 
        migrations.AddField(
 
            model_name='tutorialproposal',
 
            name='content_warning',
 
            field=models.TextField(blank=True, help_text='This will be shown on the schedule to give attendees advanced warning of topics covered in the session. ', verbose_name='Content Warning'),
 
        ),
 
        migrations.AddField(
 
            model_name='tutorialproposal',
 
            name='content_warning_html',
 
            field=models.TextField(blank=True),
 
        ),
 
        migrations.AddField(
 
            model_name='tutorialproposal',
 
            name='experience_level',
 
            field=models.IntegerField(choices=[(1, 'Beginner'), (2, 'Intermediate'), (3, 'Advanced')], help_text='What level of experience will your session be pitched at?'),
 
        ),
 
        migrations.AddField(
 
            model_name='tutorialproposal',
 
            name='primary_topic',
 
            field=models.IntegerField(choices=[(1, 'Linux'), (2, 'Software'), (3, 'Hardware'), (4, 'Firmware'), (5, 'System Administration / Operations'), (6, 'Security'), (7, 'Documentation'), (8, 'Community'), (9, 'Science & Data'), (10, 'Galleries, Libraries, Archives & Museums (GLAM)'), (11, 'Multimedia'), (12, 'Aerospace / UAV'), (13, 'Agriculture'), (14, 'Other')], help_text='What is the primary topic area for your session?'),
 
        ),
 
        migrations.AddField(
 
            model_name='tutorialproposal',
 
            name='require_approval',
 
            field=models.BooleanField(default=False, help_text='Do you require further approval from your employer or institution before you can confirm your availability to present?'),
 
        ),
 
        migrations.AlterField(
 
            model_name='talkproposal',
 
            name='recording_release',
 
            field=models.BooleanField(default=True, help_text="I allow Linux Australia to release any recordings of presentations covered by this proposal, on YouTube under the standard YouTube licence, and on other platforms under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (<a href='https://creativecommons.org/licenses/by-nc-sa/4.0/'> CC BY-NC-SA 4.0</a>) licence."),
 
        ),
 
        migrations.AlterField(
 
            model_name='talkproposal',
 
            name='target_audience',
 
            field=models.IntegerField(choices=[(4, 'Developer'), (3, 'Community'), (1, 'End User'), (2, 'Business')], help_text='Who is the target audience for your session?'),
 
        ),
 
        migrations.AlterField(
 
            model_name='tutorialproposal',
 
            name='recording_release',
 
            field=models.BooleanField(default=True, help_text="I allow Linux Australia to release any recordings of presentations covered by this proposal, on YouTube under the standard YouTube licence, and on other platforms under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (<a href='https://creativecommons.org/licenses/by-nc-sa/4.0/'> CC BY-NC-SA 4.0</a>) licence."),
 
        ),
 
        migrations.AlterField(
 
            model_name='tutorialproposal',
 
            name='target_audience',
 
            field=models.IntegerField(choices=[(4, 'Developer'), (3, 'Community'), (1, 'End User'), (2, 'Business')], help_text='Who is the target audience for your session?'),
 
        ),
 
        migrations.DeleteModel(
 
            name='MiniconfProposal',
 
        ),
 
    ]
pinaxcon/proposals/models.py
Show inline comments
 
from django.db import models
 
from django.utils.translation import ugettext_lazy as _
 

	
 
from symposion.proposals.models import ProposalBase
 
from symposion.text_parser import parse
 

	
 

	
 
class Proposal(ProposalBase):
 

	
 
    TARGET_USER = 1
 
    TARGET_BUSINESS = 2
 
    TARGET_COMMUNITY = 3
 
    TARGET_DEVELOPER = 4
 

	
 
    TARGET_AUDIENCES = [
 
        (TARGET_DEVELOPER, "Developer"),
 
        (TARGET_COMMUNITY, "Community"),
 
        (TARGET_USER, "End User"),
 
        (TARGET_BUSINESS, "Business"),
 
    ]
 

	
 
    TOPIC_LINUX = 1
 
    TOPIC_SOFTWARE = 2
 
    TOPIC_HARDWARE = 3
 
    TOPIC_FIRMWARE = 4
 
    TOPIC_SYSADMIN = 5
 
    TOPIC_SECURITY = 6
 
    TOPIC_DOCUMENTATION = 7
 
    TOPIC_COMMUNITY = 8
 
    TOPIC_SCIENCE = 9
 
    TOPIC_GLAM = 10
 
    TOPIC_MULTIMEDIA = 11
 
    TOPIC_AEROSPACE = 12
 
    TOPIC_AGRICULTURE = 13
 
    TOPIC_OTHER = 14
 

	
 
    PROPOSAL_TOPIC = [
 
        (TOPIC_LINUX, "Linux"),
 
        (TOPIC_SOFTWARE, "Software"),
 
        (TOPIC_HARDWARE, "Hardware"),
 
        (TOPIC_FIRMWARE, "Firmware"),
 
        (TOPIC_SYSADMIN, "System Administration / Operations"),
 
        (TOPIC_SECURITY, "Security"),
 
        (TOPIC_DOCUMENTATION, "Documentation"),
 
        (TOPIC_COMMUNITY, "Community"),
 
        (TOPIC_SCIENCE, "Science & Data"),
 
        (TOPIC_GLAM, "Galleries, Libraries, Archives & Museums (GLAM)"),
 
        (TOPIC_MULTIMEDIA, "Multimedia"),
 
        (TOPIC_AEROSPACE, "Aerospace / UAV"),
 
        (TOPIC_AGRICULTURE, "Agriculture"),
 
        (TOPIC_OTHER, "Other"),
 
    ]
 

	
 
    LEVEL_BEGINNER = 1
 
    LEVEL_INTERMEDIATE = 2
 
    LEVEL_ADVANCED = 3
 

	
 
    EXPERIENCE_LEVEL = [
 
        (LEVEL_BEGINNER, "Beginner"),
 
        (LEVEL_INTERMEDIATE, "Intermediate"),
 
        (LEVEL_ADVANCED, "Advanced"),
 
    ]
 

	
 
    target_audience = models.IntegerField(
 
        choices=TARGET_AUDIENCES,
 
        help_text="Who is the target audience for your session?",
 
    )
 

	
 
    recording_release = models.BooleanField(
 
        default=True,
 
        help_text="I allow Linux Australia to release any recordings of "
 
        "presentations covered by this proposal, on YouTube under the "
 
        "standard YouTube licence, and on other platforms under the "
 
        "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International "
 
        "(<a href='https://creativecommons.org/licenses/by-nc-sa/4.0/'> "
 
        "CC BY-NC-SA 4.0</a>) licence."
 
    )
 

	
 
    materials_release = models.BooleanField(
 
        default=True,
 
        help_text="I allow Linux Australia to release any other material "
 
        "(such as slides) from presentations covered by this proposal, under "
 
        "the <a "
 
        "href='https://creativecommons.org/licenses/by-sa/3.0/au/deed.en'> "
 
        "Creative Commons Attribution-Share Alike Australia 3.0 Licence</a>"
 
    )
 

	
 
    class Meta:
 
        abstract = True
 

	
 

	
 
class SessionProposal(Proposal):
 
    """
 
    Base Session Proposal
 

	
 
    This is not a meta class as we want a single table to store the common
 
    data across all session proposal types.
 
    """
 

	
 
    TOPIC_SOFTWARE = 1
 
    TOPIC_HARDWARE = 2
 
    TOPIC_FIRMWARE = 3
 
    TOPIC_KERNEL = 4
 
    TOPIC_DOCUMENTATION = 5
 
    TOPIC_COMMUNITY = 6
 
    TOPIC_SECURITY = 7
 
    TOPIC_OPERATIONS = 8
 
    TOPIC_OTHER = 9
 

	
 
    PROPOSAL_TOPIC = [
 
        (TOPIC_SOFTWARE, "Software"),
 
        (TOPIC_HARDWARE, "Hardware"),
 
        (TOPIC_FIRMWARE, "Firmware"),
 
        (TOPIC_KERNEL, "Linux Kernel"),
 
        (TOPIC_DOCUMENTATION, "Documentation"),
 
        (TOPIC_COMMUNITY, "Community"),
 
        (TOPIC_SECURITY, "Security"),
 
        (TOPIC_OPERATIONS, "Deployment & Operations"),
 
        (TOPIC_OTHER, "Other"),
 
    ]
 

	
 
    LEVEL_BEGINNER = 1
 
    LEVEL_INTERMEDIATE = 2
 
    LEVEL_ADVANCED = 3
 

	
 
    EXPERIENCE_LEVEL = [
 
        (LEVEL_BEGINNER, "Beginner"),
 
        (LEVEL_INTERMEDIATE, "Intermediate"),
 
        (LEVEL_ADVANCED, "Advanced"),
 
    ]
 

	
 
    primary_topic = models.IntegerField(
 
        choices=PROPOSAL_TOPIC,
 
        help_text="What is the primary topic area for your session?"
 
    )
 

	
 
    experience_level = models.IntegerField(
 
        choices=EXPERIENCE_LEVEL,
 
        help_text="What level of experience will your session be pitched at?"
 
    )
 

	
 
    require_approval = models.BooleanField(
 
        default=False,
 
        help_text="Do you require further approval from your employer or "
 
        "institution before you can confirm your availability to present?"
 
    )
 

	
 

	
 
class TalkProposal(SessionProposal):
 

	
 
    class Meta:
 
        verbose_name = "talk proposal"
 

	
 

	
 
class TutorialProposal(SessionProposal):
 

	
 
    class Meta:
 
        verbose_name = "tutorial proposal"
 

	
 

	
 
class MiniconfProposal(Proposal):
 
    """
 
    Miniconf Proposal
 

	
 
    Note that this is just a Proposal, not a SessionProposal, as it does not
 
    require a number of fields that the others use.
 
    """
 

	
 
    target_audience = models.IntegerField(choices=Proposal.TARGET_AUDIENCES,
 
                                          default=Proposal.TARGET_DEVELOPER)
 

	
 
    class Meta:
 
        verbose_name = "miniconf proposal"
 

	
 

	
 
class MiniconfSessionProposal(SessionProposal):
 
    """
 
    Base Miniconf Session Proposal
 
    """
 
    content_warning = models.TextField(
 
        "Content Warning",
 
        help_text=_("This will be shown on the schedule to give attendees "
 
                    "advanced warning of topics covered in the session. "),
 
        blank=True,
 
    )
 
    content_warning_html = models.TextField(blank=True)
 

	
 
    class Meta:
 
        abstract = True
 

	
 
    def save(self, *args, **kwargs):
 
        self.content_warning_html = parse(self.content_warning)
 
        return super(Proposal, self).save(*args, **kwargs)
 

	
 
class GlamCommunityProposal(MiniconfSessionProposal):
 

	
 
    class Meta:
 
        verbose_name = "GO GLAM Miniconf Proposal"
 

	
 

	
 
class KernelProposal(MiniconfSessionProposal):
 

	
 
    class Meta:
 
        verbose_name = "Kernel Miniconf Proposal"
 

	
 

	
 
class OpenHardwareProposal(MiniconfSessionProposal):
 

	
 
    FORMAT_PRESENTATION = 1
 
    FORMAT_TUTORIAL = 2
 
    FORMAT_HANDS_ON = 3
 

	
 
    TALK_FORMATS = [
 
        (FORMAT_PRESENTATION, "Presentation"),
 
        (FORMAT_TUTORIAL, "Tutorial"),
 
        (FORMAT_HANDS_ON, "Hands-on"),
 
    ]
 

	
 
    talk_format = models.IntegerField(
 
        choices=TALK_FORMATS,
 
        default=FORMAT_PRESENTATION,
 
        help_text="Will your session be a presentation, tutorial or hands-on "
 
        "(e.g how to use KiCAD or some other tooling)?"
 
    )
 
class TalkProposal(Proposal):
 

	
 
    class Meta:
 
        verbose_name = "Open Hardware Miniconf Proposal"
 
        verbose_name = "talk proposal"
 

	
 

	
 
class SysAdminProposal(MiniconfSessionProposal):
 
class TutorialProposal(Proposal):
 

	
 
    class Meta:
 
        verbose_name = "System Administration Miniconf Proposal"
 
        verbose_name = "tutorial proposal"
pinaxcon/registrasion/forms.py
Show inline comments
...
 
@@ -16,21 +16,22 @@ class YesNoField(forms.TypedChoiceField):
 

	
 

	
 
class ProfileForm(forms.ModelForm):
 
    ''' A form for requesting badge and profile information. '''
 

	
 
    required_css_class = 'label-required'
 

	
 
    class Meta:
 
        model = models.AttendeeProfile
 
        exclude = [
 
            'attendee',
 
            'children',
 
            'lca_announce',
 
            'lca_chat',
 
            'future_conference',
 
        ]
 
        widgets = {
 
            'past_lca': forms.widgets.CheckboxSelectMultiple
 
        }
 
        field_classes = {
 
            "of_legal_age": YesNoField,
 
        }
pinaxcon/registrasion/management/commands/populate_inventory.py
Show inline comments
...
 
@@ -118,25 +118,25 @@ class Command(BaseCommand):
 
        #                 "holders, speakers, miniconf organisers, and invited "
 
        #                 "guests.",
 
        #     required=False,
 
        #     render_type=inv.Category.RENDER_TYPE_RADIO,
 
        #     limit_per_user=1,
 
        #     order=40,
 
        # )
 
        # self.t_shirt = self.find_or_make(
 
        #     inv.Category,
 
        #     ("name",),
 
        #     name="Shirt",
 
        #     description="Commemorative conference shirts, featuring the "
 
        #                 f"linux.conf.au {settings.LCA_START.year} artwork. "
 
        #                 f"linux.conf.au {settings.CONF_START.year} artwork. "
 
        #                 "View the <a href=\"/attend/shirts/\">"
 
        #                 "sizing guide</a>.",
 
        #     required=False,
 
        #     render_type=inv.Category.RENDER_TYPE_ITEM_QUANTITY,
 
        #     order=50,
 
        # )
 
        # self.accommodation = self.find_or_make(
 
        #     inv.Category,
 
        #     ("name",),
 
        #     name="Accommodation at University of Tasmania",
 
        #     description="Accommodation at the University of Tasmania colleges "
 
        #                 "and apartments. You can come back and book your "
pinaxcon/registrasion/migrations/0001_initial.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# Generated by Django 1.9.7 on 2016-09-22 06:25
 
from __future__ import unicode_literals
 

	
 
from django.db import migrations, models
 
import django.db.models.deletion
 
import django_countries.fields
 

	
 

	
 
_PAST_EVENTS = (
 
    (1999, "1999 Melbourne (CALU)"),
 
    (2001, "2001 Sydney"),
 
    (2002, "2002 Brisbane"),
 
    (2003, "2003 Perth"),
 
    (2004, "2004 Adelaide"),
 
    (2005, "2005 Canberra"),
 
    (2006, "2006 Dunedin"),
 
    (2007, "2007 Sydney"),
 
    (2008, "2008 Melbourne"),
 
    (2009, "2009 Hobart"),
 
    (2010, "2010 Wellington"),
 
    (2011, "2011 Brisbane"),
 
    (2012, "2012 Ballarat"),
 
    (2013, "2013 Canberra"),
 
    (2014, "2014 Perth"),
 
    (2015, "2015 Auckland"),
 
    (2016, "2016 Geelong"),
 
    (2017, "2017 Hobart"),
 
    (2018, "2018 Sydney"),
 
    (2019, "2019 Christchurch"),
 
    (2020, "2020 Gold Coast"),
 
    (2021, "2021 Online"),
 
    (1999, "CALU 1999 Melbourne"),
 
    (2001, "LCA2001 Sydney"),
 
    (2002, "LCA2002 Brisbane"),
 
    (2003, "LCA2003 Perth"),
 
    (2004, "LCA2004 Adelaide"),
 
    (2005, "LCA2005 Canberra"),
 
    (2006, "LCA2006 Dunedin"),
 
    (2007, "LCA2007 Sydney"),
 
    (2008, "LCA2008 Melbourne"),
 
    (2009, "LCA2009 Hobart"),
 
    (2010, "LCA2010 Wellington"),
 
    (2011, "LCA2011 Brisbane"),
 
    (2012, "LCA2012 Ballarat"),
 
    (2013, "LCA2013 Canberra"),
 
    (2014, "LCA2014 Perth"),
 
    (2015, "LCA2015 Auckland"),
 
    (2016, "LCA2016 Geelong"),
 
    (2017, "LCA2017 Hobart"),
 
    (2018, "LCA2018 Sydney"),
 
    (2019, "LCA2019 Christchurch"),
 
    (2020, "LCA2020 Gold Coast"),
 
    (2021, "LCA2021 Online"),
 
    (2022, "LCA2022 Online"),
 
)
 

	
 

	
 
def populate(apps, schema_editor):
 
    PastEvent = apps.get_model("pinaxcon_registrasion","PastEvent")
 

	
 
    all_such = PastEvent.objects.all()
 
    by_year = dict((event.year, event) for event in all_such)
 

	
 
    events = []
 
    for past_event in _PAST_EVENTS:
 
        if past_event[0] in by_year:
pinaxcon/registrasion/migrations/0015_auto_20221208_0102.py
Show inline comments
 
new file 100644
 
# Generated by Django 2.2.28 on 2022-12-07 14:02
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('pinaxcon_registrasion', '0014_auto_20201123_2319'),
 
    ]
 

	
 
    operations = [
 
        migrations.AlterField(
 
            model_name='attendeeprofile',
 
            name='address_line_1',
 
            field=models.CharField(blank=True, help_text='This address, if provided, will appear on your invoices. It is also where we will ship your Open Hardware Kit if you are allocated one.', max_length=1024, verbose_name='Address line 1'),
 
        ),
 
        migrations.AlterField(
 
            model_name='attendeeprofile',
 
            name='children',
 
            field=models.CharField(blank=True, help_text="Everything Open is a family friendly conference and provides free child-care for pre-school children from 6 months up to 5 years. We hope to also provide a programme for older children and will let you know closer to the conference. If you're wanting to bring your children, please let us know their age(s) so we can ensure we have enough spaces available.", max_length=256, verbose_name='Child Ages and Information'),
 
        ),
 
        migrations.AlterField(
 
            model_name='attendeeprofile',
 
            name='lca_chat',
 
            field=models.BooleanField(blank=True, default=False, help_text='lca-chat is a high-traffic mailing list used by attendees during the week of the conference for general discussion.', verbose_name='Subscribe to the chat mailing list'),
 
        ),
 
        migrations.AlterField(
 
            model_name='attendeeprofile',
 
            name='of_legal_age',
 
            field=models.BooleanField(blank=True, help_text='Being under 18 will not stop you from attending the conference. We need to know whether you are over 18 to allow us to cater for you at venues that serve alcohol.', verbose_name='Are you over 18?'),
 
        ),
 
        migrations.AlterField(
 
            model_name='attendeeprofile',
 
            name='past_lca',
 
            field=models.ManyToManyField(blank=True, to='pinaxcon_registrasion.PastEvent', verbose_name='Which past events have you attended?'),
 
        ),
 
    ]
pinaxcon/registrasion/models.py
Show inline comments
...
 
@@ -164,66 +164,66 @@ class AttendeeProfile(rego.AttendeeProfileBase):
 
        blank=True,
 
    )
 
    gender = models.CharField(
 
        verbose_name="Gender",
 
        help_text="Gender data will only be used for demographic purposes.",
 
        max_length=64,
 
        blank=True,
 
    )
 

	
 
    children = models.CharField(
 
        verbose_name="Child Ages and Information",
 
        max_length=256,
 
        help_text="Linux.conf.au is a family friendly conference and provides "
 
        help_text="Everything Open is a family friendly conference and provides "
 
            "free child-care for pre-school children from 6 months up to 5 years. We "
 
            "hope to also provide a programme for older children and will let you "
 
            "know closer to the conference. If you're wanting to bring your children "
 
            "to LCA, please let us know their age(s) so we can ensure we have "
 
            "know closer to the conference. If you're wanting to bring your children, "
 
            "please let us know their age(s) so we can ensure we have "
 
            "enough spaces available.",
 
        blank=True
 
    )
 

	
 
    linux_australia = models.BooleanField(
 
        verbose_name="Linux Australia membership",
 
        help_text="Select this field to register for free "
 
                  "<a href='http://www.linux.org.au/'>Linux Australia</a> "
 
                  "membership.",
 
        blank=True,
 
    )
 

	
 
    lca_announce = models.BooleanField(
 
        verbose_name="Subscribe to lca-announce list",
 
        help_text="Select to be subscribed to the low-traffic lca-announce "
 
                  "mailing list",
 
        blank=True,
 
    )
 

	
 
    lca_chat = models.BooleanField(
 
        verbose_name="Subscribe to the LCA chat list",
 
        verbose_name="Subscribe to the chat mailing list",
 
        help_text="lca-chat is a high-traffic mailing list used by "
 
                  "attendees during the week of the conference for general "
 
                  "discussion.",
 
        blank=True,
 
        default=False,
 
    )
 

	
 
    future_conference = models.BooleanField(
 
        verbose_name = "Reuse my login for future Linux Australia conferences?",
 
        help_text="Select to have your login details made available to future "
 
                  "Linux Australia conferences who share the same Single Sign "
 
                  "On system.",
 
        blank=True,
 
        default=False,
 
    )
 

	
 
    past_lca = models.ManyToManyField(
 
        PastEvent,
 
        verbose_name="Which past linux.conf.au events have you attended?",
 
        verbose_name="Which past events have you attended?",
 
        blank=True,
 
    )
 

	
 
    def first_name(self):
 
        return wrap(self.name, 15, break_long_words=False)[0]
 

	
 
    def last_name(self):
 
        names = wrap(self.name, 15, break_long_words=False)
 
        return names[1] if len(names) > 1 else ''
pinaxcon/settings.py
Show inline comments
...
 
@@ -354,32 +354,26 @@ AUTHENTICATION_BACKENDS = [
 
    'symposion.teams.backends.TeamPermissionsBackend',
 
    'django.contrib.auth.backends.ModelBackend',
 
    'djangosaml2.backends.Saml2Backend',
 
]
 

	
 
LOGIN_URL = '/saml2/login/'
 
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
 

	
 
CONFERENCE_ID = 1
 
PROPOSAL_FORMS = {
 
    "talk": "pinaxcon.proposals.forms.TalkProposalForm",
 
    "tutorial": "pinaxcon.proposals.forms.TutorialProposalForm",
 
    "miniconf": "pinaxcon.proposals.forms.MiniconfProposalForm",
 
    ### LCA2022 Miniconfs
 
    "glam-community-miniconf": "pinaxcon.proposals.forms.GlamCommunityProposalForm",
 
    "kernel-miniconf": "pinaxcon.proposals.forms.KernelProposalForm",
 
    "open-hardware-miniconf": "pinaxcon.proposals.forms.OpenHardwareProposalForm",
 
    "sysadmin-miniconf": "pinaxcon.proposals.forms.SysAdminProposalForm",
 
}
 
MAIN_CONFERENCE_PROPOSAL_KINDS = ("Talk", "Miniconf")
 
MAIN_CONFERENCE_PROPOSAL_KINDS = ("Talk",)
 

	
 
# Registrasion bits:
 
ATTENDEE_PROFILE_MODEL = "pinaxcon.registrasion.models.AttendeeProfile"
 
ATTENDEE_PROFILE_FORM = "pinaxcon.registrasion.forms.ProfileForm"
 
INVOICE_CURRENCY = "AUD"
 
GST_RATE =  Decimal('0.1')
 
TICKET_PRODUCT_CATEGORY = 1
 
TERMS_PRODUCT_CATEGORY = 2
 
ATTENDEE_PROFILE_FORM = "pinaxcon.registrasion.forms.ProfileForm"
 

	
 
#REGIDESK
 
REGIDESK_BOARDING_GROUP = "Ready For Boarding"
...
 
@@ -446,25 +440,25 @@ SAML_CONFIG = {
 
if 'SAML_CONFIG_LOADER' in os.environ:
 
    SAML_CONFIG_LOADER = os.environ.get('SAML_CONFIG_LOADER')
 

	
 
DEFAULT_FILE_STORAGE = os.environ.get('DEFAULT_FILE_STORAGE', 'gapc_storage.storage.GoogleCloudStorage')
 
GAPC_STORAGE = {
 
    'num_retries': 2,
 
}
 

	
 
SETTINGS_EXPORT = [
 
    'DEBUG',
 
    'ANALYTICS_KEY',
 
    'TIME_ZONE',
 
    'LCA_START',
 
    'CONF_START',
 
    'CONFERENCE_EMAIL',
 
]
 

	
 
if DEV_MODE and DEV_MODE == "LAPTOP":
 
    print("ENABLING LAPTOP MODE")
 
    from .devmode_settings import *
 

	
 

	
 
class Category(object):
 
    tickets = []
 

	
 
    @classmethod
...
 
@@ -509,35 +503,35 @@ class SpeakersDinnerCat(Category):
 
        cls.tickets.append(t)
 
        return t
 

	
 

	
 
class PenguinDinnerCat(Category):
 
    @classmethod
 
    def create(cls, name: str, price: Decimal, description: str, reservation: timedelta) -> PenguinDinnerTicket:
 
        t = PenguinDinnerTicket(name, price, description, reservation, cls)
 
        cls.tickets.append(t)
 
        return t
 

	
 

	
 
CONFERENCE_NAME = os.environ.get('CONFERENCE_NAME', 'linux.conf.au')
 
CONFERENCE_NAME_SHORT = os.environ.get('CONFERENCE_NAME_SHORT', 'LCA')
 
CONFERENCE_NAME = os.environ.get('CONFERENCE_NAME', 'Everything Open')
 
CONFERENCE_NAME_SHORT = os.environ.get('CONFERENCE_NAME_SHORT', 'EO')
 
CONFERENCE_EMAIL = os.environ.get('CONFERENCE_EMAIL', DEFAULT_FROM_EMAIL)
 
LCA_TZINFO = pytz.timezone(TIME_ZONE)
 
LCA_START = LCA_TZINFO.localize(datetime(2022, 1, 14))
 
LCA_END = LCA_TZINFO.localize(datetime(2022, 1, 16))
 
LCA_MINICONF_END = LCA_TZINFO.localize(datetime(2022, 1, 14, 23, 59))
 
EARLY_BIRD_DEADLINE = LCA_TZINFO.localize(datetime(2022, 12, 1))
 
PENGUIN_DINNER_TICKET_DATE = date(2022, 1, 14)
 
SPEAKER_DINNER_TICKET_DATE = date(2022, 1, 15)
 
PDNS_TICKET_DATE = date(2022, 1, 16)
 
CONF_TZINFO = pytz.timezone(TIME_ZONE)
 
CONF_START = CONF_TZINFO.localize(datetime(2023, 3, 14))
 
CONF_END = CONF_TZINFO.localize(datetime(2023, 3, 16))
 
CONF_MINICONF_END = CONF_TZINFO.localize(datetime(2023, 3, 14, 23, 59))
 
EARLY_BIRD_DEADLINE = CONF_TZINFO.localize(datetime(2023, 1, 28))
 
PENGUIN_DINNER_TICKET_DATE = date(2023, 3, 15)
 
SPEAKER_DINNER_TICKET_DATE = date(2023, 3, 14)
 
PDNS_TICKET_DATE = date(2023, 3, 16)
 

	
 
TSHIRT_PRICE = Decimal("25.00")
 

	
 
CONTRIBUTOR = Ticket("Contributor", Decimal("300.00"), Decimal("250.00"))
 
PROFESSIONAL = Ticket("Professional", Decimal("125.00"), Decimal("100.00"))
 
HOBBYIST = Ticket("Hobbyist", Decimal("70.00"), None)
 
STUDENT = Ticket("Student", Decimal("30.00"), None)
 
MINICONF_ONLY = Ticket("Miniconf Only", Decimal("25.00"), None)
 

	
 
MEDIA = Ticket("Media", Decimal("0.0"), None)
 
SPEAKER = Ticket("Speaker", Decimal("0.0"), None)
 
SPONSOR = Ticket("Sponsor", Decimal("0.0"), None)
pinaxcon/templates/nav.html
Show inline comments
 
{% load sitetree %}
 
{% load static %}
 

	
 
<nav class="navbar navbar-expand-lg navbar-light bg-blaze">
 
<nav class="navbar navbar-expand-lg navbar-light bg-dawn-sea">
 
  <div class="container">
 
    <a class="navbar-brand" href="/">
 
      <img src="{% static 'lca/lca2022.svg' %}" alt="linux.conf.au 2022 logo" height="56px">
 
      <img src="{% static 'img/eo2023.svg' %}" alt="Everything Open 2023 logo" height="56px">
 
    </a>
 

	
 
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
 
      <span class="navbar-toggler-icon"></span>
 
    </button>
 

	
 
    {% sitetree_menu from "main" include "trunk" template "sitetree_header.html" %}
 
  </div>
 
</nav>
pinaxcon/templates/registrasion/badge.svg
Show inline comments
...
 
@@ -88,25 +88,25 @@
 
        <path d="M187.63,365.65A1.72,1.72,0,0,1,187,365a2,2,0,0,1,0-1.91,1.79,1.79,0,0,1,.65-.66,1.85,1.85,0,0,1,.94-.24,1.79,1.79,0,0,1,.93.24,1.74,1.74,0,0,1,.66.66,2,2,0,0,1,0,1.91,1.68,1.68,0,0,1-.66.66,1.79,1.79,0,0,1-.93.24A1.85,1.85,0,0,1,187.63,365.65Zm1.69-.27a1.4,1.4,0,0,0,.53-.55,1.76,1.76,0,0,0,0-1.59,1.4,1.4,0,0,0-.53-.55,1.58,1.58,0,0,0-1.5,0,1.34,1.34,0,0,0-.53.55,1.76,1.76,0,0,0,0,1.59,1.34,1.34,0,0,0,.53.55,1.51,1.51,0,0,0,1.5,0Z" fill="#231f20"/>
 
        <path d="M192.34,362.39a1.7,1.7,0,0,1,.87-.21v.34h-.08a1.21,1.21,0,0,0-1,.38,1.57,1.57,0,0,0-.34,1.06v1.9h-.35v-3.65h.34v.8A1.27,1.27,0,0,1,192.34,362.39Z" fill="#231f20"/>
 
        <path d="M194.29,365.76a1.73,1.73,0,0,1-.62-.34l.16-.28a1.87,1.87,0,0,0,.58.32,2.3,2.3,0,0,0,.74.12,1.43,1.43,0,0,0,.81-.18.57.57,0,0,0,.27-.5.47.47,0,0,0-.15-.37.79.79,0,0,0-.35-.19,4.52,4.52,0,0,0-.58-.14,5,5,0,0,1-.7-.16,1.08,1.08,0,0,1-.46-.3.81.81,0,0,1-.19-.56.86.86,0,0,1,.37-.72,1.67,1.67,0,0,1,1-.28,2.3,2.3,0,0,1,.69.1,1.53,1.53,0,0,1,.56.26l-.16.28a1.73,1.73,0,0,0-.51-.25,2.33,2.33,0,0,0-.59-.08,1.29,1.29,0,0,0-.77.19.58.58,0,0,0-.26.49.5.5,0,0,0,.15.39.91.91,0,0,0,.36.2c.14,0,.34.09.6.14a6.32,6.32,0,0,1,.69.17,1.07,1.07,0,0,1,.44.28.73.73,0,0,1,.19.54.87.87,0,0,1-.38.73,1.82,1.82,0,0,1-1.07.27A2.63,2.63,0,0,1,194.29,365.76Z" fill="#231f20"/>
 
        <rect y="317.34" width="297.64" height="37.27" fill="#00b1c5"/>
 
        <path d="M175.69,399.54a13.12,13.12,0,1,1,0-26.24,12.52,12.52,0,0,1,9,3.61l-2.53,2.53a9.12,9.12,0,0,0-6.46-2.56,9.54,9.54,0,0,0,0,19.07,8.75,8.75,0,0,0,6.62-2.62,7.47,7.47,0,0,0,2-4.51H176v-3.59h11.8a11.5,11.5,0,0,1,.2,2.24,11.85,11.85,0,0,1-3.11,8.39A12,12,0,0,1,175.69,399.54Z" fill="#557ebf"/>
 
        <path d="M206.9,391.1a8.45,8.45,0,1,1-8.45-8.45A8.34,8.34,0,0,1,206.9,391.1Zm-3.7,0a4.77,4.77,0,1,0-4.75,5.12A4.86,4.86,0,0,0,203.2,391.1Z" fill="#ea4535"/>
 
        <path d="M225.9,391.09a8.45,8.45,0,1,1-8.45-8.45A8.34,8.34,0,0,1,225.9,391.09Zm-3.7,0a4.77,4.77,0,1,0-4.75,5.12A4.86,4.86,0,0,0,222.2,391.09Z" fill="#f9bc15"/>
 
        <path d="M244,383.15v15.17c0,6.24-3.68,8.8-8,8.8a8,8,0,0,1-7.48-5l3.23-1.35a4.66,4.66,0,0,0,4.25,3c2.79,0,4.52-1.73,4.52-5v-1.21h-.13a5.77,5.77,0,0,1-4.45,1.92,8.47,8.47,0,0,1,0-16.9,5.86,5.86,0,0,1,4.45,1.89h.13v-1.38Zm-3.27,8c0-3-2-5.15-4.51-5.15s-4.51,2.18-4.51,5.15,2,5.09,4.51,5.09S240.68,394.07,240.68,391.12Z" fill="#557ebf"/>
 
        <path d="M250.66,374.21V399H247V374.21Z" fill="#36a852"/>
 
        <path d="M265.49,393.87l2.88,1.92a8.4,8.4,0,0,1-7,3.75,8.26,8.26,0,0,1-8.38-8.45c0-5,3.61-8.45,8-8.45s6.53,3.49,7.23,5.38l.39,1-11.3,4.67a4.3,4.3,0,0,0,4.1,2.56A4.82,4.82,0,0,0,265.49,393.87Zm-8.87-3,7.56-3.13a3.28,3.28,0,0,0-3.14-1.79A4.63,4.63,0,0,0,256.62,390.83Z" fill="#ea4535"/>
 
        <rect x="160.95" y="373.04" width="112" height="36" fill="none"/>
 
        <text transform="translate(84.43 102.23)" font-size="15" fill="#231f20" font-family="SourceSansPro-Regular, Source Sans Pro">Janua<tspan x="38.69" y="0" letter-spacing="0.02em">r</tspan>
 
            <tspan x="44.26" y="0">y 14 - 16 2022</tspan>
 
            <tspan x="44.26" y="0">y 14 - 16 2023</tspan>
 
        </text>
 
        <g id="Layer_2" data-name="Layer 2">
 
            <g id="emperor">
 
                <path d="M256.88,261.71a24.47,24.47,0,0,0,.69,2.7c.18.24,1.25,4.65,1.31,4.83s1.27,3.41,1.33,3.65.75,2.64.86,3.3.7,4.07.7,4.73.05,2.4.05,2.64v3.59a29.61,29.61,0,0,1-.11,3.65,28.94,28.94,0,0,1-.75,4,11.44,11.44,0,0,1-1.22,3.36c-.33.61-.63,1.2-.92,1.2a7.23,7.23,0,0,1-2-2.34c.34-2.76,1.55-4.62,1.84-8.51a85.54,85.54,0,0,0,0-8.63c-.15-2.46-1.14-12.94-1.32-13.3a15.43,15.43,0,0,1-.58-1.74A10.23,10.23,0,0,1,256.88,261.71Z" fill="#d2d3d4"/>
 
                <path d="M258.3,257.3s-.75,2.93-.75,3.42-.52.82-.23,2,1.15,4.32,1.38,5.1c.1.34.49,1.43.93,2.72.58,1.66,1.26,3.65,1.55,4.77.52,2,1.28,11.51.81,14.44s-1.55,9.18-2,10.08-.92,1-1.45.66a3.9,3.9,0,0,1-1.1-1.62,10.69,10.69,0,0,0-.75-1.32,10.24,10.24,0,0,0,.4-1.44c.12-.66.06.3.64,1.26s1.1,1.8,1.5,1.08a11.51,11.51,0,0,0,1.68-4.32c.06-1.56.87-3.78.81-6.65s-.23-8.21-.46-9.41a46.4,46.4,0,0,0-1.22-5.16c-.29-.53-2.26-7.6-2.42-8a9,9,0,0,1-.76-2.87c.12-.6,1-3.59,1-3.9A3.31,3.31,0,0,1,258.3,257.3Z" fill="#231f20"/>
 
                <path d="M246.39,245.73a33.05,33.05,0,0,1,4.59-.36c.44.18,2.69,1.62,2.69,1.62s2.69,2.87,2.86,4,.7,8.81.78,9.08a26.09,26.09,0,0,1-.43,2.6,13.09,13.09,0,0,0,0,2c.09.72.78,4.31.86,4.76s.61,3.87.7,4.31.35,3.87.35,4.23.34,3.59.34,3.86v4.77c0,.27-.52,4.41-.6,5.12s-1.82,6.11-1.74,6.38-2.69,6.2-2.69,6.83-1.55,2.6-2,3.05A24.68,24.68,0,0,1,247.6,310a16.91,16.91,0,0,1-4.33.54c-.61,0-7.73-.45-8.23-.45s-1.91-1-2.17-1.08-1-1.09-1.31-1.18a9.16,9.16,0,0,1-1.91-1.88,21.34,21.34,0,0,1-.61-2.07c-.17-.63-.69-4.14-.78-4.59s-.43-3.23-.6-3.77.17-6.29-.09-7.28,1.91-8.53,2.08-9.34,3.64-8.72,3.47-10.25.87-11.59.95-12.58,2.34-4.58,3.12-5.3S244.22,246.09,246.39,245.73Z" fill="#fff"/>
 
                <path d="M254.8,249.32s-2-2.33-1.48-1.7-1.47-.81-1.47-.81-.52.36-.6.09-.27.28-.44.63-.6-.63-.6-.63l-.44.62-.69-.43-.35,1.08-.69-.54.43,1.08h-.95l.61.62-1.22-.17.35,1.07-.87-.35.09.71-.78-.19.34.81h-.69l.26.39.27.42-.69-.28.61.81-.61-.09-.61-.28-1-1.78.86-3.14,2.69-1.71,2.88-.09,2,.27,2.69,2.34Z" fill="#6e6f72"/>
 
                <g clip-path="url(#clip-path)">
 
                    <g clip-path="url(#clip-path-2)">
 
                        <image width="111" height="129" transform="translate(243.01 246.45) scale(0.13)" xlink:href="data:image/png;base64,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" style="isolation:isolate"/>
 
                    </g>
 
                </g>
pinaxcon/templates/site_base.html
Show inline comments
...
 
@@ -12,31 +12,31 @@
 
<head>
 
  <meta charset="utf-8">
 
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
 
  <meta name="description" content="">
 
  <meta name="viewport" content="width=device-width, initial-scale=1">
 

	
 
  <title>{{ head_title }}</title>
 

	
 
  <meta property="og:type" content="website" />
 

	
 
  <!-- Cards -->
 
  <meta property="og:title" content="{{ head_title }}">
 
  <meta property="og:description" content="linux.conf.au 2022 - Jan 14-16 2022, Online, Worldwide" />
 
  <meta property="og:description" content="Everything Open 2023 - March 14-16 2023, Melbourne, Australia" />
 
  <meta property="og:url" content="{{ request.scheme }}://{{ request.get_host }}{{ request.path }}">
 
  <meta name="twitter:site" content="@linuxconfau">
 
  <meta name="twitter:site" content="@_everythingopen">
 
  <meta name="twitter:image:alt" content="{{ head_title }}" />
 
  <meta name="twitter:card" content="summary">
 
  <meta name="twitter:image" content="{{ request.scheme }}://{{ request.get_host }}/media/img/card/lca_badge.1ef714c1.png" />
 
  <meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}/media/img/card/lca_badge.1ef714c1.png" />
 
  <meta name="twitter:image" content="{{ request.scheme }}://{{ request.get_host }}/media/img/card/eo-badge.ba30d338.png" />
 
  <meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}/media/img/card/eo-badge.ba30d338.png" />
 
  <meta property="og:image:width" content="400" />
 
  <meta property="og:image:height" content="400" />
 

	
 
  {% block styles %}
 
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
 
  <link href="{% sass_src 'scss/app.scss' %}" rel="stylesheet" type="text/css" />
 
  {% block extra_style %}{% endblock %}
 
  {% endblock %}
 

	
 
  {% block extra_head_base %}
 
  {% block extra_head %}{% endblock %}
 
  {% endblock %}
...
 
@@ -112,37 +112,42 @@
 
    {% endblock %}
 

	
 
    {% block extra_body_base %}
 
    {% block extra_body %}
 
    {% endblock %}
 
    {% endblock %}
 
  </main>
 

	
 
  <footer class="footer mt-4 d-print-none">
 
    <div class="container py-4">
 
      <div class="row">
 
        <div class="col-md-4 pb-4">
 
          <strong>linux.conf.au 2022</strong> <br>
 
          Jan 14-16 2022 <br>
 
          Online, Worldwide <br>
 
          <a href="mailto:{{ settings.CONFERENCE_EMAIL }}" alt="Email"><i class="far fa-envelope"></i></a>&nbsp;&nbsp;
 
          <a href="https://twitter.com/linuxconfau" alt="Twitter"><i class="fab fa-twitter"></i></a>&nbsp;&nbsp;
 
          <a href="https://www.facebook.com/linuxconferenceaustralia/" alt="Facebook"><i class="fab fa-facebook"></i></a>
 
          <strong>Everything Open 2023</strong> <br>
 
          March 14-16 2023 <br>
 
          Naarm (Melbourne), Australia <br>
 
          Timezone: AEDT - UTC+11 <br>
 
          <a href="mailto:contact@everythingopen.au" alt="Email"><i class="bi-envelope-fill"></i></a>&nbsp;&nbsp;<a
 
            href="https://twitter.com/_everythingopen" alt="Twitter"><i class="bi-twitter"></i></a>&nbsp;&nbsp;<a
 
            href="https://www.linkedin.com/showcase/everythingopen/" alt="LinkedIn"><i class="bi-linkedin"></i></a>
 

	
 
          <a href="mailto:{{ settings.CONFERENCE_EMAIL }}" alt="Email"><i class="far fa-envelope"></i></a>&nbsp;&nbsp;<a
 
            href="https://twitter.com/_everythingopen" alt="Twitter"><i class="fab fa-twitter"></i></a>&nbsp;&nbsp;<a
 
            href="https://www.facebook.com/linuxconferenceaustralia/" alt="Facebook"><i class="fab fa-facebook"></i></a>&nbsp;&nbsp;<a
 
            href="https://www.linkedin.com/showcase/everythingopen/" alt="LinkedIn"><i class="fab fa-linkedin"></i></a>
 
        </div>
 
        <div class="col-md-4 pb-4 text-center">
 
          <img src="{% static 'lca/lca_horiz_colour.svg' %}" alt="linux.conf.au logo" class="footer-logo">
 
          <a href="https://linux.org.au"><img src="{% static 'lca/la_logo.svg' %}" alt="Linux Australia logo" class="footer-image"></a>
 
          <a href="https://linux.org.au"><img src="{% static 'img/la_logo.svg' %}" alt="Linux Australia logo" class="footer-image"></a>
 
        </div>
 
        <div class="col-md-4 pb-4 text-right">
 
          <small>
 
            <a href="#">Back to top</a><br>
 
            &copy; 2021 linux.conf.au and <a href="http://linux.org.au/">Linux Australia</a><br>
 
            &copy; 2022 Everything Open and <a href="http://linux.org.au/">Linux Australia</a><br>
 
            Linux is a registered trademark of Linus Torvalds <br>
 
            <a href="/colophon/">Colophon</a>
 
          </small>
 
        </div>
 
      </div>
 
    </div>
 
  </footer>
 

	
 
</body>
 
</html>
pinaxcon/templates/symposion/dashboard/_categories.html
Show inline comments
...
 
@@ -63,25 +63,25 @@
 
      <p>If you would like to change the details on your badge or your attendee statistics, you may edit your attendee profile here.</p>
 
      <div>
 
        <a class="btn btn-primary" role="button" href="{% url "attendee_edit" %}">Edit attendee profile</a>
 
        {% flag "badge_preview" %}
 
        <a class="btn btn-info" role="button" href="{% url "user_badge" %}">Preview my badge</a>
 
        {% endflag %}
 
      </div>
 
    </div>
 
    <div class="col-md-6 mb-3 mb-md-0">
 
      <h3>Account Management</h3>
 
      <p>If you would like to change your registered email address or password, you can use our self-service account management portal</p>
 
      <div>
 
        <a class="btn btn-primary" role="button" href="https://login.linux.conf.au/manage/">Account Management</a>
 
        <a class="btn btn-primary" role="button" href="https://login.everythingopen.au/manage/">Account Management</a>
 
      </div>
 
    </div>
 
  </div>
 

	
 
  {% items_pending as pending %}
 
  <div class="row">
 
    <div class="col-12">
 
      <h3 class="my-3">Account</h3>
 
    </div>
 
  </div>
 

	
 
  <div class="row">
pinaxcon/templates/symposion/proposals/_proposal_fields.html
Show inline comments
...
 
@@ -102,24 +102,35 @@
 
    <p></p>
 
  </div>
 
</div>
 

	
 
<div class="row">
 
  <label class="list-label col-md-2">Private Abstract</label>
 
  <div class="col-md-10">
 
    <div class="private_abstract monospace-text">{{ proposal.private_abstract_html|safe }}&nbsp;</div>
 
    <p></p>
 
  </div>
 
</div>
 

	
 
<div class="row">
 
  <label class="list-label col-md-2">Content Warning</label>
 
  <div class="col-md-10">
 
    {% if proposal.content_warning_html %}
 
    <div class="content_warning monospace-text">{{ proposal.content_warning_html|safe }}</div>
 
    {% else %}
 
    <div class="content_warning monospace-text"><b>No Content Warning Provided</b></div>
 
    {% endif %}
 
  </div>
 
</div>
 

	
 
<div class="row">
 
  <label class="list-label col-md-2">Project</label>
 
  <div class="col-md-10">
 
    {% if proposal.project %}
 
    <p>{{ proposal.project|safe }}&nbsp;</p>
 
    {% else %}
 
    <p><b>None Provided</b></p>
 
    {% endif %}
 
  </div>
 
</div>
 

	
 
<div class="row">
pinaxcon/templates/symposion/schedule/schedule_conference.html
Show inline comments
...
 
@@ -37,25 +37,25 @@
 

	
 
  <div class="tab-content d-print-block my-3" id="schedule-tabContent">
 
    {% for section in sections %}
 
      {% cache 600 "schedule-table" section.schedule.section %}
 
      {% for timetable in section.days %}
 
      <div class="row tab-pane fade {% if forloop.first %}show active{% endif %} d-print-block" id="{{ timetable.day.date|date:"l"|lower}}" role="tabpanel" aria-labelledby="schedule_day_{{ timetable.day.date|date:"l"|lower}}-tab">
 
        <div class="col-12">
 
          <h2 class="my-4">
 
            {{ section.schedule.section.name }}
 
            <span class="clearfix d-sm-block d-md-none"></span>
 
            <small class="text-muted">{{ timetable.day.date|date:"l" }}, {{ timetable.day.date }}</small>
 
          </h2>
 
          <p class="timezone-info small">Conference times are in {{ settings.LCA_START|date:'T' }} (UTC{{ settings.LCA_START|date:'O' }}). <span class="d-print-none">Current talks will be highlighted.</span></p>
 
          <p class="timezone-info small">Conference times are in {{ settings.CONF_START|date:'T' }} (UTC{{ settings.CONF_START|date:'O' }}). <span class="d-print-none">Current talks will be highlighted.</span></p>
 
          <div class="table-responsive d-none d-md-block">
 
            {% include "symposion/schedule/_grid.html" %}
 
          </div>
 
          <div class="mobile-schedule d-sm-block d-md-none">
 
            {% include "symposion/schedule/_mobile.html" %}
 
          </div>
 
        </div>
 
      </div>
 
      {% endfor %}
 
      {% endcache %}
 
    {% endfor %}
 
  </div>
pinaxcon/templates/symposion/schedule/schedule_detail.html
Show inline comments
...
 
@@ -7,24 +7,24 @@
 

	
 
{% block head_title %}{{ schedule.section.name }} Schedule{% endblock %}
 
{% block page_title %}{{ schedule.section.name }} Schedule{% endblock%}
 

	
 
{% block content %}
 
  {% cache 600 "schedule-detail-table" schedule.section %}
 
    {% for timetable in days %}
 
    <div class="row timetable-day">
 
      <div class="col-12">
 
        <h2 class="my-4">
 
          {{ timetable.day.date|date:"l" }}, {{ timetable.day.date }}
 
        </h2>
 
        <p class="timezone-info small">Conference times are in {{ settings.LCA_START|date:'T' }} (UTC{{ settings.LCA_START|date:'O' }}). <span class="d-print-none">Current talks will be highlighted.</span></p>
 
        <p class="timezone-info small">Conference times are in {{ settings.CONF_START|date:'T' }} (UTC{{ settings.CONF_START|date:'O' }}). <span class="d-print-none">Current talks will be highlighted.</span></p>
 
        <div class="table-responsive d-none d-md-block">
 
          {% include "symposion/schedule/_grid.html" %}
 
        </div>
 
        <div class="mobile-schedule d-sm-block d-md-none">
 
          {% include "symposion/schedule/_mobile.html" %}
 
        </div>
 
      </div>
 
    </div>
 
    {% endfor %}
 
  {% endcache %}
 
{% endblock %}
pinaxcon/templates/symposion/schedule/schedule_edit.html
Show inline comments
...
 
@@ -15,25 +15,25 @@
 
        <input type="submit" name="submit" value="Submit" />
 
        <input type="submit" id="delete" name="delete" value="Delete Schedule" />
 
      </form>
 
    </div>
 
  </div>
 

	
 
  {% for timetable in days %}
 
  <div class="row">
 
    <div class="col-12">
 
      <h2 class="my-4">
 
        {{ timetable.day.date|date:"l" }}, {{ timetable.day.date }}
 
      </h2>
 
      <p class="timezone-info small">Conference times are in {{ settings.LCA_START|date:'T' }} (UTC{{ settings.LCA_START|date:'O' }}). <span class="d-print-none">Current talks will be highlighted.</span></p>
 
      <p class="timezone-info small">Conference times are in {{ settings.CONF_START|date:'T' }} (UTC{{ settings.CONF_START|date:'O' }}). <span class="d-print-none">Current talks will be highlighted.</span></p>
 
      <div class="table-responsive d-none d-md-block">
 
        {% include "symposion/schedule/_grid.html" with edit_schedule=True %}
 
      </div>
 
      <div class="mobile-schedule d-sm-block d-md-none">
 
        {% include "symposion/schedule/_mobile.html" with edit_schedule=True %}
 
      </div>
 
    </div>
 
  </div>
 
  {% endfor %}
 

	
 
  <div class="modal fade" id="slotEditModal"></div>
 
{% endblock %}
static/src/img/eo2023.svg
Show inline comments
 
new file 100644
 
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="180" height="35" viewBox="0 0 180 35"><path d="M14,15.85v.83H5.34V4.08h8.43v.83H6.26v5H13v.81H6.26v5.16Z" fill="#fff"/><path d="M27.27,4.08l-5.62,12.6h-.91L15.12,4.08h1l5.09,11.41,5.1-11.41Z" fill="#fff"/><path d="M38,15.85v.83H29.3V4.08h8.43v.83H30.22v5h6.72v.81H30.22v5.16Z" fill="#fff"/><path d="M50.09,16.68l-3-4.21a9.37,9.37,0,0,1-1.23.09h-3.6v4.12h-.92V4.08h4.52a5.65,5.65,0,0,1,3.73,1.13,3.84,3.84,0,0,1,1.35,3.12A3.85,3.85,0,0,1,48,12.27l3.15,4.41Zm-4.23-4.93a4.69,4.69,0,0,0,3.08-.89A3.12,3.12,0,0,0,50,8.33,3.11,3.11,0,0,0,48.94,5.8a4.69,4.69,0,0,0-3.08-.89h-3.6v6.84Z" fill="#fff"/><path d="M58,12.34v4.34h-.92V12.34L52,4.08h1l4.55,7.42,4.56-7.42h1Z" fill="#fff"/><path d="M67.73,4.91H63.2V4.08h10v.83H68.65V16.68h-.92Z" fill="#fff"/><path d="M85.71,4.08v12.6H84.8v-6H76.37v6h-.92V4.08h.92v5.8H84.8V4.08Z" fill="#fff"/><path d="M90.11,4.08H91v12.6h-.91Z" fill="#fff"/><path d="M105.68,4.08v12.6h-.76L96.33,5.74V16.68h-.91V4.08h.77l8.57,11V4.08Z" fill="#fff"/><path d="M119.07,10.44H120v4.71a5.49,5.49,0,0,1-2,1.21,7.56,7.56,0,0,1-2.49.41,6.76,6.76,0,0,1-3.37-.83,6,6,0,0,1-2.36-2.28,6.37,6.37,0,0,1-.86-3.28,6.34,6.34,0,0,1,.86-3.27,6,6,0,0,1,2.36-2.29A6.92,6.92,0,0,1,115.47,4a7.26,7.26,0,0,1,2.55.44,5.57,5.57,0,0,1,2,1.29l-.57.61a4.72,4.72,0,0,0-1.77-1.14,6.29,6.29,0,0,0-2.17-.35,6,6,0,0,0-2.93.72,5.21,5.21,0,0,0-2,2,5.53,5.53,0,0,0-.74,2.83,5.46,5.46,0,0,0,2.79,4.82,5.91,5.91,0,0,0,2.92.73,5.5,5.5,0,0,0,3.58-1.16Z" fill="#fff"/><path d="M147.91,5.3a3.84,3.84,0,0,1,1.35,3.12,3.81,3.81,0,0,1-1.35,3.1,5.65,5.65,0,0,1-3.73,1.13h-3.6v4.12h-.92V4.17h4.52A5.65,5.65,0,0,1,147.91,5.3Zm-.65,5.64a3.09,3.09,0,0,0,1.06-2.52,3.11,3.11,0,0,0-1.06-2.53A4.69,4.69,0,0,0,144.18,5h-3.6v6.82h3.6A4.69,4.69,0,0,0,147.26,10.94Z"/><path d="M161.05,15.94v.83h-8.7V4.17h8.43V5h-7.51v5H160v.81h-6.72v5.16Z"/><path d="M174.66,4.17v12.6h-.76L165.31,5.83V16.77h-.91V4.17h.77l8.57,11V4.17Z"/><path d="M131.65,4a6.18,6.18,0,0,0-3.33,0,6.35,6.35,0,0,0-1.83.85l.63.63a5.41,5.41,0,0,1,4.26-.63,5.67,5.67,0,0,1,2.56,1.51A5.56,5.56,0,0,1,135.44,9a5.28,5.28,0,0,1,0,2.87,5.65,5.65,0,0,1-1.53,2.57A5.87,5.87,0,0,1,131.31,16a5.32,5.32,0,0,1-2.88,0,5.56,5.56,0,0,1-2.56-1.5,5.56,5.56,0,0,1-1.5-2.56,5.32,5.32,0,0,1,0-2.88,5.61,5.61,0,0,1,.61-1.4l-.63-.62a6.32,6.32,0,0,0-.84,1.83,6.21,6.21,0,0,0,0,3.34,6.7,6.7,0,0,0,4.67,4.67,6.18,6.18,0,0,0,3.33,0,6.69,6.69,0,0,0,3-1.8,6.88,6.88,0,0,0,1.81-3,6.18,6.18,0,0,0,0-3.33,6.83,6.83,0,0,0-4.7-4.7Z" fill="#231f20"/><path d="M43.19,31.11V23.92L39.66,30h-.3l-3.51-6v7.17h-.6v-8.4h.51l3.76,6.49,3.76-6.49h.5v8.4Z"/><path d="M52.52,30.55v.56h-5.8v-8.4h5.62v.55h-5v3.31h4.48v.54H47.33v3.44Z"/><path d="M54.75,22.71h.61v7.84H60.2v.56H54.75Z"/><path d="M68.13,27.48a2,2,0,0,1,.48,1.41,1.91,1.91,0,0,1-.78,1.64,3.93,3.93,0,0,1-2.32.58H61.77v-8.4h3.5a3.57,3.57,0,0,1,2.13.55,1.87,1.87,0,0,1,.76,1.59,1.91,1.91,0,0,1-.38,1.22,2.08,2.08,0,0,1-1,.7A2.34,2.34,0,0,1,68.13,27.48Zm-5.75-4.25v3.35h2.87a3,3,0,0,0,1.7-.42,1.48,1.48,0,0,0,.59-1.26A1.44,1.44,0,0,0,67,23.66a2.94,2.94,0,0,0-1.7-.43Zm5,6.92a1.68,1.68,0,0,0,0-2.62,3.31,3.31,0,0,0-1.85-.42H62.38v3.47h3.13A3.22,3.22,0,0,0,67.36,30.15Z"/><path d="M72.12,30.61a4.09,4.09,0,0,1-1.56-1.53,4.26,4.26,0,0,1,1.56-5.88,4.82,4.82,0,0,1,4.47,0,4.07,4.07,0,0,1,1.56,1.52,4.47,4.47,0,0,1,0,4.37,4,4,0,0,1-1.56,1.52,4.74,4.74,0,0,1-4.47,0Zm4.14-.49a3.56,3.56,0,0,0,1.35-1.32,3.8,3.8,0,0,0,.49-1.89A3.75,3.75,0,0,0,77.61,25a3.52,3.52,0,0,0-1.35-1.33,4,4,0,0,0-3.82,0A3.52,3.52,0,0,0,71.09,25a3.65,3.65,0,0,0-.49,1.89,3.7,3.7,0,0,0,.49,1.89,3.56,3.56,0,0,0,1.35,1.32,4,4,0,0,0,3.82,0Z"/><path d="M81.66,30.24a3.74,3.74,0,0,1-.88-2.7V22.71h.61v4.81a3.31,3.31,0,0,0,.7,2.31,2.65,2.65,0,0,0,2.06.77,2.62,2.62,0,0,0,2-.77,3.31,3.31,0,0,0,.71-2.31V22.71h.61v4.83a3.74,3.74,0,0,1-.89,2.7,3.77,3.77,0,0,1-5,0Z"/><path d="M96.2,31.11l-2-2.81a6.07,6.07,0,0,1-.81.06H91v2.75h-.62v-8.4h3a3.77,3.77,0,0,1,2.48.75,2.56,2.56,0,0,1,.9,2.08,2.7,2.7,0,0,1-.51,1.67,2.77,2.77,0,0,1-1.46,1l2.1,2.94Zm-2.82-3.29a3.11,3.11,0,0,0,2.05-.6,2.06,2.06,0,0,0,.71-1.68,2.1,2.1,0,0,0-.71-1.69,3.17,3.17,0,0,0-2.05-.59H91v4.56Z"/><path d="M105.84,22.71v8.4h-.5l-5.73-7.3v7.3H99v-8.4h.52L105.23,30V22.71Z"/><path d="M114.57,30.55v.56h-5.8v-8.4h5.62v.55h-5v3.31h4.48v.54h-4.48v3.44Z"/><path d="M123.61,30.55v.56h-5.77v-.44l3.55-3.52a5.09,5.09,0,0,0,.94-1.2,2.33,2.33,0,0,0,.25-1,1.53,1.53,0,0,0-.55-1.26,2.36,2.36,0,0,0-1.58-.46,3.66,3.66,0,0,0-1.38.24,2.66,2.66,0,0,0-1,.73l-.43-.38a3.16,3.16,0,0,1,1.22-.85,4.4,4.4,0,0,1,1.67-.3,3,3,0,0,1,2,.6,2,2,0,0,1,.73,1.62,2.65,2.65,0,0,1-.29,1.23,5.38,5.38,0,0,1-1.08,1.37l-3.09,3.08Z" fill="#fff"/><path d="M126.29,30.64a3.28,3.28,0,0,1-1.16-1.48,6.26,6.26,0,0,1,0-4.51,3.34,3.34,0,0,1,1.16-1.48,3.07,3.07,0,0,1,3.42,0,3.43,3.43,0,0,1,1.17,1.48,6.41,6.41,0,0,1,0,4.51,3.37,3.37,0,0,1-1.17,1.48,3,3,0,0,1-3.42,0Zm3.11-.48a2.78,2.78,0,0,0,.94-1.27,5.16,5.16,0,0,0,.34-2,5.21,5.21,0,0,0-.34-2,2.78,2.78,0,0,0-.94-1.27,2.45,2.45,0,0,0-2.8,0,2.85,2.85,0,0,0-.94,1.27,5.42,5.42,0,0,0-.33,2,5.37,5.37,0,0,0,.33,2,2.85,2.85,0,0,0,.94,1.27,2.45,2.45,0,0,0,2.8,0Z" fill="#fff"/><path d="M138.2,30.55v.56h-5.77v-.44L136,27.15a4.83,4.83,0,0,0,.94-1.2,2.2,2.2,0,0,0,.25-1,1.53,1.53,0,0,0-.55-1.26,2.35,2.35,0,0,0-1.57-.46,3.71,3.71,0,0,0-1.39.24,2.66,2.66,0,0,0-1,.73l-.43-.38a3.16,3.16,0,0,1,1.22-.85,4.4,4.4,0,0,1,1.67-.3,3,3,0,0,1,2,.6,2,2,0,0,1,.73,1.62,2.77,2.77,0,0,1-.28,1.23,5.87,5.87,0,0,1-1.08,1.37l-3.1,3.08Z" fill="#fff"/><path d="M144,27a2.18,2.18,0,0,1,.72,1.7,2.42,2.42,0,0,1-.33,1.26,2.25,2.25,0,0,1-1,.85,3.68,3.68,0,0,1-1.6.32,4.81,4.81,0,0,1-1.71-.31,3,3,0,0,1-1.25-.82l.31-.47a3,3,0,0,0,1.11.74,3.88,3.88,0,0,0,1.54.29,2.58,2.58,0,0,0,1.72-.5,1.84,1.84,0,0,0,0-2.73,3,3,0,0,0-1.84-.49h-.53v-.44l2.49-3.18h-4.48v-.55h5.27v.43l-2.52,3.23A3.27,3.27,0,0,1,144,27Z" fill="#fff"/></svg>
static/src/img/la_logo.svg
Show inline comments
 
file renamed from static/src/lca/la_logo.svg to static/src/img/la_logo.svg
static/src/lca/lca2022.svg
Show inline comments
 
deleted file
static/src/lca/lca_horiz_blue.svg
Show inline comments
 
deleted file
static/src/lca/lca_horiz_colour.svg
Show inline comments
 
deleted file
vendor/regidesk/regidesk/models.py
Show inline comments
...
 
@@ -210,27 +210,27 @@ class CheckIn(models.Model):
 
                traits.append("miniconf_org")
 
            else:
 
                traits.append("miniconf_speaker")
 

	
 
        return traits
 

	
 
    def _generate_venueless_token(self):
 
        """ Generate token for Venueless login """
 
        if not self.venueless_traits:
 
            return ""
 

	
 
        issued_at = datetime.datetime.utcnow()
 
        expiry = settings.LCA_END + datetime.timedelta(days=1)
 
        expiry = settings.CONF_END + datetime.timedelta(days=1)
 
        if self.user.attendee.ticket_type == "Miniconf Only":
 
            # Miniconf only ticket holders have limited access
 
            expiry = settings.LCA_MINICONF_END
 
            expiry = settings.CONF_MINICONF_END
 

	
 
        payload = {
 
            "iss": settings.VENUELESS_TOKEN_ISSUER,
 
            "aud": settings.VENUELESS_AUDIENCE,
 
            "iat": issued_at,
 
            "exp": expiry,
 
            "uid": self.venueless_user_id,
 
            "traits": self.venueless_traits.split(','),
 
        }
 
        token = jwt.encode(payload, settings.VENUELESS_SECRET, algorithm="HS256")
 
        return token
vendor/regidesk/regidesk/templates/regidesk/ci_overview.html
Show inline comments
...
 
@@ -27,43 +27,43 @@
 
            <dt class="col-sm-3">Name</dt>
 
            <dd class="col-sm-9">{{ user.attendee.attendeeprofilebase.attendeeprofile.name }}</dd>
 

	
 
            <dt class="col-sm-3">Company</dt>
 
            <dd class="col-sm-9">{% if ticket_type == "Student" or ticket_type == "Hobbyist" or "Only" in ticket_type %}{% else %}{{ user.attendee.attendeeprofilebase.attendeeprofile.company }}{% endif %}</dd>
 

	
 
            <dt class="col-sm-3">Free Text 1</dt>
 
            <dd class="col-sm-9">{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_1 }}</dd>
 

	
 
            <dt class="col-sm-3">Free Text 2</dt>
 
            <dd class="col-sm-9">{{ user.attendee.attendeeprofilebase.attendeeprofile.free_text_2 }}</dd>
 

	
 
            {% comment "Not needed for LCA2022 online" %}
 
            {% comment "Not needed for EO2023" %}
 
            <dt class="col-sm-3">Penguin Dinner Tickets</dt>
 
            <dd class="col-sm-9">{{ penguin_dinner_count }}</dd>
 

	
 
            <dt class="col-sm-3">Speaker Dinner Tickets</dt>
 
            <dd class="col-sm-9">{{ speakers_dinner_count }}</dd>
 

	
 
            <dt class="col-sm-3">PDNS Tickets</dt>
 
            <dd class="col-sm-9">{{ pdns_count }}</dd>
 
            {% endcomment %}
 

	
 
            <dt class="col-sm-3">Over 18 years</dt>
 
            <dd class="col-sm-9">{% if user.attendee.attendeeprofilebase.attendeeprofile.of_legal_age %}Yes{% else %}<strong class="red">NO</strong>{% endif %}</dd>
 

	
 
            <dt class="col-sm-3">Username</dt>
 
            <dd class="col-sm-9">{{ user.username }}</dd>
 
        </dl>
 

	
 
        {% comment "Not needed for LCA2022 online" %}
 
        {% comment "Not needed for EO2023" %}
 
        <h4>Shirts ordered</h4>
 
        <table class="table card-text">
 
            {% for shirt in shirts%}
 
            <tr>
 
                <td>{{ shirt.product }}</td>
 
                <td>{{ shirt.quantity }}</td>
 
            </tr>
 
            {% endfor %}
 
        </table>
 
        {% endcomment %}
 
    </div>
 
</div>
...
 
@@ -119,25 +119,25 @@
 
            <input class="btn btn-secondary" type="submit" value="Mark Badge as Printed">
 
        </form>
 
        <form method="post" class="d-inline-block">
 
            <input type="checkbox" name="unbadge" value="unbadge" checked hidden>
 
            <input class="btn btn-danger pull-right" type="submit" value="Reprint Badge">
 
        </form>
 
        <p class="d-inline-block">
 
            <a class="btn btn-outline-info" href="{% url 'badge_print' user.id %}" target="_blank">Preview Badge for Printing</a>
 
        </p>
 
    </div>
 
</div>
 

	
 
{% comment "Not needed for LCA2022 online" %}
 
{% comment "Not needed for EO2023" %}
 
<div class="card {% if check_in.schwag_given %}border-success{% else %}border-danger{% endif %} my-3">
 
    <div class="card-header {% if check_in.schwag_given %}text-white bg-success{% endif %}">Schwag</div>
 
    <div class="card-body">
 
        <dl class="row card-text">
 
            <dt class="col-sm-3">Status</dt>
 
            <dd class="col-sm-9">{% if check_in.schwag_given %}Marked{% else %}Not marked{% endif %} as given</dd>
 
        </dl>
 
        <form method="post">
 
            <input type="checkbox" name="schwag" value="schwag" checked hidden>
 
            <input class="btn {% if check_in.schwag_given %}btn-warning{% else %}btn-primary{% endif %}" type="submit" value="Give Schwag">
 
        </form>
 
    </div>
...
 
@@ -146,25 +146,25 @@
 

	
 
<div class="card my-3">
 
    <div class="card-header">Log Exception</div>
 
    <div class="card-body">
 
        <form method="post" class="card-text">
 
            <textarea class="form-control" rows="3" name="exception">{{ check_in.review_text }}</textarea>
 
            <p class="help-block">Reminder: Please tell attendee to email the conference team with the details as well.</p>
 
            <input class="btn btn-primary" type="submit" value="Log Information">
 
        </form>
 
    </div>
 
</div>
 

	
 
{% comment "Not needed for LCA2022 online" %}
 
{% comment "Not needed for EO2023" %}
 
<div class="card my-3 {% if check_in.checked_in_bool and check_in.schwag_given %}border-success{% elif check_in.checked_in_bool or check_in.schwag_given %}card-warning{% else %}card-danger{% endif %}">
 
    <div class="card-header {% if check_in.checked_in_bool and check_in.schwag_given %}text-white bg-success{% elif check_in.checked_in_bool or check_in.schwag_given %}bg-warning{% endif %}">Bulk actions</div>
 
    <div class="card-body">
 
        <p>Mark attendee as checked in and schwag given</p>
 
        <dl class="row card-text">
 
            <dt class="col-sm-3">Status</dt>
 
            <dd class="col-sm-9">
 
                {% if check_in.checked_in_bool or check_in.schwag_given %}
 
                One of the items in bulk action is marked as given already
 
                {% else %}
 
                Both items are marked as unreceived
 
                {% endif %}
vendor/registrasion/registrasion/views.py
Show inline comments
...
 
@@ -339,25 +339,25 @@ def _guided_registration_profile_and_voucher(request):
 
    voucher_form, voucher_handled = _handle_voucher(request, "voucher")
 
    profile_form, profile_handled = _handle_profile(request, "profile")
 

	
 
    voucher_section = GuidedRegistrationSection(
 
        title="Voucher Code",
 
        form=voucher_form,
 
    )
 

	
 
    profile_section = GuidedRegistrationSection(
 
        title="Profile and Personal Information",
 
        form=profile_form,
 
        description=("<div class=\"text-info\"><em>You can come back and edit these details any time before "
 
                     "January 1 2022.</em></div>"),
 
                     "March 10 2023.</em></div>"),
 
    )
 

	
 
    return [voucher_section, profile_section]
 

	
 

	
 
@login_required
 
def review(request):
 
    ''' View for the review page. '''
 

	
 
    return render(
 
        request,
 
        "registrasion/review.html",
vendor/symposion/schedule/views.py
Show inline comments
...
 
@@ -212,24 +212,25 @@ def schedule_presentation_detail(request, pk):
 
    }
 
    return render(request, "symposion/schedule/presentation_detail.html", ctx)
 

	
 

	
 
def has_contact_perm(user):
 
    return user.has_perm('symposion_speakers.can_view_contact_details') or user.is_staff
 

	
 

	
 
def make_speaker_dict(speaker, can_view_contact_details):
 
    return {
 
        'name': speaker.name,
 
        'twitter': speaker.twitter_username,
 
        'mastodon': speaker.mastodon_username,
 
        'contact': speaker.email if can_view_contact_details else 'redacted',
 
        'picture_url': speaker_photo(None, speaker, 120),
 
        'code': speaker.code,
 
        'biography': speaker.biography,
 
        'username': speaker.user.username if can_view_contact_details else '',
 
    }
 

	
 

	
 
def schedule_json(request):
 
    slots = Slot.objects.filter(
 
        day__schedule__published=True,
 
        day__schedule__hidden=False
...
 
@@ -277,39 +278,41 @@ def schedule_json(request):
 
                "abstract": slot.content.abstract,
 
                "conf_url": "%s://%s%s" % (
 
                    protocol,
 
                    Site.objects.get_current().domain,
 
                    reverse("schedule_presentation_detail", args=[slot.content.pk])
 
                ),
 
                "cancelled": slot.content.cancelled,
 
                "released": slot.content.proposal.recording_release,
 
                "track": track_name,
 
            })
 
            if not slot.content.speaker.twitter_username == '':
 
                slot_data["twitter_id"] = slot.content.speaker.twitter_username
 
            if not slot.content.speaker.mastodon_username == '':
 
                slot_data["mastodon_id"] = slot.content.speaker.mastodon_username
 
        else:
 
            slot_data.update({
 
                "name": slot.content_override if slot.content_override else "Slot",
 
            })
 
        data.append(slot_data)
 

	
 
    return HttpResponse(
 
        json.dumps({"schedule": data}, indent=2),
 
        content_type="application/json"
 
    )
 

	
 

	
 
class EventFeed(ICalFeed):
 

	
 
    product_id = '-//linux.conf.au/schedule//EN'
 
    product_id = '-//2023.everythingopen.au/schedule//EN'
 
    timezone = settings.TIME_ZONE
 
    filename = 'conference.ics'
 

	
 
    def description(self):
 
        return Conference.objects.all().first().title
 

	
 
    def items(self):
 
        return Slot.objects.filter(
 
            day__schedule__published=True,
 
            day__schedule__hidden=False
 
        ).exclude(
 
            kind__label='shortbreak'
vendor/symposion/speakers/forms.py
Show inline comments
...
 
@@ -2,35 +2,37 @@ from django import forms
 

	
 
from symposion.speakers.models import Speaker
 

	
 

	
 
class SpeakerForm(forms.ModelForm):
 

	
 
    required_css_class = 'label-required'
 

	
 
    class Meta:
 
        model = Speaker
 
        fields = [
 
            "name",
 
            "pronouns",
 
            "biography",
 
            "experience",
 
            "photo",
 
            #"telephone",
 
            "telephone",
 
            "local_timezone",
 
            "homepage",
 
            "twitter_username",
 
            "mastodon_username",
 
            "accessibility",
 
            #"travel_assistance",
 
            #"accommodation_assistance",
 
            #"assistance",
 
            "travel_assistance",
 
            "accommodation_assistance",
 
            "assistance",
 
            "agreement",
 
        ]
 

	
 
    def __init__(self, *a, **k):
 
        super(SpeakerForm, self).__init__(*a, **k)
 
        self.fields['agreement'].required = True
 
        self.fields['biography'].required = True
 
        self.fields['local_timezone'].required = True
 

	
 
    def clean_twitter_username(self):
 
        value = self.cleaned_data["twitter_username"]
 
        if value.startswith("@"):
vendor/symposion/speakers/migrations/0011_auto_20221208_0102.py
Show inline comments
 
new file 100644
 
# Generated by Django 2.2.28 on 2022-12-07 14:02
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('symposion_speakers', '0010_speaker_local_timezone'),
 
    ]
 

	
 
    operations = [
 
        migrations.AddField(
 
            model_name='speaker',
 
            name='mastodon_username',
 
            field=models.CharField(blank=True, help_text='Your Mastodon account', max_length=100),
 
        ),
 
        migrations.AddField(
 
            model_name='speaker',
 
            name='pronouns',
 
            field=models.CharField(blank=True, max_length=20, verbose_name='Pronouns'),
 
        ),
 
        migrations.AlterField(
 
            model_name='speaker',
 
            name='assistance',
 
            field=models.TextField(blank=True, help_text='We have budget set aside to provide financial assistance to speakers and attendees who might otherwise find it difficult to attend. Please provide details on why you require travel and/or accommodation assistance in order to present your proposed sessions. For travel assistance, please also tell us where you will be coming from (country, state, etc) to assist with planning.', verbose_name='Travel/Accommodation assistance details'),
 
        ),
 
        migrations.AlterField(
 
            model_name='speaker',
 
            name='travel_assistance',
 
            field=models.BooleanField(blank=True, default=False, help_text='Check this box if you require assistance to travel to the conference in order to present your proposed sessions.', verbose_name='Travel assistance required'),
 
        ),
 
    ]
vendor/symposion/speakers/models.py
Show inline comments
...
 
@@ -17,24 +17,28 @@ User = get_user_model()
 
class Speaker(models.Model):
 

	
 
    user = models.OneToOneField(
 
        User,
 
        null=True,
 
        related_name="speaker_profile",
 
        verbose_name=_("User"),
 
        on_delete=models.CASCADE,
 
    )
 
    name = models.CharField(verbose_name=_("Name"), max_length=100,
 
                            help_text=_("As you would like it to appear in the"
 
                                        " conference programme."))
 
    pronouns = models.CharField(verbose_name=_("Pronouns"),
 
        max_length=20,
 
        blank=True,
 
    )
 
    biography = models.TextField(
 
        blank=True,
 
        help_text=_("This will appear on the conference website and in the "
 
                    "programme.  Please write in the third person, eg 'Alice "
 
                    "is a Moblin hacker...', 150-200 words. " +
 
                    constants.TEXT_FIELD_MONOSPACE_NOTE),
 
        verbose_name=_("Biography"),
 
    )
 
    biography_html = models.TextField(blank=True)
 
    experience = models.TextField(
 
        blank=True,
 
        help_text=_("Have you had any experience presenting elsewhere? If so, "
...
 
@@ -59,49 +63,54 @@ class Speaker(models.Model):
 
                    "present from. The conference organisers will "
 
                    "use this to assist with scheduling talks.")
 
    )
 
    homepage = models.URLField(
 
        blank=True,
 
        help_text=_(u"Your home page, if you have one")
 
    )
 
    twitter_username = models.CharField(
 
        max_length=15,
 
        blank=True,
 
        help_text=_(u"Your Twitter account")
 
    )
 
    mastodon_username = models.CharField(
 
        max_length=100,
 
        blank=True,
 
        help_text=_(u"Your Mastodon account")
 
    )
 
    accessibility = models.TextField(
 
        blank=True,
 
        help_text=_("Let us know how we can help you during the conference, for example "
 
                    "your accessibility requirements, whether you require access to child "
 
                    "minding facilities, or anything else you think we should know about."),
 
        verbose_name=_("Other requirements"))
 
    accessibility_html = models.TextField(blank=True)
 
    travel_assistance = models.BooleanField(
 
        blank=True,
 
        default=False,
 
        help_text=_("Check this box if you require assistance to travel to linux.conf.au "
 
        help_text=_("Check this box if you require assistance to travel to the conference "
 
                    "in order to present your proposed sessions."),
 
        verbose_name=_("Travel assistance required"),
 
    )
 
    accommodation_assistance = models.BooleanField(
 
        blank=True,
 
        default=False,
 
        help_text=_("Check this box if you require us to provide you with accommodation "
 
                    "in order to present your proposed sessions."),
 
        verbose_name=_("Accommodation assistance required"),
 
    )
 
    assistance = models.TextField(
 
        blank=True,
 
        help_text=_("We have budget set aside to provide financial assistance to "
 
                    "linux.conf.au speakers and attendees who might otherwise find it difficult to attend. "
 
                    "speakers and attendees who might otherwise find it difficult to attend. "
 
                    "Please provide details on why you require travel and/or accommodation assistance "
 
                    "in order to present your proposed sessions. "
 
                    "For travel assistance, please also tell us where you will be coming from "
 
                    "(country, state, etc) to assist with planning."),
 
        verbose_name=_("Travel/Accommodation assistance details"))
 
    assistance_html = models.TextField(blank=True)
 
    agreement = models.BooleanField(
 
        default=False,
 
        help_text=_("I agree to the "
 
                    "<a href=\"/attend/terms-and-conditions\"> "
 
                    "terms and conditions of attendance</a>, and I have read, "
 
                    "understood, and agree to act according to the standards set "
0 comments (0 inline, 0 general)