QRCode – A thank you note


Given that the mailing lists are often used to ask questions when we get in trouble, report bugs and other issues, conduct public discussion between strong headed individuals, we quickly forget what a fantastic platform Pharo is.
Last month I implemented a rough MVP-style ticket sales platform that was successfully used to sell and validate at the entrance, about 1000 digital, online tickets for a relatively large 3000+ attendance event (a party). It took only a couple of days to build and deploy, and it was a lot of fun – it was even done in ‘unstable’ Pharo 7.
Early on I decided to identify each individual ticket by a unique URL. For easier presentation and scanning purposes, I encoded that URL in a QR code.
Although I am grateful for the whole Pharo ecosystem (including Seaside), we all build on top of other people’s work, I was especially happy with Jochen Rick’s QRCode package (http://smalltalkhub.com/#!/~JochenRick/QRCode/). This is such a great piece of work !
It worked right out of the box in Pharo 7 (even though it is from 2013/2014), was well designed, easy to figure out, was well documented, had unit tests. I can’t say anything bad about it, it is as close to perfect as I have ever seen. So: thanks Jochen, you made my day !
Here is how a ticket generates its own QR code:

^ self url asString asQRCode formWithQuietZone magnifyBy: 5

Just beautiful.
It is also easy (for a non-graphics, non-UI person like me) to combine the QR code with some text:
T123Ticket >>#asQRCodeWithText

| form font |
form := Form extent: 535 @ 185 depth: 1.
font := LogicalFont familyName: ‘Bitmap DejaVu Sans’ pointSize: 14.
self asQRCode displayOn: form at: 0 @ 0.
form getCanvas
drawString: self url asString at: 180 @ 20 font: font color: Color black;
drawString: self id36, ‘ – ‘, ticketId asString at: 180 @ 45 font: font color: Color black;
drawString: (name ifNil: [ ‘N.N’ ]) at: 180 @ 90  font: font color: Color black;
drawString: (email ifNil: [ ‘@’ ]) at: 180 @ 115 font: font color: Color black;
drawString: (phone ifNil: [ ‘+’ ]) at: 180 @ 140 font: font color: Color black.
^ form

Next we combine this with a nice template designed by a graphics artist:
T123Ticket >>#asQRCodeWithTextInTemplate
| templateFile form |
templateFile := ‘tickets123-template-{1}.jpg’ format: { self event id }.
form := PluginBasedJPEGReadWriter formFromFileNamed: templateFile.
self asQRCodeWithText displayOn: form at: 20@540.
^ form
And finally, the ticket form is encoded as a JPEG (to be mailed and so on):
T123Ticket >>#asJPEGBytes
^ ByteArray streamContents: [ :out |
PluginBasedJPEGReadWriter putForm: self asQRCodeWithTextInTemplate onStream: out ]
I also found GT Inspector very handy (again) in doing back end work (managing payments and other administration), especially the ability to use Spotter on a collection open in an inspector.
Anyway, I know many of you have similar happy experiences, I just wanted to share (one of) mine.
Thanks Jochen, thanks everyone.
%d bloggers like this: