I've moved back to Quod Libet from Rhythmbox this week (the only thing I miss is Rhythmbox's "Recently Added" category). One gotcha which took me a while to work out: to use Quod Libet plugins, they have to go into ~/.quodlibet/plugins. Copy them from /usr/share/quodlibet/plugins (which is where they are installed by default, on Ubuntu at least) to that directory and you should be fine.
I also installed some binaries of the new version, even though I am on Ubuntu Breezy: see http://www.ubuntuforums.org/showthread.php?t=131304&page=3 for Ubuntu packages.
I was really heartened by this article which outlines the recent Desktop Architecture Meeting 3 in Portland, where a bunch of Linux desktop folk got together to discuss how to move Linux on the desktop forward. This is an issue which is dear to my heart, as I use Linux exclusively, both at work and home. Particularly important to me is what was called "sound suckage", something which desperately needs fixing. I have a few issues with sound myself on my Ubuntu (still Breezy, need to upgrade to Edgy soon):
Aside from this (which, as you can see, is very important to me), it's also interesting to read about plans to make hardware for support more comprehensive. It still pains me that my laptop internal wireless is not working (though that may be fixed in Edgy - we'll see). Until hardware manufacturers buy in, and you can buy a computer with Linux in PC World, Linux on the desktop will stay grounded. (Though I noticed a PC in Woolworths had StarOffice on it the other day, which I suppose is a start of sorts.)
I'd also like to reiterate a point made elsewhere: why is it I can get 3D spinning windows on my screen, but my wireless doesn't work, external projectors work sometimes and not others, and I have to manually stop sound daemons to use Flash? Although those issues are dull, they are the real barriers to the uptake of Linux on the desktop; not the fact it doesn't look like the Mac UI.
Yesterday, I mentioned I have added RSS feed capabilities to FlickrLilli. I thought it might be worth sharing my experiences of this, as it took me a good couple of hours to iron out the wrinkles and get a valid feed.
Update: Thanks to Thomas Hurst (see comments) for pointing out that I can just use the output from the existing partial and escape it again.
I had a lot of code for fetching photos from Flickr and displaying them as HTML: I wanted to reuse these as much as possible. The examples below simplify, as FlickrLilli is a special case and doesn't have a database back-end; for the example, I have assumed a photo database which stores Flickr-like photo objects.
FlickrLilli doesn't use ActiveRecord, but has objects corresponding to photos from Flickr. For the purposes of this example, let's assume a photo actually corresponds to a table in the database called photos, and has a model that looks like this:
class Photo < ActiveRecord::Base
has_and_belongs_to_many :tags
belongs_to :owner
# Show tag names in a human-readable string.
# (Thanks to Tim [see comments] for reminding me of this syntax.)
def tag_str
tags.map(&:name).join(", ")
end
end
And that the model supplies these attributes (which mirrors Flickr metadata on a photo):
FlickrLilli uses a single partial to render a photo as HTML in different contexts (app/views/main/_metadata.rhtml). Paraphrasing a bit, this looks like:
<h2><%=h photo.title %></h2> <p><%= image_tag(photo.image_url) %></p> <p><strong>Tags:</strong> <%=h photo.tag_str %></p> <div class="photo_details"> <p><strong>Licence:</strong> <%= photo.licence %></p> <p><strong>Date and time taken:</strong> <%= photo.date_taken %></p> <p><strong>Owner:</strong> <%= link_to photo.owner.username, photo.owner.homepage %></p> <p><strong>Description:</strong><br/> <%=h photo.description %> </p>
Given these two existing components (a model and an HTML partial for a photo), I set about writing my feed generator. It needed:
This was pretty quick to write. Again, using a simplified version for the purposes of exposition, I added the action to my MainController class (in app/controllers/main_controller.rb):
def rss # Get the 10 most recent photos @photos = Photo.find :all, :limit => 10, :order => 'date_taken DESC' # Title for the RSS feed @feed_title = "10 most recent photos" # Get the absolute URL which produces the feed @feed_url = "http://" + request.host_with_port + request.request_uri # Description of the feed as a whole @feed_description = "10 most recent photos" # Set the content type to the standard one for RSS response.headers['Content-Type'] = 'application/rss+xml' # Render the feed using an RXML template render :action => 'rss', :layout => false end
There are a couple of key things to note here:
This uses the RXML template provided by Rails to generate the XML document. There is an example in the Rails documentation, but as far as I can see it doesn't produce a properly-valid feed, as it lacks an <?xml version="1.0"?> declaration. Here's my template, which went into app/views/main/rss.rxml:
xml.instruct!
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
xml.channel do
xml.title @feed_title
xml.link @feed_url
xml.description @feed_description
xml.language "en-gb"
for photo in @photos
xml.item do
xml.pubDate photo.date_taken.rfc822
xml.title h(photo.title)
xml.link photo.image_url
xml.guid photo.image_url
xml.description do
xml << h(render(:partial => 'metadata', :locals => {:photo => photo}))
end
end
end
end
end
Things of note:
rfc822, which returns a string suitable for use inside the <pubDate> element of an RSS feed.xml << h(...) syntax directly appends some content to the XML output, attaching it to the currently active element (in this case, the <description>).render method, passing the photo in as a local. The whole lot is then filtered through the h method to escape all the HTML. This will result in some parts of the HTML being "double escaped"; however, when decoded by the reader at the other end, it should be proper single-escaped HTML again.Applications like Firefox look at the filename suffix of a downloaded file to determine how to handle it. If we make the RSS feed available at a URL like http://localhost/rss, the downloaded file will be called rss, and some applications won't be able to work out what to do with it.
So it gets properly treated as an XML file, I add a custom route to config/routes.rb:
map.connect '/rss.xml', :controller => 'main', :action => 'rss'
And that's it!
Because I'm feeling generous, and because I wanted to check all the above actually worked, I put together a really simple Rails application which fleshes this out and includes a sample SQLite database and migrations. It's attached below. To run it, just use script/server, then browse to http://localhost:3000/rss.xml. When I tested it, it produced a valid RSS feed.
I tend to use FlickrLilli to do the same search over and over (I use open as this provides good material for presentations on open source, naturally). I decided to hack a quick RSS feed facility into FlickrLilli to support this mode of working. It's just a link added to the search results page, but it means you can get a feed of the Creative Commons images in Flickr matching your query. This is updated in real time (it should be cached really, but like I say, it's a quick hack at the moment). Give it a spin and let me know how it performs. It would probably be best if you didn't batter it every 5 seconds, as it does a live search for every query at the moment. By the way, I am quite surprised that Flickr doesn't provide this facility on general searches, though it does seem to provide feeds for groups and pools (I think).
FlickrLilli is a project I've been working on/off with for about a year now. The idea is that it provides a search interface across Flickr's Creative Commons content; I use it myself to source royalty-free images for presentations. It was a really early Rails project of mine, so the code was a bit ropey in places; and I've had many problems hosting it, as it used to be a bit "bursty" and create dozens of HTTP requests very close together (AJAX, don't you know), which made all the hosting I've tried break. I spent a lot of time rewriting the XML parsing to make it more efficient, but still problems.
A couple of months ago I embarked on a major rewrite. This time I decided to remove a lot of the AJAX request load by rejigging the interface, so details for pictures are loaded on request; I also rewrote all the AJAX stuff so it degrades gracefully and works on more browsers (including IE, which was a problem before), using Unobtrusive Javascript. This was the biggest challenge. And I redid much of the CSS so it resizes better (still problematic on really small screens, but I'm no CSS expert); it should also work with all the CSS off in ancient browsers. I've retained the login feature, which enables you to login to your Flickr account and make comments/add favourites from inside FlickrLilli. There are still issues with the Javascript on browsers other than Firefox, but at least it all works with Javascript turned off if necessary.
I've now completed all this, and you can see the results at http://flickrlilli.org.uk/. Enjoy! Let me know if it breaks! (It's only on cheap shared hosting and I had to revert it to REXML, so more than likely it will fall over within a few minutes of me posting this.)
I would encourage you to write to your local MP (e.g. via TheyWorkForYou.com) and encourage them to sign this Early Day Motion:
http://edmi.parliament.uk/EDMi/EDMDetails.aspx?EDMID=31752
Here's the full text of the motion:
That this House congratulates the Open University and other schools, colleges and universities for utilising free and open source software to deliver cost-effective educational benefit not just for their own institutions but also the wider community; and expresses concern that Becta and the Department for Education and Skills, through the use of outdated purchasing frameworks, are effectively denying schools the option of benefiting from both free and open source software and the value and experience small and medium ICT companies could bring to the schools market.
An interesting paper about the "piracy paradox" of the fashion industry: despite a lack of protection for fashion designs and rampant copying in cheap knock-offs (though with IP still invested in brands), the fashion industry innovates at a rapid click and attracts enormous investment. I haven't the time or skill to read all 94 pages, but the introduction, conclusion and some of body of the text are interesting (open source gets a footnote). From my skim, it looks like the authors largely attribute the paradox to the positional ("this year's look") and ephemeral nature of fashion. They go so far as to say that copying is actually beneficial to the industry and accelerates innovation. I think there's a case for saying IT is "positional", in the sense that there are trends and people gain recognition for being "on the bleeding edge" in adopting new technologies; so some of the arguments are adaptable. There are good arguments made here against the assumption that IP protectionism leads to innovation.
Update: Mr. Molina's S3 library is available at http://amazon.rubyforge.org/. I've downloaded it. I had a sinking feeling (all my hard work...),combined with a feeling of relief (no more hard work!), as I looked through it. It looks very good. Clearly the work of a super Ruby programmer (my library is very verbose by comparison, though in its defence is a bit easier to follow). The usage patterns are nice and clean. Plus it has an interactive shell, which is nice. I think I would probably use it in preference to my library. So I have the feeling I won't be doing much more work on s33r for now... (but see the comments for a very nice vote of confidence).
By the way, here's code for doing the same thing as Peter's example, but using my s33r library:
#!/usr/bin/env ruby
require 'rubygems'
require 's33r'
local_file = ARGV[0]
base_name = File.basename(local_file)
bucket = ARGV[1]
puts "Uploading #{local_file} as '#{base_name}' to '#{bucket}'"
S33r::NamedBucket.new('accesskeyhere', 'secretaccesskeyhere',
:default_bucket => bucket) do |client|
client.put_file(local_file, base_name)
end
puts "Uploaded!"
None of that messing about with mimetypes or reading in files: put_file does that for you :). Plus there's a sample (and simple) Rails app. called fors33r bundled with it, which displays all your buckets and enables you to upload files into them. s33r can be installed as a gem, by the way...
Not much content in there, but here's a short report on the recent Web 2 point 0 seminar I presented.
I noticed someone else using Google Trends to demonstrate the falling volume of "Linux" as a search term, which they take to mean that interest in Linux is falling and Linux itself is being marginalised. An interesting debate, but one which is difficult to come up with good evidence for. Based purely on the interest in OpenAdvantage Linux training, I'd say people still have a healthy interest, but that's hardly good statistics.
Anyway, that's beside the point. I thought it would be interesting to look at the relative popularity of 4 of the big open source CMSs, with respect to how often they turn up in Google searches, using the aforementioned Google Trends.
What I found interesting here was that, according to Google, searches for Mambo have dropped off a fair bit, while Joomla! is on the ascendant; also, Drupal has overtaken Plone in terms of search volumes. Also looks like Drupal is very popular in Hungary and Canada. Probably nothing in it, but I think it could be an indicator that the Mambo Foundation probably wasn't a great idea, in terms of making a product ubiquitous. Also interesting that Joomla! is now winning awards, which Mambo was doing last year; and Mambo seems to have faded from the limelight somewhat.