Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eventyay-Common: Add option to create video access to the event #385

Merged
merged 13 commits into from
Nov 1, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.16 on 2024-10-25 03:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("pretixbase", "0002_question_description"),
]

operations = [
migrations.AddField(
model_name="event",
name="is_video_creation",
field=models.BooleanField(default=False),
)
]
5 changes: 5 additions & 0 deletions src/pretix/base/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,11 @@ class Event(EventMixin, LoggedModel):
),
default=["web"],
)
is_video_creation = models.BooleanField(
verbose_name=_("Add video call"),
help_text=_("Create Video platform for Event."),
default=False,
)
objects = ScopedManager(organizer="organizer")

class Meta:
Expand Down
15 changes: 15 additions & 0 deletions src/pretix/control/forms/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ class EventWizardFoundationForm(forms.Form):
label=_("This is an event series"),
required=False,
)
is_video_creation = forms.BooleanField(
label=_("Create Video platform for this Event."),
help_text=_("This will create a new Video platform for this event."),
required=False,
widget=forms.CheckboxInput(attrs={"class": "form-check-input"}),
)

def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
Expand Down Expand Up @@ -152,6 +158,7 @@ def __init__(self, *args, **kwargs):
self.organizer = kwargs.pop("organizer")
self.locales = kwargs.get("locales")
self.has_subevents = kwargs.pop("has_subevents")
self.is_video_creation = kwargs.pop("is_video_creation")
self.user = kwargs.pop("user")
kwargs.pop("session")
super().__init__(*args, **kwargs)
Expand Down Expand Up @@ -287,6 +294,7 @@ def __init__(self, *args, **kwargs):
self.session = kwargs.pop("session")
kwargs.pop("has_subevents")
self.user = kwargs.pop("user")
kwargs.pop("is_video_creation")
super().__init__(*args, **kwargs)

self.fields["copy_from_event"] = EventChoiceField(
Expand Down Expand Up @@ -361,6 +369,9 @@ class Meta:


class EventUpdateForm(I18nModelForm):
is_video_creation = forms.BooleanField(
required=False,
)

def __init__(self, *args, **kwargs):
self.change_slug = kwargs.pop("change_slug", False)
Expand Down Expand Up @@ -400,6 +411,9 @@ def __init__(self, *args, **kwargs):
),
widget=forms.CheckboxSelectMultiple,
)
self.is_video_creation = self.initial.get("is_video_creation")
if self.is_video_creation:
self.fields["is_video_creation"].disabled = True

def clean_domain(self):
d = self.cleaned_data["domain"]
Expand Down Expand Up @@ -470,6 +484,7 @@ class Meta:
"geo_lat",
"geo_lon",
"sales_channels",
"is_video_creation",
]
field_classes = {
"date_from": SplitDateTimeField,
Expand Down
18 changes: 3 additions & 15 deletions src/pretix/eventyay_common/forms/event.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
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 validate_event_settings
from pretix.control.forms import MultipleLanguagesWidget
from pretix.control.forms.event import EventWizardFoundationForm


class EventCommonSettingsForm(SettingsForm):
Expand All @@ -16,8 +13,8 @@ class EventCommonSettingsForm(SettingsForm):
)

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

def clean(self):
Expand All @@ -28,14 +25,5 @@ def clean(self):
return data

def __init__(self, *args, **kwargs):
self.event = kwargs['obj']
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.')
)
141 changes: 102 additions & 39 deletions src/pretix/eventyay_common/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,100 +10,163 @@
logger = logging.getLogger(__name__)


@shared_task(bind=True, max_retries=5, default_retry_delay=60) # Retries up to 5 times with a 60-second delay
@shared_task(
bind=True, max_retries=5, default_retry_delay=60
) # Retries up to 5 times with a 60-second delay
def send_organizer_webhook(self, user_id, organizer):
# Define the payload to send to the webhook
payload = {
'name': organizer.get('name'),
'slug': organizer.get('slug'),
'action': organizer.get('action')
"name": organizer.get("name"),
"slug": organizer.get("slug"),
"action": organizer.get("action"),
}
# Define the headers, including the Authorization header with the Bearer token
headers = get_header_token(user_id)

try:
# Send the POST request with the payload and the headers
response = requests.post(settings.TALK_HOSTNAME + '/webhook/organiser/',
json=payload,
headers=headers)
response = requests.post(
settings.TALK_HOSTNAME + "/webhook/organiser/",
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)
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
@shared_task(
bind=True, max_retries=5, default_retry_delay=60
) # Retries up to 5 times with a 60-second delay
def send_team_webhook(self, user_id, team):
# Define the payload to send to the webhook
payload = {
'organiser_slug': team.get('organiser_slug'),
'name': team.get('name'),
'old_name': team.get('old_name'),
'all_events': team.get('all_events'),
'can_create_events': team.get('can_create_events'),
'can_change_teams': team.get('can_change_teams'),
'can_change_organiser_settings': team.get('can_change_organizer_settings'),
'can_change_event_settings': team.get('can_change_event_settings'),
'action': team.get('action')
"organiser_slug": team.get("organiser_slug"),
"name": team.get("name"),
"old_name": team.get("old_name"),
"all_events": team.get("all_events"),
"can_create_events": team.get("can_create_events"),
"can_change_teams": team.get("can_change_teams"),
"can_change_organiser_settings": team.get("can_change_organizer_settings"),
"can_change_event_settings": team.get("can_change_event_settings"),
"action": team.get("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/team/',
json=payload,
headers=headers)
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)
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
@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
"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 = requests.post(
settings.TALK_HOSTNAME + "/webhook/event/", 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)
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 create_world(self, is_video_creation, event_data):
"""
Create a video system for the specified event.

:param self: Task instance
:param is_video_creation: A boolean indicating whether the user has chosen to add a video.
:param event_data: A dictionary containing the following event details:
- id (str): The unique identifier for the event.
- title (str): The title of the event.
- timezone (str): The timezone in which the event takes place.
- locale (str): The locale for the event.
- token (str): Authorization token for making the request.
- has_permission (bool): Indicates if the user has 'can_create_events' permission or is in admin session mode.

To successfully create a world, both conditions must be satisfied:
- The user must have the necessary permission.
- The user must choose to create a video.
"""
event_slug = event_data.get("id")
title = event_data.get("title")
event_timezone = event_data.get("timezone")
locale = event_data.get("locale")
token = event_data.get("token")
has_permission = event_data.get("has_permission")

payload = {
"id": event_slug,
"title": title,
"timezone": event_timezone,
"locale": locale,
}

headers = {"Authorization": "Bearer " + token}

if is_video_creation and has_permission:
odkhang marked this conversation as resolved.
Show resolved Hide resolved
try:
requests.post(
"{}/api/v1/create-world/".format(settings.VIDEO_SERVER_HOSTNAME),
json=payload,
headers=headers,
)
except requests.exceptions.ConnectionError as e:
logger.error("Connection error: %s", str(e))
raise self.retry(exc=e)
except requests.exceptions.Timeout as e:
logger.error("Request timed out: %s", str(e))
raise self.retry(exc=e)
except requests.exceptions.RequestException as e:
logger.error("Request failed: %s", str(e))
raise self.retry(exc=e)


def get_header_token(user_id):
# Fetch the user and organizer instances
user_model = get_user_model()
Expand All @@ -113,7 +176,7 @@ def get_header_token(user_id):

# Define the headers, including the Authorization header with the Bearer token
headers = {
'Authorization': f'Bearer {token}',
'Content-Type': 'application/json',
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
return headers
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ <h1>{{ request.event.name }} {% trans "- Settings" %}</h1>
{% bootstrap_field form.date_to layout="control" %}
{% bootstrap_field form.currency layout="control" %}
{% bootstrap_field form.sales_channels layout="control" %}
<div>
<label class="col-md-3 control-label">{% trans "Create video for this event" %}</label>
{% bootstrap_field form.is_video_creation %}
</div>
</fieldset>
<fieldset>
<legend>{% trans "Localization" %}</legend>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
</div>
</div>
</div>
{% bootstrap_field form.is_video_creation layout="horizontal" %}
{% bootstrap_field form.organizer layout="horizontal" %}
<div class="form-group">
<label class="col-md-3 control-label">{% trans "Event type" %}</label>
Expand Down
Loading
Loading