If you code PHP, you probably use XDebug for debugging your code. Some IDEs deal with the gubbins required for starting and stopping the debugger for you, but other debugging clients (like DBGp Client for Vim) require you to manually append XDEBUG_SESSION_START=1 to the end of your page's query string before you try to connect the debugger.
Inspired by this blog post, I wrote a bookmarklet to toggle XDebug on or off at the click of a button, by adding XDEBUG_SESSION_START=1 if it's not already in the URL, or toggling between XDEBUG_SESSION_START=1 and XDEBUG_SESSION_STOP=1 if it is.
To add it to your browser, drag the following link to your Bookmarks toolbar Toggle XDebug
For various reasons, I decided that it was time to do away with the stock firmware on my HTC Legend and install CyanogenMod.
The CyanogenMod wiki details the process for rooting the phone, installing a custom recovery image, an installing CM, but I found the following process much simpler:
Place the image in C:\Android and rename it to recovery.img
Install the custom recovery image with the command fastboot flash recovery recovery.img. You can now boot into Recovery by selecting "RECOVERY" from the bootloader menu.
Apparrently some phones have issues with this method as the kernel needs to be flashed seperately from CM, but I didn't find this necessary with the Legend.
As I mentioned in a previous post, I recent learnt about CoffeeScript, a quick way of writing nice clean Javascript. The CoffeeScript website has instructions for installing the compiler, first requiring installation of Node.js, which a lot of tutorials show you how to install from Git, and also requiring NPM which is usually installed by curling a shell script directly into bash(!). On Ubuntu, the install process is much simpler and less ripe for security holes:
I decided that I'd spend the final day trying to write some code, so I began trying to implement the Google Docs Viewer idea from Day 1.
I started off trying to write a Moodle Filter plugin to change file download links into iframes. However it quickly became apparent that the link I wanted to change wasn't actually processed by the filter, so I had to try something else.
I moved on to modifying the Moodle File Resource plugin - it currently attempts to embed PDF files if it can, so I used that as a starting point. However due to the previous 2 days of information being stuffed in my head, I didn't do things in any logical order and ended up in a bit of a mess. I really need to start again with the following approach:
* Create a new table in Moodle's database to hold single-use tokens against a file's path
* Create a copy of Moodle's file.php that allows you to request a file without logging in, but only if requested with a token that's stored against that file's path.
* Get this page working so that Google Docs Viewer can request the test file with the test token and display it.
* Change the code that attempts to embed PDFs to embed any file type supported by Google Docs Reader
* Get the embed code working for the test file with the test token
* Implement code to generate and store a single-use token when the resource page is requested, pass it to Google via the embed code and delete it after the file is requested once. Also implement a cron job to clean up expired tokens if they aren't used.
I finished off the afternoon by having a chat with Ian Tasker from SchoolsICT (who also sponsored the event), and James and Nigel from ULCC who produce the Moodle ILP plugin. The discussion we had gave me a great insight into what their system is capable of, and I'm looking forward to get to grips with writing some plugins for it myself.
The second day of Dev8D started with my Moodle Plugins workshop. It was reasonably well attended and the people who were there seemed to find it useful. I certainly found it an enjoyable experience.
After lunch I attended Jack Franklin's sessions on CoffeeScript. It's a really interesting idea, and next time I've got some Javascript to write I'll try writing CoffeeScript instead to see if it really does save me time and effort.
The project zone had a brilliant demo of the "ghetto touch-table" from the University of Southampton - basically a home-made Microsoft Surface-style set-up. The thing that really interested me about it was it's simplicity - a sheet of Perspex with IR light shining through it, and a camera to pick up light that gets reflected down by an object touching the surface. It only had a few purpose-built apps that could use the touch functionality, but I'd love to see it again once they've got it controlling the OS.
Dev8D 2012 has come and gone this week. The event's so intense that I tend to forget each day what I did the previous day, so this post will try and order my thoughts a bit and make sure I remember what happened.
Day 1
In Alex Bilbie's packed HTML5 talk, I finally understood that you really can start using HTML5 now. html5shiv adds support for new block elements like <section> and <article> to old versions of IE, which means you can semantically mark up a page's structure without having to resort to a million <div> elements.
In the Unix and Vim surgery I learnt that using lines selected visually in Vim can be reselected by typing gv which I'll be using a lot.
I was planning to enter the Jorum API challenge. Jorum is a repository for open educational resources, and I thought it would be a cool idea to try and implement a Moodle repository plugin to pull in resources from Jorum. However, the Jorum API needs some serious re-engineering to make it useful - it just returns too much data. You need to be able to search for keywords within a collection, request details of an item within the results, and request individual files within that item. Currently, trying to do this gives you all sorts of data pertaining to an object's parents, children and siblings, to the extent that you can't even work out what needs to be thrown away to end up with just what you wanted. Until a better API is available, I won't be looking at it any further.
During the Afternoon I had a chat with the Moodle developers from the University of Sussex. They showed me Google Docs Viewer which lets you embed any PDF or MS Office file in a web page, even without a Google Docs account. This would have seriously cool applications if used in conjunction with Moodle resources, as it could be used to allow a lot of files that currently require office software to view to be viewable right in the Moodle page. There's a bit of work to do making this work securely, but I think it's feasible.
I just accidentally made a commit in git that I didn't want - I'd made several changes at once and wanted to commit them separately. Instead I did one big commit so I wanted to get back to a state where I had the uncommitted changes. The methods of undoing a commit (git reset and git revert) dont cut it here, as they just take you back to the previous commit, and lose the changes you made. Here's what I came up with:
git show > ~/uncommit.patch # Take the commit I just made and store the differences in a patch
git reset --hard HEAD^ # Reset to the previous commit
patch -p1 < ~/uncommit.patch # Re-apply the changes
If you've got some changes that aren't committed yet that you still want to keep, you'll want to do make a second patch from the output of git diff before resetting.
I'm fed up of making notes on scrappy bits of paper that I lose, so with some money I got for Christmas I got myself a Boogie Board Rip. I'm not going to do a full-blown review here, but essentially it's an etch-a-sketch on top of a portable graphics tablet. The graphics tablet bit is battery powered, and converts what you draw to PDF. The PDFs can be accessed by plugging the board into a PC via a Micro USB cable. Some people complain that it's not very good for drawing, but I only wanted it for writing and it's great for that.
After using the board for a couple of days I found this piece of software and this blog post. It turns out that as well as appearing as a USB storage device when plugged in, it also appears as a human interface device and spits out a stream of binary (32 bytes of it to be exact) for each event that occurs on the device (button presses, movement of the stylus, etc). With a bit of help from the aforementioned blog post I've managed to decode the binary and write a short Ruby script that reports what's happened each time you do something.
The script as it stands at time of posting is shown below. The latest version is available on github.
begin
lsusb = `lsusb`
if lsusb.split("\n").select{|l| l.include?"2047:ffe7"}.count ==0raise"Boogie Board Rip not currently connected"
end
begin
dmesg = `dmesg`
bbdev = dmesg.split("\n").select{|l| l.match "2047:FFE7.*hidraw[0-9]"}.pop.match("(hidraw[0-9]+)").to_s
raise RuntimeError if bbdev.empty?
rescue NoMethodError, RuntimeError
raise"Boogie Board Rip detected, but device's path could not be determined"
end
events =[]
threads =[]
thread = Thread.new do
board = File.new("/dev/"+bbdev,'r')while true do
data = board.sysread(32)
event = Array.new()
data.bytes {|b| event << b }
events << event
end
end
threads << thread
thread = Thread.new do
previous = Array.new(32,0)
current =[]while true do
current = events.shift
next if current.nil?if current[10]!= previous[10]
state = current[10]
pstate = previous[10]
lock =32
erase =4
wake =2if(pstate == pstate | lock)&&(state != state | lock)puts"Board unlocked"
elsif (pstate != pstate | lock)&&(state == state | lock)puts"Board locked"
end
if(pstate == pstate | erase)&&(state != state | erase)puts"Erase released"
elsif (pstate != pstate | erase)&&(state == state | erase)puts"Erase Pressed"
end
if(pstate == pstate | wake)&&(state != state | wake)puts"Wake released"
elsif (pstate != pstate | wake)&&(state == state | wake)puts"Wake Pressed"
end
end
if current[3]!= previous[3]
state = current[3]
pstate = previous[3]
detected =32
contact =1if(pstate == pstate | detected)&&(state != state | detected)puts"Pen Lost"
elsif (pstate != pstate | detected)&&(state == state | detected)puts"Pen Detected"
end
if(pstate == pstate | contact)&&(state != state | contact)puts"Pen contact lost"
elsif (pstate != pstate | contact)&&(state == state | contact)puts"Pen contact detected"
end
end
cury = current[4]+(current[5]*256)
curx = current[6]+(current[7]*256)
prey = previous[4]+(previous[5]*256)
prex = previous[6]+(previous[7]*256)if cury != prey || curx != prex
puts"Pen moved from ("+prex.to_s+","+prey.to_s+") to ("+curx.to_s+","+cury.to_s+")"
end
previous = current
end
end
threads << thread
threads.each{|thread| thread.join}
rescue RuntimeError => error
puts error
end
It's very rudimentary at the moment, and needs to be run as root so the device can be accessed, but hopefully with a bit more hacking I'll be able to get something graphical up and running. It also strikes me that you should be able to use the Boogie Board like a Wacom tablet if someone would be good enough to write a device driver. It's a bit beyond me but the information's pretty much all there in the script!
I'm sitting at my computer about to cancel my subscription to Spotify Premium. They'd like to know why I'm cancelling, which is fair enough, so I'm going to go through the reasons here. It might get a bit long, but hopefully it'll be worth reading. If I get a bit passionate I'll probably swear a bit too. Stick with it.
The Short Version
Spotify is no longer worth £10 a month to me.
The Long Version
There's a few reasons why I've decided to cancel my subscription. Once this is for certain: it's nothing to do with the service. Spotify as a concept and a technical implementation is excellent. I've used it for about two years, first as a free user then as a subscriber. I will probably continue using it as a free user.
No Comment
However, I do have a few issues with Spotify as a company, particularly when it comes to customer service. Lets take a couple of examples.
I have always ripped my music to the free high-quality Ogg Vorbis format, rather than MP3. Spotify also uses Ogg Vorbis for streaming, yet doesn't allow you to play your own Ogg files through Spotify, only MP3s. When I questioned their customer support about this I pretty much received "Fuck off and die, no comment". I mean, I'm not a journalist probing you for a juicy story, I'm a paying customer who wants to use your software! Is it too much to ask for a proper answer?
Another fine example of this attitude is this Get Satisfaction thread pertaining to an issue with the Spotify Android client. Essentially, if you try to use a decent sized MicroSD card to sync your Spotify songs offline, it tells you the card is full and won't sync. Spotify's initial response was akin to "have you tried turning it off an on again?". After they realised this didn't work, they simply said "We can't recreate this" and stopped responding. That was a year ago. There have been 34 further reports from customers.
Pay Per Play
The primary reason I'm leaving has very little to do with Spotify themselves. It has to do with the other people who make Spotify work: the record companies and musicians.
If you follow my blog you'll know that InsideOut Music, purveyors of the world's finest Progressive Metal, recently pulled their entire catalogue from Spotify with no warning. They have since posted a statement explaining why. This seems to be a bit of a trend recently, as a couple of articles on from around the web show. The trouble is that, as Techcrunch put it, they're "totally missing the point".
InsideOut justify their departure with the sweeping statement that "Physical sales are dropping drastically in all countries where Spotify is active." No shit, Sherlock. Physical sales? Physical sales have been dropping since the invention of the iPod. The noise that these labels make is all focusing on how much artists get paid. Now if you're in a band, correct me if I'm wrong, but if I want to make sure you get a decent amount of money from me, I'm not going to buy your CD. I'm going to pay to come to one of your gigs, and probably buy some merchandise. Am I right?
It actually surprises me how much I, and apparently other people, will pay for gigs and merchandise. Through Spotify, I've discovered some amazing bands who I'd love to see live. If Arjen A. Lucassen's Star One tour the UK, there's virtually no ticket price that I'd consider too much. If I'd joined Spotify a year later than I did, InsideOut would have already pulled the music, and I wouldn't have known that. Every time Iron Maiden play a gig, there's a T-shirt which you can only get at that gig, featuring their mascot Eddie. They usually cost £20/£25 a time, and they sell like the hottest of cakes. Stop worrying about how much you get paid per play, start worrying about how people find out when you're playing, and that you've got T-shirts to sell them. Spotify can help you do this.
Conclusion
When it comes down to it, the problem is that the people responsible for keeping a large portion of the music I love on Spotify don't get it. For the service to be worth money to me, they need to get it. I will still keep using Spotify Free as my primary way of discovering new music. Is your music on there?
I'm back in the land of the living after catching the dreaded lurgy on Monday morning. I'm pretty convinced this was in no small part to a lack of proper nourishment and excess of tasty beer consumed over the weekend. What can I say? I was busy.
Those of you who follow me in any capacity online will be at least peripherally aware that I've been involved in organising this year's OggCamp, a 2-day unconference/barcamp style event celebrating Open Technology. It was an amazing event, with talks and sessions covering music, electronics, ethics, and of course software and computing. From my point of view, everything to do with the event went really well, and I'd just like to the opportunity to share my highlights and thank some people.
The first highlight for me happened at about 3pm on Saturday. I got a call on the radio from Tony, one of my co-organisers, to this effect:
Hello Mark? Can you get some loo roll brought to the gents? There's three cubicles and we've all run out of paper!
Another cool thing for me was Adam Sweet coming up to me after the live podcast recording and chatting to me about how it went. Those of you unfamiliar with the name, Adam is one of the presenters of LugRadio, the long-running Linux podcast whose live event, LugRadio Live, gave rise to the first Oggcamp 3 years ago. The reason that this was a particular highlight for me was that listening to Adam and his partners in crime including Stuart "Aq" Langridge and Chris Proctor who I also had a good chat with was what made me want to get into radio and podcasting in the first place. Musicians, imagine being told you've just played a good set by the band who first made you think "I want to play like that" when you heard them.
The final highlight I'd like to share is the sheer relief when everything fell in to place at the last minute. The doors opened at 10am on Saturday, and people could submit talks to be given throughout the day. Our first scheduled talk was to start at 11. Around 10.30, I realised that our first speaker was no-where to be seen, and a lot of the talks people were proposing weren't appearing on the scheduling system. Slightly panicked, I proceeded to sit down with my laptop and try and work out where everyone's talks were. By 10.50, I'd managed to debug the problem and fix it, just in time for us to get on stage for our welcome talk. At 10.55, our first speaker walked in the door. I love it when a plan comes together.
Lastly, there are a lot of people I'd like to thank publicly, in no particular order:
Tony Whitmore, for somehow managing to keep an eye on everything in the lead-up to and during the event (not least the finances) without his head exploding.
Dan Lynch, for always having an idea when a problem arose.