Compare commits

..
206 changed files with 62338 additions and 66594 deletions
+5 -10
View File
@@ -1,16 +1,11 @@
Contributing to pretix Contributing to pretix
====================== ======================
Welcome to pretix, we are happy that you would like to contribute. Hey there and welcome to pretix!
Before you do so, please make sure to read the following documents:
- [Contribution workflow](https://docs.pretix.eu/dev/development/contribution/general.html) * We've got a contributors guide in [our documentation](https://docs.pretix.eu/dev/development/contribution/) together with notes on the [development setup](https://docs.pretix.eu/dev/development/setup.html).
- [AI-assisted contribution policy](https://docs.pretix.eu/dev/development/contribution/ai.html)
- [Coding style and quality](https://docs.pretix.eu/dev/development/contribution/style.html)
- [Development setup](https://docs.pretix.eu/dev/development/setup.html)
- [Code of Conduct](https://docs.pretix.eu/dev/development/contribution/codeofconduct.html)
Before we can accept your first PR we'll need you to sign [our **Contributor License Agreement** (CLA)](https://pretix.eu/about/en/cla). * Please note that we have a [Code of Conduct](https://docs.pretix.eu/dev/development/contribution/codeofconduct.html) in place that applies to all project contributions, including issues, pull requests, etc.
You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/trust/licensing/faq/) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
* Before we can accept a PR from you we'll need you to sign [our CLA](https://pretix.eu/about/en/cla). You can find more information about the how and why in our [License FAQ](https://docs.pretix.eu/trust/licensing/faq/) and in our [license change blog post](https://pretix.eu/about/en/blog/20210412-license/).
**Before contributing new functionality, always open a discussion first.**
+1 -2
View File
@@ -1,4 +1,4 @@
FROM python:3.13-trixie FROM python:3.11-bookworm
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
@@ -31,7 +31,6 @@ RUN apt-get update && \
mkdir /etc/pretix && \ mkdir /etc/pretix && \
mkdir /data && \ mkdir /data && \
useradd -ms /bin/bash -d /pretix -u 15371 pretixuser && \ useradd -ms /bin/bash -d /pretix -u 15371 pretixuser && \
chmod 0755 /pretix && \
echo 'pretixuser ALL=(ALL) NOPASSWD:SETENV: /usr/bin/supervisord' >> /etc/sudoers && \ echo 'pretixuser ALL=(ALL) NOPASSWD:SETENV: /usr/bin/supervisord' >> /etc/sudoers && \
mkdir /static && \ mkdir /static && \
mkdir /etc/supervisord mkdir /etc/supervisord
+6 -13
View File
@@ -16,7 +16,6 @@ Field Type Description
id integer Internal ID of the program time id integer Internal ID of the program time
start datetime The start date time for this program time slot. start datetime The start date time for this program time slot.
end datetime The end date time for this program time slot. end datetime The end date time for this program time slot.
location multi-lingual string The program time slot's location (or ``null``)
===================================== ========================== ======================================================= ===================================== ========================== =======================================================
.. versionchanged:: TODO .. versionchanged:: TODO
@@ -55,20 +54,17 @@ Endpoints
{ {
"id": 2, "id": 2,
"start": "2025-08-14T22:00:00Z", "start": "2025-08-14T22:00:00Z",
"end": "2025-08-15T00:00:00Z", "end": "2025-08-15T00:00:00Z"
"location": null
}, },
{ {
"id": 3, "id": 3,
"start": "2025-08-12T22:00:00Z", "start": "2025-08-12T22:00:00Z",
"end": "2025-08-13T22:00:00Z", "end": "2025-08-13T22:00:00Z"
"location": null
}, },
{ {
"id": 14, "id": 14,
"start": "2025-08-15T22:00:00Z", "start": "2025-08-15T22:00:00Z",
"end": "2025-08-17T22:00:00Z", "end": "2025-08-17T22:00:00Z"
"location": null
} }
] ]
} }
@@ -103,8 +99,7 @@ Endpoints
{ {
"id": 1, "id": 1,
"start": "2025-08-15T22:00:00Z", "start": "2025-08-15T22:00:00Z",
"end": "2025-10-27T23:00:00Z", "end": "2025-10-27T23:00:00Z"
"location": null
} }
:param organizer: The ``slug`` field of the organizer to fetch :param organizer: The ``slug`` field of the organizer to fetch
@@ -130,8 +125,7 @@ Endpoints
{ {
"start": "2025-08-15T10:00:00Z", "start": "2025-08-15T10:00:00Z",
"end": "2025-08-15T22:00:00Z", "end": "2025-08-15T22:00:00Z"
"location": null
} }
**Example response**: **Example response**:
@@ -145,8 +139,7 @@ Endpoints
{ {
"id": 17, "id": 17,
"start": "2025-08-15T10:00:00Z", "start": "2025-08-15T10:00:00Z",
"end": "2025-08-15T22:00:00Z", "end": "2025-08-15T22:00:00Z"
"location": null
} }
:param organizer: The ``slug`` field of the organizer of the event/item to create a program time for :param organizer: The ``slug`` field of the organizer of the event/item to create a program time for
-24
View File
@@ -1,24 +0,0 @@
.. _`aipolicy`:
AI-assisted contribution policy
===============================
pretix is maintained by humans.
Every discussion, issue, and pull request is read and reviewed by humans (and sometimes machines, too).
We ask you to respect the time and effort put in by these humans by not sending low-effort, unqualified work, since it puts the burden of validation on the maintainer.
Therefore, the pretix project has strict rules for AI usage:
- **All AI usage in any form must be disclosed.** You must state the tool you used (e.g. Claude Code, Cursor, Amp) along with the extent that the work was AI-assisted.
- **The human-in-the-loop must fully understand all code.** If you can't explain what your changes do and how they interact with the greater system without the aid of AI tools, do not contribute to this project.
- **Issues and discussions can use AI assistance but must have a full human-in-the-loop.** This means that any content generated with AI must have been reviewed and edited by a human before submission. AI is very good at being overly verbose and including noise that distracts from the main point. Humans must do their research and trim this down.
- **No AI-generated media is allowed (art, images, videos, audio, etc.).** Text and code are the only acceptable AI-generated content, per the other rules in this policy.
- **Bad AI drivers will be excluded from the project.** People who produce bad contributions that are clearly AI (slop) will be blocked from our organization without warning.
This policy was inspired by the `ghostty project`_.
.. _ghostty project: https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md
+11 -30
View File
@@ -1,39 +1,23 @@
Contribution workflow General remarks
===================== ===============
You are interested in contributing to pretix? That is awesome! You are interested in contributing to pretix? That is awesome!
If youre new to contributing to open source software, dont be afraid. Well happily review your code and give you If youre new to contributing to open source software, dont be afraid. Well happily review your code and give you
constructive and friendly feedback on your changes. Every contribution should go through the following steps. constructive and friendly feedback on your changes.
Discussion & Design First of all, you'll need pretix running locally on your machine. Head over to :ref:`devsetup` to learn how to do this.
-------------------
pretix is a large and mature project with more of a decade of history and hopefully many more decades to come.
Keeping pretix in good shape over long timeframes is first and foremost a fight against complexity.
With every additional feature, complexity grows, and both features and complexity are hard to remove.
Even if you are doing the initial work of the contribution, accepting the contribution is not free for us.
Not only will we need to maintain the feature, but every feature adds cost to the maintenance of every other feature it interacts with, and every feature adds effort for users to understand how pretix works.
Therefore, we must carefully select what features we add, based on how well they fit the system in general and of how much use they will be to our larger user base.
We strongly ask you to **create a discussion on GitHub for every new feature idea** outlining the use case and the proposed implementation design.
Pull requests without prior discussion will likely just be closed.
For bug fixes and very minor changes, you can skip this step and open a PR right away.
Development
-----------
To develop your contribution, you'll need pretix running locally on your machine. Head over to :ref:`devsetup` to learn how to do this.
If you run into any problems on your way, please do not hesitate to ask us anytime! If you run into any problems on your way, please do not hesitate to ask us anytime!
While developing, please have a look at our :ref:`aipolicy` and our guidelines on :ref:`codestyle`. Please note that we bound ourselves to a :ref:`coc` that applies to all communication around the project. You can be
assured that we will not tolerate any form of harassment.
Sending a patch Sending a patch
--------------- ---------------
Once you have a first draft of your changes, please `create a pull request`_ on our `GitHub repository`_. If you improved pretix in any way, we'd be very happy if you contribute it
back to the main code base! The easiest way to do so is to `create a pull request`_
on our `GitHub repository`_.
We recommend that you create a feature branch for every issue you work on so the changes can We recommend that you create a feature branch for every issue you work on so the changes can
be reviewed individually. be reviewed individually.
@@ -41,17 +25,14 @@ Please use the test suite to check whether your changes break any existing featu
the code style checks to confirm you are consistent with pretix's coding style. You'll the code style checks to confirm you are consistent with pretix's coding style. You'll
find instructions on this in the :ref:`checksandtests` section of the development setup guide. find instructions on this in the :ref:`checksandtests` section of the development setup guide.
We automatically run the tests and the code style check on every pull request through GitHub Actions and we wont We automatically run the tests and the code style check on every pull request on Travis CI and we wont
accept any pull requests without all tests passing. However, if you don't find out *why* they are not passing, accept any pull requests without all tests passing. However, if you don't find out *why* they are not passing,
just send the pull request and tell us we'll be glad to help. just send the pull request and tell us we'll be glad to help.
If you add a new feature, please include appropriate documentation into your patch. If you fix a bug, If you add a new feature, please include appropriate documentation into your patch. If you fix a bug,
please include a regression test, i.e. a test that fails without your changes and passes after applying your changes. please include a regression test, i.e. a test that fails without your changes and passes after applying your changes.
Again: If you get stuck, do not hesitate to contact us through GitHub discussions. Again: If you get stuck, do not hesitate to contact any of us, or Raphael personally at mail@raphaelmichel.de.
Please note that we bound ourselves to a :ref:`coc` that applies to all communication around the project. You can be
assured that we will not tolerate any form of harassment.
.. _create a pull request: https://help.github.com/articles/creating-a-pull-request/ .. _create a pull request: https://help.github.com/articles/creating-a-pull-request/
.. _GitHub repository: https://github.com/pretix/pretix .. _GitHub repository: https://github.com/pretix/pretix
-1
View File
@@ -6,5 +6,4 @@ Contributing to pretix
general general
style style
ai
codeofconduct codeofconduct
+2 -2
View File
@@ -1,7 +1,5 @@
.. spelling:word-list:: Rebase rebasing .. spelling:word-list:: Rebase rebasing
.. _`codestyle`:
Coding style and quality Coding style and quality
======================== ========================
@@ -30,6 +28,8 @@ Code
Commits and Pull Requests Commits and Pull Requests
------------------------- -------------------------
Most commits should start as pull requests, therefore this applies to the titles of pull requests as well since Most commits should start as pull requests, therefore this applies to the titles of pull requests as well since
the pull request title will become the commit message on merge. We prefer merging with GitHub's "Squash and merge" the pull request title will become the commit message on merge. We prefer merging with GitHub's "Squash and merge"
feature if the PR contains multiple commits that do not carry value to keep. If there is value in keeping the feature if the PR contains multiple commits that do not carry value to keep. If there is value in keeping the
+7 -7
View File
@@ -33,9 +33,9 @@ dependencies = [
"bleach==6.3.*", "bleach==6.3.*",
"celery==5.6.*", "celery==5.6.*",
"chardet==5.2.*", "chardet==5.2.*",
"cryptography>=47.0.0", "cryptography>=44.0.0",
"css-inline==0.20.*", "css-inline==0.20.*",
"defusedcsv>=3.0.0", "defusedcsv>=1.1.0",
"dnspython==2.*", "dnspython==2.*",
"Django[argon2]==5.2.*", "Django[argon2]==5.2.*",
"django-bootstrap3==26.1", "django-bootstrap3==26.1",
@@ -76,7 +76,7 @@ dependencies = [
"paypal-checkout-serversdk==1.0.*", "paypal-checkout-serversdk==1.0.*",
"PyJWT==2.12.*", "PyJWT==2.12.*",
"phonenumberslite==9.0.*", "phonenumberslite==9.0.*",
"Pillow==12.2.*", "Pillow==12.1.*",
"pretix-plugin-build", "pretix-plugin-build",
"protobuf==7.34.*", "protobuf==7.34.*",
"psycopg2-binary", "psycopg2-binary",
@@ -90,14 +90,14 @@ dependencies = [
"pytz-deprecation-shim==0.1.*", "pytz-deprecation-shim==0.1.*",
"pyuca", "pyuca",
"qrcode==8.2", "qrcode==8.2",
"redis==7.4.*", "redis==7.1.*",
"reportlab==4.4.*", "reportlab==4.4.*",
"requests==2.32.*", "requests==2.32.*",
"sentry-sdk==2.58.*", "sentry-sdk==2.56.*",
"sepaxml==2.7.*", "sepaxml==2.7.*",
"stripe==7.9.*", "stripe==7.9.*",
"text-unidecode==1.*", "text-unidecode==1.*",
"tlds>=2026041800", "tlds>=2020041600",
"tqdm==4.*", "tqdm==4.*",
"ua-parser==1.0.*", "ua-parser==1.0.*",
"vobject==0.9.*", "vobject==0.9.*",
@@ -117,7 +117,7 @@ dev = [
"isort==8.0.*", "isort==8.0.*",
"pep8-naming==0.15.*", "pep8-naming==0.15.*",
"potypo", "potypo",
"pytest-asyncio>=1.3.0", "pytest-asyncio>=0.24",
"pytest-cache", "pytest-cache",
"pytest-cov", "pytest-cov",
"pytest-django==4.*", "pytest-django==4.*",
+1 -1
View File
@@ -19,4 +19,4 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see # You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>. # <https://www.gnu.org/licenses/>.
# #
__version__ = "2026.5.0.dev0" __version__ = "2026.4.0.dev0"
+2 -2
View File
@@ -191,7 +191,7 @@ class InlineItemAddOnSerializer(serializers.ModelSerializer):
class InlineItemProgramTimeSerializer(serializers.ModelSerializer): class InlineItemProgramTimeSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = ItemProgramTime model = ItemProgramTime
fields = ('start', 'end', 'location') fields = ('start', 'end')
class ItemBundleSerializer(serializers.ModelSerializer): class ItemBundleSerializer(serializers.ModelSerializer):
@@ -222,7 +222,7 @@ class ItemBundleSerializer(serializers.ModelSerializer):
class ItemProgramTimeSerializer(serializers.ModelSerializer): class ItemProgramTimeSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = ItemProgramTime model = ItemProgramTime
fields = ('id', 'start', 'end', 'location') fields = ('id', 'start', 'end')
def validate(self, data): def validate(self, data):
data = super().validate(data) data = super().validate(data)
+3 -25
View File
@@ -31,9 +31,7 @@ from pretix.api.serializers.order import OrderPositionSerializer
from pretix.api.serializers.organizer import ( from pretix.api.serializers.organizer import (
CustomerSerializer, GiftCardSerializer, CustomerSerializer, GiftCardSerializer,
) )
from pretix.base.models import ( from pretix.base.models import Order, OrderPosition, ReusableMedium
Device, Order, OrderPosition, ReusableMedium, TeamAPIToken,
)
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -82,7 +80,8 @@ class ReusableMediaSerializer(I18nAwareModelSerializer):
) )
if 'linked_orderposition' in self.context['request'].query_params.getlist('expand'): if 'linked_orderposition' in self.context['request'].query_params.getlist('expand'):
# Permission Check performed in to_representation # No additional permission check performed, documented limitation of the permission system
# Would get to complex/unusable otherwise since the permission depends on the event
self.fields['linked_orderposition'] = NestedOrderPositionSerializer(read_only=True) self.fields['linked_orderposition'] = NestedOrderPositionSerializer(read_only=True)
else: else:
self.fields['linked_orderposition'] = serializers.PrimaryKeyRelatedField( self.fields['linked_orderposition'] = serializers.PrimaryKeyRelatedField(
@@ -118,27 +117,6 @@ class ReusableMediaSerializer(I18nAwareModelSerializer):
) )
return data return data
def to_representation(self, instance):
r = super().to_representation(instance)
request = self.context.get('request')
# late permission evaluations for checks that depend on the actual linked events
expand_nested = self.context['request'].query_params.getlist('expand')
perm_holder = request.auth if isinstance(request.auth, (Device, TeamAPIToken)) else request.user
if 'linked_orderposition' in expand_nested:
if instance.linked_orderposition is not None:
event = instance.linked_orderposition.order.event
if not perm_holder.has_event_permission(event.organizer, event, 'event.orders:read', request):
r['linked_orderposition'] = {'id': instance.linked_orderposition.id}
if 'linked_giftcard.owner_ticket' in expand_nested:
gc = instance.linked_giftcard
if gc is not None and gc.owner_ticket is not None:
event = gc.owner_ticket.order.event
if not perm_holder.has_event_permission(event.organizer, event, 'event.orders:read', request):
r['linked_giftcard']['owner_ticket'] = {'id': instance.linked_giftcard.owner_ticket.id}
return r
class Meta: class Meta:
model = ReusableMedium model = ReusableMedium
fields = ( fields = (
+6 -13
View File
@@ -769,11 +769,7 @@ class PaymentDetailsField(serializers.Field):
pp = value.payment_provider pp = value.payment_provider
if not pp: if not pp:
return {} return {}
try: return pp.api_payment_details(value)
return pp.api_payment_details(value)
except Exception:
logger.exception("Failed to retrieve payment_details")
return {}
class OrderPaymentSerializer(I18nAwareModelSerializer): class OrderPaymentSerializer(I18nAwareModelSerializer):
@@ -1416,7 +1412,6 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
qa = QuotaAvailability() qa = QuotaAvailability()
qa.queue(*[q for q, d in quota_diff_for_locking.items() if d > 0]) qa.queue(*[q for q, d in quota_diff_for_locking.items() if d > 0])
qa.compute() qa.compute()
v_avail = {}
# These are not technically correct as diff use due to the time offset applied above, so let's prevent accidental # These are not technically correct as diff use due to the time offset applied above, so let's prevent accidental
# use further down # use further down
@@ -1446,13 +1441,11 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
voucher_usage[v] += 1 voucher_usage[v] += 1
if voucher_usage[v] > 0: if voucher_usage[v] > 0:
if v not in v_avail: redeemed_in_carts = CartPosition.objects.filter(
v.refresh_from_db(fields=['redeemed']) Q(voucher=pos_data['voucher']) & Q(event=self.context['event']) & Q(expires__gte=now_dt)
redeemed_in_carts = CartPosition.objects.filter( ).exclude(pk__in=[cp.pk for cp in delete_cps])
Q(voucher=v) & Q(event=self.context['event']) & Q(expires__gte=now_dt) v_avail = v.max_usages - v.redeemed - redeemed_in_carts.count()
).exclude(pk__in=[cp.pk for cp in delete_cps]) if v_avail < voucher_usage[v]:
v_avail[v] = v.max_usages - v.redeemed - redeemed_in_carts.count()
if v_avail[v] < voucher_usage[v]:
errs[i]['voucher'] = [ errs[i]['voucher'] = [
'The voucher has already been used the maximum number of times.' 'The voucher has already been used the maximum number of times.'
] ]
-13
View File
@@ -286,19 +286,6 @@ class GiftCardSerializer(I18nAwareModelSerializer):
) )
return data return data
def to_representation(self, instance):
r = super().to_representation(instance)
request = self.context.get('request')
# late permission evaluations for checks that depend on the actual linked events
if 'owner_ticket' in self.context['request'].query_params.getlist('expand'):
owner_ticket = instance.owner_ticket
if owner_ticket:
event = owner_ticket.order.event
perm_holder = request.auth if isinstance(request.auth, (Device, TeamAPIToken)) else request.user
if not perm_holder.has_event_permission(event.organizer, event, 'event.orders:read', request):
r['owner_ticket'] = {'id': instance.owner_ticket.id}
return r
class Meta: class Meta:
model = GiftCard model = GiftCard
fields = ('id', 'secret', 'issuance', 'value', 'currency', 'testmode', 'expires', 'conditions', 'owner_ticket', fields = ('id', 'secret', 'issuance', 'value', 'currency', 'testmode', 'expires', 'conditions', 'owner_ticket',
+1 -1
View File
@@ -1122,7 +1122,7 @@ class CheckinViewSet(viewsets.ReadOnlyModelViewSet):
permission = 'event.orders:read' permission = 'event.orders:read'
def get_queryset(self): def get_queryset(self):
qs = Checkin.all.filter(list__event=self.request.event).select_related( qs = Checkin.all.filter().select_related(
"position", "position",
"device", "device",
) )
+28 -43
View File
@@ -381,15 +381,12 @@ class EventOrderViewSet(OrderViewSetMixin, viewsets.ModelViewSet):
resp = HttpResponse(ct.file.file.read(), content_type='text/uri-list') resp = HttpResponse(ct.file.file.read(), content_type='text/uri-list')
return resp return resp
else: else:
return FileResponse( resp = FileResponse(ct.file.file, content_type=ct.type)
ct.file.file, resp['Content-Disposition'] = 'attachment; filename="{}-{}-{}{}"'.format(
filename='{}-{}-{}{}'.format( self.request.event.slug.upper(), order.code,
self.request.event.slug.upper(), order.code, provider.identifier, ct.extension
provider.identifier, ct.extension
),
as_attachment=True,
content_type=ct.type
) )
return resp
@action(detail=True, methods=['POST']) @action(detail=True, methods=['POST'])
def mark_paid(self, request, **kwargs): def mark_paid(self, request, **kwargs):
@@ -1306,17 +1303,14 @@ class EventOrderPositionViewSet(OrderPositionViewSetMixin, viewsets.ModelViewSet
raise NotFound() raise NotFound()
ftype, ignored = mimetypes.guess_type(answer.file.name) ftype, ignored = mimetypes.guess_type(answer.file.name)
return FileResponse( resp = FileResponse(answer.file, content_type=ftype or 'application/binary')
answer.file, resp['Content-Disposition'] = 'attachment; filename="{}-{}-{}-{}"'.format(
filename='{}-{}-{}-{}'.format( self.request.event.slug.upper(),
self.request.event.slug.upper(), pos.order.code,
pos.order.code, pos.positionid,
pos.positionid, os.path.basename(answer.file.name).split('.', 1)[1]
os.path.basename(answer.file.name).split('.', 1)[1]
),
as_attachment=True,
content_type=ftype or 'application/binary'
) )
return resp
@action(detail=True, url_name="printlog", url_path="printlog", methods=["POST"]) @action(detail=True, url_name="printlog", url_path="printlog", methods=["POST"])
def printlog(self, request, **kwargs): def printlog(self, request, **kwargs):
@@ -1371,18 +1365,15 @@ class EventOrderPositionViewSet(OrderPositionViewSetMixin, viewsets.ModelViewSet
if hasattr(image_file, 'seek'): if hasattr(image_file, 'seek'):
image_file.seek(0) image_file.seek(0)
return FileResponse( resp = FileResponse(image_file, content_type=ftype or 'application/binary')
image_file, resp['Content-Disposition'] = 'attachment; filename="{}-{}-{}-{}.{}"'.format(
filename='{}-{}-{}-{}.{}'.format( self.request.event.slug.upper(),
self.request.event.slug.upper(), pos.order.code,
pos.order.code, pos.positionid,
pos.positionid, key,
key, extension,
extension,
),
as_attachment=True,
content_type=ftype or 'application/binary'
) )
return resp
@action(detail=True, url_name='download', url_path='download/(?P<output>[^/]+)') @action(detail=True, url_name='download', url_path='download/(?P<output>[^/]+)')
def download(self, request, output, **kwargs): def download(self, request, output, **kwargs):
@@ -1408,15 +1399,12 @@ class EventOrderPositionViewSet(OrderPositionViewSetMixin, viewsets.ModelViewSet
resp = HttpResponse(ct.file.file.read(), content_type='text/uri-list') resp = HttpResponse(ct.file.file.read(), content_type='text/uri-list')
return resp return resp
else: else:
return FileResponse( resp = FileResponse(ct.file.file, content_type=ct.type)
ct.file.file, resp['Content-Disposition'] = 'attachment; filename="{}-{}-{}-{}{}"'.format(
filename='{}-{}-{}-{}{}'.format( self.request.event.slug.upper(), pos.order.code, pos.positionid,
self.request.event.slug.upper(), pos.order.code, pos.positionid, provider.identifier, ct.extension
provider.identifier, ct.extension
),
as_attachment=True,
content_type=ct.type
) )
return resp
@action(detail=True, methods=['POST']) @action(detail=True, methods=['POST'])
def regenerate_secrets(self, request, **kwargs): def regenerate_secrets(self, request, **kwargs):
@@ -1998,12 +1986,9 @@ class InvoiceViewSet(viewsets.ReadOnlyModelViewSet):
if not invoice.file: if not invoice.file:
raise RetryException() raise RetryException()
return FileResponse( resp = FileResponse(invoice.file.file, content_type='application/pdf')
invoice.file.file, resp['Content-Disposition'] = 'attachment; filename="{}.pdf"'.format(invoice.number)
filename='{}.pdf'.format(invoice.number), return resp
as_attachment=True,
content_type='application/pdf'
)
@action(detail=True, methods=['POST']) @action(detail=True, methods=['POST'])
def transmit(self, request, **kwargs): def transmit(self, request, **kwargs):
-80
View File
@@ -19,10 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see # You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>. # <https://www.gnu.org/licenses/>.
# #
import ipaddress
import logging import logging
import smtplib
import socket
from itertools import groupby from itertools import groupby
from smtplib import SMTPResponseException from smtplib import SMTPResponseException
from typing import TypeVar from typing import TypeVar
@@ -240,80 +237,3 @@ def base_renderers(sender, **kwargs):
def get_email_context(**kwargs): def get_email_context(**kwargs):
return PlaceholderContext(**kwargs).render_all() return PlaceholderContext(**kwargs).render_all()
def create_connection(address, timeout=socket.getdefaulttimeout(),
source_address=None, *, all_errors=False):
# Taken from the python stdlib, extended with a check for local ips
host, port = address
exceptions = []
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
if not getattr(settings, "MAIL_CUSTOM_SMTP_ALLOW_PRIVATE_NETWORKS", False):
ip_addr = ipaddress.ip_address(sa[0])
if ip_addr.is_multicast:
raise socket.error(f"Request to multicast address {sa[0]} blocked")
if ip_addr.is_loopback or ip_addr.is_link_local:
raise socket.error(f"Request to local address {sa[0]} blocked")
if ip_addr.is_private:
raise socket.error(f"Request to private address {sa[0]} blocked")
sock = None
try:
sock = socket.socket(af, socktype, proto)
if timeout is not socket.getdefaulttimeout():
sock.settimeout(timeout)
if source_address:
sock.bind(source_address)
sock.connect(sa)
# Break explicitly a reference cycle
exceptions.clear()
return sock
except socket.error as exc:
if not all_errors:
exceptions.clear() # raise only the last error
exceptions.append(exc)
if sock is not None:
sock.close()
if len(exceptions):
try:
if not all_errors:
raise exceptions[0]
raise ExceptionGroup("create_connection failed", exceptions)
finally:
# Break explicitly a reference cycle
exceptions.clear()
else:
raise socket.error("getaddrinfo returns an empty list")
class CheckPrivateNetworkMixin:
# _get_socket taken 1:1 from smtplib, just with a call to our own create_connection
def _get_socket(self, host, port, timeout):
# This makes it simpler for SMTP_SSL to use the SMTP connect code
# and just alter the socket connection bit.
if timeout is not None and not timeout:
raise ValueError('Non-blocking socket (timeout=0) is not supported')
if self.debuglevel > 0:
self._print_debug('connect: to', (host, port), self.source_address)
return create_connection((host, port), timeout, self.source_address)
class SMTP(CheckPrivateNetworkMixin, smtplib.SMTP):
pass
# SMTP used here instead of mixin, because smtp.SMTP_SSL._get_socket calls super()._get_socket and then wraps this socket
# super()._get_socket needs to be our version from the mixin
class SMTP_SSL(smtplib.SMTP_SSL, SMTP): # noqa: N801
pass
class CheckPrivateNetworkSmtpBackend(EmailBackend):
@property
def connection_class(self):
return SMTP_SSL if self.use_ssl else SMTP
+3 -13
View File
@@ -47,7 +47,6 @@ from django.utils.formats import localize
from django.utils.translation import gettext, gettext_lazy as _ from django.utils.translation import gettext, gettext_lazy as _
from pretix.base.models import Event from pretix.base.models import Event
from pretix.base.models.auth import PermissionHolder
from pretix.helpers.safe_openpyxl import ( # NOQA: backwards compatibility for plugins using excel_safe from pretix.helpers.safe_openpyxl import ( # NOQA: backwards compatibility for plugins using excel_safe
SafeWorkbook, remove_invalid_excel_chars as excel_safe, SafeWorkbook, remove_invalid_excel_chars as excel_safe,
) )
@@ -60,20 +59,11 @@ class BaseExporter:
This is the base class for all data exporters This is the base class for all data exporters
""" """
def __init__(self, event, organizer, permission_holder: PermissionHolder=None, progress_callback=lambda v: None): def __init__(self, event, organizer, progress_callback=lambda v: None):
"""
:param event: Event context, can also be a queryset of events for multi-event exports
:param organizer: Organizer context
:param user: The user who triggered the export (or None).
:param token: The API token that triggered the export (or None).
:param device: The device that triggered the export (or None)
:param progress_callback: Callback function with progress
"""
self.event = event self.event = event
self.organizer = organizer self.organizer = organizer
self.progress_callback = progress_callback self.progress_callback = progress_callback
self.is_multievent = isinstance(event, QuerySet) self.is_multievent = isinstance(event, QuerySet)
self.permission_holder = permission_holder
if isinstance(event, QuerySet): if isinstance(event, QuerySet):
self.events = event self.events = event
self.event = None self.event = None
@@ -190,7 +180,7 @@ class BaseExporter:
return True return True
@classmethod @classmethod
def get_required_event_permission(cls) -> Optional[str]: def get_required_event_permission(cls) -> str:
""" """
The permission level required to use this exporter for events. For multi-event-exports, this will be used The permission level required to use this exporter for events. For multi-event-exports, this will be used
to limit the selection of events. Will be ignored if the ``OrganizerLevelExportMixin`` mixin is used. to limit the selection of events. Will be ignored if the ``OrganizerLevelExportMixin`` mixin is used.
@@ -205,7 +195,7 @@ class OrganizerLevelExportMixin:
raise TypeError("required_event_permission may not be called on OrganizerLevelExportMixin") raise TypeError("required_event_permission may not be called on OrganizerLevelExportMixin")
@classmethod @classmethod
def get_required_organizer_permission(cls) -> Optional[str]: def get_required_organizer_permission(cls) -> str:
""" """
The permission level required to use this exporter. Must be set for organizer-level exports. Set to `None` to The permission level required to use this exporter. Must be set for organizer-level exports. Set to `None` to
allow everyone with any access to the organizer. allow everyone with any access to the organizer.
-14
View File
@@ -1103,25 +1103,13 @@ class PaymentListExporter(ListExporter):
def iterate_list(self, form_data): def iterate_list(self, form_data):
provider_names = dict(get_all_payment_providers()) provider_names = dict(get_all_payment_providers())
i_numbers = Invoice.objects.filter(
order=OuterRef('order_id'),
).values('order').annotate(
m=GroupConcat('full_invoice_no', delimiter=', ')
).values(
'm'
).order_by()
payments = OrderPayment.objects.filter( payments = OrderPayment.objects.filter(
order__event__in=self.events, order__event__in=self.events,
state__in=form_data.get('payment_states', []) state__in=form_data.get('payment_states', [])
).annotate(
order_invoice_numbers=Subquery(i_numbers, output_field=CharField()),
).select_related('order').prefetch_related('order__event').order_by('created') ).select_related('order').prefetch_related('order__event').order_by('created')
refunds = OrderRefund.objects.filter( refunds = OrderRefund.objects.filter(
order__event__in=self.events, order__event__in=self.events,
state__in=form_data.get('refund_states', []) state__in=form_data.get('refund_states', [])
).annotate(
order_invoice_numbers=Subquery(i_numbers, output_field=CharField()),
).select_related('order').prefetch_related('order__event').order_by('created') ).select_related('order').prefetch_related('order__event').order_by('created')
if form_data.get('end_date_range'): if form_data.get('end_date_range'):
@@ -1147,7 +1135,6 @@ class PaymentListExporter(ListExporter):
headers = [ headers = [
_('Event slug'), _('Order'), _('Payment ID'), _('Creation date'), _('Completion date'), _('Status'), _('Event slug'), _('Order'), _('Payment ID'), _('Creation date'), _('Completion date'), _('Status'),
_('Status code'), _('Amount'), _('Payment method'), _('Comment'), _('Matching ID'), _('Payment details'), _('Status code'), _('Amount'), _('Payment method'), _('Comment'), _('Matching ID'), _('Payment details'),
_('Invoice numbers'),
] ]
yield headers yield headers
@@ -1185,7 +1172,6 @@ class PaymentListExporter(ListExporter):
obj.comment if isinstance(obj, OrderRefund) else "", obj.comment if isinstance(obj, OrderRefund) else "",
matching_id, matching_id,
payment_details, payment_details,
obj.order_invoice_numbers,
] ]
yield row yield row
+2 -8
View File
@@ -90,7 +90,7 @@ from pretix.base.settings import (
COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL, COUNTRIES_WITH_STATE_IN_ADDRESS, COUNTRY_STATE_LABEL,
PERSON_NAME_SALUTATIONS, PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS, PERSON_NAME_SALUTATIONS, PERSON_NAME_SCHEMES, PERSON_NAME_TITLE_GROUPS,
) )
from pretix.base.templatetags.rich_text import URL_RE, rich_text from pretix.base.templatetags.rich_text import rich_text
from pretix.base.timemachine import time_machine_now from pretix.base.timemachine import time_machine_now
from pretix.control.forms import ( from pretix.control.forms import (
ExtFileField, ExtValidationMixin, SizeValidationMixin, SplitDateTimeField, ExtFileField, ExtValidationMixin, SizeValidationMixin, SplitDateTimeField,
@@ -227,15 +227,9 @@ class NamePartsFormField(forms.MultiValueField):
# bots. # bots.
r'^[^$€/%§{}<>~]*$', r'^[^$€/%§{}<>~]*$',
message=_('Please do not use special characters in names.') message=_('Please do not use special characters in names.')
),
RegexValidator(
URL_RE,
inverse_match=True,
message=_('Please do not use special characters in names.')
) )
] ]
} }
self.max_length = defaults['max_length']
self.scheme_name = kwargs.pop('scheme') self.scheme_name = kwargs.pop('scheme')
self.titles = kwargs.pop('titles') self.titles = kwargs.pop('titles')
self.scheme = PERSON_NAME_SCHEMES.get(self.scheme_name) self.scheme = PERSON_NAME_SCHEMES.get(self.scheme_name)
@@ -293,7 +287,7 @@ class NamePartsFormField(forms.MultiValueField):
if self.require_all_fields and not all(v for v in value): if self.require_all_fields and not all(v for v in value):
raise forms.ValidationError(self.error_messages['incomplete'], code='required') raise forms.ValidationError(self.error_messages['incomplete'], code='required')
if sum(len(v) for v in value.values() if v) > (self.max_length or 250): if sum(len(v) for v in value.values() if v) > 250:
raise forms.ValidationError(_('Please enter a shorter name.'), code='max_length') raise forms.ValidationError(_('Please enter a shorter name.'), code='max_length')
if value.get("salutation") == "empty": if value.get("salutation") == "empty":
-13
View File
@@ -24,7 +24,6 @@ from urllib.parse import urlparse, urlsplit
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from django.conf import settings from django.conf import settings
from django.core.exceptions import BadRequest
from django.http import Http404, HttpRequest, HttpResponse from django.http import Http404, HttpRequest, HttpResponse
from django.middleware.common import CommonMiddleware from django.middleware.common import CommonMiddleware
from django.urls import get_script_prefix, resolve from django.urls import get_script_prefix, resolve
@@ -348,18 +347,6 @@ class SecurityMiddleware(MiddlewareMixin):
return resp return resp
class RejectInvalidInputMiddleware(MiddlewareMixin):
def process_request(self, request):
# Nullbytes in GET/POST parameters are mostly harmless, as they will later fail on database insertion, but it
# keeps spamming our error logs whenever someone tries to run a vulnerability scanner.
if "\x00" in request.META['QUERY_STRING'] or "%00" in request.META['QUERY_STRING']:
raise BadRequest("Invalid characters in input.")
if request.method in ('POST', 'PUT', 'PATCH') and request.content_type == "application/x-www-form-urlencoded":
if any("\x00" in value for key, value_list in request.POST.lists() for value in value_list):
raise BadRequest("Invalid characters in input.")
class CustomCommonMiddleware(CommonMiddleware): class CustomCommonMiddleware(CommonMiddleware):
def get_full_path_with_slash(self, request): def get_full_path_with_slash(self, request):
@@ -1,19 +0,0 @@
# Generated by Django 4.2.27 on 2026-01-21 12:06
import i18nfield.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0298_pluggable_permissions"),
]
operations = [
migrations.AddField(
model_name="itemprogramtime",
name="location",
field=i18nfield.fields.I18nTextField(max_length=200, null=True),
)
]
-4
View File
@@ -70,10 +70,6 @@ def parse_csv(file, length=None, mode="strict", charset=None):
except ImportError: except ImportError:
charset = file.charset charset = file.charset
data = data.decode(charset or "utf-8", mode) data = data.decode(charset or "utf-8", mode)
# remove stray linebreaks from the end of the file
data = data.rstrip("\n")
# If the file was modified on a Mac, it only contains \r as line breaks # If the file was modified on a Mac, it only contains \r as line breaks
if '\r' in data and '\n' not in data: if '\r' in data and '\n' not in data:
data = data.replace('\r', '\n') data = data.replace('\r', '\n')
+3 -9
View File
@@ -29,9 +29,7 @@ import inspect
import logging import logging
import os import os
import threading import threading
from pathlib import Path
import django
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
@@ -76,14 +74,10 @@ def _transactions_mark_order_dirty(order_id, using=None):
if "PYTEST_CURRENT_TEST" in os.environ: if "PYTEST_CURRENT_TEST" in os.environ:
# We don't care about Order.objects.create() calls in test code so let's try to figure out if this is test code # We don't care about Order.objects.create() calls in test code so let's try to figure out if this is test code
# or not. # or not.
for frame in inspect.stack()[1:]: for frame in inspect.stack():
if ( if 'pretix/base/models/orders' in frame.filename:
'pretix/base/models/orders' in frame.filename
or Path(frame.filename).is_relative_to(Path(django.__file__).parent)
):
# Ignore model- and django-internal code
continue continue
elif 'test_' in frame.filename or 'conftest.py' in frame.filename: elif 'test_' in frame.filename or 'conftest.py in frame.filename':
return return
elif 'pretix/' in frame.filename or 'pretix_' in frame.filename: elif 'pretix/' in frame.filename or 'pretix_' in frame.filename:
# This went through non-test code, let's consider it non-test # This went through non-test code, let's consider it non-test
-21
View File
@@ -38,7 +38,6 @@ import operator
import secrets import secrets
from datetime import timedelta from datetime import timedelta
from functools import reduce from functools import reduce
from typing import Protocol
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import ( from django.contrib.auth.models import (
@@ -68,14 +67,6 @@ class EmailAddressTakenError(IntegrityError):
pass pass
class PermissionHolder(Protocol):
def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool:
...
def has_organizer_permission(self, organizer, perm_name=None, request=None):
...
class UserManager(BaseUserManager): class UserManager(BaseUserManager):
""" """
This is the user manager for our custom user model. See the User This is the user manager for our custom user model. See the User
@@ -705,18 +696,6 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
return self.teams.exists() return self.teams.exists()
class UserWithStaffSession:
# Wrapper around a User object with a staff session, implementing the PermissionHolder Protocol
def __init__(self, user):
self.user = user
def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool:
return True
def has_organizer_permission(self, organizer, perm_name=None, request=None):
return True
class UserKnownLoginSource(models.Model): class UserKnownLoginSource(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE, related_name="known_login_sources") user = models.ForeignKey('User', on_delete=models.CASCADE, related_name="known_login_sources")
agent_type = models.CharField(max_length=255, null=True, blank=True) agent_type = models.CharField(max_length=255, null=True, blank=True)
+1 -2
View File
@@ -229,7 +229,7 @@ class Device(LoggedModel):
""" """
return self._organizer_permission_set() if self.organizer == organizer else set() return self._organizer_permission_set() if self.organizer == organizer else set()
def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool: def has_event_permission(self, organizer, event, perm_name=None, request=None) -> bool:
""" """
Checks if this token is part of a team that grants access of type ``perm_name`` Checks if this token is part of a team that grants access of type ``perm_name``
to the event ``event``. to the event ``event``.
@@ -238,7 +238,6 @@ class Device(LoggedModel):
:param event: The event to check :param event: The event to check
:param perm_name: The permission, e.g. ``event.orders:read`` :param perm_name: The permission, e.g. ``event.orders:read``
:param request: This parameter is ignored and only defined for compatibility reasons. :param request: This parameter is ignored and only defined for compatibility reasons.
:param session_key: This parameter is ignored and only defined for compatibility reasons.
:return: bool :return: bool
""" """
has_event_access = (self.all_events and organizer == self.organizer) or ( has_event_access = (self.all_events and organizer == self.organizer) or (
-6
View File
@@ -715,12 +715,6 @@ class Event(EventMixin, LoggedModel):
self.settings.name_scheme = 'given_family' self.settings.name_scheme = 'given_family'
self.settings.payment_banktransfer_invoice_immediately = True self.settings.payment_banktransfer_invoice_immediately = True
self.settings.low_availability_percentage = 10 self.settings.low_availability_percentage = 10
self.settings.mail_send_order_free_attendee = True
self.settings.mail_send_order_placed_attendee = True
self.settings.mail_send_order_paid_attendee = True
self.settings.mail_send_order_approved_attendee = True
self.settings.mail_send_order_approved_free_attendee = True
self.settings.mail_text_download_reminder_attendee = True
@property @property
def social_image(self): def social_image(self):
-7
View File
@@ -2306,17 +2306,10 @@ class ItemProgramTime(models.Model):
:type start: datetime :type start: datetime
:param end: The date and time this program time ends :param end: The date and time this program time ends
:type end: datetime :type end: datetime
:param location: venue
:type location: str
""" """
item = models.ForeignKey('Item', related_name='program_times', on_delete=models.CASCADE) item = models.ForeignKey('Item', related_name='program_times', on_delete=models.CASCADE)
start = models.DateTimeField(verbose_name=_("Start")) start = models.DateTimeField(verbose_name=_("Start"))
end = models.DateTimeField(verbose_name=_("End")) end = models.DateTimeField(verbose_name=_("End"))
location = I18nTextField(
null=True, blank=True,
max_length=200,
verbose_name=_("Location"),
)
def clean(self): def clean(self):
if hasattr(self, 'item') and self.item and self.item.event.has_subevents: if hasattr(self, 'item') and self.item and self.item.event.has_subevents:
+2 -2
View File
@@ -590,7 +590,7 @@ class Order(LockModel, LoggedModel):
not kwargs.get('force_save_with_deferred_fields', None) and not kwargs.get('force_save_with_deferred_fields', None) and
(not update_fields or ('require_approval' not in update_fields and 'status' not in update_fields)) (not update_fields or ('require_approval' not in update_fields and 'status' not in update_fields))
): ):
_fail("It is unsafe to call save() on an Order with deferred fields since we can't check if you missed " _fail("It is unsafe to call save() on an OrderFee with deferred fields since we can't check if you missed "
"creating a transaction. Call save(force_save_with_deferred_fields=True) if you really want to do " "creating a transaction. Call save(force_save_with_deferred_fields=True) if you really want to do "
"this.") "this.")
@@ -2841,7 +2841,7 @@ class OrderPosition(AbstractPosition):
if Transaction.key(self) != self.__initial_transaction_key or self.canceled != self.__initial_canceled or not self.pk: if Transaction.key(self) != self.__initial_transaction_key or self.canceled != self.__initial_canceled or not self.pk:
_transactions_mark_order_dirty(self.order_id, using=kwargs.get('using', None)) _transactions_mark_order_dirty(self.order_id, using=kwargs.get('using', None))
elif not kwargs.get('force_save_with_deferred_fields', None): elif not kwargs.get('force_save_with_deferred_fields', None):
_fail("It is unsafe to call save() on an OrderPosition with deferred fields since we can't check if you missed " _fail("It is unsafe to call save() on an OrderFee with deferred fields since we can't check if you missed "
"creating a transaction. Call save(force_save_with_deferred_fields=True) if you really want to do " "creating a transaction. Call save(force_save_with_deferred_fields=True) if you really want to do "
"this.") "this.")
+1 -8
View File
@@ -319,9 +319,6 @@ class TeamQuerySet(models.QuerySet):
def event_permission_q(cls, perm_name): def event_permission_q(cls, perm_name):
from ..permissions import assert_valid_event_permission from ..permissions import assert_valid_event_permission
if perm_name is None:
return Q()
if perm_name.startswith('can_') and perm_name in OLD_TO_NEW_EVENT_COMPAT: # legacy if perm_name.startswith('can_') and perm_name in OLD_TO_NEW_EVENT_COMPAT: # legacy
return reduce(operator.and_, [cls.event_permission_q(p) for p in OLD_TO_NEW_EVENT_COMPAT[perm_name]]) return reduce(operator.and_, [cls.event_permission_q(p) for p in OLD_TO_NEW_EVENT_COMPAT[perm_name]])
assert_valid_event_permission(perm_name, allow_legacy=False) assert_valid_event_permission(perm_name, allow_legacy=False)
@@ -334,9 +331,6 @@ class TeamQuerySet(models.QuerySet):
def organizer_permission_q(cls, perm_name): def organizer_permission_q(cls, perm_name):
from ..permissions import assert_valid_organizer_permission from ..permissions import assert_valid_organizer_permission
if perm_name is None:
return Q()
if perm_name.startswith('can_') and perm_name in OLD_TO_NEW_ORGANIZER_COMPAT: # legacy if perm_name.startswith('can_') and perm_name in OLD_TO_NEW_ORGANIZER_COMPAT: # legacy
return reduce(operator.and_, [cls.organizer_permission_q(p) for p in OLD_TO_NEW_ORGANIZER_COMPAT[perm_name]]) return reduce(operator.and_, [cls.organizer_permission_q(p) for p in OLD_TO_NEW_ORGANIZER_COMPAT[perm_name]])
assert_valid_organizer_permission(perm_name, allow_legacy=False) assert_valid_organizer_permission(perm_name, allow_legacy=False)
@@ -556,7 +550,7 @@ class TeamAPIToken(models.Model):
""" """
return self.team.organizer_permission_set() if self.team.organizer == organizer else set() return self.team.organizer_permission_set() if self.team.organizer == organizer else set()
def has_event_permission(self, organizer, event, perm_name=None, request=None, session_key=None) -> bool: def has_event_permission(self, organizer, event, perm_name=None, request=None) -> bool:
""" """
Checks if this token is part of a team that grants access of type ``perm_name`` Checks if this token is part of a team that grants access of type ``perm_name``
to the event ``event``. to the event ``event``.
@@ -565,7 +559,6 @@ class TeamAPIToken(models.Model):
:param event: The event to check :param event: The event to check
:param perm_name: The permission, e.g. ``event.orders:read`` :param perm_name: The permission, e.g. ``event.orders:read``
:param request: This parameter is ignored and only defined for compatibility reasons. :param request: This parameter is ignored and only defined for compatibility reasons.
:param session_key: This parameter is ignored and only defined for compatibility reasons.
:return: bool :return: bool
""" """
has_event_access = (self.team.all_events and organizer == self.team.organizer) or ( has_event_access = (self.team.all_events and organizer == self.team.organizer) or (
+15 -32
View File
@@ -54,7 +54,7 @@ from bidi import get_display
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles import finders from django.contrib.staticfiles import finders
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db.models import Exists, Max, Min, OuterRef from django.db.models import Max, Min
from django.db.models.fields.files import FieldFile from django.db.models.fields.files import FieldFile
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.deconstruct import deconstructible from django.utils.deconstruct import deconstructible
@@ -76,7 +76,7 @@ from reportlab.pdfgen.canvas import Canvas
from reportlab.platypus import Paragraph from reportlab.platypus import Paragraph
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import Checkin, Event, Order, OrderPosition, Question from pretix.base.models import Event, Order, OrderPosition, Question
from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.base.signals import layout_image_variables, layout_text_variables from pretix.base.signals import layout_image_variables, layout_text_variables
from pretix.base.templatetags.money import money_filter from pretix.base.templatetags.money import money_filter
@@ -379,13 +379,6 @@ DEFAULT_VARIABLES = OrderedDict((
str(p) for p in generate_compressed_addon_list(op, order, ev) str(p) for p in generate_compressed_addon_list(op, order, ev)
]) ])
}), }),
("checked_in_addons", {
"label": _("List of Checked-In Add-Ons"),
"editor_sample": _("Add-on 1\n2x Add-on 2"),
"evaluate": lambda op, order, ev: "\n".join([
str(p) for p in generate_compressed_addon_list(op, order, ev, only_checked_in=True)
])
}),
("organizer", { ("organizer", {
"label": _("Organizer name"), "label": _("Organizer name"),
"editor_sample": _("Event organizer company"), "editor_sample": _("Event organizer company"),
@@ -498,9 +491,9 @@ DEFAULT_VARIABLES = OrderedDict((
) if op.valid_until else "" ) if op.valid_until else ""
}), }),
("program_times", { ("program_times", {
"label": _("Program times"), "label": _("Program times: date and time"),
"editor_sample": _( "editor_sample": _(
"2017-05-31 10:00 12:00, Room 1\n2017-05-31 14:00 16:00, Room 2\n2017-05-31 14:00 2017-06-01 14:00, Building A"), "2017-05-31 10:00 12:00\n2017-05-31 14:00 16:00\n2017-05-31 14:00 2017-06-01 14:00"),
"evaluate": lambda op, order, ev: get_program_times(op, ev) "evaluate": lambda op, order, ev: get_program_times(op, ev)
}), }),
("medium_identifier", { ("medium_identifier", {
@@ -748,31 +741,21 @@ def get_seat(op: OrderPosition):
def get_program_times(op: OrderPosition, ev: Event): def get_program_times(op: OrderPosition, ev: Event):
ptstr = [] return '\n'.join([
for pt in op.item.program_times.all(): datetimerange(
ptstr.append([ pt.start.astimezone(ev.timezone),
datetimerange( pt.end.astimezone(ev.timezone),
pt.start.astimezone(ev.timezone), as_html=False
pt.end.astimezone(ev.timezone), ) for pt in op.item.program_times.all()
as_html=False ])
),
(', ' + ', '.join(
l.strip() for l in str(pt.location).splitlines() if l.strip())
) if str(pt.location).strip() else ''
])
return '\n'.join(''.join(l) for l in ptstr)
def generate_compressed_addon_list(op, order, event, only_checked_in=False): def generate_compressed_addon_list(op, order, event):
itemcount = defaultdict(int) itemcount = defaultdict(int)
addon_qs = ( addons = [p for p in (
op.addons.all() if 'addons' in getattr(op, '_prefetched_objects_cache', {}) op.addons.all() if 'addons' in getattr(op, '_prefetched_objects_cache', {})
else op.addons.select_related('item', 'variation') else op.addons.select_related('item', 'variation')
) ) if not p.canceled]
if only_checked_in:
addon_qs = addon_qs.filter(Exists(Checkin.objects.filter(position=OuterRef('pk'))), canceled=False)
addons = [p for p in addon_qs if not p.canceled]
for pos in addons: for pos in addons:
itemcount[pos.item, pos.variation] += 1 itemcount[pos.item, pos.variation] += 1
@@ -929,7 +912,7 @@ class Renderer:
# We do not use str.format like in emails so we (a) can evaluate lazily and (b) can re-implement this # We do not use str.format like in emails so we (a) can evaluate lazily and (b) can re-implement this
# 1:1 on other platforms that render PDFs through our API (libpretixprint) # 1:1 on other platforms that render PDFs through our API (libpretixprint)
return re.sub(r'\{([-a-zA-Z0-9:_]+)\}', replace, text) return re.sub(r'\{([a-zA-Z0-9:_]+)\}', replace, text)
elif o['content'].startswith('itemmeta:'): elif o['content'].startswith('itemmeta:'):
if op.variation_id: if op.variation_id:
-28
View File
@@ -38,7 +38,6 @@ SOURCE_NAMES = {
None: _('European Central Bank'), # backwards-compatibility None: _('European Central Bank'), # backwards-compatibility
'eu:ecb:eurofxref-daily': _('European Central Bank'), 'eu:ecb:eurofxref-daily': _('European Central Bank'),
'cz:cnb:rate-fixing-daily': _('Czech National Bank'), 'cz:cnb:rate-fixing-daily': _('Czech National Bank'),
'pl:nbp:table-a': _('National Bank of Poland'),
} }
@@ -50,7 +49,6 @@ def fetch_rates(sender, **kwargs):
source_tasks = { source_tasks = {
'eu:ecb:eurofxref-daily': fetch_ecb_rates, 'eu:ecb:eurofxref-daily': fetch_ecb_rates,
'cz:cnb:rate-fixing-daily': fetch_cnb_cz_rates, 'cz:cnb:rate-fixing-daily': fetch_cnb_cz_rates,
'pl:nbp:table-a': fetch_nbp_pl_rates,
} }
for source_name, task in source_tasks.items(): for source_name, task in source_tasks.items():
@@ -146,29 +144,3 @@ def fetch_cnb_cz_rates():
rate=rate, rate=rate,
) )
) )
@app.task()
def fetch_nbp_pl_rates():
"""
Fetches currency rates from the Polish National Bank.
"""
r = requests.get("https://api.nbp.pl/api/exchangerates/tables/A/", headers={
"Accept": "application/json",
})
r.raise_for_status()
data = r.json()[0]
source_date = datetime.strptime(data["effectiveDate"], "%Y-%m-%d").date()
for r in data["rates"]:
rate = Decimal(r["mid"]).quantize(Decimal('0.000001'))
ExchangeRate.objects.update_or_create(
source='pl:nbp:table-a',
source_currency=r["code"],
other_currency='PLN',
defaults=dict(
source_date=source_date,
rate=rate,
)
)
+3 -19
View File
@@ -40,7 +40,6 @@ from pretix.base.models import (
CachedFile, Device, Event, Organizer, ScheduledEventExport, TeamAPIToken, CachedFile, Device, Event, Organizer, ScheduledEventExport, TeamAPIToken,
User, cachedfile_name, User, cachedfile_name,
) )
from pretix.base.models.auth import UserWithStaffSession
from pretix.base.models.exports import ScheduledOrganizerExport from pretix.base.models.exports import ScheduledOrganizerExport
from pretix.base.services.mail import mail from pretix.base.services.mail import mail
from pretix.base.services.tasks import ( from pretix.base.services.tasks import (
@@ -212,12 +211,7 @@ def init_event_exporters(event, user=None, token=None, device=None, request=None
if not perm_holder.has_event_permission(event.organizer, event, permission_name, request) and not staff_session: if not perm_holder.has_event_permission(event.organizer, event, permission_name, request) and not staff_session:
continue continue
exporter: BaseExporter = response( exporter: BaseExporter = response(event=event, organizer=event.organizer, **kwargs)
event=event,
organizer=event.organizer,
permission_holder=token or device or (UserWithStaffSession(user) if staff_session else user),
**kwargs
)
if not exporter.available_for_user(user if user and user.is_authenticated else None): if not exporter.available_for_user(user if user and user.is_authenticated else None):
continue continue
@@ -249,12 +243,7 @@ def init_organizer_exporters(
continue continue
if issubclass(response, OrganizerLevelExportMixin): if issubclass(response, OrganizerLevelExportMixin):
exporter: BaseExporter = response( exporter: BaseExporter = response(event=Event.objects.none(), organizer=organizer, **kwargs)
event=Event.objects.none(),
organizer=organizer,
permission_holder=token or device or (UserWithStaffSession(user) if staff_session else user),
**kwargs,
)
try: try:
if not perm_holder.has_organizer_permission(organizer, response.get_required_organizer_permission(), request) and not staff_session: if not perm_holder.has_organizer_permission(organizer, response.get_required_organizer_permission(), request) and not staff_session:
@@ -306,12 +295,7 @@ def init_organizer_exporters(
if not _has_permission_on_any_team_cache[permission_name] and not staff_session: if not _has_permission_on_any_team_cache[permission_name] and not staff_session:
continue continue
exporter: BaseExporter = response( exporter: BaseExporter = response(event=_event_list_cache[permission_name], organizer=organizer, **kwargs)
event=_event_list_cache[permission_name],
organizer=organizer,
permission_holder=token or device or (UserWithStaffSession(user) if staff_session else user),
**kwargs,
)
if not exporter.available_for_user(user if user and user.is_authenticated else None): if not exporter.available_for_user(user if user and user.is_authenticated else None):
continue continue
+1 -15
View File
@@ -58,7 +58,6 @@ from pretix.base.invoicing.transmission import (
from pretix.base.models import ( from pretix.base.models import (
ExchangeRate, Invoice, InvoiceAddress, InvoiceLine, Order, OrderFee, ExchangeRate, Invoice, InvoiceAddress, InvoiceLine, Order, OrderFee,
) )
from pretix.base.models.orders import OrderPayment
from pretix.base.models.tax import EU_CURRENCIES from pretix.base.models.tax import EU_CURRENCIES
from pretix.base.services.tasks import ( from pretix.base.services.tasks import (
TransactionAwareProfiledEventTask, TransactionAwareTask, TransactionAwareProfiledEventTask, TransactionAwareTask,
@@ -103,7 +102,7 @@ def build_invoice(invoice: Invoice) -> Invoice:
introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString) introductory = invoice.event.settings.get('invoice_introductory_text', as_type=LazyI18nString)
additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString) additional = invoice.event.settings.get('invoice_additional_text', as_type=LazyI18nString)
footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString) footer = invoice.event.settings.get('invoice_footer_text', as_type=LazyI18nString)
if lp and lp.payment_provider and lp.state not in (OrderPayment.PAYMENT_STATE_FAILED, OrderPayment.PAYMENT_STATE_CANCELED): if lp and lp.payment_provider:
if 'payment' in inspect.signature(lp.payment_provider.render_invoice_text).parameters: if 'payment' in inspect.signature(lp.payment_provider.render_invoice_text).parameters:
payment = str(lp.payment_provider.render_invoice_text(invoice.order, lp)) payment = str(lp.payment_provider.render_invoice_text(invoice.order, lp))
else: else:
@@ -205,19 +204,6 @@ def build_invoice(invoice: Invoice) -> Invoice:
invoice.foreign_currency_rate = rate.rate.quantize(Decimal('0.0001'), ROUND_HALF_UP) invoice.foreign_currency_rate = rate.rate.quantize(Decimal('0.0001'), ROUND_HALF_UP)
invoice.foreign_currency_rate_date = rate.source_date invoice.foreign_currency_rate_date = rate.source_date
invoice.foreign_currency_source = 'cz:cnb:rate-fixing-daily' invoice.foreign_currency_source = 'cz:cnb:rate-fixing-daily'
elif invoice.event.settings.invoice_eu_currencies == 'PLN' and invoice.event.currency != 'PLN':
invoice.foreign_currency_display = 'PLN'
if settings.FETCH_ECB_RATES:
rate = ExchangeRate.objects.filter(
source='pl:nbp:table-a',
source_currency=invoice.event.currency,
other_currency=invoice.foreign_currency_display,
source_date__gt=now().date() - timedelta(days=7)
).first()
if rate:
invoice.foreign_currency_rate = rate.rate.quantize(Decimal('0.0001'), ROUND_HALF_UP)
invoice.foreign_currency_rate_date = rate.source_date
invoice.foreign_currency_source = 'pl:nbp:table-a'
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
ia = None ia = None
+2 -3
View File
@@ -727,6 +727,8 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti
_check_date(event, time_machine_now_dt) _check_date(event, time_machine_now_dt)
products_seen = Counter() products_seen = Counter()
q_avail = Counter()
v_avail = Counter()
v_usages = Counter() v_usages = Counter()
v_budget = {} v_budget = {}
deleted_positions = set() deleted_positions = set()
@@ -791,9 +793,6 @@ def _check_positions(event: Event, now_dt: datetime, time_machine_now_dt: dateti
shared_lock_objects=[event] shared_lock_objects=[event]
) )
q_avail = Counter()
v_avail = Counter()
# Check maximum order size # Check maximum order size
limit = min(int(event.settings.max_items_per_order), settings.PRETIX_MAX_ORDER_SIZE) limit = min(int(event.settings.max_items_per_order), settings.PRETIX_MAX_ORDER_SIZE)
if sum(1 for cp in sorted_positions if not cp.addon_to) > limit: if sum(1 for cp in sorted_positions if not cp.addon_to) > limit:
-2
View File
@@ -574,7 +574,6 @@ DEFAULTS = {
('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU ' ('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU '
'country that uses a different currency.')), 'country that uses a different currency.')),
('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')), ('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')),
('PLN', _('Based on National Bank of Poland daily rates, whenever the invoice amount is not in PLN.')),
), ),
), ),
'serializer_kwargs': dict( 'serializer_kwargs': dict(
@@ -583,7 +582,6 @@ DEFAULTS = {
('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU ' ('True', _('Based on European Central Bank daily rates, whenever the invoice recipient is in an EU '
'country that uses a different currency.')), 'country that uses a different currency.')),
('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')), ('CZK', _('Based on Czech National Bank daily rates, whenever the invoice amount is not in CZK.')),
('PLN', _('Based on National Bank of Poland daily rates, whenever the invoice amount is not in PLN.')),
), ),
), ),
}, },
-4
View File
@@ -20,7 +20,6 @@
# <https://www.gnu.org/licenses/>. # <https://www.gnu.org/licenses/>.
# #
import logging import logging
import re
from collections import defaultdict from collections import defaultdict
from datetime import timedelta from datetime import timedelta
from importlib import import_module from importlib import import_module
@@ -53,7 +52,6 @@ from pretix.celery_app import app
from pretix.helpers.http import redirect_to_url from pretix.helpers.http import redirect_to_url
logger = logging.getLogger('pretix.base.tasks') logger = logging.getLogger('pretix.base.tasks')
RE_ASYNC_ID = re.compile(r"^[a-zA-Z0-9\-]+$")
class AsyncMixin: class AsyncMixin:
@@ -135,8 +133,6 @@ class AsyncMixin:
def get_result(self, request): def get_result(self, request):
if not request.GET.get('async_id'): if not request.GET.get('async_id'):
raise BadRequest("No async_id given") raise BadRequest("No async_id given")
if not RE_ASYNC_ID.match(request.GET.get('async_id')):
raise BadRequest("Invalid async_id given")
res = AsyncResult(request.GET.get('async_id')) res = AsyncResult(request.GET.get('async_id'))
if 'ajax' in self.request.GET: if 'ajax' in self.request.GET:
return JsonResponse(self._return_ajax_result(res, timeout=0.25)) return JsonResponse(self._return_ajax_result(res, timeout=0.25))
+1 -6
View File
@@ -574,7 +574,7 @@ class ItemCreateForm(I18nModelForm):
instance.bundles.create(bundled_item=b.bundled_item, bundled_variation=b.bundled_variation, instance.bundles.create(bundled_item=b.bundled_item, bundled_variation=b.bundled_variation,
count=b.count, designated_price=b.designated_price) count=b.count, designated_price=b.designated_price)
for pt in self.cleaned_data['copy_from'].program_times.all(): for pt in self.cleaned_data['copy_from'].program_times.all():
instance.program_times.create(start=pt.start, end=pt.end, location=pt.location) instance.program_times.create(start=pt.start, end=pt.end)
item_copy_data.send(sender=self.event, source=self.cleaned_data['copy_from'], target=instance) item_copy_data.send(sender=self.event, source=self.cleaned_data['copy_from'], target=instance)
@@ -1354,10 +1354,6 @@ class ItemProgramTimeForm(I18nModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['end'].widget.attrs['data-date-after'] = '#id_{prefix}-start_0'.format(prefix=self.prefix) self.fields['end'].widget.attrs['data-date-after'] = '#id_{prefix}-start_0'.format(prefix=self.prefix)
self.fields['location'].widget.attrs['rows'] = '3'
self.fields['location'].widget.attrs['placeholder'] = _(
'Sample Conference Center, Heidelberg, Germany'
)
class Meta: class Meta:
model = ItemProgramTime model = ItemProgramTime
@@ -1365,7 +1361,6 @@ class ItemProgramTimeForm(I18nModelForm):
fields = [ fields = [
'start', 'start',
'end', 'end',
'location'
] ]
field_classes = { field_classes = {
'start': forms.SplitDateTimeField, 'start': forms.SplitDateTimeField,
+1 -1
View File
@@ -436,7 +436,7 @@ class OrderPositionAddForm(forms.Form):
d['used_membership'] = [m for m in self.memberships if str(m.pk) == d['used_membership']][0] d['used_membership'] = [m for m in self.memberships if str(m.pk) == d['used_membership']][0]
else: else:
d['used_membership'] = None d['used_membership'] = None
if d.get("count", 1) > 1 and d.get("seat"): if d.get("count", 1) and d.get("seat"):
raise ValidationError({ raise ValidationError({
"seat": _("You can not choose a seat when adding multiple products at once.") "seat": _("You can not choose a seat when adding multiple products at once.")
}) })
+1 -11
View File
@@ -28,7 +28,7 @@ from django.forms import formset_factory
from django.forms.utils import ErrorDict from django.forms.utils import ErrorDict
from django.urls import reverse from django.urls import reverse
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _, pgettext_lazy from django.utils.translation import gettext_lazy as _
from i18nfield.forms import I18nInlineFormSet from i18nfield.forms import I18nInlineFormSet
from pretix.base.forms import I18nModelForm from pretix.base.forms import I18nModelForm
@@ -102,16 +102,6 @@ class SubEventBulkForm(SubEventForm):
required=False, required=False,
limit_choices=('date_from', 'date_to'), limit_choices=('date_from', 'date_to'),
) )
skip_if_overlap = forms.BooleanField(
label=pgettext_lazy('subevent', 'Skip dates that overlap with any existing date'),
help_text=pgettext_lazy(
'subevent',
'This can be useful if all your dates happen in the same location and no repeated dates should '
'be created in conflict with existing special events. This respects even inactive dates and works best if '
'all dates have both a start and end time.'
),
required=False,
)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.event = kwargs['event'] self.event = kwargs['event']
@@ -34,7 +34,6 @@
{% bootstrap_form_errors form %} {% bootstrap_form_errors form %}
{% bootstrap_field form.start layout="control" %} {% bootstrap_field form.start layout="control" %}
{% bootstrap_field form.end layout="control" %} {% bootstrap_field form.end layout="control" %}
{% bootstrap_field form.location layout="control" %}
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
@@ -60,7 +59,6 @@
<div class="panel-body form-horizontal"> <div class="panel-body form-horizontal">
{% bootstrap_field formset.empty_form.start layout="control" %} {% bootstrap_field formset.empty_form.start layout="control" %}
{% bootstrap_field formset.empty_form.end layout="control" %} {% bootstrap_field formset.empty_form.end layout="control" %}
{% bootstrap_field formset.empty_form.location layout="control" %}
</div> </div>
</div> </div>
{% endescapescript %} {% endescapescript %}
@@ -108,7 +108,7 @@
</a> </a>
</p> </p>
{% endif %} {% endif %}
<form action="#will-be-overridden" method="post"> <form action="{% url "control:organizer.device.bulk_edit" organizer=request.organizer.slug %}" method="post">
{% csrf_token %} {% csrf_token %}
{% for field in filter_form %} {% for field in filter_form %}
{{ field.as_hidden }} {{ field.as_hidden }}
@@ -379,8 +379,6 @@
<i class="fa fa-calendar"></i> {% trans "Add many time slots" %}</button> <i class="fa fa-calendar"></i> {% trans "Add many time slots" %}</button>
</p> </p>
</div> </div>
<hr />
{% bootstrap_field form.skip_if_overlap layout="control" horizontal_label_class='sr-only' horizontal_field_class='col-md-12' %}
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>{% trans "General information" %}</legend> <legend>{% trans "General information" %}</legend>
+13 -16
View File
@@ -234,21 +234,13 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
self.request.event.log_action('pretix.event.footerlinks.changed', user=self.request.user, data={ self.request.event.log_action('pretix.event.footerlinks.changed', user=self.request.user, data={
'data': self.footer_links_formset.cleaned_data 'data': self.footer_links_formset.cleaned_data
}) })
if form.has_changed():
change_data = { self.request.event.log_action('pretix.event.changed', user=self.request.user, data={
k: (form.cleaned_data.get(k).name k: (form.cleaned_data.get(k).name
if isinstance(form.cleaned_data.get(k), File) if isinstance(form.cleaned_data.get(k), File)
else form.cleaned_data.get(k)) else form.cleaned_data.get(k))
for k in form.changed_data for k in form.changed_data
} })
meta_changed = {}
for f in self.meta_forms:
if f.has_changed():
meta_changed[f.property.name] = f.cleaned_data["value"]
if meta_changed:
change_data['meta_data'] = meta_changed
if change_data:
self.request.event.log_action('pretix.event.changed', user=self.request.user, data=change_data)
tickets.invalidate_cache.apply_async(kwargs={'event': self.request.event.pk}) tickets.invalidate_cache.apply_async(kwargs={'event': self.request.event.pk})
messages.success(self.request, _('Your changes have been saved.')) messages.success(self.request, _('Your changes have been saved.'))
@@ -771,7 +763,12 @@ class InvoicePreview(EventPermissionRequiredMixin, View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
fname, ftype, fcontent = build_preview_invoice_pdf(request.event) fname, ftype, fcontent = build_preview_invoice_pdf(request.event)
resp = HttpResponse(fcontent, content_type=ftype) resp = HttpResponse(fcontent, content_type=ftype)
resp['Content-Disposition'] = 'inline; filename="{}"'.format(fname) if settings.DEBUG:
# attachment is more secure as we're dealing with user-generated stuff here, but inline is much more convenient during debugging
resp['Content-Disposition'] = 'inline; filename="{}"'.format(fname)
resp._csp_ignore = True
else:
resp['Content-Disposition'] = 'attachment; filename="{}"'.format(fname)
return resp return resp
@@ -300,4 +300,5 @@ class SysReportView(AdministratorPermissionRequiredMixin, TemplateView):
resp = HttpResponse(data) resp = HttpResponse(data)
resp['Content-Type'] = mime resp['Content-Type'] = mime
resp['Content-Disposition'] = 'inline; filename="{}"'.format(name) resp['Content-Disposition'] = 'inline; filename="{}"'.format(name)
resp._csp_ignore = True
return resp return resp
+6 -2
View File
@@ -1447,8 +1447,12 @@ class ItemUpdateGeneral(ItemDetailMixin, EventPermissionRequiredMixin, MetaDataE
meta_changed = {} meta_changed = {}
for f in self.meta_forms: for f in self.meta_forms:
if f.has_changed(): meta_changed.update({
meta_changed[f.property.name] = f.cleaned_data["value"] k: (f.cleaned_data.get(k).name
if isinstance(f.cleaned_data.get(k), File)
else f.cleaned_data.get(k))
for k in f.changed_data
})
if meta_changed: if meta_changed:
change_data['meta_data'] = meta_changed change_data['meta_data'] = meta_changed
+31 -18
View File
@@ -79,9 +79,9 @@ from pretix.base.email import get_email_context
from pretix.base.exporter import MultiSheetListExporter from pretix.base.exporter import MultiSheetListExporter
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
CachedFile, CachedTicket, Checkin, Invoice, InvoiceAddress, Item, CachedCombinedTicket, CachedFile, CachedTicket, Checkin, Invoice,
ItemVariation, LogEntry, Order, QuestionAnswer, Quota, InvoiceAddress, Item, ItemVariation, LogEntry, Order, QuestionAnswer,
ScheduledEventExport, generate_secret, Quota, ScheduledEventExport, generate_secret,
) )
from pretix.base.models.orders import ( from pretix.base.models.orders import (
CancellationRequest, OrderFee, OrderPayment, OrderPosition, OrderRefund, CancellationRequest, OrderFee, OrderPayment, OrderPosition, OrderRefund,
@@ -710,21 +710,34 @@ class OrderDownload(AsyncAction, OrderView):
resp = HttpResponseRedirect(value.file.file.read()) resp = HttpResponseRedirect(value.file.file.read())
return resp return resp
else: else:
return FileResponse( resp = FileResponse(value.file.file, content_type=value.type)
value.file.file, resp['Content-Disposition'] = 'attachment; filename="{}-{}-{}-{}{}"'.format(
filename='{}-{}-{}-{}{}'.format( self.request.event.slug.upper(), self.order.code, self.order_position.positionid,
self.request.event.slug.upper(), self.order.code, self.order_position.positionid, self.output.identifier, value.extension
self.output.identifier, value.extension
),
content_type=value.type
) )
return resp
elif isinstance(value, CachedCombinedTicket):
if value.type == 'text/uri-list':
resp = HttpResponseRedirect(value.file.file.read())
return resp
else:
resp = FileResponse(value.file.file, content_type=value.type)
resp['Content-Disposition'] = 'attachment; filename="{}-{}-{}{}"'.format(
self.request.event.slug.upper(), self.order.code, self.output.identifier, value.extension
)
return resp
else: else:
return redirect(self.get_self_url()) return redirect(self.get_self_url())
def get_last_ct(self): def get_last_ct(self):
ct = CachedTicket.objects.filter( if 'position' in self.kwargs:
order_position=self.order_position, provider=self.output.identifier, file__isnull=False ct = CachedTicket.objects.filter(
).last() order_position=self.order_position, provider=self.output.identifier, file__isnull=False
).last()
else:
ct = CachedCombinedTicket.objects.filter(
order=self.order, provider=self.output.identifier, file__isnull=False
).last()
if not ct or not ct.file: if not ct or not ct.file:
return None return None
return ct return ct
@@ -1818,15 +1831,15 @@ class InvoiceDownload(EventPermissionRequiredMixin, View):
return redirect(self.get_order_url()) return redirect(self.get_order_url())
try: try:
return FileResponse( resp = FileResponse(self.invoice.file.file, content_type='application/pdf')
self.invoice.file.file,
filename='{}.pdf'.format(re.sub("[^a-zA-Z0-9-_.]+", "_", self.invoice.number)),
content_type='application/pdf'
)
except FileNotFoundError: except FileNotFoundError:
invoice_pdf_task.apply(args=(self.invoice.pk,)) invoice_pdf_task.apply(args=(self.invoice.pk,))
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
resp['Content-Disposition'] = 'inline; filename="{}.pdf"'.format(re.sub("[^a-zA-Z0-9-_.]+", "_", self.invoice.number))
resp._csp_ignore = True # Some browser's PDF readers do not work with CSP
return resp
class OrderExtend(OrderView): class OrderExtend(OrderView):
permission = 'event.orders:write' permission = 'event.orders:write'
+1 -1
View File
@@ -1322,7 +1322,7 @@ class DeviceUpdateView(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixi
def form_valid(self, form): def form_valid(self, form):
if form.has_changed(): if form.has_changed():
self.object.log_action('pretix.device.changed', user=self.request.user, data={ self.object.log_action('pretix.device.changed', user=self.request.user, data={
k: form.cleaned_data[k] if k != 'limit_events' else [e.id for e in form.cleaned_data[k]] k: getattr(self.object, k) if k != 'limit_events' else [e.id for e in getattr(self.object, k).all()]
for k in form.changed_data for k in form.changed_data
}) })
+8 -2
View File
@@ -263,7 +263,12 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
resp = HttpResponse(data, content_type=mimet) resp = HttpResponse(data, content_type=mimet)
ftype = fname.split(".")[-1] ftype = fname.split(".")[-1]
resp['Content-Disposition'] = 'inline; filename="ticket-preview.{}"'.format(ftype) if settings.DEBUG:
# attachment is more secure as we're dealing with user-generated stuff here, but inline is much more convenient during debugging
resp['Content-Disposition'] = 'inline; filename="ticket-preview.{}"'.format(ftype)
resp._csp_ignore = True
else:
resp['Content-Disposition'] = 'attachment; filename="ticket-preview.{}"'.format(ftype)
return resp return resp
elif "data" in request.POST: elif "data" in request.POST:
if cf: if cf:
@@ -304,5 +309,6 @@ class FontsCSSView(TemplateView):
class PdfView(TemplateView): class PdfView(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
cf = get_object_or_404(CachedFile, id=kwargs.get("filename"), filename="background_preview.pdf") cf = get_object_or_404(CachedFile, id=kwargs.get("filename"), filename="background_preview.pdf")
resp = FileResponse(cf.file, filename=cf.filename, content_type='application/pdf') resp = FileResponse(cf.file, content_type='application/pdf')
resp['Content-Disposition'] = 'attachment; filename="{}"'.format(cf.filename)
return resp return resp
+12 -60
View File
@@ -540,31 +540,20 @@ class SubEventUpdate(EventPermissionRequiredMixin, SubEventEditorMixin, UpdateVi
# TODO: LogEntry? # TODO: LogEntry?
messages.success(self.request, _('Your changes have been saved.')) messages.success(self.request, _('Your changes have been saved.'))
if form.has_changed() or any(f.has_changed() for f in self.plugin_forms):
change_data = { data = {
k: (form.cleaned_data.get(k).name k: form.cleaned_data.get(k) for k in form.changed_data
if isinstance(form.cleaned_data.get(k), File) }
else form.cleaned_data.get(k)) for f in self.plugin_forms:
for k in form.changed_data data.update({
} k: (f.cleaned_data.get(k).name
meta_changed = {} if isinstance(f.cleaned_data.get(k), File)
for f in self.meta_forms: else f.cleaned_data.get(k))
if f.has_changed(): for k in f.changed_data
meta_changed[f.property.name] = f.cleaned_data["value"] })
if meta_changed:
change_data['meta_data'] = meta_changed
for f in self.plugin_forms:
change_data.update({
k: (f.cleaned_data.get(k).name
if isinstance(f.cleaned_data.get(k), File)
else f.cleaned_data.get(k))
for k in f.changed_data
})
if change_data:
self.object.log_action( self.object.log_action(
'pretix.subevent.changed', user=self.request.user, data=change_data 'pretix.subevent.changed', user=self.request.user, data=data
) )
for f in self.plugin_forms: for f in self.plugin_forms:
f.subevent = self.object f.subevent = self.object
f.save() f.save()
@@ -639,14 +628,6 @@ class SubEventCreate(SubEventEditorMixin, EventPermissionRequiredMixin, CreateVi
else f.cleaned_data.get(k)) else f.cleaned_data.get(k))
for k in f.cleaned_data for k in f.cleaned_data
}) })
meta_changed = {}
for f in self.meta_forms:
if f.has_changed():
meta_changed[f.property.name] = f.cleaned_data["value"]
if meta_changed:
data['meta_data'] = meta_changed
form.instance.log_action('pretix.subevent.added', data=dict(data), user=self.request.user) form.instance.log_action('pretix.subevent.added', data=dict(data), user=self.request.user)
self.save_formset(form.instance) self.save_formset(form.instance)
@@ -936,35 +917,6 @@ class SubEventBulkCreate(SubEventEditorMixin, EventPermissionRequiredMixin, Asyn
if len(subevents) > 100_000: if len(subevents) > 100_000:
raise ValidationError(_('Please do not create more than 100.000 dates at once.')) raise ValidationError(_('Please do not create more than 100.000 dates at once.'))
if form.cleaned_data.get("skip_if_overlap") and subevents:
def overlaps(a_from, a_to, b_from, b_to):
if a_from == b_from:
return True
if a_from > b_from:
# a starts after b
# check if it starts before b ends
return b_to and a_from < b_to
# a starts before b
# check if it ends before b starts
return a_to and a_to > b_from
date_min = min(se.date_from for se in subevents)
date_max = max(se.date_to or se.date_from for se in subevents)
dates_existing = list(self.request.event.subevents.annotate(
date_fromto=Coalesce('date_to', 'date_from'),
).filter(
date_from__lte=date_max,
date_fromto__gte=date_min,
).values('date_from', 'date_to'))
subevents = [
se for se in subevents if not any(
overlaps(se.date_from, se.date_to, other['date_from'], other['date_to'])
for other in dates_existing
)
]
if not subevents:
raise ValidationError(_('All dates would be skipped because they conflict with existing dates.'))
for i, se in enumerate(subevents): for i, se in enumerate(subevents):
se.save(clear_cache=False) se.save(clear_cache=False)
if i % 100 == 0: if i % 100 == 0:
+3 -3
View File
@@ -316,7 +316,7 @@ def nav_context_list(request):
page = 1 page = 1
qs_events = request.user.get_events_with_any_permission(request).filter( qs_events = request.user.get_events_with_any_permission(request).filter(
Q(name__icontains=i18ncomp(query)) | Q(slug__icontains=query) | Q(domain__domainname__iexact=query) Q(name__icontains=i18ncomp(query)) | Q(slug__icontains=query)
).annotate( ).annotate(
min_from=Min('subevents__date_from'), min_from=Min('subevents__date_from'),
max_from=Max('subevents__date_from'), max_from=Max('subevents__date_from'),
@@ -331,7 +331,7 @@ def nav_context_list(request):
else: else:
qs_orga = Organizer.objects.filter(pk__in=request.user.teams.values_list('organizer', flat=True)) qs_orga = Organizer.objects.filter(pk__in=request.user.teams.values_list('organizer', flat=True))
if query: if query:
qs_orga = qs_orga.filter(Q(name__icontains=query) | Q(slug__icontains=query) | Q(domains__domainname__iexact=query)) qs_orga = qs_orga.filter(Q(name__icontains=query) | Q(slug__icontains=query))
qs_orga = qs_orga.annotate( qs_orga = qs_orga.annotate(
n_events=Count("events") n_events=Count("events")
).order_by("-n_events") ).order_by("-n_events")
@@ -619,7 +619,7 @@ def checkinlist_select2(request, **kwargs):
qs = request.event.checkin_lists.select_related('subevent').filter( qs = request.event.checkin_lists.select_related('subevent').filter(
qf qf
).order_by('subevent__date_from', 'name', 'pk') ).order_by('name')
total = qs.count() total = qs.count()
pagesize = 20 pagesize = 20
-132
View File
@@ -19,26 +19,12 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see # You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>. # <https://www.gnu.org/licenses/>.
# #
import ipaddress
import socket
import sys
import types import types
from datetime import datetime from datetime import datetime
from http import cookies from http import cookies
from django.conf import settings
from PIL import Image from PIL import Image
from requests.adapters import HTTPAdapter from requests.adapters import HTTPAdapter
from urllib3.connection import HTTPConnection, HTTPSConnection
from urllib3.connectionpool import HTTPConnectionPool, HTTPSConnectionPool
from urllib3.exceptions import (
ConnectTimeoutError, HTTPError, LocationParseError, NameResolutionError,
NewConnectionError,
)
from urllib3.util.connection import (
_TYPE_SOCKET_OPTIONS, _set_socket_options, allowed_gai_family,
)
from urllib3.util.timeout import _DEFAULT_TIMEOUT
def monkeypatch_vobject_performance(): def monkeypatch_vobject_performance():
@@ -103,123 +89,6 @@ def monkeypatch_requests_timeout():
HTTPAdapter.send = httpadapter_send HTTPAdapter.send = httpadapter_send
def monkeypatch_urllib3_ssrf_protection():
"""
pretix allows HTTP requests to untrusted URLs, e.g. through webhooks or external API URLs. This is dangerous since
it can allow access to private networks that should not be reachable by users ("server-side request forgery", SSRF).
Validating URLs at submission is not sufficient, since with DNS rebinding an attacker can make a domain name pass
validation and then resolve to a private IP address on actual execution. Unfortunately, there seems no clean solution
to this in Python land, so we monkeypatch urllib3's connection management to check the IP address to be external
*after* the DNS resolution.
This does not work when a global http(s) proxy is used, but in that scenario the proxy can perform the validation.
"""
if getattr(settings, "ALLOW_HTTP_TO_PRIVATE_NETWORKS", False):
# Settings are not supposed to change during runtime, so we can optimize performance and complexity by skipping
# this if not needed.
return
def create_connection(
address: tuple[str, int],
timeout=_DEFAULT_TIMEOUT,
source_address: tuple[str, int] | None = None,
socket_options: _TYPE_SOCKET_OPTIONS | None = None,
) -> socket.socket:
# This is copied from urllib3.util.connection v2.3.0
host, port = address
if host.startswith("["):
host = host.strip("[]")
err = None
# Using the value from allowed_gai_family() in the context of getaddrinfo lets
# us select whether to work with IPv4 DNS records, IPv6 records, or both.
# The original create_connection function always returns all records.
family = allowed_gai_family()
try:
host.encode("idna")
except UnicodeError:
raise LocationParseError(f"'{host}', label empty or too long") from None
for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
if not getattr(settings, "ALLOW_HTTP_TO_PRIVATE_NETWORKS", False):
ip_addr = ipaddress.ip_address(sa[0])
if ip_addr.is_multicast:
raise HTTPError(f"Request to multicast address {sa[0]} blocked")
if ip_addr.is_loopback or ip_addr.is_link_local:
raise HTTPError(f"Request to local address {sa[0]} blocked")
if ip_addr.is_private:
raise HTTPError(f"Request to private address {sa[0]} blocked")
sock = None
try:
sock = socket.socket(af, socktype, proto)
# If provided, set socket level options before connecting.
_set_socket_options(sock, socket_options)
if timeout is not _DEFAULT_TIMEOUT:
sock.settimeout(timeout)
if source_address:
sock.bind(source_address)
sock.connect(sa)
# Break explicitly a reference cycle
err = None
return sock
except OSError as _:
err = _
if sock is not None:
sock.close()
if err is not None:
try:
raise err
finally:
# Break explicitly a reference cycle
err = None
else:
raise OSError("getaddrinfo returns an empty list")
class ProtectionMixin:
def _new_conn(self) -> socket.socket:
# This is 1:1 the version from urllib3.connection.HTTPConnection._new_conn v2.3.0
# just with a call to our own create_connection
try:
sock = create_connection(
(self._dns_host, self.port),
self.timeout,
source_address=self.source_address,
socket_options=self.socket_options,
)
except socket.gaierror as e:
raise NameResolutionError(self.host, self, e) from e
except socket.timeout as e:
raise ConnectTimeoutError(
self,
f"Connection to {self.host} timed out. (connect timeout={self.timeout})",
) from e
except OSError as e:
raise NewConnectionError(
self, f"Failed to establish a new connection: {e}"
) from e
sys.audit("http.client.connect", self, self.host, self.port)
return sock
class ProtectedHTTPConnection(ProtectionMixin, HTTPConnection):
pass
class ProtectedHTTPSConnection(ProtectionMixin, HTTPSConnection):
pass
HTTPConnectionPool.ConnectionCls = ProtectedHTTPConnection
HTTPSConnectionPool.ConnectionCls = ProtectedHTTPSConnection
def monkeypatch_cookie_morsel(): def monkeypatch_cookie_morsel():
# See https://code.djangoproject.com/ticket/34613 # See https://code.djangoproject.com/ticket/34613
cookies.Morsel._flags.add("partitioned") cookies.Morsel._flags.add("partitioned")
@@ -230,5 +99,4 @@ def monkeypatch_all_at_ready():
monkeypatch_vobject_performance() monkeypatch_vobject_performance()
monkeypatch_pillow_safer() monkeypatch_pillow_safer()
monkeypatch_requests_timeout() monkeypatch_requests_timeout()
monkeypatch_urllib3_ssrf_protection()
monkeypatch_cookie_morsel() monkeypatch_cookie_morsel()
+5 -5
View File
@@ -173,7 +173,6 @@ def create_thumbnail(source, size, formats=None):
# filesystem path, this only works because _open() uses safe_join, which accepts absolute paths if they match the # filesystem path, this only works because _open() uses safe_join, which accepts absolute paths if they match the
# expected base dir. For NanoCDN Files, this works because source.name is set to the storage path. # expected base dir. For NanoCDN Files, this works because source.name is set to the storage path.
source_rb = default_storage.open(source_name, mode='rb') source_rb = default_storage.open(source_name, mode='rb')
source_ext = os.path.splitext(source_name)[1].lower()
image = Image.open(BytesIO(source_rb.read()), formats=formats or settings.PILLOW_FORMATS_QUESTIONS_IMAGE) image = Image.open(BytesIO(source_rb.read()), formats=formats or settings.PILLOW_FORMATS_QUESTIONS_IMAGE)
try: try:
@@ -184,14 +183,11 @@ def create_thumbnail(source, size, formats=None):
frames = [] frames = []
durations = [] durations = []
for f in ImageSequence.Iterator(image): for f in ImageSequence.Iterator(image):
if f.mode in ("P", "PA") and source_ext == '.png':
f = f.convert('RGBA')
if f.mode not in ("1", "L", "RGB", "RGBA"):
f = f.convert('RGB')
durations.append(f.info.get("duration", 1000)) durations.append(f.info.get("duration", 1000))
frames.append(resize_image(f, size)) frames.append(resize_image(f, size))
image_out = frames[0] image_out = frames[0]
save_kwargs = {} save_kwargs = {}
source_ext = os.path.splitext(source_name)[1].lower()
if source_ext == '.jpg' or source_ext == '.jpeg': if source_ext == '.jpg' or source_ext == '.jpeg':
# Yields better file sizes for photos # Yields better file sizes for photos
@@ -215,6 +211,10 @@ def create_thumbnail(source, size, formats=None):
checksum = hashlib.md5(image.tobytes()).hexdigest() checksum = hashlib.md5(image.tobytes()).hexdigest()
name = checksum + '.' + size.replace('^', 'c') + '.' + target_ext name = checksum + '.' + size.replace('^', 'c') + '.' + target_ext
buffer = BytesIO() buffer = BytesIO()
if image_out.mode == "P" and source_ext == '.png':
image_out = image_out.convert('RGBA')
if image_out.mode not in ("1", "L", "RGB", "RGBA"):
image_out = image_out.convert('RGB')
image_out.save(fp=buffer, format=target_ext.upper(), quality=quality, **save_kwargs) image_out.save(fp=buffer, format=target_ext.upper(), quality=quality, **save_kwargs)
imgfile = ContentFile(buffer.getvalue()) imgfile = ContentFile(buffer.getvalue())
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -632,56 +632,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2021-09-15 11:22+0000\n" "PO-Revision-Date: 2021-09-15 11:22+0000\n"
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n" "Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -666,13 +666,13 @@ msgstr "توليد الرسائل …"
msgid "Unknown error." msgid "Unknown error."
msgstr "خطأ غير معروف." msgstr "خطأ غير معروف."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
#, fuzzy #, fuzzy
#| msgid "Your color has great contrast and is very easy to read!" #| msgid "Your color has great contrast and is very easy to read!"
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "اللون يتمتع بتباين كبير وتسهل قراءته!" msgstr "اللون يتمتع بتباين كبير وتسهل قراءته!"
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
#, fuzzy #, fuzzy
#| msgid "Your color has decent contrast and is probably good-enough to read!" #| msgid "Your color has decent contrast and is probably good-enough to read!"
msgid "" msgid ""
@@ -680,46 +680,46 @@ msgid ""
"requirements." "requirements."
msgstr "اللون يحظى بتباين معقول ويمكن أن يكون مناسب للقراءة!" msgstr "اللون يحظى بتباين معقول ويمكن أن يكون مناسب للقراءة!"
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "البحث في الاستفسارات" msgstr "البحث في الاستفسارات"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "الكل" msgstr "الكل"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "لا شيء" msgstr "لا شيء"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "المختارة فقط" msgstr "المختارة فقط"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "قم باستخدم اسم مختلف داخليا" msgstr "قم باستخدم اسم مختلف داخليا"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "اضغط لاغلاق الصفحة" msgstr "اضغط لاغلاق الصفحة"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "لم تقم بحفظ التعديلات!" msgstr "لم تقم بحفظ التعديلات!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -632,56 +632,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2025-10-31 17:00+0000\n" "PO-Revision-Date: 2025-10-31 17:00+0000\n"
"Last-Translator: Núria Masclans <nuriamasclansserrat@gmail.com>\n" "Last-Translator: Núria Masclans <nuriamasclansserrat@gmail.com>\n"
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -644,11 +644,11 @@ msgstr "Generant missatges…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Error desconegut." msgstr "Error desconegut."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "El teu color té molt contrast i garanteix bona accessibilitat." msgstr "El teu color té molt contrast i garanteix bona accessibilitat."
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
@@ -656,7 +656,7 @@ msgstr ""
"El teu color té un contrast acceptable i compleix els requisits mínims " "El teu color té un contrast acceptable i compleix els requisits mínims "
"daccessibilitat." "daccessibilitat."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
@@ -664,40 +664,40 @@ msgstr ""
"El color no té prou contrast amb el blanc i pot afectar a l'accessibilitat " "El color no té prou contrast amb el blanc i pot afectar a l'accessibilitat "
"del lloc web." "del lloc web."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Consulta de cerca" msgstr "Consulta de cerca"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Tots" msgstr "Tots"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Cap" msgstr "Cap"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Només seleccionats" msgstr "Només seleccionats"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "Introdueix un número de pàgina entre 1 i %(max)s." msgstr "Introdueix un número de pàgina entre 1 i %(max)s."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "Número de pàgina no vàlid." msgstr "Número de pàgina no vàlid."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Utilitza un nom diferent internament" msgstr "Utilitza un nom diferent internament"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Prem per tancar" msgstr "Prem per tancar"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Tens canvis sense desar!" msgstr "Tens canvis sense desar!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-01-08 04:00+0000\n" "PO-Revision-Date: 2026-01-08 04:00+0000\n"
"Last-Translator: Jiří Pastrňák <jiri@pastrnak.email>\n" "Last-Translator: Jiří Pastrňák <jiri@pastrnak.email>\n"
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -657,57 +657,57 @@ msgstr "Vytváření zpráv…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Neznámá chyba." msgstr "Neznámá chyba."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "Tato barva má velmi dobrý kontrast a je velmi dobře čitelná." msgstr "Tato barva má velmi dobrý kontrast a je velmi dobře čitelná."
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
"Tato barva má slušný kontrast a pravděpodobně je dostatečně dobře čitelná." "Tato barva má slušný kontrast a pravděpodobně je dostatečně dobře čitelná."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Hledaný výraz" msgstr "Hledaný výraz"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Všechny" msgstr "Všechny"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Žádný" msgstr "Žádný"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Pouze vybrané" msgstr "Pouze vybrané"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Interně používat jiný název" msgstr "Interně používat jiný název"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Kliknutím zavřete" msgstr "Kliknutím zavřete"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Máte neuložené změny!" msgstr "Máte neuložené změny!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -633,56 +633,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-04-22 18:00+0000\n" "PO-Revision-Date: 2024-07-10 15:00+0000\n"
"Last-Translator: Nikolai <nikolai@lengefeldt.de>\n" "Last-Translator: Nikolai <nikolai@lengefeldt.de>\n"
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
"da/>\n" "da/>\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.17\n" "X-Generator: Weblate 5.6.1\n"
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56 #: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62 #: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
@@ -682,56 +682,56 @@ msgstr "Opretter beskeder …"
msgid "Unknown error." msgid "Unknown error."
msgstr "Ukendt fejl." msgstr "Ukendt fejl."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Søgeforespørgsel" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Alle" msgstr "Alle"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Ingen" msgstr "Ingen"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Klik for at lukke" msgstr "Klik for at lukke"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Du har ændringer, der ikke er gemt!" msgstr "Du har ændringer, der ikke er gemt!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-03-17 14:27+0000\n" "PO-Revision-Date: 2026-03-17 14:27+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n" "Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -650,12 +650,12 @@ msgstr "Generiere Nachrichten…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Unbekannter Fehler." msgstr "Unbekannter Fehler."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
"Diese Farbe hat einen sehr guten Kontrast und trägt zur Barrierefreiheit bei!" "Diese Farbe hat einen sehr guten Kontrast und trägt zur Barrierefreiheit bei!"
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
@@ -663,7 +663,7 @@ msgstr ""
"Diese Farbe hat einen ausreichenden Kontrast und genügt den " "Diese Farbe hat einen ausreichenden Kontrast und genügt den "
"Mindestanforderungen der Barrierefreiheit." "Mindestanforderungen der Barrierefreiheit."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
@@ -671,40 +671,40 @@ msgstr ""
"Diese Farbe hat keinen ausreichenden Kontrast zu weiß. Die Barrierefreiheit " "Diese Farbe hat keinen ausreichenden Kontrast zu weiß. Die Barrierefreiheit "
"der Seite ist eingeschränkt." "der Seite ist eingeschränkt."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Suchbegriff" msgstr "Suchbegriff"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Alle" msgstr "Alle"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Keine" msgstr "Keine"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Nur ausgewählte" msgstr "Nur ausgewählte"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein." msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "Ungültige Seitenzahl." msgstr "Ungültige Seitenzahl."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Intern einen anderen Namen verwenden" msgstr "Intern einen anderen Namen verwenden"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Klicken zum Schließen" msgstr "Klicken zum Schließen"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Sie haben ungespeicherte Änderungen!" msgstr "Sie haben ungespeicherte Änderungen!"
-1
View File
@@ -302,7 +302,6 @@ Personalisierung
P.IVA P.IVA
PKCE-Erweiterung PKCE-Erweiterung
Platzhalterzeichen Platzhalterzeichen
PLN
Play Play
Plugin Plugin
Plugins Plugins
File diff suppressed because it is too large Load Diff
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-03-17 14:30+0000\n" "PO-Revision-Date: 2026-03-17 14:30+0000\n"
"Last-Translator: Raphael Michel <michel@rami.io>\n" "Last-Translator: Raphael Michel <michel@rami.io>\n"
"Language-Team: German (informal) <https://translate.pretix.eu/projects/" "Language-Team: German (informal) <https://translate.pretix.eu/projects/"
@@ -650,12 +650,12 @@ msgstr "Generiere Nachrichten…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Unbekannter Fehler." msgstr "Unbekannter Fehler."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
"Diese Farbe hat einen sehr guten Kontrast und trägt zur Barrierefreiheit bei!" "Diese Farbe hat einen sehr guten Kontrast und trägt zur Barrierefreiheit bei!"
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
@@ -663,7 +663,7 @@ msgstr ""
"Diese Farbe hat einen ausreichenden Kontrast und genügt den " "Diese Farbe hat einen ausreichenden Kontrast und genügt den "
"Mindestanforderungen der Barrierefreiheit." "Mindestanforderungen der Barrierefreiheit."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
@@ -671,40 +671,40 @@ msgstr ""
"Diese Farbe hat keinen ausreichenden Kontrast zu weiß. Die Barrierefreiheit " "Diese Farbe hat keinen ausreichenden Kontrast zu weiß. Die Barrierefreiheit "
"der Seite ist eingeschränkt." "der Seite ist eingeschränkt."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Suchbegriff" msgstr "Suchbegriff"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Alle" msgstr "Alle"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Keine" msgstr "Keine"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Nur ausgewählte" msgstr "Nur ausgewählte"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein." msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "Ungültige Seitenzahl." msgstr "Ungültige Seitenzahl."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Intern einen anderen Namen verwenden" msgstr "Intern einen anderen Namen verwenden"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Klicken zum Schließen" msgstr "Klicken zum Schließen"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Du hast ungespeicherte Änderungen!" msgstr "Du hast ungespeicherte Änderungen!"
@@ -302,7 +302,6 @@ Personalisierung
P.IVA P.IVA
PKCE-Erweiterung PKCE-Erweiterung
Platzhalterzeichen Platzhalterzeichen
PLN
Play Play
Plugin Plugin
Plugins Plugins
+1096 -1137
View File
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-30 11:25+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -632,56 +632,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2024-12-22 00:00+0000\n" "PO-Revision-Date: 2024-12-22 00:00+0000\n"
"Last-Translator: Dimitris Tsimpidis <tsimpidisd@gmail.com>\n" "Last-Translator: Dimitris Tsimpidis <tsimpidisd@gmail.com>\n"
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -689,14 +689,14 @@ msgstr "Δημιουργία μηνυμάτων …"
msgid "Unknown error." msgid "Unknown error."
msgstr "Άγνωστο σφάλμα." msgstr "Άγνωστο σφάλμα."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
#, fuzzy #, fuzzy
#| msgid "Your color has great contrast and is very easy to read!" #| msgid "Your color has great contrast and is very easy to read!"
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
"Το χρώμα σας έχει μεγάλη αντίθεση και είναι πολύ εύκολο να το διαβάσετε!" "Το χρώμα σας έχει μεγάλη αντίθεση και είναι πολύ εύκολο να το διαβάσετε!"
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
#, fuzzy #, fuzzy
#| msgid "Your color has decent contrast and is probably good-enough to read!" #| msgid "Your color has decent contrast and is probably good-enough to read!"
msgid "" msgid ""
@@ -706,46 +706,46 @@ msgstr ""
"Το χρώμα σας έχει αξιοπρεπή αντίθεση και είναι ίσως αρκετά καλό για να " "Το χρώμα σας έχει αξιοπρεπή αντίθεση και είναι ίσως αρκετά καλό για να "
"διαβάσετε!" "διαβάσετε!"
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Όλα" msgstr "Όλα"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Κανένας" msgstr "Κανένας"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά" msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Κάντε κλικ για να κλείσετε" msgstr "Κάντε κλικ για να κλείσετε"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -632,56 +632,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-03-30 03:00+0000\n" "PO-Revision-Date: 2026-03-30 03:00+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n" "Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -648,12 +648,12 @@ msgstr "Generando mensajes…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Error desconocido." msgstr "Error desconocido."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
"El color tiene un gran contraste y proporcionará una excelente accesibilidad." "El color tiene un gran contraste y proporcionará una excelente accesibilidad."
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
@@ -661,7 +661,7 @@ msgstr ""
"El color tiene un contraste decente y es suficiente para los requisitos " "El color tiene un contraste decente y es suficiente para los requisitos "
"mínimos de accesibilidad." "mínimos de accesibilidad."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
@@ -669,40 +669,40 @@ msgstr ""
"El color no tiene suficiente contraste con el blanco. La accesibilidad de su " "El color no tiene suficiente contraste con el blanco. La accesibilidad de su "
"sitio se verá afectada." "sitio se verá afectada."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Consulta de búsqueda" msgstr "Consulta de búsqueda"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Todos" msgstr "Todos"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Ninguno" msgstr "Ninguno"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Solamente seleccionados" msgstr "Solamente seleccionados"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "Introduce un número de página entre 1 y %(max)s." msgstr "Introduce un número de página entre 1 y %(max)s."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "Número de página inválido." msgstr "Número de página inválido."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Usar un nombre diferente internamente" msgstr "Usar un nombre diferente internamente"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Click para cerrar" msgstr "Click para cerrar"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "¡Tienes cambios sin guardar!" msgstr "¡Tienes cambios sin guardar!"
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2025-08-04 14:16+0200\n" "PO-Revision-Date: 2025-08-04 14:16+0200\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
@@ -633,56 +633,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2025-12-24 00:00+0000\n" "PO-Revision-Date: 2025-12-24 00:00+0000\n"
"Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n" "Last-Translator: Hijiri Umemoto <hijiri@umemoto.org>\n"
"Language-Team: Estonian <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Estonian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -633,56 +633,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2024-09-06 08:47+0000\n" "PO-Revision-Date: 2024-09-06 08:47+0000\n"
"Last-Translator: Albizuri <oier@puntu.eus>\n" "Last-Translator: Albizuri <oier@puntu.eus>\n"
"Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Basque <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -645,56 +645,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Guztiak" msgstr "Guztiak"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2021-11-10 05:00+0000\n" "PO-Revision-Date: 2021-11-10 05:00+0000\n"
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n" "Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -663,56 +663,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "Tuntematon virhe." msgstr "Tuntematon virhe."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Kaikki" msgstr "Kaikki"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Käytä toista nimeä sisäisesti" msgstr "Käytä toista nimeä sisäisesti"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Sulje klikkaamalla" msgstr "Sulje klikkaamalla"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Sinulla on tallentamattomia muutoksia!" msgstr "Sinulla on tallentamattomia muutoksia!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -632,56 +632,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: French\n" "Project-Id-Version: French\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-03-18 12:23+0000\n" "PO-Revision-Date: 2026-03-18 12:23+0000\n"
"Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n" "Last-Translator: CVZ-es <damien.bremont@casadevelazquez.org>\n"
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -650,12 +650,12 @@ msgstr "Création de messages …"
msgid "Unknown error." msgid "Unknown error."
msgstr "Erreur inconnue." msgstr "Erreur inconnue."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
"Votre choix de couleur a un bon contraste et il est très facile à lire." "Votre choix de couleur a un bon contraste et il est très facile à lire."
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
@@ -663,7 +663,7 @@ msgstr ""
"Votre choix de couleur est assez bon pour la lecture et offre un bon " "Votre choix de couleur est assez bon pour la lecture et offre un bon "
"contraste." "contraste."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
@@ -671,40 +671,40 @@ msgstr ""
"Votre choix de couleur n'est pas assez contrastée par rapport au blanc. " "Votre choix de couleur n'est pas assez contrastée par rapport au blanc. "
"L'accessibilité de votre site en sera affectée." "L'accessibilité de votre site en sera affectée."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Requête de recherche" msgstr "Requête de recherche"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Tous" msgstr "Tous"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Aucun" msgstr "Aucun"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Seuls les sélectionnés" msgstr "Seuls les sélectionnés"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "Saisir le numéro de page entre 1 et %(max)s." msgstr "Saisir le numéro de page entre 1 et %(max)s."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "Numéro de page invalide." msgstr "Numéro de page invalide."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Utiliser un nom différent en interne" msgstr "Utiliser un nom différent en interne"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Cliquez pour fermer" msgstr "Cliquez pour fermer"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Vous avez des modifications non sauvegardées !" msgstr "Vous avez des modifications non sauvegardées !"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-03-02 21:00+0000\n" "PO-Revision-Date: 2026-03-02 21:00+0000\n"
"Last-Translator: Sandra Rial Pérez <sandrarial@gestiontickets.online>\n" "Last-Translator: Sandra Rial Pérez <sandrarial@gestiontickets.online>\n"
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -646,13 +646,13 @@ msgstr "Xerando mensaxes…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Erro descoñecido." msgstr "Erro descoñecido."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
"A túa cor ten un gran contraste e proporcionará unha excelente " "A túa cor ten un gran contraste e proporcionará unha excelente "
"accesibilidade." "accesibilidade."
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
@@ -660,7 +660,7 @@ msgstr ""
"A túa cor ten un contraste decente e é suficiente para os requisitos mínimos " "A túa cor ten un contraste decente e é suficiente para os requisitos mínimos "
"de accesibilidade." "de accesibilidade."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
@@ -668,40 +668,40 @@ msgstr ""
"A túa cor non ten suficiente contraste co branco. A accesibilidade do teu " "A túa cor non ten suficiente contraste co branco. A accesibilidade do teu "
"sitio web verase afectada." "sitio web verase afectada."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "Consultar unha procura" msgstr "Consultar unha procura"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Todos" msgstr "Todos"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Ningún" msgstr "Ningún"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "Soamente seleccionados" msgstr "Soamente seleccionados"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "Introduza o número de páxina entre 1 e %(max)s." msgstr "Introduza o número de páxina entre 1 e %(max)s."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "Número de páxina non válido." msgstr "Número de páxina non válido."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Usar un nome diferente internamente" msgstr "Usar un nome diferente internamente"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Click para cerrar" msgstr "Click para cerrar"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Tes cambios sen gardar!" msgstr "Tes cambios sen gardar!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-02-09 21:00+0000\n" "PO-Revision-Date: 2026-02-09 21:00+0000\n"
"Last-Translator: roi belotsercovsky <rbelotsercovsky@gmail.com>\n" "Last-Translator: roi belotsercovsky <rbelotsercovsky@gmail.com>\n"
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/" "Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
@@ -638,56 +638,56 @@ msgstr "יוצר הודעות…"
msgid "Unknown error." msgid "Unknown error."
msgstr "שגיאה לא ידועה." msgstr "שגיאה לא ידועה."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "לצבע שלך יש ניגודיות מצויינת ויאפשר נגישות טובה." msgstr "לצבע שלך יש ניגודיות מצויינת ויאפשר נגישות טובה."
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "לצבע שלך יש ניגודיות סבירה ומתאים לדרישות הנגישות המינימליות." msgstr "לצבע שלך יש ניגודיות סבירה ומתאים לדרישות הנגישות המינימליות."
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "לצבע שלך יש ניגודיות חלשה מדי ביחד לצבע לבן. נגישות האתר תיפגע." msgstr "לצבע שלך יש ניגודיות חלשה מדי ביחד לצבע לבן. נגישות האתר תיפגע."
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "שאילתת חיפוש" msgstr "שאילתת חיפוש"
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "הכל" msgstr "הכל"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "כלום" msgstr "כלום"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "שנבחרו בלבד" msgstr "שנבחרו בלבד"
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "הכנס מספר דף בין 1 ל %(max)s." msgstr "הכנס מספר דף בין 1 ל %(max)s."
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "מספר דף לא תקין." msgstr "מספר דף לא תקין."
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "השתמש בשם אחר לצורך פנימי" msgstr "השתמש בשם אחר לצורך פנימי"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "לחץ לסגירה" msgstr "לחץ לסגירה"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "יש לך שינויים שלא נשמרו!" msgstr "יש לך שינויים שלא נשמרו!"
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2025-03-16 10:17+0000\n" "PO-Revision-Date: 2025-03-16 10:17+0000\n"
"Last-Translator: Robert Rigo <kontakt@bicikli.hr>\n" "Last-Translator: Robert Rigo <kontakt@bicikli.hr>\n"
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -634,56 +634,56 @@ msgstr ""
msgid "Unknown error." msgid "Unknown error."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
msgid "" msgid ""
"Your color has decent contrast and is sufficient for minimum accessibility " "Your color has decent contrast and is sufficient for minimum accessibility "
"requirements." "requirements."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "" msgstr ""
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-04-28 09:04+0000\n" "POT-Creation-Date: 2026-03-17 14:06+0000\n"
"PO-Revision-Date: 2026-01-23 15:00+0000\n" "PO-Revision-Date: 2026-01-23 15:00+0000\n"
"Last-Translator: Vajda Tamás <vajda.tamas@szwg.hu>\n" "Last-Translator: Vajda Tamás <vajda.tamas@szwg.hu>\n"
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-" "Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
@@ -680,13 +680,13 @@ msgstr "Üzenetek generálása…"
msgid "Unknown error." msgid "Unknown error."
msgstr "Ismeretlen hiba." msgstr "Ismeretlen hiba."
#: pretix/static/pretixcontrol/js/ui/main.js:310 #: pretix/static/pretixcontrol/js/ui/main.js:309
#, fuzzy #, fuzzy
#| msgid "Your color has great contrast and is very easy to read!" #| msgid "Your color has great contrast and is very easy to read!"
msgid "Your color has great contrast and will provide excellent accessibility." msgid "Your color has great contrast and will provide excellent accessibility."
msgstr "A választott színek remek kontrasztot adnak, és nagyon könnyű olvasni!" msgstr "A választott színek remek kontrasztot adnak, és nagyon könnyű olvasni!"
#: pretix/static/pretixcontrol/js/ui/main.js:314 #: pretix/static/pretixcontrol/js/ui/main.js:313
#, fuzzy #, fuzzy
#| msgid "Your color has decent contrast and is probably good-enough to read!" #| msgid "Your color has decent contrast and is probably good-enough to read!"
msgid "" msgid ""
@@ -695,46 +695,46 @@ msgid ""
msgstr "" msgstr ""
"A választott színek kontrasztja elégséges, és valószínűleg jól olvasható!" "A választott színek kontrasztja elégséges, és valószínűleg jól olvasható!"
#: pretix/static/pretixcontrol/js/ui/main.js:318 #: pretix/static/pretixcontrol/js/ui/main.js:317
msgid "" msgid ""
"Your color has insufficient contrast to white. Accessibility of your site " "Your color has insufficient contrast to white. Accessibility of your site "
"will be impacted." "will be impacted."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:446 #: pretix/static/pretixcontrol/js/ui/main.js:445
#: pretix/static/pretixcontrol/js/ui/main.js:466 #: pretix/static/pretixcontrol/js/ui/main.js:465
msgid "Search query" msgid "Search query"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:464 #: pretix/static/pretixcontrol/js/ui/main.js:463
msgid "All" msgid "All"
msgstr "Összes" msgstr "Összes"
#: pretix/static/pretixcontrol/js/ui/main.js:465 #: pretix/static/pretixcontrol/js/ui/main.js:464
msgid "None" msgid "None"
msgstr "Semmi" msgstr "Semmi"
#: pretix/static/pretixcontrol/js/ui/main.js:469 #: pretix/static/pretixcontrol/js/ui/main.js:468
msgid "Selected only" msgid "Selected only"
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:842 #: pretix/static/pretixcontrol/js/ui/main.js:841
msgid "Enter page number between 1 and %(max)s." msgid "Enter page number between 1 and %(max)s."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:845 #: pretix/static/pretixcontrol/js/ui/main.js:844
msgid "Invalid page number." msgid "Invalid page number."
msgstr "" msgstr ""
#: pretix/static/pretixcontrol/js/ui/main.js:1003 #: pretix/static/pretixcontrol/js/ui/main.js:1002
msgid "Use a different name internally" msgid "Use a different name internally"
msgstr "Használj másik nevet" msgstr "Használj másik nevet"
#: pretix/static/pretixcontrol/js/ui/main.js:1043 #: pretix/static/pretixcontrol/js/ui/main.js:1042
msgid "Click to close" msgid "Click to close"
msgstr "Bezárásért kattints" msgstr "Bezárásért kattints"
#: pretix/static/pretixcontrol/js/ui/main.js:1124 #: pretix/static/pretixcontrol/js/ui/main.js:1123
msgid "You have unsaved changes!" msgid "You have unsaved changes!"
msgstr "Mentetlen változtatások!" msgstr "Mentetlen változtatások!"

Some files were not shown because too many files have changed in this diff Show More