mirror of
https://github.com/pretix/pretix.git
synced 2026-05-07 15:34:02 +00:00
Use async actions for order export
This commit is contained in:
@@ -21,3 +21,4 @@ def export(event: str, fileid: str, provider: str, form_data: Dict[str, Any]) ->
|
|||||||
file.filename, file.type, data = ex.render(form_data)
|
file.filename, file.type, data = ex.render(form_data)
|
||||||
file.file.save(cachedfile_name(file, file.filename), ContentFile(data))
|
file.file.save(cachedfile_name(file, file.filename), ContentFile(data))
|
||||||
file.save()
|
file.save()
|
||||||
|
return file.pk
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ class AsyncAction:
|
|||||||
# but handle the mssage itself
|
# but handle the mssage itself
|
||||||
data.update({
|
data.update({
|
||||||
'redirect': self.get_success_url(res.info),
|
'redirect': self.get_success_url(res.info),
|
||||||
|
'success': True,
|
||||||
'message': str(self.get_success_message(res.info))
|
'message': str(self.get_success_message(res.info))
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
@@ -80,6 +81,7 @@ class AsyncAction:
|
|||||||
# but handle the mssage itself
|
# but handle the mssage itself
|
||||||
data.update({
|
data.update({
|
||||||
'redirect': self.get_error_url(),
|
'redirect': self.get_error_url(),
|
||||||
|
'success': False,
|
||||||
'message': str(self.get_error_message(res.info))
|
'message': str(self.get_error_message(res.info))
|
||||||
})
|
})
|
||||||
return data
|
return data
|
||||||
@@ -103,6 +105,7 @@ class AsyncAction:
|
|||||||
if "ajax" in self.request.POST or "ajax" in self.request.GET:
|
if "ajax" in self.request.POST or "ajax" in self.request.GET:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'ready': True,
|
'ready': True,
|
||||||
|
'success': True,
|
||||||
'redirect': self.get_success_url(value),
|
'redirect': self.get_success_url(value),
|
||||||
'message': str(self.get_success_message(value))
|
'message': str(self.get_success_message(value))
|
||||||
})
|
})
|
||||||
@@ -113,6 +116,7 @@ class AsyncAction:
|
|||||||
if "ajax" in self.request.POST or "ajax" in self.request.GET:
|
if "ajax" in self.request.POST or "ajax" in self.request.GET:
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'ready': True,
|
'ready': True,
|
||||||
|
'success': False,
|
||||||
'redirect': self.get_error_url(),
|
'redirect': self.get_error_url(),
|
||||||
'message': str(self.get_error_message(exception))
|
'message': str(self.get_error_message(exception))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
<h3 class="panel-title">{{ e.verbose_name }}</h3>
|
<h3 class="panel-title">{{ e.verbose_name }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<form action="" method="post" class="form-horizontal">
|
<form action="{% url "control:event.orders.export.do" event=request.event.slug organizer=request.organizer.slug %}"
|
||||||
|
method="post" class="form-horizontal" data-asynctask data-asynctask-download
|
||||||
|
data-asynctask-long>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<input type="hidden" name="exporter" value="{{ e.identifier }}" />
|
<input type="hidden" name="exporter" value="{{ e.identifier }}" />
|
||||||
{% bootstrap_form e.form layout='horizontal' %}
|
{% bootstrap_form e.form layout='horizontal' %}
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ urlpatterns = [
|
|||||||
name='event.invoice.download'),
|
name='event.invoice.download'),
|
||||||
url(r'^orders/overview/$', orders.OverView.as_view(), name='event.orders.overview'),
|
url(r'^orders/overview/$', orders.OverView.as_view(), name='event.orders.overview'),
|
||||||
url(r'^orders/export/$', orders.ExportView.as_view(), name='event.orders.export'),
|
url(r'^orders/export/$', orders.ExportView.as_view(), name='event.orders.export'),
|
||||||
|
url(r'^orders/export/do$', orders.ExportDoView.as_view(), name='event.orders.export.do'),
|
||||||
url(r'^orders/go$', orders.OrderGo.as_view(), name='event.orders.go'),
|
url(r'^orders/go$', orders.OrderGo.as_view(), name='event.orders.go'),
|
||||||
url(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
url(r'^orders/$', orders.OrderList.as_view(), name='event.orders'),
|
||||||
url(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'),
|
url(r'^waitinglist/$', waitinglist.WaitingListView.as_view(), name='event.orders.waitinglist'),
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from pretix.base.services.stats import order_overview
|
|||||||
from pretix.base.signals import (
|
from pretix.base.signals import (
|
||||||
register_data_exporters, register_payment_providers,
|
register_data_exporters, register_payment_providers,
|
||||||
)
|
)
|
||||||
|
from pretix.base.views.async import AsyncAction
|
||||||
from pretix.control.forms.orders import (
|
from pretix.control.forms.orders import (
|
||||||
CommentForm, ExporterForm, ExtendForm, OrderContactForm, OrderLocaleForm,
|
CommentForm, ExporterForm, ExtendForm, OrderContactForm, OrderLocaleForm,
|
||||||
OrderPositionChangeForm,
|
OrderPositionChangeForm,
|
||||||
@@ -622,9 +623,7 @@ class OrderGo(EventPermissionRequiredMixin, View):
|
|||||||
return redirect('control:event.orders', event=request.event.slug, organizer=request.event.organizer.slug)
|
return redirect('control:event.orders', event=request.event.slug, organizer=request.event.organizer.slug)
|
||||||
|
|
||||||
|
|
||||||
class ExportView(EventPermissionRequiredMixin, TemplateView):
|
class ExportMixin:
|
||||||
permission = 'can_view_orders'
|
|
||||||
template_name = 'pretixcontrol/orders/export.html'
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def exporters(self):
|
def exporters(self):
|
||||||
@@ -640,10 +639,22 @@ class ExportView(EventPermissionRequiredMixin, TemplateView):
|
|||||||
exporters.append(ex)
|
exporters.append(ex)
|
||||||
return exporters
|
return exporters
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
ctx = super().get_context_data(**kwargs)
|
class ExportDoView(EventPermissionRequiredMixin, ExportMixin, AsyncAction, View):
|
||||||
ctx['exporters'] = self.exporters
|
permission = 'can_view_orders'
|
||||||
return ctx
|
task = export
|
||||||
|
|
||||||
|
def get_success_message(self, value):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_success_url(self, value):
|
||||||
|
return reverse('cachedfile.download', kwargs={'id': str(value)})
|
||||||
|
|
||||||
|
def get_error_url(self):
|
||||||
|
return reverse('control:event.orders.export', kwargs={
|
||||||
|
'event': self.request.event.slug,
|
||||||
|
'organizer': self.request.event.organizer.slug
|
||||||
|
})
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def exporter(self):
|
def exporter(self):
|
||||||
@@ -651,13 +662,14 @@ class ExportView(EventPermissionRequiredMixin, TemplateView):
|
|||||||
if ex.identifier == self.request.POST.get("exporter"):
|
if ex.identifier == self.request.POST.get("exporter"):
|
||||||
return ex
|
return ex
|
||||||
|
|
||||||
def post(self, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
if not self.exporter:
|
if not self.exporter:
|
||||||
messages.error(self.request, _('The selected exporter was not found.'))
|
messages.error(self.request, _('The selected exporter was not found.'))
|
||||||
return redirect('control:event.orders.export', kwargs={
|
return redirect('control:event.orders.export', kwargs={
|
||||||
'event': self.request.event.slug,
|
'event': self.request.event.slug,
|
||||||
'organizer': self.request.event.organizer.slug
|
'organizer': self.request.event.organizer.slug
|
||||||
})
|
})
|
||||||
|
|
||||||
if not self.exporter.form.is_valid():
|
if not self.exporter.form.is_valid():
|
||||||
messages.error(self.request, _('There was a problem processing your input. See below for error details.'))
|
messages.error(self.request, _('There was a problem processing your input. See below for error details.'))
|
||||||
return self.get(*args, **kwargs)
|
return self.get(*args, **kwargs)
|
||||||
@@ -666,6 +678,14 @@ class ExportView(EventPermissionRequiredMixin, TemplateView):
|
|||||||
cf.date = now()
|
cf.date = now()
|
||||||
cf.expires = now() + timedelta(days=3)
|
cf.expires = now() + timedelta(days=3)
|
||||||
cf.save()
|
cf.save()
|
||||||
export.apply_async(args=(self.request.event.id, str(cf.id), self.exporter.identifier,
|
return self.do(self.request.event.id, str(cf.id), self.exporter.identifier, self.exporter.form.cleaned_data)
|
||||||
self.exporter.form.cleaned_data))
|
|
||||||
return redirect(reverse('cachedfile.download', kwargs={'id': str(cf.id)}))
|
|
||||||
|
class ExportView(EventPermissionRequiredMixin, ExportMixin, TemplateView):
|
||||||
|
permission = 'can_view_orders'
|
||||||
|
template_name = 'pretixcontrol/orders/export.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
ctx = super().get_context_data(**kwargs)
|
||||||
|
ctx['exporters'] = self.exporters
|
||||||
|
return ctx
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
var async_task_id = null;
|
var async_task_id = null;
|
||||||
var async_task_timeout = null;
|
var async_task_timeout = null;
|
||||||
var async_task_check_url = null;
|
var async_task_check_url = null;
|
||||||
|
var async_task_old_url = null;
|
||||||
|
var async_task_is_download = false;
|
||||||
|
var async_task_is_long = false;
|
||||||
|
|
||||||
function async_task_check() {
|
function async_task_check() {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -20,13 +23,26 @@ function async_task_check() {
|
|||||||
function async_task_check_callback(data, jqXHR, status) {
|
function async_task_check_callback(data, jqXHR, status) {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (data.ready && data.redirect) {
|
if (data.ready && data.redirect) {
|
||||||
|
if (async_task_is_download && data.success) {
|
||||||
|
waitingDialog.hide();
|
||||||
|
if (location.href.indexOf("async_id") !== -1) {
|
||||||
|
history.replaceState({}, "pretix", async_task_old_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
location.href = data.redirect;
|
location.href = data.redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
async_task_timeout = window.setTimeout(async_task_check, 250);
|
async_task_timeout = window.setTimeout(async_task_check, 250);
|
||||||
$("#loadingmodal p").text(gettext('Your request has been queued on the server and will now be ' +
|
|
||||||
'processed. If this takes longer than two minutes, please contact us or go ' +
|
if (async_task_is_long) {
|
||||||
'back in your browser and try again.'));
|
$("#loadingmodal p").text(gettext('Your request has been queued on the server and will now be ' +
|
||||||
|
'processed. Depending on the size of your event, this might take up to a ' +
|
||||||
|
'few minutes.'));
|
||||||
|
} else {
|
||||||
|
$("#loadingmodal p").text(gettext('Your request has been queued on the server and will now be ' +
|
||||||
|
'processed. If this takes longer than two minutes, please contact us or go ' +
|
||||||
|
'back in your browser and try again.'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function async_task_check_error(jqXHR, textStatus, errorThrown) {
|
function async_task_check_error(jqXHR, textStatus, errorThrown) {
|
||||||
@@ -35,6 +51,9 @@ function async_task_check_error(jqXHR, textStatus, errorThrown) {
|
|||||||
if (c.length > 0) {
|
if (c.length > 0) {
|
||||||
$("body").data('ajaxing', false);
|
$("body").data('ajaxing', false);
|
||||||
waitingDialog.hide();
|
waitingDialog.hide();
|
||||||
|
if (location.href.indexOf("async_id") !== -1) {
|
||||||
|
history.replaceState({}, "pretix", async_task_old_url);
|
||||||
|
}
|
||||||
ajaxErrDialog.show(c.first().html());
|
ajaxErrDialog.show(c.first().html());
|
||||||
} else {
|
} else {
|
||||||
if (jqXHR.status >= 400 && jqXHR.status < 500) {
|
if (jqXHR.status >= 400 && jqXHR.status < 500) {
|
||||||
@@ -54,6 +73,12 @@ function async_task_callback(data, jqXHR, status) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
$("body").data('ajaxing', false);
|
$("body").data('ajaxing', false);
|
||||||
if (data.redirect) {
|
if (data.redirect) {
|
||||||
|
if (async_task_is_download && data.success) {
|
||||||
|
waitingDialog.hide();
|
||||||
|
if (location.href.indexOf("async_id") !== -1) {
|
||||||
|
history.replaceState({}, "pretix", async_task_old_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
location.href = data.redirect;
|
location.href = data.redirect;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -61,9 +86,15 @@ function async_task_callback(data, jqXHR, status) {
|
|||||||
async_task_check_url = data.check_url;
|
async_task_check_url = data.check_url;
|
||||||
async_task_timeout = window.setTimeout(async_task_check, 100);
|
async_task_timeout = window.setTimeout(async_task_check, 100);
|
||||||
|
|
||||||
$("#loadingmodal p").text(gettext('Your request has been queued on the server and will now be ' +
|
if (async_task_is_long) {
|
||||||
'processed. If this takes longer than two minutes, please contact us or go ' +
|
$("#loadingmodal p").text(gettext('Your request has been queued on the server and will now be ' +
|
||||||
'back in your browser and try again.'));
|
'processed. Depending on the size of your event, this might take up to a ' +
|
||||||
|
'few minutes.'));
|
||||||
|
} else {
|
||||||
|
$("#loadingmodal p").text(gettext('Your request has been queued on the server and will now be ' +
|
||||||
|
'processed. If this takes longer than two minutes, please contact us or go ' +
|
||||||
|
'back in your browser and try again.'));
|
||||||
|
}
|
||||||
if (location.href.indexOf("async_id") === -1) {
|
if (location.href.indexOf("async_id") === -1) {
|
||||||
history.pushState({}, "Waiting", async_task_check_url.replace(/ajax=1/, ''));
|
history.pushState({}, "Waiting", async_task_check_url.replace(/ajax=1/, ''));
|
||||||
}
|
}
|
||||||
@@ -99,6 +130,9 @@ $(function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
async_task_id = null;
|
async_task_id = null;
|
||||||
|
async_task_is_download = $(this).is("[data-asynctask-download]");
|
||||||
|
async_task_is_long = $(this).is("[data-asynctask-long]");
|
||||||
|
async_task_old_url = location.href;
|
||||||
$("body").data('ajaxing', true);
|
$("body").data('ajaxing', true);
|
||||||
waitingDialog.show(gettext('We are processing your request …'));
|
waitingDialog.show(gettext('We are processing your request …'));
|
||||||
$("#loadingmodal p").text(gettext('We are currently sending your request to the server. If this takes longer ' +
|
$("#loadingmodal p").text(gettext('We are currently sending your request to the server. If this takes longer ' +
|
||||||
|
|||||||
Reference in New Issue
Block a user