Compare commits

..

1 Commits

Author SHA1 Message Date
Mira Weller
6d49b350f0 Handle duplicate column names in CSV import
- display a warning message to the user
- automatically rename columns by adding "__1", "__2", ... suffixes
2025-12-02 14:37:43 +01:00
5 changed files with 29 additions and 18 deletions

View File

@@ -47,6 +47,19 @@ class DataImportError(LazyLocaleException):
super().__init__(msg)
def rename_duplicates(values):
used = set()
had_duplicates = False
for i, value in enumerate(values):
c = 0
while values[i] in used:
c += 1
values[i] = f'{value}__{c}'
had_duplicates = True
used.add(values[i])
return had_duplicates
def parse_csv(file, length=None, mode="strict", charset=None):
file.seek(0)
data = file.read(length)
@@ -70,6 +83,7 @@ def parse_csv(file, length=None, mode="strict", charset=None):
return None
reader = csv.DictReader(io.StringIO(data), dialect=dialect)
reader._had_duplicates = rename_duplicates(reader.fieldnames)
return reader

View File

@@ -146,7 +146,7 @@ class BaseProcessView(AsyncAction, FormView):
else:
charset = None
try:
return parse_csv(self.file.file, 1024 * 1024, charset=charset)
reader = parse_csv(self.file.file, 1024 * 1024, charset=charset)
except UnicodeDecodeError:
messages.warning(
self.request,
@@ -155,7 +155,16 @@ class BaseProcessView(AsyncAction, FormView):
"Some characters were replaced with a placeholder."
)
)
return parse_csv(self.file.file, 1024 * 1024, "replace", charset=charset)
reader = parse_csv(self.file.file, 1024 * 1024, "replace", charset=charset)
if reader._had_duplicates:
messages.warning(
self.request,
_(
"Multiple columns of the CSV file have the same name and were renamed automatically. We "
"recommend that you rename these in your source file to avoid problems during import."
)
)
return reader
@cached_property
def parsed_list(self):

View File

@@ -711,7 +711,7 @@ class PaypalMethod(BasePaymentProvider):
description = '{prefix}{orderstring}{postfix}'.format(
prefix='{} '.format(self.settings.prefix) if self.settings.prefix else '',
orderstring=__('Order {order} for {event}').format(
event=self.event.name,
event=request.event.name,
order=payment.order.code
),
postfix=' {}'.format(self.settings.postfix) if self.settings.postfix else ''

View File

@@ -47,14 +47,6 @@ from pretix.celery_app import app
from pretix.helpers.format import format_map
def _chunks(lst, n):
"""
Yield successive n-sized chunks from lst.
"""
for i in range(0, len(lst), n):
yield lst[i:i + n]
@app.task(base=ProfiledEventTask, acks_late=True)
def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict, objects: list, items: list,
subevent: int, subevents_from: datetime, subevents_to: datetime,
@@ -63,11 +55,12 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
attach_ical: bool = False) -> None:
failures = []
user = User.objects.get(pk=user) if user else None
orders = Order.objects.filter(pk__in=objects, event=event)
subject = LazyI18nString(subject)
message = LazyI18nString(message)
attachments_for_log = [cf.filename for cf in CachedFile.objects.filter(pk__in=attachments)] if attachments else []
def _send_to_order(o):
for o in orders:
send_to_order = recipients in ('both', 'orders')
try:
@@ -186,11 +179,6 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
except SendMailException:
failures.append(o.email)
for chunk in _chunks(objects, 1000):
orders = Order.objects.filter(pk__in=chunk, event=event)
for o in orders:
_send_to_order(o)
@app.task(base=ProfiledEventTask, acks_late=True)
def send_mails_to_waitinglist(event: Event, user: int, subject: dict, message: dict, objects: list,

View File

@@ -67,7 +67,7 @@ $panel-success-heading-bg: var(--pretix-brand-success-tint-50);
$panel-danger-border: var(--pretix-brand-danger-tint-50);
$panel-danger-heading-bg: var(--pretix-brand-danger-tint-50);
$panel-warning-border: var(--pretix-brand-warning-tint-50);
$panel-warning-heading-bg: var(--pretix-brand-warning-tint-50);
$panel-warning-heading-bg: var(--pretix-brand-warning-tine-50);
$panel-default-border: #e5e5e5 !default;
$panel-default-heading-bg: #e5e5e5 !default;