forked from CGM_Public/pretix_original
Compare commits
95 Commits
django-oau
...
fix-issue-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73c10320f0 | ||
|
|
a3ce3b9af3 | ||
|
|
b6461e9303 | ||
|
|
f7dfd51c2c | ||
|
|
3b98d87a26 | ||
|
|
f045062055 | ||
|
|
eb501dd1ea | ||
|
|
2d8793c355 | ||
|
|
d32bd717b7 | ||
|
|
6e6b75d55e | ||
|
|
50b5f760bb | ||
|
|
9ab2e61c31 | ||
|
|
4876a0b61f | ||
|
|
56bbcb65c3 | ||
|
|
5bb1cb498f | ||
|
|
6bf23b0fdd | ||
|
|
5deb1a8c69 | ||
|
|
1523137300 | ||
|
|
04ef097eb1 | ||
|
|
a5d4434a64 | ||
|
|
3b3c668153 | ||
|
|
d339d67111 | ||
|
|
a8aee6c824 | ||
|
|
6466987493 | ||
|
|
ff962805cd | ||
|
|
2b5f46164f | ||
|
|
d74451ded1 | ||
|
|
62f0c82d8d | ||
|
|
5b587774bb | ||
|
|
88ea8ee2ea | ||
|
|
56e0ab8378 | ||
|
|
a9ae237b1a | ||
|
|
27823b7bf6 | ||
|
|
4231cd2576 | ||
|
|
6aa5196f18 | ||
|
|
c1eac5e91e | ||
|
|
410e06364a | ||
|
|
ae137f8f16 | ||
|
|
f9f3f9f868 | ||
|
|
395eadde47 | ||
|
|
2be790fa45 | ||
|
|
f9d78eaf1a | ||
|
|
2d5d27e950 | ||
|
|
c6fa19d771 | ||
|
|
3129253eef | ||
|
|
b69ab86458 | ||
|
|
80f7ae0b76 | ||
|
|
160f9a4363 | ||
|
|
24b5b9373d | ||
|
|
178c40aee6 | ||
|
|
49c41878d2 | ||
|
|
fa4c29cf23 | ||
|
|
75b93eebc5 | ||
|
|
5a406abdd6 | ||
|
|
6712baf534 | ||
|
|
4d9243151f | ||
|
|
b89a4f7b32 | ||
|
|
c80d5b1bb2 | ||
|
|
0334c2f433 | ||
|
|
6bc46b7aec | ||
|
|
3ebe622189 | ||
|
|
25fb1ee3be | ||
|
|
a3586a73f1 | ||
|
|
93eb041acc | ||
|
|
63894ca3da | ||
|
|
73b2cce435 | ||
|
|
0a711f4965 | ||
|
|
75bf200aac | ||
|
|
11307de30a | ||
|
|
863db60786 | ||
|
|
f5a1adedca | ||
|
|
ea74688633 | ||
|
|
57738f19bf | ||
|
|
7b5ce5e198 | ||
|
|
d5f9beef69 | ||
|
|
eee39b1300 | ||
|
|
c2fdea020d | ||
|
|
f87e089734 | ||
|
|
0fad7472c0 | ||
|
|
bd0a223066 | ||
|
|
782c1a5d39 | ||
|
|
5c99d3bf69 | ||
|
|
5e6307acc9 | ||
|
|
d4bfa9d773 | ||
|
|
b7f540251c | ||
|
|
cb17d80b63 | ||
|
|
86b28b9b53 | ||
|
|
fac404631c | ||
|
|
fd547014a9 | ||
|
|
d23a625415 | ||
|
|
199416b904 | ||
|
|
0a7a113b4e | ||
|
|
5978a715b5 | ||
|
|
71beb54eb4 | ||
|
|
b92981353f |
@@ -345,7 +345,7 @@ to speed up various operations::
|
||||
The location of redis, as a URL of the form ``redis://[:password]@localhost:6379/0``
|
||||
or ``unix://[:password]@/path/to/socket.sock?db=0``
|
||||
|
||||
``session``
|
||||
``sessions``
|
||||
When this is set to ``True``, redis will be used as the session storage.
|
||||
|
||||
``sentinels``
|
||||
@@ -521,4 +521,4 @@ pretix can optionally make use of a GeoIP database for some features. It needs a
|
||||
|
||||
|
||||
.. _GeoAcumen: https://github.com/geoacumen/geoacumen-country
|
||||
.. _GeoLite2: https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
|
||||
.. _GeoLite2: https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
|
||||
|
||||
@@ -94,7 +94,9 @@ If you want the user to return to your application after the payment is complete
|
||||
"Plugins". Enable the plugin "Redirection from order page". Then, go to the new page "Settings", then "Redirection".
|
||||
Enter the base URL of your web application. This will allow you to redirect to pages under this base URL later on.
|
||||
For example, if you want users to be redirected to ``https://example.org/order/return?tx_id=1234``, you could now
|
||||
either enter ``https://example.org`` or ``https://example.org/order/``.
|
||||
either enter ``https://example.org/order/`` or ``https://example.org/``.
|
||||
Please note that in the latter case the trailing slash is required, ``https://example.org`` is not allowed to prevent.
|
||||
Only base URLs with a secure (``https://``) or local (``http://localhost``) origin are permitted.
|
||||
|
||||
The user will be redirected back to your page instead of pretix' order confirmation page after the payment,
|
||||
**regardless of whether it was successful or not**. We will append an ``error=…`` query parameter with an error
|
||||
|
||||
@@ -179,6 +179,11 @@ country string Attendee countr
|
||||
state string Attendee state (ISO 3166-2 code). Only supported in
|
||||
AU, BR, CA, CN, MY, MX, and US, otherwise ``null``.
|
||||
voucher integer Internal ID of the voucher used for this position (or ``null``)
|
||||
voucher_budget_use money (string) Amount of money discounted by the voucher, corresponding
|
||||
to how much of the ``budget`` of the voucher is consumed.
|
||||
**Important:** Do not rely on this amount to be a useful
|
||||
value if the position's price, product or voucher
|
||||
are changed *after* the order was created. Can be ``null``.
|
||||
tax_rate decimal (string) VAT rate applied for this position
|
||||
tax_value money (string) VAT included in this position
|
||||
tax_rule integer The ID of the used tax rule (or ``null``)
|
||||
@@ -367,6 +372,7 @@ List of all orders
|
||||
"country": "DE",
|
||||
"state": null,
|
||||
"voucher": null,
|
||||
"voucher_budget_use": null,
|
||||
"tax_rate": "0.00",
|
||||
"tax_value": "0.00",
|
||||
"tax_rule": null,
|
||||
@@ -589,6 +595,7 @@ Fetching individual orders
|
||||
"country": "DE",
|
||||
"state": null,
|
||||
"voucher": null,
|
||||
"voucher_budget_use": null,
|
||||
"tax_rate": "0.00",
|
||||
"tax_rule": null,
|
||||
"tax_value": "0.00",
|
||||
@@ -1541,6 +1548,7 @@ List of all order positions
|
||||
},
|
||||
"attendee_email": null,
|
||||
"voucher": null,
|
||||
"voucher_budget_use": null,
|
||||
"tax_rate": "0.00",
|
||||
"tax_rule": null,
|
||||
"tax_value": "0.00",
|
||||
@@ -1654,6 +1662,7 @@ Fetching individual positions
|
||||
},
|
||||
"attendee_email": null,
|
||||
"voucher": null,
|
||||
"voucher_budget_use": null,
|
||||
"tax_rate": "0.00",
|
||||
"tax_rule": null,
|
||||
"tax_value": "0.00",
|
||||
|
||||
@@ -34,6 +34,7 @@ internal_id string Can be used for
|
||||
contact_name string Contact person (or ``null``)
|
||||
contact_name_parts object of strings Decomposition of contact name (i.e. given name, family name)
|
||||
contact_email string Contact person email address (or ``null``)
|
||||
contact_cc_email string Copy email addresses, can be multiple separated by comma (or ``null``)
|
||||
booth string Booth number (or ``null``). Maximum 100 characters.
|
||||
locale string Locale for communication with the exhibitor.
|
||||
access_code string Access code for the exhibitor to access their data or use the lead scanning app (read-only).
|
||||
@@ -109,6 +110,7 @@ Endpoints
|
||||
"title": "Dr"
|
||||
},
|
||||
"contact_email": "johnson@as.example.org",
|
||||
"contact_cc_email": "miller@as.example.org,smith@as.example.org",
|
||||
"booth": "A2",
|
||||
"locale": "de",
|
||||
"access_code": "VKHZ2FU84",
|
||||
@@ -162,6 +164,7 @@ Endpoints
|
||||
"title": "Dr"
|
||||
},
|
||||
"contact_email": "johnson@as.example.org",
|
||||
"contact_cc_email": "miller@as.example.org,smith@as.example.org",
|
||||
"booth": "A2",
|
||||
"locale": "de",
|
||||
"access_code": "VKHZ2FU84",
|
||||
@@ -365,6 +368,7 @@ Endpoints
|
||||
"title": "Dr"
|
||||
},
|
||||
"contact_email": "johnson@as.example.org",
|
||||
"contact_cc_email": "miller@as.example.org,smith@as.example.org",
|
||||
"booth": "A2",
|
||||
"locale": "de",
|
||||
"allow_lead_scanning": true,
|
||||
@@ -394,6 +398,7 @@ Endpoints
|
||||
"title": "Dr"
|
||||
},
|
||||
"contact_email": "johnson@as.example.org",
|
||||
"contact_cc_email": "miller@as.example.org,smith@as.example.org",
|
||||
"booth": "A2",
|
||||
"locale": "de",
|
||||
"access_code": "VKHZ2FU84",
|
||||
@@ -454,6 +459,7 @@ Endpoints
|
||||
"title": "Dr"
|
||||
},
|
||||
"contact_email": "johnson@as.example.org",
|
||||
"contact_cc_email": "miller@as.example.org,smith@as.example.org",
|
||||
"booth": "A2",
|
||||
"locale": "de",
|
||||
"access_code": "VKHZ2FU84",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
sphinx==7.0.*
|
||||
sphinx==7.2.*
|
||||
jinja2==3.1.*
|
||||
sphinx-rtd-theme
|
||||
sphinxcontrib-httpdomain
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-e ../
|
||||
sphinx==7.0.*
|
||||
sphinx==7.2.*
|
||||
jinja2==3.1.*
|
||||
sphinx-rtd-theme
|
||||
sphinxcontrib-httpdomain
|
||||
|
||||
@@ -19,4 +19,3 @@ Then, head to the **Bundled products** tab of the "conference ticket" and add th
|
||||
|
||||
Once a customer tries to buy the € 450 conference ticket, a sub-product will be added and the price will automatically be split into the two components, leading to a correct computation of taxes.
|
||||
|
||||
You can find more use cases in these specialized guides:
|
||||
|
||||
@@ -31,41 +31,41 @@ dependencies = [
|
||||
"BeautifulSoup4==4.12.*",
|
||||
"bleach==5.0.*",
|
||||
"celery==5.3.*",
|
||||
"chardet==5.1.*",
|
||||
"chardet==5.2.*",
|
||||
"cryptography>=3.4.2",
|
||||
"css-inline==0.8.*",
|
||||
"css-inline==0.13.*",
|
||||
"defusedcsv>=1.1.0",
|
||||
"dj-static",
|
||||
"Django==4.2.*",
|
||||
"django-bootstrap3==23.1.*",
|
||||
"django-compressor==4.3.*",
|
||||
"django-bootstrap3==23.6.*",
|
||||
"django-compressor==4.4",
|
||||
"django-countries==7.5.*",
|
||||
"django-filter==23.2",
|
||||
"django-filter==23.5",
|
||||
"django-formset-js-improved==0.5.0.3",
|
||||
"django-formtools==2.4.1",
|
||||
"django-formtools==2.5.1",
|
||||
"django-hierarkey==1.1.*",
|
||||
"django-hijack==3.3.*",
|
||||
"django-hijack==3.4.*",
|
||||
"django-i18nfield==1.9.*,>=1.9.4",
|
||||
"django-libsass==0.9",
|
||||
"django-localflavor==4.0",
|
||||
"django-markup",
|
||||
"django-oauth-toolkit==2.3.*",
|
||||
"django-otp==1.2.*",
|
||||
"django-phonenumber-field==7.1.*",
|
||||
"django-redis==5.2.*",
|
||||
"django-otp==1.3.*",
|
||||
"django-phonenumber-field==7.3.*",
|
||||
"django-redis==5.4.*",
|
||||
"django-scopes==2.0.*",
|
||||
"django-statici18n==2.3.*",
|
||||
"django-statici18n==2.4.*",
|
||||
"djangorestframework==3.14.*",
|
||||
"dnspython==2.3.*",
|
||||
"dnspython==2.5.*",
|
||||
"drf_ujson2==1.7.*",
|
||||
"geoip2==4.*",
|
||||
"importlib_metadata==7.*", # Polyfill, we can probably drop this once we require Python 3.10+
|
||||
"isoweek",
|
||||
"jsonschema",
|
||||
"kombu==5.3.*",
|
||||
"libsass==0.22.*",
|
||||
"libsass==0.23.*",
|
||||
"lxml",
|
||||
"markdown==3.4.3", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
|
||||
"markdown==3.5.2", # 3.3.5 requires importlib-metadata>=4.4, but django-bootstrap3 requires importlib-metadata<3.
|
||||
# We can upgrade markdown again once django-bootstrap3 upgrades or once we drop Python 3.6 and 3.7
|
||||
"mt-940==4.30.*",
|
||||
"oauthlib==3.2.*",
|
||||
@@ -73,27 +73,26 @@ dependencies = [
|
||||
"packaging",
|
||||
"paypalrestsdk==1.13.*",
|
||||
"paypal-checkout-serversdk==1.0.*",
|
||||
"PyJWT==2.7.*",
|
||||
"PyJWT==2.8.*",
|
||||
"phonenumberslite==8.13.*",
|
||||
"Pillow==9.5.*",
|
||||
"Pillow==10.2.*",
|
||||
"pretix-plugin-build",
|
||||
"protobuf==4.23.*",
|
||||
"protobuf==4.25.*",
|
||||
"psycopg2-binary",
|
||||
"pycountry",
|
||||
"pycparser==2.21",
|
||||
"pycryptodome==3.18.*",
|
||||
"pycryptodome==3.20.*",
|
||||
"pypdf==3.9.*",
|
||||
"python-bidi==0.4.*", # Support for Arabic in reportlab
|
||||
"python-dateutil==2.8.*",
|
||||
"python-u2flib-server==4.*",
|
||||
"python-dateutil==2.9.*",
|
||||
"pytz",
|
||||
"pytz-deprecation-shim==0.1.*",
|
||||
"pyuca",
|
||||
"qrcode==7.4.*",
|
||||
"redis==4.6.*",
|
||||
"reportlab==4.0.*",
|
||||
"redis==5.0.*",
|
||||
"reportlab==4.1.*",
|
||||
"requests==2.31.*",
|
||||
"sentry-sdk==1.15.*",
|
||||
"sentry-sdk==1.40.*",
|
||||
"sepaxml==2.6.*",
|
||||
"slimit",
|
||||
"static3==0.7.*",
|
||||
@@ -103,33 +102,31 @@ dependencies = [
|
||||
"tqdm==4.*",
|
||||
"vat_moss_forked==2020.3.20.0.11.0",
|
||||
"vobject==0.9.*",
|
||||
"webauthn==0.4.*",
|
||||
"webauthn==2.0.*",
|
||||
"zeep==4.2.*"
|
||||
]
|
||||
|
||||
[project.optional-dependencies]
|
||||
memcached = ["pylibmc"]
|
||||
dev = [
|
||||
"aiohttp==3.8.*",
|
||||
"aiohttp==3.9.*",
|
||||
"coverage",
|
||||
"coveralls",
|
||||
"fakeredis==2.18.*",
|
||||
"flake8==6.0.*",
|
||||
"fakeredis==2.21.*",
|
||||
"flake8==7.0.*",
|
||||
"freezegun",
|
||||
"isort==5.12.*",
|
||||
"isort==5.13.*",
|
||||
"pep8-naming==0.13.*",
|
||||
"potypo",
|
||||
"pycodestyle==2.10.*",
|
||||
"pyflakes==3.0.*",
|
||||
"pytest-asyncio",
|
||||
"pytest-cache",
|
||||
"pytest-cov",
|
||||
"pytest-django==4.*",
|
||||
"pytest-mock==3.10.*",
|
||||
"pytest-rerunfailures==11.*",
|
||||
"pytest-mock==3.12.*",
|
||||
"pytest-rerunfailures==13.*",
|
||||
"pytest-sugar",
|
||||
"pytest-xdist==3.3.*",
|
||||
"pytest==7.3.*",
|
||||
"pytest-xdist==3.5.*",
|
||||
"pytest==8.0.*",
|
||||
"responses",
|
||||
]
|
||||
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
# 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/>.
|
||||
#
|
||||
__version__ = "2024.2.0.dev0"
|
||||
__version__ = "2024.3.0.dev0"
|
||||
|
||||
@@ -486,11 +486,11 @@ class OrderPositionSerializer(I18nAwareModelSerializer):
|
||||
'company', 'street', 'zipcode', 'city', 'country', 'state', 'discount',
|
||||
'attendee_email', 'voucher', 'tax_rate', 'tax_value', 'secret', 'addon_to', 'subevent', 'checkins',
|
||||
'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data', 'seat', 'canceled',
|
||||
'valid_from', 'valid_until', 'blocked')
|
||||
'valid_from', 'valid_until', 'blocked', 'voucher_budget_use')
|
||||
read_only_fields = (
|
||||
'id', 'order', 'positionid', 'item', 'variation', 'price', 'voucher', 'tax_rate', 'tax_value', 'secret',
|
||||
'addon_to', 'subevent', 'checkins', 'downloads', 'answers', 'tax_rule', 'pseudonymization_id', 'pdf_data',
|
||||
'seat', 'canceled', 'discount', 'valid_from', 'valid_until', 'blocked'
|
||||
'seat', 'canceled', 'discount', 'valid_from', 'valid_until', 'blocked', 'voucher_budget_use'
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -35,6 +35,7 @@ from django.http import Http404
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext
|
||||
from django_filters.rest_framework import DjangoFilterBackend, FilterSet
|
||||
from django_scopes import scopes_disabled
|
||||
from packaging.version import parse
|
||||
@@ -586,6 +587,32 @@ def _redeem_process(*, checkinlists, raw_barcode, answers_data, datetime, force,
|
||||
'list': MiniCheckinListSerializer(list_by_event[revoked_matches[0].event_id]).data,
|
||||
}, status=400)
|
||||
else:
|
||||
if media.linked_orderposition.order.event_id not in list_by_event:
|
||||
# Medium exists but connected ticket is for the wrong event
|
||||
if not simulate:
|
||||
checkinlists[0].event.log_action('pretix.event.checkin.unknown', data={
|
||||
'datetime': datetime,
|
||||
'type': checkin_type,
|
||||
'list': checkinlists[0].pk,
|
||||
'barcode': raw_barcode,
|
||||
'searched_lists': [cl.pk for cl in checkinlists]
|
||||
}, user=user, auth=auth)
|
||||
Checkin.objects.create(
|
||||
position=None,
|
||||
successful=False,
|
||||
error_reason=Checkin.REASON_INVALID,
|
||||
error_explanation=gettext('Medium connected to other event'),
|
||||
**common_checkin_args,
|
||||
)
|
||||
return Response({
|
||||
'detail': 'Not found.', # for backwards compatibility
|
||||
'status': 'error',
|
||||
'reason': Checkin.REASON_INVALID,
|
||||
'reason_explanation': gettext('Medium connected to other event'),
|
||||
'require_attention': False,
|
||||
'checkin_texts': [],
|
||||
'list': MiniCheckinListSerializer(checkinlists[0]).data,
|
||||
}, status=404)
|
||||
op_candidates = [media.linked_orderposition]
|
||||
if list_by_event[media.linked_orderposition.order.event_id].addon_match:
|
||||
op_candidates += list(media.linked_orderposition.addons.all())
|
||||
|
||||
@@ -189,7 +189,7 @@ class TemplateBasedMailRenderer(BaseHTMLMailRenderer):
|
||||
tpl = get_template(self.template_name)
|
||||
body_html = tpl.render(htmlctx)
|
||||
|
||||
inliner = css_inline.CSSInliner(remove_style_tags=True)
|
||||
inliner = css_inline.CSSInliner(keep_style_tags=False)
|
||||
body_html = inliner.inline(body_html)
|
||||
|
||||
return body_html
|
||||
|
||||
@@ -86,6 +86,7 @@ class InvoiceExporterMixin:
|
||||
('', _('All payment providers')),
|
||||
] + [
|
||||
(k, v.verbose_name) for k, v in self.event.get_payment_providers().items()
|
||||
if not v.is_meta
|
||||
],
|
||||
required=False,
|
||||
help_text=_('Only include invoices for orders that have at least one payment attempt '
|
||||
|
||||
@@ -257,8 +257,8 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
tax_rates = self._get_all_tax_rates(qs)
|
||||
|
||||
headers = [
|
||||
_('Event slug'), _('Order code'), _('Order total'), _('Status'), _('Email'), _('Phone number'),
|
||||
_('Order date'), _('Order time'), _('Company'), _('Name'),
|
||||
_('Event slug'), _('Event name'), _('Order code'), _('Order total'), _('Status'), _('Email'),
|
||||
_('Phone number'), _('Order date'), _('Order time'), _('Company'), _('Name'),
|
||||
]
|
||||
name_scheme = PERSON_NAME_SCHEMES[self.event.settings.name_scheme] if not self.is_multievent else None
|
||||
if name_scheme and len(name_scheme['fields']) > 1:
|
||||
@@ -335,6 +335,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
|
||||
row = [
|
||||
self.event_object_cache[order.event_id].slug,
|
||||
str(self.event_object_cache[order.event_id].name),
|
||||
order.code,
|
||||
order.total,
|
||||
order.get_extended_status_display(),
|
||||
@@ -436,6 +437,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
|
||||
headers = [
|
||||
_('Event slug'),
|
||||
_('Event name'),
|
||||
_('Order code'),
|
||||
_('Status'),
|
||||
_('Email'),
|
||||
@@ -472,6 +474,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
tz = ZoneInfo(order.event.settings.timezone)
|
||||
row = [
|
||||
self.event_object_cache[order.event_id].slug,
|
||||
str(self.event_object_cache[order.event_id].name),
|
||||
order.code,
|
||||
_("canceled") if op.canceled else order.get_extended_status_display(),
|
||||
order.email,
|
||||
@@ -550,6 +553,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
|
||||
headers = [
|
||||
_('Event slug'),
|
||||
_('Event name'),
|
||||
_('Order code'),
|
||||
_('Position ID'),
|
||||
_('Status'),
|
||||
@@ -651,6 +655,7 @@ class OrderListExporter(MultiSheetListExporter):
|
||||
tz = ZoneInfo(self.event_object_cache[order.event_id].settings.timezone)
|
||||
row = [
|
||||
self.event_object_cache[order.event_id].slug,
|
||||
str(self.event_object_cache[order.event_id].name),
|
||||
order.code,
|
||||
op.positionid,
|
||||
_("canceled") if op.canceled else order.get_extended_status_display(),
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
from bootstrap3.renderers import (
|
||||
FieldRenderer as BaseFieldRenderer,
|
||||
InlineFieldRenderer as BaseInlineFieldRenderer,
|
||||
)
|
||||
from django.forms import (
|
||||
CheckboxInput, CheckboxSelectMultiple, ClearableFileInput, RadioSelect,
|
||||
SelectDateWidget,
|
||||
)
|
||||
|
||||
|
||||
class FieldRenderer(BaseFieldRenderer):
|
||||
# Local application of https://github.com/zostera/django-bootstrap3/pull/859
|
||||
|
||||
def post_widget_render(self, html):
|
||||
if isinstance(self.widget, CheckboxSelectMultiple):
|
||||
html = self.list_to_class(html, "checkbox")
|
||||
elif isinstance(self.widget, RadioSelect):
|
||||
html = self.list_to_class(html, "radio")
|
||||
elif isinstance(self.widget, SelectDateWidget):
|
||||
html = self.fix_date_select_input(html)
|
||||
elif isinstance(self.widget, ClearableFileInput):
|
||||
html = self.fix_clearable_file_input(html)
|
||||
elif isinstance(self.widget, CheckboxInput):
|
||||
html = self.put_inside_label(html)
|
||||
return html
|
||||
|
||||
|
||||
class InlineFieldRenderer(BaseInlineFieldRenderer):
|
||||
# Local application of https://github.com/zostera/django-bootstrap3/pull/859
|
||||
|
||||
def post_widget_render(self, html):
|
||||
if isinstance(self.widget, CheckboxSelectMultiple):
|
||||
html = self.list_to_class(html, "checkbox")
|
||||
elif isinstance(self.widget, RadioSelect):
|
||||
html = self.list_to_class(html, "radio")
|
||||
elif isinstance(self.widget, SelectDateWidget):
|
||||
html = self.fix_date_select_input(html)
|
||||
elif isinstance(self.widget, ClearableFileInput):
|
||||
html = self.fix_clearable_file_input(html)
|
||||
elif isinstance(self.widget, CheckboxInput):
|
||||
html = self.put_inside_label(html)
|
||||
return html
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 4.2.9 on 2024-01-30 11:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("pretixbase", "0256_itemvariation_unavail_modes"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="item",
|
||||
name="default_price",
|
||||
field=models.DecimalField(decimal_places=2, default=0, max_digits=13),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
@@ -37,9 +37,7 @@ import json
|
||||
import operator
|
||||
from datetime import timedelta
|
||||
from functools import reduce
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import webauthn
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import (
|
||||
AbstractBaseUser, BaseUserManager, PermissionsMixin,
|
||||
@@ -53,13 +51,12 @@ from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_otp.models import Device
|
||||
from django_scopes import scopes_disabled
|
||||
from u2flib_server.utils import (
|
||||
pub_key_from_der, websafe_decode, websafe_encode,
|
||||
)
|
||||
from webauthn.helpers.structs import PublicKeyCredentialDescriptor
|
||||
|
||||
from pretix.base.i18n import language
|
||||
from pretix.helpers.urls import build_absolute_uri
|
||||
|
||||
from ...helpers.u2f import pub_key_from_der, websafe_decode
|
||||
from .base import LoggingMixin
|
||||
|
||||
|
||||
@@ -608,7 +605,12 @@ class U2FDevice(Device):
|
||||
json_data = models.TextField()
|
||||
|
||||
@property
|
||||
def webauthnuser(self):
|
||||
def webauthndevice(self):
|
||||
d = json.loads(self.json_data)
|
||||
return PublicKeyCredentialDescriptor(websafe_decode(d['keyHandle']))
|
||||
|
||||
@property
|
||||
def webauthnpubkey(self):
|
||||
d = json.loads(self.json_data)
|
||||
# We manually need to convert the pubkey from DER format (used in our
|
||||
# former U2F implementation) to the format required by webauthn. This
|
||||
@@ -620,16 +622,7 @@ class U2FDevice(Device):
|
||||
pub_key.public_numbers().x, pub_key.public_numbers().y
|
||||
)
|
||||
)
|
||||
return webauthn.WebAuthnUser(
|
||||
d['keyHandle'],
|
||||
self.user.email,
|
||||
str(self.user),
|
||||
settings.SITE_URL,
|
||||
d['keyHandle'],
|
||||
websafe_encode(pub_key),
|
||||
1,
|
||||
urlparse(settings.SITE_URL).netloc
|
||||
)
|
||||
return pub_key
|
||||
|
||||
|
||||
class WebAuthnDevice(Device):
|
||||
@@ -641,14 +634,9 @@ class WebAuthnDevice(Device):
|
||||
sign_count = models.IntegerField(default=0)
|
||||
|
||||
@property
|
||||
def webauthnuser(self):
|
||||
return webauthn.WebAuthnUser(
|
||||
self.ukey,
|
||||
self.user.email,
|
||||
str(self.user),
|
||||
settings.SITE_URL,
|
||||
self.credential_id,
|
||||
self.pub_key,
|
||||
self.sign_count,
|
||||
urlparse(settings.SITE_URL).netloc
|
||||
)
|
||||
def webauthndevice(self):
|
||||
return PublicKeyCredentialDescriptor(websafe_decode(self.credential_id))
|
||||
|
||||
@property
|
||||
def webauthnpubkey(self):
|
||||
return websafe_decode(self.pub_key)
|
||||
|
||||
@@ -265,6 +265,9 @@ class EventMixin:
|
||||
|
||||
@property
|
||||
def event_microdata(self):
|
||||
if self.settings.event_microdata:
|
||||
return self.settings.event_microdata
|
||||
|
||||
import json
|
||||
|
||||
eventdict = {
|
||||
|
||||
@@ -430,7 +430,7 @@ class Item(LoggedModel):
|
||||
help_text=_("If this product has multiple variations, you can set different prices for each of the "
|
||||
"variations. If a variation does not have a special price or if you do not have variations, "
|
||||
"this price will be used."),
|
||||
max_digits=13, decimal_places=2, null=True
|
||||
max_digits=13, decimal_places=2,
|
||||
)
|
||||
free_price = models.BooleanField(
|
||||
default=False,
|
||||
|
||||
@@ -351,9 +351,6 @@ class Voucher(LoggedModel):
|
||||
'variations.'))
|
||||
if variation and not item.variations.filter(pk=variation.pk).exists():
|
||||
raise ValidationError(_('This variation does not belong to this product.'))
|
||||
if item.has_variations and not variation and data.get('block_quota'):
|
||||
raise ValidationError(_('You can only block quota if you specify a specific product variation. '
|
||||
'Otherwise it might be unclear which quotas to block.'))
|
||||
if item.category and item.category.is_addon:
|
||||
raise ValidationError(_('It is currently not possible to create vouchers for add-on products.'))
|
||||
elif block_quota:
|
||||
@@ -431,7 +428,15 @@ class Voucher(LoggedModel):
|
||||
elif old_instance.variation:
|
||||
quotas |= set(old_instance.variation.quotas.filter(subevent=old_instance.subevent))
|
||||
elif old_instance.item:
|
||||
quotas |= set(old_instance.item.quotas.filter(subevent=old_instance.subevent))
|
||||
if old_instance.item.has_variations:
|
||||
quotas |= set(
|
||||
Quota.objects.filter(pk__in=Quota.variations.through.objects.filter(
|
||||
itemvariation__item=old_instance.item,
|
||||
quota__subevent=old_instance.subevent,
|
||||
).values('quota_id'))
|
||||
)
|
||||
else:
|
||||
quotas |= set(old_instance.item.quotas.filter(subevent=old_instance.subevent))
|
||||
return quotas
|
||||
|
||||
@staticmethod
|
||||
@@ -446,13 +451,19 @@ class Voucher(LoggedModel):
|
||||
|
||||
if quota:
|
||||
new_quotas = {quota}
|
||||
elif item and item.has_variations and not variation:
|
||||
raise ValidationError(_('You can only block quota if you specify a specific product variation. '
|
||||
'Otherwise it might be unclear which quotas to block.'))
|
||||
elif item and variation:
|
||||
new_quotas = set(variation.quotas.filter(subevent=data.get('subevent')))
|
||||
elif item and not item.has_variations:
|
||||
new_quotas = set(item.quotas.filter(subevent=data.get('subevent')))
|
||||
elif item and item.has_variations:
|
||||
new_quotas = set(
|
||||
Quota.objects.filter(
|
||||
pk__in=Quota.variations.through.objects.filter(
|
||||
itemvariation__item=old_instance.item,
|
||||
quota__subevent=data.get('subevent'),
|
||||
).values('quota_id')
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise ValidationError(_('You need to select a specific product or quota if this voucher should reserve '
|
||||
'tickets.'))
|
||||
|
||||
@@ -104,10 +104,10 @@ def build_invoice(invoice: Invoice) -> Invoice:
|
||||
expire_date=date_format(invoice.order.expires, "SHORT_DATE_FORMAT")
|
||||
)
|
||||
|
||||
invoice.introductory_text = str(introductory).replace('\n', '<br />')
|
||||
invoice.additional_text = str(additional).replace('\n', '<br />')
|
||||
invoice.introductory_text = str(introductory).replace('\n', '<br />').replace('\r', '')
|
||||
invoice.additional_text = str(additional).replace('\n', '<br />').replace('\r', '')
|
||||
invoice.footer_text = str(footer)
|
||||
invoice.payment_provider_text = str(payment).replace('\n', '<br />')
|
||||
invoice.payment_provider_text = str(payment).replace('\n', '<br />').replace('\r', '')
|
||||
invoice.payment_provider_stamp = str(payment_stamp) if payment_stamp else None
|
||||
|
||||
try:
|
||||
@@ -462,10 +462,10 @@ def build_preview_invoice_pdf(event):
|
||||
footer = event.settings.get('invoice_footer_text', as_type=LazyI18nString)
|
||||
payment = _("A payment provider specific text might appear here.")
|
||||
|
||||
invoice.introductory_text = str(introductory).replace('\n', '<br />')
|
||||
invoice.additional_text = str(additional).replace('\n', '<br />')
|
||||
invoice.introductory_text = str(introductory).replace('\n', '<br />').replace('\r', '')
|
||||
invoice.additional_text = str(additional).replace('\n', '<br />').replace('\r', '')
|
||||
invoice.footer_text = str(footer)
|
||||
invoice.payment_provider_text = str(payment).replace('\n', '<br />')
|
||||
invoice.payment_provider_text = str(payment).replace('\n', '<br />').replace('\r', '')
|
||||
invoice.payment_provider_stamp = _('paid')
|
||||
invoice.invoice_to_name = _("John Doe")
|
||||
invoice.invoice_to_street = _("214th Example Street")
|
||||
@@ -488,7 +488,7 @@ def build_preview_invoice_pdf(event):
|
||||
InvoiceLine.objects.create(
|
||||
invoice=invoice, description=_("Sample product {}").format(i + 1),
|
||||
gross_value=tax.gross, tax_value=tax.tax,
|
||||
tax_rate=tax.rate
|
||||
tax_rate=tax.rate, tax_name=tax.name
|
||||
)
|
||||
else:
|
||||
for i in range(5):
|
||||
|
||||
@@ -383,6 +383,7 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st
|
||||
if event:
|
||||
with scopes_disabled():
|
||||
event = Event.objects.get(id=event)
|
||||
organizer = event.organizer
|
||||
backend = event.get_mail_backend()
|
||||
cm = lambda: scope(organizer=event.organizer) # noqa
|
||||
elif organizer:
|
||||
|
||||
@@ -136,7 +136,7 @@ def send_notification_mail(notification: Notification, user: User):
|
||||
tpl_html = get_template('pretixbase/email/notification.html')
|
||||
|
||||
body_html = tpl_html.render(ctx)
|
||||
inliner = css_inline.CSSInliner(remove_style_tags=True)
|
||||
inliner = css_inline.CSSInliner(keep_style_tags=False)
|
||||
body_html = inliner.inline(body_html)
|
||||
|
||||
tpl_plain = get_template('pretixbase/email/notification.txt')
|
||||
|
||||
@@ -90,8 +90,8 @@ class QuotaAvailability:
|
||||
self._count_waitinglist = count_waitinglist
|
||||
self._ignore_closed = ignore_closed
|
||||
self._full_results = full_results
|
||||
self._item_to_quotas = defaultdict(list)
|
||||
self._var_to_quotas = defaultdict(list)
|
||||
self._item_to_quotas = defaultdict(set)
|
||||
self._var_to_quotas = defaultdict(set)
|
||||
self._early_out = early_out
|
||||
self._quota_objects = {}
|
||||
self.results = {}
|
||||
@@ -243,13 +243,16 @@ class QuotaAvailability:
|
||||
quota_id__in=[q.pk for q in quotas]
|
||||
).values('quota_id', 'item_id')
|
||||
for m in q_items:
|
||||
self._item_to_quotas[m['item_id']].append(self._quota_objects[m['quota_id']])
|
||||
self._item_to_quotas[m['item_id']].add(self._quota_objects[m['quota_id']])
|
||||
|
||||
q_vars = Quota.variations.through.objects.filter(
|
||||
quota_id__in=[q.pk for q in quotas]
|
||||
).values('quota_id', 'itemvariation_id')
|
||||
).values('quota_id', 'itemvariation_id', 'itemvariation__item_id')
|
||||
for m in q_vars:
|
||||
self._var_to_quotas[m['itemvariation_id']].append(self._quota_objects[m['quota_id']])
|
||||
self._var_to_quotas[m['itemvariation_id']].add(self._quota_objects[m['quota_id']])
|
||||
# We can't be 100% certain that a quota, when it is connected to a variation, is also always connected to
|
||||
# the parent item, so we double-check here just to be sure.
|
||||
self._item_to_quotas[m['itemvariation__item_id']].add(self._quota_objects[m['quota_id']])
|
||||
|
||||
self._compute_orders(quotas, q_items, q_vars, size_left)
|
||||
|
||||
@@ -378,7 +381,10 @@ class QuotaAvailability:
|
||||
Q(
|
||||
Q(
|
||||
Q(variation_id__isnull=True) &
|
||||
Q(item_id__in={i['item_id'] for i in q_items if i['quota_id'] in quota_ids})
|
||||
Q(item_id__in=(
|
||||
{i['item_id'] for i in q_items if i['quota_id'] in quota_ids} |
|
||||
{i['itemvariation__item_id'] for i in q_vars if i['quota_id'] in quota_ids}
|
||||
))
|
||||
) | Q(
|
||||
variation_id__in={i['itemvariation_id'] for i in q_vars if i['quota_id'] in quota_ids}
|
||||
) | Q(
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
{# this is the version from django 3.x, prior to https://github.com/django/django/commit/5942ab5eb165ee2e759174e297148a40dd855920 so that django-bootstrap3 can keep doing its magic #}
|
||||
{% with id=widget.attrs.id %}<ul{% if id %} id="{{ id }}"{% endif %}{% if widget.attrs.class %} class="{{ widget.attrs.class }}"{% endif %}>{% for group, options, index in widget.optgroups %}{% if group %}
|
||||
<li>{{ group }}<ul{% if id %} id="{{ id }}_{{ index }}"{% endif %}>{% endif %}{% for option in options %}
|
||||
<li>{% include option.template_name with widget=option %}</li>{% endfor %}{% if group %}
|
||||
</ul></li>{% endif %}{% endfor %}
|
||||
</ul>{% endwith %}
|
||||
@@ -123,8 +123,6 @@ class ClearableBasenameFileInput(forms.ClearableFileInput):
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if hasattr(self.file, 'display_name'):
|
||||
return self.file.display_name
|
||||
return self.file.name
|
||||
|
||||
@property
|
||||
@@ -219,15 +217,17 @@ class ExtValidationMixin:
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
data = super().clean(*args, **kwargs)
|
||||
if isinstance(data, UploadedFile):
|
||||
filename = data.name
|
||||
|
||||
from ...base.models import CachedFile
|
||||
if isinstance(data, (UploadedFile, CachedFile)):
|
||||
filename = data.name if isinstance(data, UploadedFile) else data.filename
|
||||
ext = os.path.splitext(filename)[1]
|
||||
ext = ext.lower()
|
||||
if ext not in self.ext_whitelist:
|
||||
raise forms.ValidationError(_("Filetype not allowed!"))
|
||||
|
||||
if ext in IMAGE_EXTS:
|
||||
validate_uploaded_file_for_valid_image(data)
|
||||
validate_uploaded_file_for_valid_image(data if isinstance(data, UploadedFile) else data.file)
|
||||
|
||||
return data
|
||||
|
||||
@@ -257,6 +257,12 @@ class CachedFileField(ExtFileField):
|
||||
if isinstance(data, File):
|
||||
if hasattr(data, '_uploaded_to'):
|
||||
return data._uploaded_to
|
||||
|
||||
try:
|
||||
self.clean(data)
|
||||
except ValidationError:
|
||||
return None
|
||||
|
||||
cf = CachedFile.objects.create(
|
||||
expires=now() + datetime.timedelta(days=1),
|
||||
date=now(),
|
||||
@@ -268,6 +274,9 @@ class CachedFileField(ExtFileField):
|
||||
cf.save()
|
||||
data._uploaded_to = cf
|
||||
return cf
|
||||
if isinstance(data, CachedFile):
|
||||
return data
|
||||
|
||||
return super().bound_data(data, initial)
|
||||
|
||||
def clean(self, *args, **kwargs):
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
# 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/>.
|
||||
#
|
||||
from bootstrap3.renderers import FieldRenderer, InlineFieldRenderer
|
||||
from bootstrap3.text import text_value
|
||||
from django.forms import CheckboxInput, CheckboxSelectMultiple, RadioSelect
|
||||
from django.forms.utils import flatatt
|
||||
@@ -27,8 +28,6 @@ from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import pgettext
|
||||
from i18nfield.forms import I18nFormField
|
||||
|
||||
from pretix.base.forms.renderers import FieldRenderer, InlineFieldRenderer
|
||||
|
||||
|
||||
def render_label(content, label_for=None, label_class=None, label_title='', label_id='', optional=False):
|
||||
"""
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
{% endblocktrans %}
|
||||
</em>
|
||||
{% endif %}
|
||||
{% if position.attendee_name %}
|
||||
– <span class="fa fa-user" aria-hidden="true"></span>
|
||||
{{ position.attendee_name }}
|
||||
{% endif %}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
@@ -234,7 +234,62 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group poweredby">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Style" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-poweredby-style">
|
||||
<option value="dark">{% trans "Dark" %}</option>
|
||||
<option value="white">{% trans "Light" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group imagecontent">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Image content" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-imagecontent">
|
||||
<option value="">{% trans "Empty" %}</option>
|
||||
{% for varname, var in images.items %}
|
||||
<option value="{{ varname }}">{{ var.label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text textcontent">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Content" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-content">
|
||||
{% for varname, var in variables.items %}
|
||||
{% if not var.hidden %}
|
||||
<option data-sample="{{ var.editor_sample }}" {% if var.migrate_from %}data-old-value="{{ var.migrate_from }}"{% endif %} value="{{ varname }}">{{ var.label }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for p in request.organizer.meta_properties.all %}
|
||||
<option value="meta:{{ p.name }}">
|
||||
{% trans "Event attribute:" %} {{ p.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
{% for p in request.event.item_meta_properties.all %}
|
||||
<option value="itemmeta:{{ p.name }}">
|
||||
{% trans "Item attribute:" %} {{ p.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
<option value="other_i18n">{% trans "Other… (multilingual)" %}</option>
|
||||
<option value="other">{% trans "Other…" %}</option>
|
||||
</select>
|
||||
<textarea type="text" value="" class="input-block-level form-control"
|
||||
id="toolbox-content-other"></textarea>
|
||||
<div class="i18n-form-group" id="toolbox-content-other-i18n">
|
||||
{% for l in request.event.settings.locales %}
|
||||
<textarea id="toolbox-content-other-{{ l }}" rows="3" class="input-block-level form-control" title="{{ l }}" lang="{{ l }}"></textarea>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p class="help-block" id="toolbox-content-other-help">
|
||||
<a href="?placeholders=true" target="_blank">{% trans "Show available placeholders" %}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group position">
|
||||
<hr/>
|
||||
<div class="col-sm-6">
|
||||
<label>{% trans "x (mm)" %}</label><br>
|
||||
<input type="number" value="13" class="input-block-level form-control" step="0.01"
|
||||
@@ -277,6 +332,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text">
|
||||
<div class="col-sm-6">
|
||||
<label>{% trans "Width (mm)" %}</label><br>
|
||||
<input type="number" value="13" class="input-block-level form-control" step="0.01"
|
||||
id="toolbox-textwidth">
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label>{% trans "Rotation (°)" %}</label><br>
|
||||
<input type="number" value="0" class="input-block-level form-control" step="0.1"
|
||||
id="toolbox-textrotation">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text">
|
||||
<hr/>
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Font" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-fontfamily">
|
||||
<option>Open Sans</option>
|
||||
{% for family in fonts.keys %}
|
||||
<option>{{ family }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text">
|
||||
<div class="col-sm-6">
|
||||
<label>{% trans "Font size (pt)" %}</label><br>
|
||||
@@ -335,83 +414,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Font" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-fontfamily">
|
||||
<option>Open Sans</option>
|
||||
{% for family in fonts.keys %}
|
||||
<option>{{ family }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text">
|
||||
<div class="col-sm-6">
|
||||
<label>{% trans "Width (mm)" %}</label><br>
|
||||
<input type="number" value="13" class="input-block-level form-control" step="0.01"
|
||||
id="toolbox-textwidth">
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label>{% trans "Rotation (°)" %}</label><br>
|
||||
<input type="number" value="0" class="input-block-level form-control" step="0.1"
|
||||
id="toolbox-textrotation">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group poweredby">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Style" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-poweredby-style">
|
||||
<option value="dark">{% trans "Dark" %}</option>
|
||||
<option value="white">{% trans "Light" %}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group imagecontent">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Image content" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-imagecontent">
|
||||
<option value="">{% trans "Empty" %}</option>
|
||||
{% for varname, var in images.items %}
|
||||
<option value="{{ varname }}">{{ var.label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row control-group text textcontent">
|
||||
<div class="col-sm-12">
|
||||
<label>{% trans "Content" %}</label><br>
|
||||
<select class="input-block-level form-control" id="toolbox-content">
|
||||
{% for varname, var in variables.items %}
|
||||
{% if not var.hidden %}
|
||||
<option data-sample="{{ var.editor_sample }}" {% if var.migrate_from %}data-old-value="{{ var.migrate_from }}"{% endif %} value="{{ varname }}">{{ var.label }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for p in request.organizer.meta_properties.all %}
|
||||
<option value="meta:{{ p.name }}">
|
||||
{% trans "Event attribute:" %} {{ p.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
{% for p in request.event.item_meta_properties.all %}
|
||||
<option value="itemmeta:{{ p.name }}">
|
||||
{% trans "Item attribute:" %} {{ p.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
<option value="other_i18n">{% trans "Other… (multilingual)" %}</option>
|
||||
<option value="other">{% trans "Other…" %}</option>
|
||||
</select>
|
||||
<textarea type="text" value="" class="input-block-level form-control"
|
||||
id="toolbox-content-other"></textarea>
|
||||
<div class="i18n-form-group" id="toolbox-content-other-i18n">
|
||||
{% for l in request.event.settings.locales %}
|
||||
<textarea id="toolbox-content-other-{{ l }}" rows="3" class="input-block-level form-control" title="{{ l }}" lang="{{ l }}"></textarea>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p class="help-block" id="toolbox-content-other-help">
|
||||
<a href="?placeholders=true" target="_blank">{% trans "Show available placeholders" %}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-toolbox-text panel panel-default">
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
|
||||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations under the License.
|
||||
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
from urllib.parse import quote
|
||||
from urllib.parse import quote, urlparse
|
||||
|
||||
import webauthn
|
||||
from django.conf import settings
|
||||
@@ -54,6 +54,7 @@ from django.utils.http import url_has_allowed_host_and_scheme
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import TemplateView
|
||||
from django_otp import match_token
|
||||
from webauthn.helpers import generate_challenge
|
||||
|
||||
from pretix.base.auth import get_auth_backends
|
||||
from pretix.base.forms.auth import (
|
||||
@@ -62,7 +63,6 @@ from pretix.base.forms.auth import (
|
||||
from pretix.base.models import TeamInvite, U2FDevice, User, WebAuthnDevice
|
||||
from pretix.base.services.mail import SendMailException
|
||||
from pretix.helpers.http import redirect_to_url
|
||||
from pretix.helpers.webauthn import generate_challenge
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -389,6 +389,10 @@ def get_u2f_appid(request):
|
||||
return settings.SITE_URL
|
||||
|
||||
|
||||
def get_webauthn_rp_id(request):
|
||||
return urlparse(settings.SITE_URL).hostname
|
||||
|
||||
|
||||
class Login2FAView(TemplateView):
|
||||
template_name = 'pretixcontrol/auth/login_2fa.html'
|
||||
|
||||
@@ -427,25 +431,41 @@ class Login2FAView(TemplateView):
|
||||
devices = U2FDevice.objects.filter(user=self.user)
|
||||
|
||||
for d in devices:
|
||||
credential_current_sign_count = d.sign_count if isinstance(d, WebAuthnDevice) else 0
|
||||
try:
|
||||
wu = d.webauthnuser
|
||||
|
||||
if isinstance(d, U2FDevice):
|
||||
# RP_ID needs to be appId for U2F devices, but we can't
|
||||
# set it that way in U2FDevice.webauthnuser, since that
|
||||
# breaks the frontend part.
|
||||
wu.rp_id = settings.SITE_URL
|
||||
|
||||
webauthn_assertion_response = webauthn.WebAuthnAssertionResponse(
|
||||
wu,
|
||||
resp,
|
||||
challenge,
|
||||
settings.SITE_URL,
|
||||
uv_required=False # User Verification
|
||||
webauthn_assertion_response = webauthn.verify_authentication_response(
|
||||
credential=resp,
|
||||
expected_challenge=base64.b64decode(challenge),
|
||||
expected_rp_id=get_webauthn_rp_id(self.request),
|
||||
expected_origin=settings.SITE_URL,
|
||||
credential_public_key=d.webauthnpubkey,
|
||||
credential_current_sign_count=credential_current_sign_count,
|
||||
)
|
||||
sign_count = webauthn_assertion_response.verify()
|
||||
sign_count = webauthn_assertion_response.new_sign_count
|
||||
if sign_count < credential_current_sign_count:
|
||||
raise Exception("Possible replay attack, sign count not higher")
|
||||
except Exception:
|
||||
logger.exception('U2F login failed')
|
||||
if isinstance(d, U2FDevice):
|
||||
# https://www.w3.org/TR/webauthn/#sctn-appid-extension says
|
||||
# "When verifying the assertion, expect that the rpIdHash MAY be the hash of the AppID instead of the RP ID."
|
||||
try:
|
||||
webauthn_assertion_response = webauthn.verify_authentication_response(
|
||||
credential=resp,
|
||||
expected_challenge=base64.b64decode(challenge),
|
||||
expected_rp_id=get_u2f_appid(self.request),
|
||||
expected_origin=settings.SITE_URL,
|
||||
credential_public_key=d.webauthnpubkey,
|
||||
credential_current_sign_count=credential_current_sign_count,
|
||||
)
|
||||
if webauthn_assertion_response.new_sign_count < 1:
|
||||
raise Exception("Possible replay attack, sign count set")
|
||||
except Exception:
|
||||
logger.exception('U2F login failed')
|
||||
else:
|
||||
valid = True
|
||||
break
|
||||
else:
|
||||
logger.exception('Webauthn login failed')
|
||||
else:
|
||||
if isinstance(d, WebAuthnDevice):
|
||||
d.sign_count = sign_count
|
||||
@@ -471,23 +491,24 @@ class Login2FAView(TemplateView):
|
||||
ctx = super().get_context_data()
|
||||
if 'webauthn_challenge' in self.request.session:
|
||||
del self.request.session['webauthn_challenge']
|
||||
challenge = generate_challenge(32)
|
||||
self.request.session['webauthn_challenge'] = challenge
|
||||
challenge = generate_challenge()
|
||||
self.request.session['webauthn_challenge'] = base64.b64encode(challenge).decode()
|
||||
devices = [
|
||||
device.webauthnuser for device in WebAuthnDevice.objects.filter(confirmed=True, user=self.user)
|
||||
device.webauthndevice for device in WebAuthnDevice.objects.filter(confirmed=True, user=self.user)
|
||||
] + [
|
||||
device.webauthnuser for device in U2FDevice.objects.filter(confirmed=True, user=self.user)
|
||||
device.webauthndevice for device in U2FDevice.objects.filter(confirmed=True, user=self.user)
|
||||
]
|
||||
if devices:
|
||||
webauthn_assertion_options = webauthn.WebAuthnAssertionOptions(
|
||||
devices,
|
||||
challenge
|
||||
auth_options = webauthn.generate_authentication_options(
|
||||
rp_id=get_webauthn_rp_id(self.request),
|
||||
challenge=challenge,
|
||||
allow_credentials=devices,
|
||||
)
|
||||
ad = webauthn_assertion_options.assertion_dict
|
||||
ad['extensions'] = {
|
||||
'appid': get_u2f_appid(self.request)
|
||||
}
|
||||
ctx['jsondata'] = json.dumps(ad)
|
||||
|
||||
# Backwards compatibility to U2F
|
||||
j = json.loads(webauthn.options_to_json(auth_options))
|
||||
j["extensions"] = {"appid": get_u2f_appid(self.request)}
|
||||
ctx['jsondata'] = json.dumps(j)
|
||||
return ctx
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
@@ -674,6 +674,7 @@ def itemvar_select2(request, **kwargs):
|
||||
{
|
||||
'id': k,
|
||||
'text': str(v),
|
||||
'inactive': d,
|
||||
}
|
||||
for k, v, d in choices
|
||||
],
|
||||
@@ -715,6 +716,7 @@ def itemvars_select2(request, **kwargs):
|
||||
{
|
||||
'id': k,
|
||||
'text': str(v),
|
||||
'inactive': d,
|
||||
}
|
||||
for k, v, d in choices
|
||||
],
|
||||
|
||||
@@ -35,10 +35,9 @@
|
||||
import base64
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import time
|
||||
from collections import defaultdict
|
||||
from urllib.parse import quote, urlparse
|
||||
from urllib.parse import quote
|
||||
|
||||
import webauthn
|
||||
from django.conf import settings
|
||||
@@ -57,6 +56,7 @@ from django.views.generic import FormView, ListView, TemplateView, UpdateView
|
||||
from django_otp.plugins.otp_static.models import StaticDevice
|
||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||
from django_scopes import scopes_disabled
|
||||
from webauthn.helpers import generate_challenge, generate_user_handle
|
||||
|
||||
from pretix.base.auth import get_auth_backends
|
||||
from pretix.base.forms.auth import ReauthForm
|
||||
@@ -70,9 +70,9 @@ from pretix.control.forms.users import StaffSessionForm
|
||||
from pretix.control.permissions import (
|
||||
AdministratorPermissionRequiredMixin, StaffMemberRequiredMixin,
|
||||
)
|
||||
from pretix.control.views.auth import get_u2f_appid
|
||||
from pretix.control.views.auth import get_u2f_appid, get_webauthn_rp_id
|
||||
from pretix.helpers.http import redirect_to_url
|
||||
from pretix.helpers.webauthn import generate_challenge, generate_ukey
|
||||
from pretix.helpers.u2f import websafe_encode
|
||||
|
||||
REAL_DEVICE_TYPES = (TOTPDevice, WebAuthnDevice, U2FDevice)
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -105,25 +105,41 @@ class ReauthView(TemplateView):
|
||||
devices = U2FDevice.objects.filter(user=self.request.user)
|
||||
|
||||
for d in devices:
|
||||
credential_current_sign_count = d.sign_count if isinstance(d, WebAuthnDevice) else 0
|
||||
try:
|
||||
wu = d.webauthnuser
|
||||
|
||||
if isinstance(d, U2FDevice):
|
||||
# RP_ID needs to be appId for U2F devices, but we can't
|
||||
# set it that way in U2FDevice.webauthnuser, since that
|
||||
# breaks the frontend part.
|
||||
wu.rp_id = settings.SITE_URL
|
||||
|
||||
webauthn_assertion_response = webauthn.WebAuthnAssertionResponse(
|
||||
wu,
|
||||
resp,
|
||||
challenge,
|
||||
settings.SITE_URL,
|
||||
uv_required=False # User Verification
|
||||
webauthn_assertion_response = webauthn.verify_authentication_response(
|
||||
credential=resp,
|
||||
expected_challenge=base64.b64decode(challenge),
|
||||
expected_rp_id=get_webauthn_rp_id(self.request),
|
||||
expected_origin=settings.SITE_URL,
|
||||
credential_public_key=d.webauthnpubkey,
|
||||
credential_current_sign_count=credential_current_sign_count,
|
||||
)
|
||||
sign_count = webauthn_assertion_response.verify()
|
||||
sign_count = webauthn_assertion_response.new_sign_count
|
||||
if sign_count < credential_current_sign_count:
|
||||
raise Exception("Possible replay attack, sign count not higher")
|
||||
except Exception:
|
||||
logger.exception('U2F login failed')
|
||||
if isinstance(d, U2FDevice):
|
||||
# https://www.w3.org/TR/webauthn/#sctn-appid-extension says
|
||||
# "When verifying the assertion, expect that the rpIdHash MAY be the hash of the AppID instead of the RP ID."
|
||||
try:
|
||||
webauthn_assertion_response = webauthn.verify_authentication_response(
|
||||
credential=resp,
|
||||
expected_challenge=base64.b64decode(challenge),
|
||||
expected_rp_id=get_u2f_appid(self.request),
|
||||
expected_origin=settings.SITE_URL,
|
||||
credential_public_key=d.webauthnpubkey,
|
||||
credential_current_sign_count=credential_current_sign_count,
|
||||
)
|
||||
if webauthn_assertion_response.new_sign_count < 1:
|
||||
raise Exception("Possible replay attack, sign count set")
|
||||
except Exception:
|
||||
logger.exception('U2F login failed')
|
||||
else:
|
||||
valid = True
|
||||
break
|
||||
else:
|
||||
logger.exception('Webauthn login failed')
|
||||
else:
|
||||
if isinstance(d, WebAuthnDevice):
|
||||
d.sign_count = sign_count
|
||||
@@ -162,23 +178,24 @@ class ReauthView(TemplateView):
|
||||
ctx = super().get_context_data()
|
||||
if 'webauthn_challenge' in self.request.session:
|
||||
del self.request.session['webauthn_challenge']
|
||||
challenge = generate_challenge(32)
|
||||
self.request.session['webauthn_challenge'] = challenge
|
||||
challenge = generate_challenge()
|
||||
self.request.session['webauthn_challenge'] = base64.b64encode(challenge).decode()
|
||||
devices = [
|
||||
device.webauthnuser for device in WebAuthnDevice.objects.filter(confirmed=True, user=self.request.user)
|
||||
device.webauthndevice for device in WebAuthnDevice.objects.filter(confirmed=True, user=self.request.user)
|
||||
] + [
|
||||
device.webauthnuser for device in U2FDevice.objects.filter(confirmed=True, user=self.request.user)
|
||||
device.webauthndevice for device in U2FDevice.objects.filter(confirmed=True, user=self.request.user)
|
||||
]
|
||||
if devices:
|
||||
webauthn_assertion_options = webauthn.WebAuthnAssertionOptions(
|
||||
devices,
|
||||
challenge
|
||||
auth_options = webauthn.generate_authentication_options(
|
||||
rp_id=get_webauthn_rp_id(self.request),
|
||||
challenge=challenge,
|
||||
allow_credentials=devices,
|
||||
)
|
||||
ad = webauthn_assertion_options.assertion_dict
|
||||
ad['extensions'] = {
|
||||
'appid': get_u2f_appid(self.request)
|
||||
}
|
||||
ctx['jsondata'] = json.dumps(ad)
|
||||
|
||||
# Backwards compatibility to U2F
|
||||
j = json.loads(webauthn.options_to_json(auth_options))
|
||||
j["extensions"] = {"appid": get_u2f_appid(self.request)}
|
||||
ctx['jsondata'] = json.dumps(j)
|
||||
ctx['form'] = self.form
|
||||
return ctx
|
||||
|
||||
@@ -387,23 +404,26 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
|
||||
if 'webauthn_challenge' in self.request.session:
|
||||
del self.request.session['webauthn_challenge']
|
||||
|
||||
challenge = generate_challenge(32)
|
||||
ukey = generate_ukey()
|
||||
challenge = generate_challenge()
|
||||
ukey = generate_user_handle()
|
||||
|
||||
self.request.session['webauthn_challenge'] = challenge
|
||||
self.request.session['webauthn_register_ukey'] = ukey
|
||||
self.request.session['webauthn_challenge'] = base64.b64encode(challenge).decode()
|
||||
self.request.session['webauthn_register_ukey'] = base64.b64encode(ukey).decode()
|
||||
|
||||
make_credential_options = webauthn.WebAuthnMakeCredentialOptions(
|
||||
challenge,
|
||||
urlparse(settings.SITE_URL).netloc,
|
||||
urlparse(settings.SITE_URL).netloc,
|
||||
ukey,
|
||||
self.request.user.email,
|
||||
str(self.request.user),
|
||||
settings.SITE_URL,
|
||||
attestation="none"
|
||||
devices = [
|
||||
device.webauthndevice for device in WebAuthnDevice.objects.filter(confirmed=True, user=self.request.user)
|
||||
] + [
|
||||
device.webauthndevice for device in U2FDevice.objects.filter(confirmed=True, user=self.request.user)
|
||||
]
|
||||
make_credential_options = webauthn.generate_registration_options(
|
||||
rp_id=get_webauthn_rp_id(self.request),
|
||||
rp_name=get_webauthn_rp_id(self.request),
|
||||
user_id=ukey,
|
||||
user_name=self.request.user.email,
|
||||
challenge=challenge,
|
||||
exclude_credentials=devices,
|
||||
)
|
||||
ctx['jsondata'] = json.dumps(make_credential_options.registration_dict)
|
||||
ctx['jsondata'] = webauthn.options_to_json(make_credential_options)
|
||||
|
||||
return ctx
|
||||
|
||||
@@ -412,30 +432,13 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
|
||||
challenge = self.request.session['webauthn_challenge']
|
||||
ukey = self.request.session['webauthn_register_ukey']
|
||||
resp = json.loads(self.request.POST.get("token"))
|
||||
trust_anchor_dir = os.path.normpath(os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
'../../static/webauthn_trusted_attestation_roots' # currently does not exist
|
||||
))
|
||||
# We currently do not check attestation certificates, since there's no real risk
|
||||
# and we do not have any policies specifying what devices can be used. (Also, we
|
||||
# didn't get it to work.)
|
||||
# Read more: https://fidoalliance.org/fido-technotes-the-truth-about-attestation/
|
||||
trusted_attestation_cert_required = False
|
||||
self_attestation_permitted = True
|
||||
none_attestation_permitted = True
|
||||
|
||||
webauthn_registration_response = webauthn.WebAuthnRegistrationResponse(
|
||||
urlparse(settings.SITE_URL).netloc,
|
||||
settings.SITE_URL,
|
||||
resp,
|
||||
challenge,
|
||||
trust_anchor_dir,
|
||||
trusted_attestation_cert_required,
|
||||
self_attestation_permitted,
|
||||
none_attestation_permitted,
|
||||
uv_required=False
|
||||
registration_verification = webauthn.verify_registration_response(
|
||||
credential=resp,
|
||||
expected_challenge=base64.b64decode(challenge),
|
||||
expected_rp_id=get_webauthn_rp_id(self.request),
|
||||
expected_origin=settings.SITE_URL,
|
||||
)
|
||||
webauthn_credential = webauthn_registration_response.verify()
|
||||
|
||||
# Check that the credentialId is not yet registered to any other user.
|
||||
# If registration is requested for a credential that is already registered
|
||||
@@ -443,7 +446,7 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
|
||||
# ceremony, or it MAY decide to accept the registration, e.g. while deleting
|
||||
# the older registration.
|
||||
credential_id_exists = WebAuthnDevice.objects.filter(
|
||||
credential_id=webauthn_credential.credential_id
|
||||
credential_id=registration_verification.credential_id
|
||||
).first()
|
||||
if credential_id_exists:
|
||||
messages.error(request, _('This security device is already registered.'))
|
||||
@@ -451,14 +454,11 @@ class User2FADeviceConfirmWebAuthnView(RecentAuthenticationRequiredMixin, Templa
|
||||
'device': self.device.pk
|
||||
}))
|
||||
|
||||
webauthn_credential.credential_id = str(webauthn_credential.credential_id, "utf-8")
|
||||
webauthn_credential.public_key = str(webauthn_credential.public_key, "utf-8")
|
||||
|
||||
self.device.credential_id = webauthn_credential.credential_id
|
||||
self.device.ukey = ukey
|
||||
self.device.pub_key = webauthn_credential.public_key
|
||||
self.device.sign_count = webauthn_credential.sign_count
|
||||
self.device.rp_id = urlparse(settings.SITE_URL).netloc
|
||||
self.device.credential_id = websafe_encode(registration_verification.credential_id)
|
||||
self.device.ukey = websafe_encode(ukey)
|
||||
self.device.pub_key = websafe_encode(registration_verification.credential_public_key)
|
||||
self.device.sign_count = registration_verification.sign_count
|
||||
self.device.rp_id = get_webauthn_rp_id(request)
|
||||
self.device.icon_url = settings.SITE_URL
|
||||
self.device.confirmed = True
|
||||
self.device.save()
|
||||
|
||||
@@ -32,9 +32,14 @@ def clean_filename(fname):
|
||||
|
||||
"Terms.pdf" → "Terms.pdf.OybgvyAH.22c0583727d5bc.pdf"
|
||||
|
||||
This function reverses this operation:
|
||||
This function reverses this operation (leaving names without doubled extension as-is):
|
||||
|
||||
"Terms.pdf.OybgvyAH.22c0583727d5bc.pdf" → "Terms.pdf"
|
||||
"Terms.pdf" → "Terms.pdf"
|
||||
"""
|
||||
ext = '.' + fname.split('.')[-1]
|
||||
return fname.rsplit(ext + ".", 1)[0] + ext
|
||||
parts = fname.rsplit(ext + ".", 1)
|
||||
if len(parts) == 1:
|
||||
return parts[0]
|
||||
else:
|
||||
return parts[0] + ext
|
||||
|
||||
@@ -44,11 +44,12 @@ def validate_uploaded_file_for_valid_image(f):
|
||||
# have to read the data into memory.
|
||||
if hasattr(f, 'temporary_file_path'):
|
||||
file = f.temporary_file_path()
|
||||
elif hasattr(f, 'read'):
|
||||
if hasattr(f, 'seek') and callable(f.seek):
|
||||
f.seek(0)
|
||||
file = BytesIO(f.read())
|
||||
else:
|
||||
if hasattr(f, 'read'):
|
||||
file = BytesIO(f.read())
|
||||
else:
|
||||
file = BytesIO(f['content'])
|
||||
file = BytesIO(f['content'])
|
||||
|
||||
try:
|
||||
try:
|
||||
|
||||
@@ -62,7 +62,7 @@ def soft_equals(a, b):
|
||||
|
||||
def hard_equals(a, b):
|
||||
"""Implements the '===' operator."""
|
||||
if type(a) != type(b):
|
||||
if type(a) is not type(b):
|
||||
return False
|
||||
return a == b
|
||||
|
||||
|
||||
76
src/pretix/helpers/u2f.py
Normal file
76
src/pretix/helpers/u2f.py
Normal file
@@ -0,0 +1,76 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
# Backwards compatibility for old U2F key material, with code taken from
|
||||
#
|
||||
# https://github.com/Yubico/python-u2flib-server/blob/python-u2flib-server-4.0.1/u2flib_server/utils.py
|
||||
#
|
||||
# Copyright (c) 2013 Yubico AB
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or
|
||||
# without modification, are permitted provided that the following
|
||||
# conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
from base64 import urlsafe_b64decode, urlsafe_b64encode
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.serialization import load_der_public_key
|
||||
|
||||
PUB_KEY_DER_PREFIX = b'\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01' \
|
||||
b'\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00'
|
||||
|
||||
|
||||
def pub_key_from_der(der):
|
||||
return load_der_public_key(PUB_KEY_DER_PREFIX + der, default_backend())
|
||||
|
||||
|
||||
def websafe_decode(data):
|
||||
if isinstance(data, str):
|
||||
data = data.encode('ascii')
|
||||
data += b'=' * (-len(data) % 4)
|
||||
return urlsafe_b64decode(data)
|
||||
|
||||
|
||||
def websafe_encode(data):
|
||||
if isinstance(data, str):
|
||||
data = data.encode('ascii')
|
||||
return urlsafe_b64encode(data).replace(b'=', b'').decode('ascii')
|
||||
@@ -1,45 +0,0 @@
|
||||
#
|
||||
# This file is part of pretix (Community Edition).
|
||||
#
|
||||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||||
# Copyright (C) 2020-2021 rami.io GmbH and contributors
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||||
#
|
||||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||||
# this file, see <https://pretix.eu/about/en/license>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
import random
|
||||
import string
|
||||
|
||||
|
||||
def generate_challenge(challenge_len):
|
||||
return ''.join([
|
||||
random.SystemRandom().choice(string.ascii_letters + string.digits)
|
||||
for i in range(challenge_len)
|
||||
])
|
||||
|
||||
|
||||
def generate_ukey():
|
||||
"""
|
||||
Its value's id member is required, and contains an identifier
|
||||
for the account, specified by the Relying Party. This is not meant
|
||||
to be displayed to the user, but is used by the Relying Party to
|
||||
control the number of credentials - an authenticator will never
|
||||
contain more than one credential for a given Relying Party under
|
||||
the same id.
|
||||
A unique identifier for the entity. For a relying party entity,
|
||||
sets the RP ID. For a user account entity, this will be an
|
||||
arbitrary string specified by the relying party.
|
||||
"""
|
||||
return generate_challenge(20)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2021-09-15 11:22+0000\n"
|
||||
"Last-Translator: Mohamed Tawfiq <mtawfiq@wafyapp.com>\n"
|
||||
"Language-Team: Arabic <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -639,23 +639,23 @@ msgstr "لا شيء"
|
||||
msgid "Selected only"
|
||||
msgstr "المختارة فقط"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "قم باستخدم اسم مختلف داخليا"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "اضغط لاغلاق الصفحة"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "لم تقم بحفظ التعديلات!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2020-12-19 07:00+0000\n"
|
||||
"Last-Translator: albert <albert.serra.monner@gmail.com>\n"
|
||||
"Language-Team: Catalan <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -610,23 +610,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-09-15 06:00+0000\n"
|
||||
"Last-Translator: Michael <michael.happl@gmx.at>\n"
|
||||
"Language-Team: Czech <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -633,23 +633,23 @@ msgstr "Žádný"
|
||||
msgid "Selected only"
|
||||
msgstr "Pouze vybrané"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Interně používat jiný název"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Kliknutím zavřete"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Máte neuložené změny!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -610,23 +610,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2022-12-01 17:00+0000\n"
|
||||
"Last-Translator: Mie Frydensbjerg <mif@aarhus.dk>\n"
|
||||
"Language-Team: Danish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -653,23 +653,23 @@ msgstr "Ingen"
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klik for at lukke"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du har ændringer, der ikke er gemt!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"PO-Revision-Date: 2023-11-28 15:36+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2024-02-10 00:00+0000\n"
|
||||
"Last-Translator: Phin Wolkwitz <wolkwitz@rami.io>\n"
|
||||
"Language-Team: German <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
"de/>\n"
|
||||
"Language: de\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.2.1\n"
|
||||
"X-Generator: Weblate 5.3.1\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -635,23 +635,23 @@ msgstr "Keine"
|
||||
msgid "Selected only"
|
||||
msgstr "Nur ausgewählte"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr "Geben Sie eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr "Ungültige Seitenzahl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Intern einen anderen Namen verwenden"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klicken zum Schließen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Sie haben ungespeicherte Änderungen!"
|
||||
|
||||
@@ -826,24 +826,19 @@ msgid "Only available with a voucher"
|
||||
msgstr "Nur mit Gutschein verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:35
|
||||
#, fuzzy
|
||||
#| msgid "Payment method unavailable"
|
||||
msgctxt "widget"
|
||||
msgid "Not yet available"
|
||||
msgstr "Zahlungsmethode nicht verfügbar"
|
||||
msgstr "Noch nicht verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:36
|
||||
msgctxt "widget"
|
||||
msgid "Not available anymore"
|
||||
msgstr ""
|
||||
msgstr "Nicht mehr verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:37
|
||||
#, fuzzy
|
||||
#| msgctxt "widget"
|
||||
#| msgid "currently available: %s"
|
||||
msgctxt "widget"
|
||||
msgid "Currently not available"
|
||||
msgstr "aktuell verfügbar: %s"
|
||||
msgstr "Aktuell nicht verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:38
|
||||
#, javascript-format
|
||||
@@ -935,20 +930,14 @@ msgid "Continue"
|
||||
msgstr "Fortfahren"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:56
|
||||
#, fuzzy
|
||||
#| msgctxt "widget"
|
||||
#| msgid "Select variant %s"
|
||||
msgctxt "widget"
|
||||
msgid "Show variants"
|
||||
msgstr "Variante %s auswählen"
|
||||
msgstr "Varianten zeigen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:57
|
||||
#, fuzzy
|
||||
#| msgctxt "widget"
|
||||
#| msgid "Select variant %s"
|
||||
msgctxt "widget"
|
||||
msgid "Hide variants"
|
||||
msgstr "Variante %s auswählen"
|
||||
msgstr "Varianten verstecken"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:58
|
||||
msgctxt "widget"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,9 +7,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"PO-Revision-Date: 2023-11-28 15:36+0000\n"
|
||||
"Last-Translator: Raphael Michel <michel@rami.io>\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2024-02-10 00:00+0000\n"
|
||||
"Last-Translator: Phin Wolkwitz <wolkwitz@rami.io>\n"
|
||||
"Language-Team: German (informal) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix-js/de_Informal/>\n"
|
||||
"Language: de_Informal\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.2.1\n"
|
||||
"X-Generator: Weblate 5.3.1\n"
|
||||
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:56
|
||||
#: pretix/plugins/banktransfer/static/pretixplugins/banktransfer/ui.js:62
|
||||
@@ -634,23 +634,23 @@ msgstr "Keine"
|
||||
msgid "Selected only"
|
||||
msgstr "Nur ausgewählte"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr "Gib eine Seitenzahl zwischen 1 und %(max)s ein."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr "Ungültige Seitenzahl."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Intern einen anderen Namen verwenden"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klicken zum Schließen"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du hast ungespeicherte Änderungen!"
|
||||
|
||||
@@ -825,24 +825,19 @@ msgid "Only available with a voucher"
|
||||
msgstr "Nur mit Gutschein verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:35
|
||||
#, fuzzy
|
||||
#| msgid "Payment method unavailable"
|
||||
msgctxt "widget"
|
||||
msgid "Not yet available"
|
||||
msgstr "Zahlungsmethode nicht verfügbar"
|
||||
msgstr "Noch nicht verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:36
|
||||
msgctxt "widget"
|
||||
msgid "Not available anymore"
|
||||
msgstr ""
|
||||
msgstr "Nicht mehr verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:37
|
||||
#, fuzzy
|
||||
#| msgctxt "widget"
|
||||
#| msgid "currently available: %s"
|
||||
msgctxt "widget"
|
||||
msgid "Currently not available"
|
||||
msgstr "aktuell verfügbar: %s"
|
||||
msgstr "Aktuell nicht verfügbar"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:38
|
||||
#, javascript-format
|
||||
@@ -934,20 +929,14 @@ msgid "Continue"
|
||||
msgstr "Fortfahren"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:56
|
||||
#, fuzzy
|
||||
#| msgctxt "widget"
|
||||
#| msgid "Select variant %s"
|
||||
msgctxt "widget"
|
||||
msgid "Show variants"
|
||||
msgstr "Variante %s auswählen"
|
||||
msgstr "Varianten zeigen"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:57
|
||||
#, fuzzy
|
||||
#| msgctxt "widget"
|
||||
#| msgid "Select variant %s"
|
||||
msgctxt "widget"
|
||||
msgid "Hide variants"
|
||||
msgstr "Variante %s auswählen"
|
||||
msgstr "Varianten verstecken"
|
||||
|
||||
#: pretix/static/pretixpresale/js/widget/widget.js:58
|
||||
msgctxt "widget"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2019-10-03 19:00+0000\n"
|
||||
"Last-Translator: Chris Spy <chrispiropoulou@hotmail.com>\n"
|
||||
"Language-Team: Greek <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -669,23 +669,23 @@ msgstr "Κανένας"
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Χρησιμοποιήστε διαφορετικό όνομα εσωτερικά"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Κάντε κλικ για να κλείσετε"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-11-07 14:00+0000\n"
|
||||
"Last-Translator: Zona Vip <contacto@zonavip.mx>\n"
|
||||
"Language-Team: Spanish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -639,23 +639,23 @@ msgstr "Ninguno"
|
||||
msgid "Selected only"
|
||||
msgstr "Solamente seleccionados"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Usar un nombre diferente internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Click para cerrar"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "¡Tienes cambios sin guardar!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2021-11-10 05:00+0000\n"
|
||||
"Last-Translator: Jaakko Rinta-Filppula <jaakko@r-f.fi>\n"
|
||||
"Language-Team: Finnish <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -634,23 +634,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Käytä toista nimeä sisäisesti"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Sulje klikkaamalla"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Sinulla on tallentamattomia muutoksia!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: French\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-09-11 10:00+0000\n"
|
||||
"Last-Translator: Ronan LE MEILLAT <ronan.le_meillat@highcanfly.club>\n"
|
||||
"Language-Team: French <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -638,23 +638,23 @@ msgstr "Aucun"
|
||||
msgid "Selected only"
|
||||
msgstr "Seuls les sélectionnés"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Utiliser un nom différent en interne"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Cliquez pour fermer"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Vous avez des modifications non sauvegardées !"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2022-02-22 22:00+0000\n"
|
||||
"Last-Translator: Ismael Menéndez Fernández <ismael.menendez@balidea.com>\n"
|
||||
"Language-Team: Galician <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -641,23 +641,23 @@ msgstr "Ningún"
|
||||
msgid "Selected only"
|
||||
msgstr "Soamente seleccionados"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Usar un nome diferente internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Click para cerrar"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Tes cambios sen gardar!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2021-09-24 13:54+0000\n"
|
||||
"Last-Translator: ofirtro <ofir.tro@gmail.com>\n"
|
||||
"Language-Team: Hebrew <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -617,23 +617,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2024-01-31 04:00+0000\n"
|
||||
"Last-Translator: Pavle Ergović <pavleergovic@gmail.com>\n"
|
||||
"Language-Team: Croatian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -611,23 +611,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2020-01-24 08:00+0000\n"
|
||||
"Last-Translator: Prokaj Miklós <mixolid0@gmail.com>\n"
|
||||
"Language-Team: Hungarian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -657,23 +657,23 @@ msgstr "Semmi"
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Használj másik nevet"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Bezárásért kattints"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Mentetlen változtatások!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-09-20 14:01+0000\n"
|
||||
"Last-Translator: Mahdia Aliyy <mahdlyy.k@gmail.com>\n"
|
||||
"Language-Team: Indonesian <https://translate.pretix.eu/projects/pretix/"
|
||||
@@ -640,23 +640,23 @@ msgstr "Tidak ada"
|
||||
msgid "Selected only"
|
||||
msgstr "Hanya dipilih"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Gunakan nama yang berbeda secara internal"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klik untuk menutup"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Anda memiliki perubahan yang belum disimpan!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-05-18 01:00+0000\n"
|
||||
"Last-Translator: M C <micasadmail@gmail.com>\n"
|
||||
"Language-Team: Italian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -635,23 +635,23 @@ msgstr "Nessuno"
|
||||
msgid "Selected only"
|
||||
msgstr "Solo i selezionati"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Utilizza un nome diverso internamente"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Clicca per chiudere"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Hai cambiamenti non salvati!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2022-03-15 00:00+0000\n"
|
||||
"Last-Translator: Yuriko Matsunami <y.matsunami@enobyte.com>\n"
|
||||
"Language-Team: Japanese <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -637,23 +637,23 @@ msgstr "ない"
|
||||
msgid "Selected only"
|
||||
msgstr "選択したもののみ"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "内部で別の名前を使用してください"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "クリックして閉じる"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "保存されていない変更があります!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -611,23 +611,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2022-04-06 03:00+0000\n"
|
||||
"Last-Translator: Liga V <lerning_by_dreaming@gmx.de>\n"
|
||||
"Language-Team: Latvian <https://translate.pretix.eu/projects/pretix/pretix-"
|
||||
@@ -644,23 +644,23 @@ msgstr "Neviens"
|
||||
msgid "Selected only"
|
||||
msgstr "Tikai atzīmētos"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Izmantojiet citu nosaukumu iekšēji"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Noklikšķiniet, lai aizvērtu"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Jums ir nesaglabātas izmaiņas!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-11-02 13:02+0000\n"
|
||||
"Last-Translator: fyksen <fredrik@fyksen.me>\n"
|
||||
"Language-Team: Norwegian Bokmål <https://translate.pretix.eu/projects/pretix/"
|
||||
@@ -624,23 +624,23 @@ msgstr "Ingen"
|
||||
msgid "Selected only"
|
||||
msgstr "Kun valgte"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Bruk et annet navn internt"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klikk for å lukke"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Du har ikke-lagrede endringer!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-11-14 23:00+0000\n"
|
||||
"Last-Translator: Thomas Vranken <thvranken@gmail.com>\n"
|
||||
"Language-Team: Dutch <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -637,23 +637,23 @@ msgstr "Geen"
|
||||
msgid "Selected only"
|
||||
msgstr "Alleen geselecteerde"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Gebruik intern een andere naam"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klik om te sluiten"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "U heeft nog niet opgeslagen wijzigingen!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2021-08-05 04:00+0000\n"
|
||||
"Last-Translator: Maarten van den Berg <maartenberg1@gmail.com>\n"
|
||||
"Language-Team: Dutch (informal) <https://translate.pretix.eu/projects/pretix/"
|
||||
@@ -642,23 +642,23 @@ msgstr "Geen"
|
||||
msgid "Selected only"
|
||||
msgstr "Alleen geselecteerde"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Gebruik intern een andere naam"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Klik om te sluiten"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Je hebt nog niet opgeslagen wijzigingen!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: 2023-11-25 22:12+0000\n"
|
||||
"Last-Translator: c0de-bender <code-bender@mailbox.org>\n"
|
||||
"Language-Team: Polish <https://translate.pretix.eu/projects/pretix/pretix-js/"
|
||||
@@ -632,23 +632,23 @@ msgstr "Odznacz wszystko"
|
||||
msgid "Selected only"
|
||||
msgstr "Tylko wybrane"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr "Wprowadź numer strony między 1 a %(max)s."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr "Niepoprawny numer strony."
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr "Użyj innej nazwy wewnętrznie"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr "Zamknij"
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr "Masz niezapisane zmiany!"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-02-09 14:51+0000\n"
|
||||
"POT-Creation-Date: 2024-02-28 13:11+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -609,23 +609,23 @@ msgstr ""
|
||||
msgid "Selected only"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:784
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:791
|
||||
msgid "Enter page number between 1 and %(max)s."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:787
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:794
|
||||
msgid "Invalid page number."
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:945
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:952
|
||||
msgid "Use a different name internally"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:985
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:992
|
||||
msgid "Click to close"
|
||||
msgstr ""
|
||||
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1060
|
||||
#: pretix/static/pretixcontrol/js/ui/main.js:1067
|
||||
msgid "You have unsaved changes!"
|
||||
msgstr ""
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user