Skip to content

Commit b1e0c6b

Browse files
authored
Merge pull request #2 from devdaydresden/pretix-orders-address-source
Pretix orders address source
2 parents aaaead5 + 91d6daf commit b1e0c6b

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ pretix://:<pretix_token>@pretix.eu/<organizer>
4646

4747
`<organizer>` is the short name of the organizer. You can find valid organizer names at https://pretix.eu/control/organizers/.
4848

49+
A variant of the Pretix address source that uses addresses from orders is available via the
50+
`pretix-orders` address scheme:
51+
52+
Pretix orders URI Example:
53+
```
54+
pretix-orders://:<pretix_token>@pretix.eu/<organizer>/<event>
55+
```
56+
57+
The `<pretix_token>` and `<organizer>` fields are the same as for the `pretix` URI scheme.
58+
59+
`<event>` is the technical identifier for the event.
60+
4961
## License
5062

5163
This program is free software: you can redistribute it and/or modify

devday_mailbot.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22
#
3-
# Copyright 2024 Dev Day Dresden e.V.
3+
# Copyright Dev Day Dresden e.V.
44
#
55
# This program is free software: you can redistribute it and/or modify
66
# it under the terms of the GNU General Public License as published by
@@ -59,10 +59,16 @@ def get_addresses(self) -> list[str]:
5959
return sourcefile.readlines()
6060

6161

62-
class PretixAddressSource(AddressSource):
62+
class BasePretixAddressSource(AddressSource):
6363
def __init__(self, token, netloc, path):
64-
self.token, self.netloc, self.organizer = token, netloc, path[1:]
64+
if len(path) < 2:
65+
raise ValueError("path is too short")
66+
if path.count("/") < 1:
67+
raise ValueError("invalid path")
68+
self.token, self.netloc, self.organizer = token, netloc, path[1:].split("/")[0]
6569

70+
71+
class PretixCustomerAddressSource(BasePretixAddressSource):
6672
def get_addresses(self) -> list[str]:
6773
addresses = []
6874
url = f"https://{self.netloc}/api/v1/organizers/{self.organizer}/customers/"
@@ -81,14 +87,44 @@ def get_addresses(self) -> list[str]:
8187
return addresses
8288

8389

90+
class PretixOrderAddressSource(BasePretixAddressSource):
91+
def __init__(self, token, netloc, path):
92+
if len(path) < 4:
93+
raise ValueError("path is too short")
94+
if path.count("/") != 2:
95+
raise ValueError("invalid path")
96+
super().__init__(token, netloc, path)
97+
self.event = path[1:].split("/")[1]
98+
99+
def get_addresses(self) -> list[str]:
100+
addresses = []
101+
url = f"https://{self.netloc}/api/v1/organizers/{self.organizer}/events/{self.event}/orders/?status=p"
102+
while True:
103+
r = get(url, headers={"Authorization": f"Token {self.token}"})
104+
r.raise_for_status()
105+
json_data = r.json()
106+
for order in json_data["results"]:
107+
for position in order["positions"]:
108+
if position["attendee_email"]:
109+
addresses.append(position["attendee_email"])
110+
addresses.append(order["email"])
111+
if not json_data["next"]:
112+
break
113+
url = json_data["next"]
114+
return list(sorted(set(addresses)))
115+
116+
84117
def determine_address_source(src_url: str) -> AddressSource:
85118
url = urlparse(src_url)
86119

87120
if url.scheme == "file":
88121
return FileAddressSource(url.path)
89122

90123
if url.scheme == "pretix":
91-
return PretixAddressSource(url.password, url.hostname, url.path)
124+
return PretixCustomerAddressSource(url.password, url.hostname, url.path)
125+
126+
if url.scheme == "pretix-orders":
127+
return PretixOrderAddressSource(url.password, url.hostname, url.path)
92128

93129
raise ValueError(f"unsupported URL scheme {url.scheme}")
94130

0 commit comments

Comments
 (0)