diff --git a/pretix_matrix_inviter/signals.py b/pretix_matrix_inviter/signals.py index 8ad373f74a9a4c4548f99105d155b4fa79d47574..a95afd93e8525ed052c6ef71d20738c12b00181b 100644 --- a/pretix_matrix_inviter/signals.py +++ b/pretix_matrix_inviter/signals.py @@ -1,11 +1,15 @@ +import json from django import forms from django.dispatch import receiver from django.urls import resolve, reverse from django.utils.translation import ugettext_lazy as _ from pretix.base.settings import settings_hierarkey +from pretix.base.signals import logentry_display, order_placed from pretix.control.signals import nav_event_settings from pretix.presale.signals import question_form_fields +from .tasks import matrix_inviter_invite + settings_hierarkey.add_default("matrix_inviter_items", [], list) settings_hierarkey.add_default("matrix_inviter_authorization_token", "", str) settings_hierarkey.add_default("matrix_inviter_matrix_server", "", str) @@ -38,6 +42,29 @@ def add_matrix_id_question(sender, position, **kwargs): } +@receiver(order_placed, dispatch_uid="matrix_inviter_order_placed") +def order_placed(sender, order, **kwargs): + if ( + not sender.settings.matrix_inviter_authorization_token + and not sender.settings.matrix_inviter_matrix_server + and not sender.settings.matrix_inviter_matrix_room + ): + return + + for order_position in order.positions.all(): + if str(order_position.item.pk) not in sender.settings.get( + "matrix_inviter_items" + ): + continue + + if not order_position.meta_info_data.get("question_form_data", {}).get( + "matrix_inviter_matrix_id" + ): + continue + + matrix_inviter_invite.apply_async(args=(sender.pk, order.pk, order_position.pk)) + + @receiver(nav_event_settings, dispatch_uid="matrix_inviter_nav_settings") def navbar_settings(sender, request=None, **kwargs): url = resolve(request.path_info) @@ -55,3 +82,21 @@ def navbar_settings(sender, request=None, **kwargs): and url.url_name == "settings", } ] + + +@receiver(logentry_display, dispatch_uid="matrix_inviter_logentry_display") +def logentry_display(sender, logentry, **kwargs): + if not logentry.action_type.startswith("pretix_matrix_inviter"): + return + + locales = { + "pretix_matrix_inviter.invite_sent": _( + "{matrix_id} has been invited to {matrix_room}." + ), + "pretix_matrix_inviter.error": _( + "There was an error inviting {matrix_id} to {matrix_room}: {error}" + ), + } + data = json.loads(logentry.data) + + return locales[logentry.action_type].format_map(data) diff --git a/pretix_matrix_inviter/tasks.py b/pretix_matrix_inviter/tasks.py new file mode 100644 index 0000000000000000000000000000000000000000..44050b1e67a10ac5bfc36d9aac30f5afb466b782 --- /dev/null +++ b/pretix_matrix_inviter/tasks.py @@ -0,0 +1,68 @@ +import logging +import requests +from celery.exceptions import MaxRetriesExceededError +from pretix.base.models import Event, Order, OrderPosition +from pretix.base.services.tasks import TransactionAwareTask +from pretix.celery_app import app + +logger = logging.getLogger(__name__) + + +@app.task( + base=TransactionAwareTask, + bind=True, + max_retries=10, + retry_backoff=True, + retry_backoff_max=3600, +) +def matrix_inviter_invite(self, event: int, order: int, order_position: int): + order_position = OrderPosition.objects.get(pk=order_position) + + user_matrix_id = order_position.meta_info_data.get("question_form_data", {}).get( + "matrix_inviter_matrix_id" + ) + + if not user_matrix_id: + return + + event = Event.objects.get(pk=event) + order = Order.objects.get(pk=order) + room_matrix_id = event.settings.matrix_inviter_matrix_room + + try: + r = requests.post( + "https://{}/_matrix/client/v3/rooms/{}/invite".format( + event.settings.matrix_inviter_matrix_server, + room_matrix_id, + ), + headers={ + "Authorization": "Bearer {}".format( + event.settings.matrix_inviter_authorization_token + ), + }, + json={ + "user_id": user_matrix_id, + }, + ) + r.raise_for_status() + except (requests.ConnectionError, requests.HTTPError) as e: + try: + self.retry() + except MaxRetriesExceededError: + order.log_action( + "pretix_matrix_inviter.error", + data={ + "matrix_id": user_matrix_id, + "matrix_room": room_matrix_id, + "error": "HTTP Code {}".format(r.status_code), + }, + ) + raise e + + order.log_action( + "pretix_matrix_inviter.invite_sent", + data={ + "matrix_id": user_matrix_id, + "matrix_room": room_matrix_id, + }, + )