99import csv
1010import sys
1111import argparse
12+ import json
1213
1314
14- def sendMail (data , promocode , contactdata , dryrun , service ):
15+ def sendMail (pretix , pretalx , contactdata , dryrun , service ):
1516 # Create a message
17+ # Name,Role,Voucher,Link,Send,Redeem,,Name,Role,Voucher,Link
1618 my_email = 'info@pycon.se'
17- author = data ['Your name' ]
18- email = data ['Email Address' ]
19- other_email = data ['Additional speakers' ]
20- for address in [email , other_email ]:
19+ author = pretalx ['Name' ]
20+ email = pretalx ['Email' ]
21+ promocode = pretix ['Voucher' ]
22+ promolink = pretix ['Link' ]
23+ for address in [email ]:
2124 if address == "" :
2225 continue
2326 print ("Address:" , address )
2427 msg = MIMEMultipart ('alternative' )
25- msg ['Subject' ] = 'Information regarding PyCon Sweden 2023 '
28+ msg ['Subject' ] = 'Information regarding PyCon Sweden 2025 '
2629 msg ['From' ] = f'{ my_email } '
2730 msg ['To' ] = f'{ address } '
2831 msg ['Cc' ] = 'board@pycon.se'
32+ contact_name = contactdata ["name" ]
33+ contact_email = contactdata ["email" ]
34+ contact_mobile = contactdata ["mobile" ]
35+
36+ contact_others = ""
37+ for k , v in contactdata ["others" ].items ():
38+ contact_others += f" * { k } : { v } \n "
39+
2940 msgPlain = f'''Hi { author } ,
30- * Your ticket for the conference
41+ * Your ticket for the conference: { promocode } .
3142
32- Please get into eventbrint link, and use the promo-code :
43+ You can use the link below to enter the shop :
3344
34- { promocode }
45+ { promolink }
3546
36- and register yourself. It is important for us in order
47+ and register yourself. It is important for us in order
3748to control catering and generate your speaker badge.
3849You're entitled to only ONE ticket.
3950
40- https://www.eventbrite.com/e/pycon-sweden-2023-tickets-661650052117
4151
4252* Contact
4353
44- { contactdata }
54+ Your point of contact for the conference will be { contact_name } .
55+ You can reach me via in the following ways:
56+ * mobile: { contact_mobile }
57+ * email: { contact_email }
58+ { contact_others }
4559
4660We would like you to share your mobile phone so we can reach you
4761if necessary during the event.
4862
63+
4964* Program and time slot
5065
5166In case you didn't check yet, we've released our program in
5267our website. You can check there your talk date and time.
5368
54- https://www.pycon.se/#program
69+ https://pycon.se/#program
70+
5571
5672* About the presentations
5773
5874If you represent a company or want to show your company
5975please use maximum 2 slides for it and no more than 5 minutes.
6076The conference focus is Python and it shouldn't be used
61- to advertisement. So please keep this policy in mind during
77+ for advertisement. So please keep this policy in mind during
6278your talk.
6379
6480There is no template and we don't store the presentations.
6581You can decide whatever template that suits better for your
6682presentation slides.
6783
84+
6885* Regarding the presentation technicalities
6986
7087You can use resolution 1080p for your presentation (1920x1080 px).
7188We expect to have HDMI and USB-C connector for the equipment, but
7289we will confirm it on Wednesday.
7390
74- There will be wifi provided by Hilton as well.
91+ There will be wifi provided by the venue as well.
7592
7693We don't store the presentations, so you don't need to send it to
7794us in advance. All presentations will be recorded at main
7895auditorium. Videos will be released next year, but we don't
7996have yet a specific date about it.
8097
8198
99+
82100* Tips about presenting at the stage
83101
84- There is good manual or handbook for that, but we can recommend the
85- good "how to avoida death by powerpoint" with very clear points how
102+ There is no good manual or handbook for that, but we can recommend the
103+ good "how to avoid death by powerpoint" with very clear points how
86104to make great presentations.
87105
88106 https://youtu.be/Iwpi1Lm6dFo?si=vAjAQUun5dpLOxhK
89107
108+
109+
90110* About the venue
91111
92- Conference will be held at Hilton Slussen hotel , at Slussen
93- station served by subway green and red lines . It is close to
94- T-Centralen, main station located in Stockholm.
112+ Conference will be held at Clarion Hotel Stockholm , at Skanstull
113+ served by subway green line . It is close to T-Centralen, main station
114+ located in Stockholm.
95115
96116More info about the location:
97- https://www.hilton .com/en/hotels/stoslhi-hilton-stockholm-slussen /
117+ https://clarion-stockholm-hotel.hotel-ds .com/en/
98118
99- We will be at Hilton on Wednesday, November 8th, around 4 pm
119+ We will be at the venue on Wednesday, 29 October, from 4-6 pm
100120to meet organization personel and prepare for next day.
101121You're welcome to meet us there too and give a try on the
102122equipment for presentation.
@@ -105,22 +125,32 @@ def sendMail(data, promocode, contactdata, dryrun, service):
105125equipment or before the conference begins, at 8 am, or during
106126the coffee breaks. We can also check at the end of first day.
107127
128+
108129 * Credentials
109130
110131There will be a badge with your name at the entrance. If you
111132attend the gattering on Wednesday you can also fetch it there.
112133
134+
113135 * Speakers photo
114136
115137We will try to have a photo with as much speakers as possible on
116- November 8th at lunch time (around 12:00). Please stay at the
138+ 30 October at lunch time (around 12:00). Please stay at the
117139auditorium when lunch time starts for it. It will take only 5
118140minutes.
119141
142+
143+ * Halloween parthy
144+
145+ This year we will have a mingle with Halloween themed party.
146+ So bring your best costume and be scarry 🎃, and have fun.
147+ Admitance is free of charge for speakers.
148+
149+
120150Best Regards,
121- PyCon Sweden 2023 organization board
151+ PyCon Sweden 2025 organization board
122152'''
123- msg ['Cc' ] = 'board @pycon.se'
153+ msg ['Cc' ] = 'helio @pycon.se'
124154 print (msgPlain )
125155 msg .attach (MIMEText (msgPlain , 'plain' ))
126156 raw = base64 .urlsafe_b64encode (msg .as_bytes ())
@@ -138,24 +168,44 @@ def sendMail(data, promocode, contactdata, dryrun, service):
138168 print (f'Message Id: { email } would be sent' )
139169 print ('====' )
140170
171+ def get_contact (speakers_json : dict , speaker_name : str ) -> dict | None :
172+ """
173+ 3 │ "ID": "123456",
174+ 4 │ "Name": "Julius Cezar",
175+ 5 │ "Email": "julius_cezar@hl.eng.br",
176+ 6 │ "Proposal IDs": [
177+ 7 │ "ABCDEF",
178+ 8 │ "GHIJKL"
179+ 9 │ ],
180+ 10 │ "Proposal titles": [
181+ 11 │ "Python for emperors",
182+ 12 │ "Using Python to conquer the world"
183+ 13 │ ]
184+ 14 │ },
185+ """
186+ for data in speakers_json :
187+ if data ["Name" ] == speaker_name :
188+ return data
189+ # not found
190+ return None
141191
142192if __name__ == '__main__' :
143193 parse = argparse .ArgumentParser (
144194 description = "Script to send information to all speakers" )
145195 parse .add_argument (
146- "--csvfile " ,
196+ "--pretalxjson " ,
147197 required = True ,
148198 help =
149- "The CSV file dumped from Google spreadsheet with speakers information"
199+ "The JSON file dumped from Pretalx with speakers information"
150200 )
151- parse .add_argument ("--promocode " ,
201+ parse .add_argument ("--pretixcodes " ,
152202 required = True ,
153- help = "EventBrite promocode to send for speakers" )
203+ help = "Pretix promocode CSV to send for speakers" )
154204 parse .add_argument (
155- "--contactfile " ,
205+ "--contactjson " ,
156206 required = True ,
157207 help =
158- "Details from contact in a file (to avoid exposing information in the Internet"
208+ "Details from contact in a JSON file (to avoid exposing information in the Internet"
159209 )
160210 parse .add_argument ("--dryrun" ,
161211 action = 'store_true' ,
@@ -174,12 +224,19 @@ def sendMail(data, promocode, contactdata, dryrun, service):
174224 # Build the service
175225 service = googleapiclient .discovery .build ('gmail' , 'v1' , credentials = creds )
176226
177- with open (args .contactfile ) as fd :
178- contact_data = fd .read ().rstrip ()
227+ with open (args .contactjson ) as fd :
228+ contact_data = json .load (fd )
229+
230+ with open (args .pretalxjson ) as fd :
231+ speakersJSON = json .load (fd )
179232
180- with open (args .csvfile , newline = '' ) as csvfile :
233+ with open (args .pretixcodes , newline = '' ) as csvfile :
181234 csvreader = csv .DictReader (csvfile )
182235 for row in csvreader :
183- if row ['Confirmed' ].lower () == "yes" :
184- sendMail (row , args .promocode , contact_data , args .dryrun ,
236+ # Name,Role,Voucher,Link,Send,Redeem,,Name,Role,Voucher,Link
237+ data = get_contact (speakersJSON , row ['Name' ])
238+ if data is None :
239+ print (f"WARNING: { row ['Name' ]} not found" )
240+ continue
241+ sendMail (row , data , contact_data , args .dryrun ,
185242 service )
0 commit comments