Another patch of mine has gone into an open source project. I did it so long ago, I'd actually forgotten all about it. The project: RailRoad, which creates nice class diagrams for your Rails models. My patch extended it to include plugin model classes in your diagrams. Always gratifying to have my stuff included in this sort of project.
I got so sick of deleting spam off my website, I decided to install various Captcha modules to stop it happening. I've done a few quick tests, and they work far better than they did about 6 months ago. I've actually got a range of different, random captchas installed, ranging from ascii art, to phrase completion, maths questions, and missing letters. It does mean leaving a comment on my site is a bit like the Krypton Factor (for those of you old enough to remember that), but hopefully it will cut down on my spam (which was up to about 50 comments a day NOT being caught by the filters; upwards of 100-200 per day which were getting caught). I may even turn the spam filters off, as they always seemed to rate comments from my friends as spam, while letting through endless crap about viagra and porn.
Update: Paul's code is MIT licenced, so I'm putting mine out under the same licence.
A while back, I wrote some simple scripts for parsing the BBC iPlayer search pages, so I could get emails about programmes I was keeping an eye on. I also wrote a little Rack server interface so I could browse my search results easily. The downer was that I could only watch them online as downloads aren't supported on Linux, so I ended up having to go to the BBC website to watch them in a tiny window, or boot my Windows VM to download a DRM-crippled version.
However, Rob Styles noted today that there's a Ruby script out there (http://po-ru.com/diary/keeping-up-with-iplayer-dl/ by Paul Battley) which mimics an Apple iPhone, enabling you to download programmes as MP4 files without DRM. I don't have an iPhone, but I can't see why it should only be design know-it-alls who get this privilege. So I integrated that script with my Ruby/Rack web front end, spiced it up a bit, and away I go. I can now search for programmes and download the mp4s to my hard disk (if they exist - not every BBC programme has an mp4 version). Nice. Turns out Rack can also multi-thread in a decent fashion (unlike Rails), so I can even have several downloads running at once.
The code is attached. There's no licence on the download script I'm using, so I hesitate to release it under any kind of open source licence (yet). I'll contact Paul and find out what licence he's releasing under. I made a few modifications to his script to wrap it in a class for use in my app., but not many. See my previous entry (linked at the top of this post) for proper instructions/installation etc..
Also, please don't expect very clean, well-tested code here: it's something I've thrown together for my own use, and I'm putting it out there for others to use if they like. Also, I can't guarantee it will work on Windows at all. Enjoy.
My Rails book has ended up on a free download site. No comment.
In a RESTful web application design, you typically first identify the resources in your application, the nouns. For example, imagine you're writing a library app., and you're working on adding items to a catalogue. So you've got catalogues and items as your nouns.
You then decide to implement the operations on items, which live in the catalogue. In REST, HTTP verbs map onto the operations you want to perform: POST = create a new resource when you don't know what its identifier should be; PUT = update; DELETE = delete; GET = query resources. So you might end up with:
| HTTP request | Operation performed on resource | Returns |
|---|---|---|
| GET /catalogue/items?term=potter | Retrieve items containing the term "potter" | Representation of items, with a 200 OK status code |
| POST /catalogue/items Request body contains representation of new item | Add a new item to the catalogue | 201 Created status code, with Location header set to URI of new resource, and representation of resource in response body |
| PUT /catalogue/items/<control number> Request body contains representation of updated item | Replace existing representation with an updated one | 200 OK status code |
| DELETE /catalogue/items/<control number> | Remove item at the specified location | 204 No Content status code |
Fairly typical REST.
Then you realise you want to upload a whole pile of items at once, embedded in a single request for efficiency; but you don't want the client to have to wait while the items are inserted into the catalogue and properly indexed etc.. Maybe it will take 5 minutes or something, and you don't want to leave a web client hanging. Or perhaps you want to upload only a single item, but once items are uploaded they are put into a queue for processing by another system, so there's a wait.
What are your choices? Here are some ideas, partly gleaned from the RESTful Web Services book:
However, what I'm not so keen on is the idea of a job or service being a resource. Why? Well, if I want to create items in my catalog, I don't want to wrap them in a job and post them to /jobs; if I want to query my items, I don't want to have to go to a query service at /services/query or similar.
What these paths hint at to me is that an operation is being represented by that path, rather than a resource: effectively, calling them is like doing RPC: you pass the resources you want to act on as arguments to the procedure you're calling. Often, there's also some implicit resource hidden away behind the job or service. Compare:
Or:
It's kind of like the difference between object-oriented design (REST) and procedural design (RPC). While a job might look like a resource, my opinion is that it's really an amorphous wrapper around the real resource you should be representing. Typically, jobs get introduced to cope with asynchronous updates; I'd prefer to see asynchronous operations occurring on proper resources, but exposed using the batch processing approaches outlined above. Otherwise I fear you might lose your resources inside some vague blob of a "job" or "service".
I did my Ph.D. in artificial intelligence, so was interested to read a few Wikipedia articles about it. One distinction I'd never heard of was neats vs. scruffies in the field.
I put myself in the scruffies camp, probably, though I always had a yen for predicate logic and formal grammars. To my mind, some of the AI scruffies weren't scruffy enough, and tried to model human intelligence without any reference to psychological data. I tried to redress the balance a bit, and compared my program's output with psychological data on human inference during story comprehension. You can read all about it here.
At the time I did my Ph.D., I was pretty unfashionable, as I was researching symbolic AI approaches, while everyone around me seemed to be doing neural networks. However, I thought that while sub-symbolic approaches might produce intelligent output, I struggled to see how that would lead to a description of the solution, or anything that might be built on or added to by humans. If you're trying to program a reasoning system, for example, is it enough to train a neural network to create associations, or do you need to write something which can reflect on the process by which it reached its solutions? Neural nets are great for recognition tasks, but I was never convinced they were suitable for reflecting on how they completed the task. I'm sure there are plenty of counter-arguments to my limited opinion, so feel free to enlighten me.
What I've been up to recently, tech first:
I did a presentation on Rails to some students at Coventry University tonight, as part of their e-commerce M.Sc. course. Here are the materials (introductory presentation on Rails and a script for a demo. of Rails functionality).
Quite interesting. Find out about your online presence.
Here's my QDOS.
My mind is like the autumn moon
Shining clean and clear in the green pool.
No, that is not a good comparison.
Tell me, how shall I explain?