Skip to content

Commit

Permalink
Implement common component - create/update event (#323)
Browse files Browse the repository at this point in the history
* implement sso login feature

* format code

* implement eventyay-common
implement page organizer/team to create/update/delete organizer/team

* implement organizer/team create/update/delete

* implement common event create/update

* implement common event create/update

* fix isort
  • Loading branch information
odkhang authored Sep 17, 2024
1 parent c73f57c commit 19853cc
Show file tree
Hide file tree
Showing 22 changed files with 447 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,5 @@
{% include "django/forms/widgets/input.html" %}
{% if widget.wrap_label %}
{{ widget.label }}
{% if widget.incubating %}
<span class="label label-danger" data-toggle="tooltip" title="{% trans "The translation for this language is still in progress. This language can currently only be selected on development installations of pretix, not in production." %}">
{% trans "Translation in development" %}
</span>
{% elif not widget.official %}
<span class="label label-warning" data-toggle="tooltip" title="{% trans "This translation is community-maintained and requires further verification by additional translators. New or recently updated features may not be translated yet and will appear in English." %}">
{% trans "Unofficial translation" %}
</span>
{% endif %}
</label>
{% endif %}
5 changes: 2 additions & 3 deletions src/pretix/eventyay_common/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def _default_context(request):
'DEBUG': settings.DEBUG,
}
if getattr(request, 'event', None) and hasattr(request, 'organizer') and request.user.is_authenticated:
ctx['nav_items'] = get_event_navigation(request)
ctx['nav_items'] = get_global_navigation(request)

elif request.user.is_authenticated:
ctx['nav_items'] = get_global_navigation(request)
Expand Down Expand Up @@ -74,8 +74,7 @@ def get_global_navigation(request):
},
{
'label': _('Events'),
# 'url': reverse('eventyay_common:events'),
'url': '#',
'url': reverse('eventyay_common:events'),
'active': 'events' in url.url_name,
'icon': 'calendar',
},
Expand Down
Empty file.
43 changes: 43 additions & 0 deletions src/pretix/eventyay_common/forms/event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from django import forms
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from pytz import common_timezones

from pretix.base.forms import SettingsForm
from pretix.base.settings import (
PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS, validate_event_settings,
)
from pretix.control.forms import MultipleLanguagesWidget
from pretix.control.forms.event import EventWizardFoundationForm


class EventCommonSettingsForm(SettingsForm):
timezone = forms.ChoiceField(
choices=((a, a) for a in common_timezones),
label=_("Event timezone"),
)

auto_fields = [
'locales',
'locale',
]

def clean(self):
data = super().clean()
settings_dict = self.event.settings.freeze()
settings_dict.update(data)
validate_event_settings(self.event, data)
return data

def __init__(self, *args, **kwargs):
self.event = kwargs['obj']
super().__init__(*args, **kwargs)


class EventWizardCommonFoundationForm(EventWizardFoundationForm):
create_for = forms.MultipleChoiceField(
choices=settings.LANGUAGES,
label=_("Use languages"),
widget=MultipleLanguagesWidget,
help_text=_('Choose all languages that your event should be available in.')
)
45 changes: 40 additions & 5 deletions src/pretix/eventyay_common/tasks.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import requests

import requests
from celery import shared_task
from django.conf import settings
from django.contrib.auth import get_user_model
Expand All @@ -11,7 +11,7 @@


@shared_task(bind=True, max_retries=5, default_retry_delay=60) # Retries up to 5 times with a 60-second delay
def send_create_organizer_webhook(self, user_id, organizer):
def send_organizer_webhook(self, user_id, organizer):
# Define the payload to send to the webhook
payload = {
'name': organizer.get('name'),
Expand All @@ -23,7 +23,7 @@ def send_create_organizer_webhook(self, user_id, organizer):

try:
# Send the POST request with the payload and the headers
response = requests.post(settings.TALK_HOSTNAME + '/webhook/create_organiser/',
response = requests.post(settings.TALK_HOSTNAME + '/webhook/organiser/',
json=payload,
headers=headers)
response.raise_for_status() # Raise exception for bad status codes
Expand All @@ -38,7 +38,7 @@ def send_create_organizer_webhook(self, user_id, organizer):


@shared_task(bind=True, max_retries=5, default_retry_delay=60) # Retries up to 5 times with a 60-second delay
def send_create_team_webhook(self, user_id, team):
def send_team_webhook(self, user_id, team):
# Define the payload to send to the webhook
payload = {
'organiser_slug': team.get('organiser_slug'),
Expand All @@ -55,7 +55,42 @@ def send_create_team_webhook(self, user_id, team):

try:
# Send the POST request with the payload and the headers
response = requests.post(settings.TALK_HOSTNAME + '/webhook/create_team/',
response = requests.post(settings.TALK_HOSTNAME + '/webhook/team/',
json=payload,
headers=headers)
response.raise_for_status() # Raise exception for bad status codes
except requests.RequestException as e:
# Log any errors that occur
logger.error('Error sending webhook to talk component: %s', e)
# Retry the task if an exception occurs (with exponential backoff by default)
try:
self.retry(exc=e)
except self.MaxRetriesExceededError:
logger.error("Max retries exceeded for sending organizer webhook.")


@shared_task(bind=True, max_retries=5, default_retry_delay=60) # Retries up to 5 times with a 60-second delay
def send_event_webhook(self, user_id, event, action):
# Define the payload to send to the webhook
user_model = get_user_model()
user = user_model.objects.get(id=user_id)
payload = {
'organiser_slug': event.get('organiser_slug'),
'name': event.get('name'),
'slug': event.get('slug'),
'date_from': event.get('date_from'),
'date_to': event.get('date_to'),
'timezone': event.get('timezone'),
'locale': event.get('locale'),
'locales': event.get('locales'),
'user_email': user.email,
'action': action
}
headers = get_header_token(user_id)

try:
# Send the POST request with the payload and the headers
response = requests.post(settings.TALK_HOSTNAME + '/webhook/event/',
json=payload,
headers=headers)
response.raise_for_status() # Raise exception for bad status codes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{% extends "eventyay_common/base.html" %}
{% load i18n %}
{% load static %}
{% block title %}{{ request.event.name }}{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{% extends "eventyay_common/event/settings_base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% load static %}
{% load hierarkey_form %}
{% load formset_tags %}
{% block title %}{% trans "General settings" %}{% endblock %}
{% block custom_header %}
{{ block.super }}
<link type="text/css" rel="stylesheet" href="{% url "control:pdf.css" %}">
{% endblock %}
{% block inside %}
<h1>{{ request.event.name }} {% trans "- Settings" %}</h1>
<form action="" method="post" class="form-horizontal" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form_errors form %}
<div class="tabbed-form">
<fieldset>
<legend>{% trans "Basics" %}</legend>
{% bootstrap_field form.name layout="control" %}
{% bootstrap_field form.slug layout="control" %}
{% bootstrap_field form.date_from layout="control" %}
{% bootstrap_field form.date_to layout="control" %}
{% bootstrap_field form.currency layout="control" %}
{% bootstrap_field form.sales_channels layout="control" %}
</fieldset>
<fieldset>
<legend>{% trans "Localization" %}</legend>
{% bootstrap_field sform.locales layout="control" %}
{% bootstrap_field sform.locale layout="control" %}
{% bootstrap_field sform.timezone layout="control" %}
</fieldset>
</div>
<fieldset>
<h4>{% trans "Setting for Tickets system" %}
<a href='{% url "control:event.settings" organizer=request.organizer.slug event=request.event.slug %}'
class="btn btn-sm btn-default" title='{% trans "Edit" %}'
data-toggle="tooltip">
<span class="fa fa-edit"></span>
</a>
</h4>
</fieldset>
<fieldset>
<h4>{% trans "Setting for Talk system" %}
<a href='{{ talk_edit_url }}'
class="btn btn-sm btn-default" title='{% trans "Edit" %}'
data-toggle="tooltip">
<span class="fa fa-edit"></span>
</a>
</h4>
</fieldset>
<div class="form-group submit-group">
<button type="submit" class="btn btn-primary btn-save">
{% trans "Save" %}
</button>
</div>
</form>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{% extends "eventyay_common/event/base.html" %}
{% load i18n %}
{% load bootstrap3 %}
{% block title %}{{ request.event.name }}{% endblock %}
{% block content %}
{% if "congratulations" in request.GET %}
<div class="thank-you">
<span class="fa fa-check-circle"></span>

<h2>{% trans "Congratulations!" %}</h2>
<p>
<strong>{% trans "You just created an event!" %}</strong>
</p>
<p>
{% blocktrans trimmed %}
You can now scroll down and modify the settings in more detail, if you want, or you can create your
first product to start selling tickets right away!
{% endblocktrans %}
</p>
<p>
<a href="{% url "control:event.items.add" organizer=request.organizer.slug event=request.event.slug %}"
class="btn btn-default">
{% trans "Create a first product" %}
</a>
</p>
<div class="clearfix"></div>
</div>
{% endif %}

{% block inside %}
{% endblock %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,78 @@
{% load i18n %}
{% load bootstrap3 %}
{% block form %}
{% bootstrap_field form.organizer layout="horizontal" %}
<div class="form-group">
<label class="col-md-3 control-label">{% trans "Event type" %}</label>
<label class="col-md-3 control-label">{% trans "Create this event for" %}</label>
<div class="col-md-9">
<div class="big-radio radio">
<div class="radio">
<label>
<input type="radio" value="" name="{{ form.has_subevents.html_name }}" {% if not form.has_subevents.value %}checked{% endif %}>
<span class="fa fa-calendar-o"></span>
<strong>{% trans "Singular event or non-event shop" %}</strong><br>
<div class="help-block">
{% blocktrans trimmed %}
An event with individual configuration. If you create more events later, you can copy
the event to save yourself some work.
{% endblocktrans %}
</div>
<div class="help-block">
{% blocktrans trimmed %}
Examples: Conferences, workshops, trade fairs, one-off concerts, sale of digital content,
multi-day events with combination tickets.
{% endblocktrans %}
</div>
<input type="radio" name="create_for" value="tickets" {% if create_for == 'tickets' %}checked{% endif %}>
<strong>{% trans "Tickets system" %}</strong>
</label>
</div>
<div class="big-radio radio">
<div class="radio">
<label>
<input type="radio" value="on" name="{{ form.has_subevents.html_name }}" {% if form.has_subevents.avalue %}checked{% endif %}>
<span class="fa fa-calendar"></span>
<strong>{% trans "Event series or time slot booking" %}</strong>
<div class="help-block">
{% blocktrans trimmed %}
A series of events that share the same configuration. They can still be different in
their dates, locations, prices, and capacities.
{% endblocktrans %}
</div>
<input type="radio" name="create_for" value="talk" {% if create_for == 'talk' %}checked{% endif %} disabled>
<strong>{% trans "Talk system" %}</strong>
<div class="help-block">
{% blocktrans trimmed %}
Examples: Multiple presentations of the same show, same concert in multiple locations,
museums, libraries, or swimming pools,
events that need to be booked together in one cart.
Create event for Talk system only not ready yet.
{% endblocktrans %}
</div>
</label>
</div>
<div class="radio">
<label>
<input type="radio" name="create_for" value="all" {% if create_for == 'all' %}checked{% endif %}>
<strong>{% trans "Both tickets and talk system" %}</strong>
</label>
</div>
</div>
</div>
{% bootstrap_field form.organizer layout="horizontal" %}
<div class="form-group">
<label class="col-md-3 control-label">{% trans "Event type" %}</label>
<div class="col-md-9">
<div class="big-radio radio">
<label>
<input type="radio" value="" name="{{ form.has_subevents.html_name }}" {% if not form.has_subevents.value %}checked{% endif %}>
<span class="fa fa-calendar-o"></span>
<strong>{% trans "Singular event or non-event shop" %}</strong><br>
<div class="help-block">
{% blocktrans trimmed %}
An event with individual configuration. If you create more events later, you can copy
the event to save yourself some work.
{% endblocktrans %}
</div>
<div class="help-block">
{% blocktrans trimmed %}
Examples: Conferences, workshops, trade fairs, one-off concerts, sale of digital content,
multi-day events with combination tickets.
{% endblocktrans %}
</div>
</label>
</div>
<div class="big-radio radio">
<label>
<input type="radio" value="on" name="{{ form.has_subevents.html_name }}" {% if form.has_subevents.avalue %}checked{% endif %}>
<span class="fa fa-calendar"></span>
<strong>{% trans "Event series or time slot booking" %}</strong>
<div class="help-block">
{% blocktrans trimmed %}
A series of events that share the same configuration. They can still be different in
their dates, locations, prices, and capacities.
{% endblocktrans %}
</div>
<div class="help-block">
{% blocktrans trimmed %}
Examples: Multiple presentations of the same show, same concert in multiple locations,
museums, libraries, or swimming pools,
events that need to be booked together in one cart.
{% endblocktrans %}
</div>
</label>
</div>
</div>
</div>
{% bootstrap_field form.locales layout="horizontal" %}
{% endblock %}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ <h3 class="panel-title">{% trans "Filter" %}</h3>
{% for e in events %}
<tr>
<td class="event-name-col">
<strong><a href="{% url "control:event.index" organizer=e.organizer.slug event=e.slug %}">{{ e.name }}</a></strong>
<strong><a href='{% url "eventyay_common:event.update" organizer=e.organizer.slug event=e.slug %}'>{{ e.name }}</a></strong>
</td>
<td>{{ e.slug }}</td>
<td>{{ e.organizer }}</td>
Expand All @@ -106,7 +106,7 @@ <h3 class="panel-title">{% trans "Filter" %}</h3>
{% endif %}
</td>
<td class="text-right flip">
<a href="{% url "control:event.index" organizer=e.organizer.slug event=e.slug %}"
<a href='{% url "eventyay_common:event.update" organizer=e.organizer.slug event=e.slug %}'
class="btn btn-sm btn-default" title="{% trans "Edit" %}"
data-toggle="tooltip">
<span class="fa fa-edit"></span>
Expand Down
5 changes: 4 additions & 1 deletion src/pretix/eventyay_common/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.urls import re_path as url
from django.urls import re_path as url, include

from pretix.eventyay_common.views import dashboards, event, organizer, team

Expand All @@ -17,4 +17,7 @@
name='organizer.team.delete'),
url(r'^events/$', event.EventList.as_view(), name='events'),
url(r'^events/add$', event.EventCreateView.as_view(), name='events.add'),
url(r'^event/(?P<organizer>[^/]+)/(?P<event>[^/]+)/', include([
url(r'^settings/$', event.EventUpdate.as_view(), name='event.update'),
])),
]
Loading

0 comments on commit 19853cc

Please sign in to comment.