|
1 | 1 | import asyncio
|
| 2 | +import html |
2 | 3 | import json
|
3 | 4 | import os
|
4 | 5 |
|
|
8 | 9 |
|
9 | 10 | session = Session()
|
10 | 11 | headers = {
|
11 |
| - "Authorization": f"Bearer {os.environ['EVENTBRITE_TOKEN']}" |
| 12 | + "Authorization": f"Bearer {os.environ['EVENTBRITE_TOKEN']}" |
12 | 13 | }
|
13 | 14 |
|
14 | 15 | eventBriteApiUrl = "https://www.eventbriteapi.com/v3/"
|
15 | 16 | organisationId = "464103861019"
|
16 | 17 |
|
17 | 18 | monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
18 |
| -eventTemplate = "<div class=\"row card\"> <div class=\"col-12`eventClass`\"> <div class=\"row\"> <div class=\"col-sm-4 col-lg-2 event-date\"> <span class=\"event-date-month\">`month`</span> <span class=\"event-date-day\">`day`</span> <p> <span class=\"event-date-start-time\">`eventStart``eventStartAmPm` - </span> <span class=\"event-date-end-time\">`eventEnd``eventEndAmPm`</span> </p> </div> <div class=\"col-sm-8 col-lg-10 event-title\"> <span class=\"event-title\">`eventName`</span>`venueDetails`</div> </div> <div class=\"row\"> <div class=\"col-md-12 col-lg-9 event-description\"> <span class=\"event-description\">`eventDescription`</span> </div> <div class=\"col-md-12 col-lg-3 event-book-button\"> <!-- Noscript content for added SEO --> <noscript> <a href=\"https://www.eventbrite.co.uk/e/online-coding-drop-in-tickets-`eventId`\"rel=\"noopener noreferrer\" target=\"_blank\">Register</a> </noscript> <!-- You can customize this button any way you like --> <button id=\"eventbrite-widget-modal-trigger-`eventId`\" class=\"btn `registerButtonClass` float-right\" type=\"button\">`registerButtonText`</button> <script type=\"text/javascript\"> var onOrderComplete = function() { console.log('Order complete!'); };window.EBWidgets.createWidget({ widgetType: 'checkout',eventId: '`eventId`',modal: true,modalTriggerElementId: 'eventbrite-widget-modal-trigger-`eventId`',onOrderComplete}); </script> </div> </div></div>" |
| 19 | +eventTemplate = "<div class=\"row card\"> <div class=\"col-12`eventClass`\"> <div class=\"row\"> <div class=\"col-sm-4 col-lg-2 event-date\"> <span class=\"event-date-month\">`month`</span> <span class=\"event-date-day\">`day`</span> <p> <span class=\"event-date-start-time\" >`eventStart``eventStartAmPm` - </span> <span class=\"event-date-end-time\">`eventEnd``eventEndAmPm`</span> </p> </div> <div class=\"col-sm-8 col-lg-10 event-title\"> <span class=\"event-title\">`eventName`</span>`venueDetails` </div> </div> <div class=\"row\"> <div class=\"col-md-12 col-lg-9 event-description\"> <span class=\"event-description\">`eventDescription`</span> </div> <div class=\"col-md-12 col-lg-3 event-book-button\"> <!-- Noscript content for added SEO --> <noscript> <a href=\"https://www.eventbrite.co.uk/e/online-coding-drop-in-tickets-`eventId`\" rel=\"noopener noreferrer\" target=\"_blank\" >Register</a > </noscript> <!-- You can customize this button any way you like --> <button id=\"eventbrite-widget-modal-trigger-`eventId`\" class=\"btn `registerButtonClass` float-right\" type=\"button\" > `registerButtonText` </button> </div> </div> </div></div>" |
19 | 20 | venueTemplate = "<p><b>`venueName`</b>, `venueAddress`</p>"
|
20 | 21 | widgetPrefix = "var orderComplete = function () {var resultString = \"Order complete!\";alert(resultString);console.log(resultString);};"
|
21 | 22 | widgetTemplate = "/* `eventName` */ window.EBWidgets.createWidget({widgetType: 'checkout',eventId: '`eventId`',modal: true,modalTriggerElementId: '`eventbriteWidgetModalTriggerEventId`',onOrderComplete: orderComplete});"
|
22 | 23 |
|
23 | 24 | async def fetchEventTicketClasses(session, eventId):
|
24 |
| - url = eventBriteApiUrl + "events/" + str(eventId) + "/ticket_classes/" |
25 |
| - async with session.get(url = url, headers = headers) as response: |
26 |
| - responseJson = await response.json() |
27 |
| - return {'eventId': eventId, 'response': responseJson} |
| 25 | + url = eventBriteApiUrl + "events/" + str(eventId) + "/ticket_classes/" |
| 26 | + async with session.get(url = url, headers = headers) as response: |
| 27 | + responseJson = await response.json() |
| 28 | + return {'eventId': eventId, 'response': responseJson} |
28 | 29 |
|
29 | 30 | def getOrganisationEvents(organisationId):
|
30 |
| - eventsUrl = eventBriteApiUrl + "organizations/" + str(organisationId) + "/events/?time_filter=current_future&status=live" |
31 |
| - response = session.get(url = eventsUrl, headers = headers) |
32 |
| - return json.loads(response.text)['events'] |
| 31 | + eventsUrl = eventBriteApiUrl + "organizations/" + str(organisationId) + "/events/?time_filter=current_future&status=live" |
| 32 | + response = session.get(url = eventsUrl, headers = headers) |
| 33 | + return json.loads(response.text)['events'] |
33 | 34 |
|
34 | 35 | def getVenueDetails(venueId):
|
35 |
| - venuesUrl = eventBriteApiUrl + "venues/" + str(venueId) |
36 |
| - response = session.get(url = venuesUrl, headers = headers) |
37 |
| - return json.loads(response.text) |
| 36 | + venuesUrl = eventBriteApiUrl + "venues/" + str(venueId) |
| 37 | + response = session.get(url = venuesUrl, headers = headers) |
| 38 | + return json.loads(response.text) |
38 | 39 |
|
39 | 40 | async def getEventTicketClasses(eventData):
|
40 |
| - async with ClientSession() as session: |
41 |
| - asyncTasks = [] |
42 |
| - for event in eventData: |
43 |
| - asyncTasks.append(fetchEventTicketClasses(session, event['id'])) |
| 41 | + async with ClientSession() as session: |
| 42 | + asyncTasks = [] |
| 43 | + for event in eventData: |
| 44 | + asyncTasks.append(fetchEventTicketClasses(session, event['id'])) |
44 | 45 |
|
45 |
| - responses = await asyncio.gather(*asyncTasks, return_exceptions=True) |
| 46 | + responses = await asyncio.gather(*asyncTasks, return_exceptions=True) |
46 | 47 |
|
47 |
| - ticketClassData = {} |
48 |
| - for response in responses: |
49 |
| - if response['response']['pagination']['object_count'] == 0: |
50 |
| - continue |
| 48 | + ticketClassData = {} |
| 49 | + for response in responses: |
| 50 | + if response['response']['pagination']['object_count'] == 0: |
| 51 | + continue |
51 | 52 |
|
52 |
| - ticketClassData[response['eventId']] = response['response'] |
53 |
| - |
54 |
| - return ticketClassData |
| 53 | + ticketClassData[response['eventId']] = response['response'] |
| 54 | + |
| 55 | + return ticketClassData |
55 | 56 |
|
56 | 57 | def processOrganisationEventsResponse(response):
|
57 |
| - global organisationEvents |
58 |
| - organisationEvents = json.loads(response.text) |
| 58 | + global organisationEvents |
| 59 | + organisationEvents = json.loads(response.text) |
59 | 60 |
|
60 | 61 | def processEventTicketClassesResponse(response):
|
61 |
| - global ticketClasses |
62 |
| - ticketClasses = json.loads(response.text)['ticket_classes'] |
| 62 | + global ticketClasses |
| 63 | + ticketClasses = json.loads(response.text)['ticket_classes'] |
63 | 64 |
|
64 | 65 | def getEventsAsHtml(event, lambda_context):
|
65 |
| - content = "" |
66 |
| - dropins = "" |
67 |
| - huddles = "" |
68 |
| - workshops = "" |
| 66 | + content = "" |
| 67 | + dropins = "" |
| 68 | + huddles = "" |
| 69 | + workshops = "" |
| 70 | + |
| 71 | + widgets = widgetPrefix |
| 72 | + |
| 73 | + eventData = getOrganisationEvents(organisationId) |
| 74 | + ticketClassData = asyncio.run(getEventTicketClasses(eventData)) |
| 75 | + |
| 76 | + for event in eventData: |
| 77 | + if event['status'] != "live": |
| 78 | + continue |
69 | 79 |
|
70 |
| - widgets = widgetPrefix |
| 80 | + eventId = event['id'] |
| 81 | + venue = None if event['venue_id'] is None else getVenueDetails(event['venue_id']) |
71 | 82 |
|
72 |
| - eventData = getOrganisationEvents(organisationId) |
73 |
| - ticketClassData = asyncio.run(getEventTicketClasses(eventData)) |
| 83 | + ticketClasses = ticketClassData[eventId]['ticket_classes'] |
| 84 | + onSaleStatus = '' if ticketClasses == [] else ticketClasses[0]['on_sale_status'] |
| 85 | + |
| 86 | + eventClass = '' |
| 87 | + registerButtonClass = 'btn-primary' |
| 88 | + registerButtonText = 'Register' |
| 89 | + if onSaleStatus == 'SOLD_OUT': |
| 90 | + eventClass = ' event-sold-out' |
| 91 | + registerButtonClass = 'btn-default' |
| 92 | + registerButtonText = 'Sold out' |
| 93 | + |
| 94 | + startDate = datetime.strptime(event['start']['local'], "%Y-%m-%dT%H:%M:%S") |
| 95 | + endDate = datetime.strptime(event['end']['local'], "%Y-%m-%dT%H:%M:%S") |
| 96 | + |
| 97 | + month = monthNames[startDate.month - 1][:3].upper() |
| 98 | + day = startDate.day |
| 99 | + eventStart = startDate.hour |
| 100 | + eventEnd = endDate.hour |
| 101 | + eventName = html.escape(event['name']['text'] or "") |
| 102 | + eventDescription = html.escape(event['description']['text'] or "") |
| 103 | + |
| 104 | + eventStartAmPm = "am" |
| 105 | + eventEndAmPm = "am" |
| 106 | + |
| 107 | + if eventStart > 12: |
| 108 | + eventStart -= 12 |
| 109 | + eventStartAmPm = "pm" |
| 110 | + |
| 111 | + if eventEnd > 12: |
| 112 | + eventEnd -= 12 |
| 113 | + eventEndAmPm = "pm" |
| 114 | + |
| 115 | + eventHtml = eventTemplate \ |
| 116 | + .replace("`eventClass`", eventClass) \ |
| 117 | + .replace("`registerButtonClass`", registerButtonClass) \ |
| 118 | + .replace("`registerButtonText`", registerButtonText) \ |
| 119 | + .replace("`eventClass`", eventClass) \ |
| 120 | + .replace("`month`", month) \ |
| 121 | + .replace("`day`", str(day)) \ |
| 122 | + .replace("`eventStart`", str(eventStart)) \ |
| 123 | + .replace("`eventStartAmPm`", eventStartAmPm) \ |
| 124 | + .replace("`eventEnd`", str(eventEnd)) \ |
| 125 | + .replace("`eventEndAmPm`", eventEndAmPm) \ |
| 126 | + .replace("`eventName`", eventName) \ |
| 127 | + .replace("`eventDescription`", eventDescription) \ |
| 128 | + .replace("`eventId`", eventId) \ |
| 129 | + .replace("`eventbriteWidgetModalTriggerEventId`", "eventbrite-widget-modal-trigger-" + eventId) |
| 130 | + |
| 131 | + if venue is None: |
| 132 | + eventHtml = eventHtml.replace("`venueDetails`", "") |
| 133 | + else: |
| 134 | + eventHtml = eventHtml \ |
| 135 | + .replace("`venueDetails`", venueTemplate) \ |
| 136 | + .replace("`venueName`", venue['name']) \ |
| 137 | + .replace("`venueAddress`", venue['address']['localized_address_display']) |
| 138 | + |
| 139 | + widgets += "\r\n" + widgetTemplate \ |
| 140 | + .replace("`eventName`", eventName) \ |
| 141 | + .replace("`eventId`", eventId) \ |
| 142 | + .replace("`eventbriteWidgetModalTriggerEventId`", "eventbrite-widget-modal-trigger-" + eventId) |
| 143 | + |
| 144 | + content += eventHtml |
| 145 | + |
| 146 | + if 'drop' in eventName.lower() and 'in' in eventName.lower(): |
| 147 | + dropins += eventHtml |
| 148 | + elif 'huddle' in eventName.lower(): |
| 149 | + huddles += eventHtml |
| 150 | + else: |
| 151 | + workshops += eventHtml |
74 | 152 |
|
75 |
| - for event in eventData: |
76 |
| - if event['status'] != "live": |
77 |
| - continue |
78 |
| - |
79 |
| - eventId = event['id'] |
80 |
| - venue = None if event['venue_id'] is None else getVenueDetails(event['venue_id']) |
81 |
| - |
82 |
| - ticketClasses = ticketClassData[eventId]['ticket_classes'] |
83 |
| - onSaleStatus = '' if ticketClasses == [] else ticketClasses[0]['on_sale_status'] |
84 |
| - |
85 |
| - eventClass = '' |
86 |
| - registerButtonClass = 'btn-primary' |
87 |
| - registerButtonText = 'Register' |
88 |
| - if onSaleStatus == 'SOLD_OUT': |
89 |
| - eventClass = ' event-sold-out' |
90 |
| - registerButtonClass = 'btn-default' |
91 |
| - registerButtonText = 'Sold out' |
92 |
| - |
93 |
| - startDate = datetime.strptime(event['start']['local'], "%Y-%m-%dT%H:%M:%S") |
94 |
| - endDate = datetime.strptime(event['end']['local'], "%Y-%m-%dT%H:%M:%S") |
95 |
| - |
96 |
| - month = monthNames[startDate.month - 1][:3].upper() |
97 |
| - day = startDate.day |
98 |
| - eventStart = startDate.hour |
99 |
| - eventEnd = endDate.hour |
100 |
| - eventName = event['name']['text'] |
101 |
| - eventDescription = event['description']['text'] |
102 |
| - |
103 |
| - eventStartAmPm = "am" |
104 |
| - eventEndAmPm = "am" |
105 |
| - |
106 |
| - if eventStart > 12: |
107 |
| - eventStart -= 12 |
108 |
| - eventStartAmPm = "pm" |
109 |
| - |
110 |
| - if eventEnd > 12: |
111 |
| - eventEnd -= 12 |
112 |
| - eventEndAmPm = "pm" |
113 |
| - |
114 |
| - eventHtml = eventTemplate \ |
115 |
| - .replace("`eventClass`", eventClass) \ |
116 |
| - .replace("`registerButtonClass`", registerButtonClass) \ |
117 |
| - .replace("`registerButtonText`", registerButtonText) \ |
118 |
| - .replace("`eventClass`", eventClass) \ |
119 |
| - .replace("`month`", month) \ |
120 |
| - .replace("`day`", str(day)) \ |
121 |
| - .replace("`eventStart`", str(eventStart)) \ |
122 |
| - .replace("`eventStartAmPm`", eventStartAmPm) \ |
123 |
| - .replace("`eventEnd`", str(eventEnd)) \ |
124 |
| - .replace("`eventEndAmPm`", eventEndAmPm) \ |
125 |
| - .replace("`eventName`", eventName) \ |
126 |
| - .replace("`eventDescription`", eventDescription) \ |
127 |
| - .replace("`eventId`", eventId) \ |
128 |
| - .replace("`eventbriteWidgetModalTriggerEventId`", "eventbrite-widget-modal-trigger-" + eventId) |
129 |
| - |
130 |
| - if venue is None: |
131 |
| - eventHtml = eventHtml.replace("`venueDetails`", "") |
132 |
| - else: |
133 |
| - eventHtml = eventHtml \ |
134 |
| - .replace("`venueDetails`", venueTemplate) \ |
135 |
| - .replace("`venueName`", venue['name']) \ |
136 |
| - .replace("`venueAddress`", venue['address']['localized_address_display']) |
137 |
| - |
138 |
| - widgets += "\r\n" + widgetTemplate \ |
139 |
| - .replace("`eventName`", eventName) \ |
140 |
| - .replace("`eventId`", eventId) \ |
141 |
| - .replace("`eventbriteWidgetModalTriggerEventId`", "eventbrite-widget-modal-trigger-" + eventId) |
142 |
| - |
143 |
| - content += eventHtml |
144 |
| - |
145 |
| - if 'drop' in eventName.lower() and 'in' in eventName.lower(): |
146 |
| - dropins += eventHtml |
147 |
| - elif 'huddle' in eventName.lower(): |
148 |
| - huddles += eventHtml |
149 |
| - else: |
150 |
| - workshops += eventHtml |
151 |
| - |
152 |
| - if dropins == "": |
153 |
| - dropins = "<p>We don't have any drop-ins scheduled at the moment. Ask on Slack if you'd like us to arrange one.</p>" |
154 |
| - |
155 |
| - if huddles == "": |
156 |
| - huddles = "<p>We don't have any huddles scheduled at the moment. Ask on Slack if you'd like us to arrange one.</p>" |
157 |
| - |
158 |
| - if workshops == "": |
159 |
| - workshops = "<p>We don't have any workshops planned at the moment. Ask on Slack if you'd like us to arrange one.</p>" |
160 |
| - |
161 |
| - return {'statusCode': 200, 'content': content, 'dropins': dropins, 'huddles': huddles, 'workshops': workshops, 'widgets': widgets} |
| 153 | + if dropins == "": |
| 154 | + dropins = "<p>We don't have any drop-ins scheduled at the moment. Ask on Slack if you'd like us to arrange one.</p>" |
| 155 | + |
| 156 | + if huddles == "": |
| 157 | + huddles = "<p>We don't have any huddles scheduled at the moment. Ask on Slack if you'd like us to arrange one.</p>" |
| 158 | + |
| 159 | + if workshops == "": |
| 160 | + workshops = "<p>We don't have any workshops planned at the moment. Ask on Slack if you'd like us to arrange one.</p>" |
| 161 | + |
| 162 | + return {'statusCode': 200, 'content': content, 'dropins': dropins, 'huddles': huddles, 'workshops': workshops, 'widgets': widgets} |
0 commit comments