QR Codes and The Lazy Programmer
I recently did a small but tasty project in LiveCode, completing it in even less time than the typically-rapid LiveCode development cycle. The secret was to let Google find the code for me, already written and lurking in pieces lying about the LiveCode / RunRev archives.
I have a certain fascination for QR codes, for some reason, and am generally disappointed at the unimaginative uses to which they are put by most businesses (“Hey look, it took me to the company's home page!”). So finding innovative (or at least “value- added”) uses for QR codes is a bit of a hobby.
Recently, a neighbor who is the director of the Little Free Libraries project (www.littlefreelibrary.org) asked me to look into how they could put QR codes on the Little Free Libraries to allow patrons to scan the code with their smartphone and see a video or a web page with news about the libraries.
So I thought this would be a good chance to brush up on my long-neglected LiveCode server skills, despite a lack of time to spend on it. I succeeded in building an application for them, in two pieces, using barely an hour to build each piece.
The “secret” was to use Google searches to ferret out the necessary code bits from LiveCode's rich archives. Besides the Lessons section of the the LiveCode.com website, there are an annoying variety of list-serv archives, forums, and other random repositories. The trick, I tell my students, is to always start your search term with “runrev” (or “livecode”, to get really recent things).
Using this approach, I was able to get instant answers and perfectly relevant code samples for the four main bits I needed, generally from the first or second search result:
1) How do I pass information to LiveCode Server scripts?
Thanks to the LiveCode staff and user community, the application practically wrote itself. And here's how that worked:
The first step was create a QR code containing a URL to a LiveCode server script, like:
Then I created a QR code containing that URL. I like to use www.qrstuff.com but there are lots of web sites out there to let you do this. It produces a QR code and lets you download it as a PNG file:
I then decided I needed to be sure I knew how to code a redirect in a LiveCode server script, so I searched for “runrev server redirect” and found an archived list-serv posting from Andre Garzia that was just what I needed:
<?lc put "http://www.google.com" into tURL put header "Status: 301" put header "Location:" && tURL put "redirecting..." ?>
Next I needed to review how to get passed-in URL arguments in a LiveCode server script. A search for “runrev pass args to server script” found a LiveCode lesson that reminded me to use the $_GET["argname"] syntax.
By now I'd thought about the problem a bit more and realized a couple of things:
1) Maybe they'll want more than one “channel”, for different languages/topics/etc
2) Oops, they'll need mechanism to periodically redefine where each channel redirects
For the first issue, I decided to have a .TXT file containing channel-redirect assignments, laid out like:
1 <tab> URL1
Luckily, I did remember LiveCode incantation for reading in a file:
put URL "file:lflqr.txt" into tChansInfo
And another quick search for “runrev convert to array” quickly reminded me that “split” was the command I couldn't recall:
split tChansInfo by return and tab
So putting the pieces together I quickly had a script do do channel-specific redirection via QR codes:
<?lc -- get the chan parameter from the calling URL put $_GET["chan"] into tChanNum -- default for no-chan-specified is 1 if tChanNum is empty then put 1 into tChanNum end if -- find the line for that channel put URL "file:lflqr.txt" into tChansInfo -- first convert the tab-delimited lines into an array, indexed -- by channel number split tChansInfo by return and tab -- then grab the URL for the requested channel put tChansInfo[tChanNum] into tURL -- and make sure the channel is defined if tURL is empty then put "Sorry, that Channel is not defined…" else -- the channel IS defined, so emit the -- redirect to the requested channel's URL put new header "Status: 301" put new header "Location:" && tURL put "redirecting to:" & tURL end if ?>
Voila: I could scan a QR code on my phone and have a video or a PDF newsletter or a webpage appear on the screen!
That just left the issue of how to let the LFL staff refresh the contents of the channel- definition file periodically, without having to call me and without having to set them up with FTP access to my servers or teach them how to use an FTP client.
I was sure I'd once seen a Lesson on how to upload files to a server, and a quick search for “runrev upload file to server” found it for me. After a few minutes of tweaking, I had a file-upload script that they could use to send fresh channel definitions up to the server unassisted.
It first prompts them to select a file from their local drive:
They then click on Choose File and select the revised channel-definition file from a local drive:
And finally they click on Upload File:
OK, so it's a not-very-pretty, 1997-looking web page, but it gets the job done and didn't take much of my time at all to create, the secret to doing pro bono projects!
The code is pretty straight-forward, almost all swiped from the Lesson, with a few tweaks:
<?lc set the errorMode to "inline" ?> <html> <head></head> <body> <H1>Upload Form</H1> <form enctype="multipart/form-data" action="xxx_xxxxxx.lc" \ method="POST"> Choose a file to upload: \ <input name="uploadedfile" type="file" /><br /> \ <input type="submit" value="Upload File" /> </form> <p> <?lc if $_Files[uploadedfile][filename] is not empty then put "<H1>Uploaded Files</H1>" if $_Files[uploadedfile][error] then put "There was an error uploading your file:" && \ $_Files[uploadedfile][error] & "<br />" else put $_Files[uploadedfile][name] into tFileName put $_Files[uploadedfile][type] into tFileType put $_Files[uploadedfile][size] into tFileSize put $_Files[uploadedfile][filename] into tFilePath put "Your file 'lflqr.txt' was uploaded" && \ "successfully. It is" && tFileSize && \ "bytes in size." // If the file is a text file, then display what is in the file if tFileType is "text/plain" then put URL ("file:" & tFilePath) into tText put tText into URL "file:lflqr.txt" replace return with "<br>" in tText put "<h1>File Content</h1><p>" & tText & "</p>" end if end if end if ?> </p> </body></html>
[Note: Some line-continuation characters (“\”) were added for readability.]
The action="xxx_xxxxxx.lc" clause of the <form> tag was obfuscated for security reasons. The action needs to refer to the name of this script itself, so that when the form is submitted (by the Upload File button), the same script that displayed the initial file- selection page is executed a second time. The first time around, there is no $_Files[uploadedfile][filename], since no file has yet been uploaded, and therefore the upload-confirmation portion is suppressed.
Personally, I found this “script gets called twice” approach to coding web apps a bit hard to get my head around initially, but it is both common across various languages, and a very handy trick once you get it straight in your head...
So in about 2 hours of work, I was able to create a rich, fully user-maintainable application that delighted my client, thanks to LiveCode's powerful server scripting language and RunRev's deep archives accumulated over the years.
And that's why I prefer to only work in LiveCode these days: the power, speed and satisfaction-level of this tool is unmatched, in my experience!