Over the holidays we had an accidental deletion of every image on one of our phones (a Nokia N90, Symbian OS device.) Mild panic was quickly replaced with a gentle pondering on the difference between what a normal person would do in this situation vs. what a geek would do. The geek process goes something like this:
Either shut the phone down and pull the card, or use the super-secret combo hidden within the profile-switching shortcut to have the phone un-mount the card.
I’ve needed a reason to buy one of these for a long time. Good thing I had a gift card left from the holidays. I went with a Dynex gazillion-to-one card reader, not for it’s technical superiority, but because it was the only thing the shop nearby had.
Mine happens to run Ubuntu at the moment, but the results will likely be similar on other distros.
Testdisk “was primarily designed to help recover lost data storage partitions…” and includes a utility called “PhotoRec“, which is what you want.
PhotoRec is a data recovery tool designed specifically for recovering files from digital camera media. It supports a number of file-system formats, including the FAT format that Symbian OS uses on it’s memory cards. PhotoRec is a text-based, terminal application, but it does the job perfectly.
Select the mounted memory card from the list of drives (which should be easy to spot given how small memory cards are relative to modern hard drives), and send it scanning. PhotoRec can be told to look for specific file types (you want JPG’s, in this case), but by default it will look for just about any media file format that you’re likely to have on your phone. Files will be recovered and written to a local directory.
PhotoRec isn’t going to restore the images to the memory card’s file system such that the phone can see them again, but you’ll have the pictures on your Linux box now, and can copy them back over if you choose to. The naming scheme will be different, but that’s an acceptable compromise.
I have an odd fascination with Visual Programming languages, and while I’ve gotten so far as sketching out some UI concepts and object models for a text-processing focused, web-mashing, visual programming environment, I’m a long way from having anything that works. Much to my surprise then when David Ascher dropped a link to the Lily project on his blog today. Holy cow this is sweet. Think PD or Max/MSP written in JavaScript, running in a browser, with modules for popular Web API’s and JavaScript frameworks (ex., “Amazon, Flickr, Wikipedia, Yahoo; UI modules that wrap widgets from YUI, Scriptaculous, JQuery, Google Maps….”)
Check out one of the demo’s here:
(Via: Lily: JavaScript, visual programming, fun.)
The Maemo team has been quietly rocking Nokia’s world for some time now. They’re off in the background building (almost pocketable) mobile computers; fine-tuning touch interfaces and small-screen UIs; becoming experts in embedded linux; and bringing top-notch open source software and modern development tools to this unique mobile platform. For years, the Nokia tablets have sat on the side-lines as niche devices for hackers; but lately, the team has been changing the game.
The Nokia 770 and N800 have always faced an up-hill battle with market adoption given their lack of GSM/CDMA support. “Is it a phone?” is one of the first questions people ask when they see me using one these devices. Saying “No, it’s a web tablet” only brings a look of confusion. Thankfully, the latest software releases, wider market recognition of UMPC’s, and the iPhone release, have had a huge impact on the perception of the N800.
The Internet Tablet OS 2007 edition 4.2007.26-8 upgrade (released earlier this month) brought Skype support to the N800. While perhaps playing second fiddle to a Flash upgrade that makes YouTube work better, adding Skype greatly improves the likelyhood of using the N800 as a portable VoIP device. However, even more significant is the recent Internet Communications Software Update for N800. This update adds SIP support to the N800 for VoIP calls — a feature that turned my N800 into my new desk-phone at work.
At Optaros, we use Asterisk to run our phone infrastructure. There are the occasional physical SIP phones in conference rooms, but in general, we use soft-phones running on our laptops to make and receive calls. The downside here is portability. Even using WIFI, a laptop doesn’t make the best cordless phone. But an N800 does. The N800 is actually quite nice as a cordless phone; and with WIFI available in the office, at home, and at nearly every business in Austin, my phone extension can now be routed to my Nokia device and be available almost everywhere.
It may take awhile for the market to notice this, but Nokia is quietly taking the top-spot in mobile linux and VoIP hardware know-how. The Nokia linux tablets aren’t quite ready for the general consumer (in terms of usability), and the marketing messages aren’t there yet either — but the R&D is, and the technology will be ready to drop-in and rock the mobile-phone world as soon as the strategy dictates.
Awhile back, Ubuntu announced a mobile and embedded edition of it’s popular Linux distribution. The buzz was around the possibility of Ubuntu Mobile showing up on future UMPCs. The news caught my eye, but didn’t really get my attention until the plans for Ubuntu 7.10 (Gutsy Gibbon) were announced:
“Ubuntu 7.10 will be the first Ubuntu release to offer a complete mobile and embedded edition built with the Hildon user interface components” (developed by Nokia for the Maemo platform.)
Now that’s interesting. Could it be that we’ll see Ubuntu Mobile booting on Nokia N800’s? It’s certainly a possibility — and one that could bring a larger breadth of software to Nokia’s mobile Linux tablets.
However, as interesting as it may be if Nokia adopts Ubuntu, the possibilities for wider Hildon support didn’t hit me until my drive home today. It was one of those obvious moments. I had been using my Nokia N800 while walking to my car, so the touch- and small-screen friendly UI was fresh in my mind. Then I started thinking about my Car PC. It uses a 7″ touch screen and runs Ubuntu (a full distribution, with a UI designed for full-size monitors.) Running Gnome on my cheap, in-car 7″ monitor makes for a pretty lousy experience. Text is hard to read, and everything is too small to click on. However, if this news is right, Ubuntu 7.10 will change all of that. I’ll be able to run Hildon on my Car PC! That’s killer. Imagine having Canola running in-car, sitting on 100GB of multimedia…
Django “lorem ipsum” generator (and a new contrib.webdesign module)
The Django Web Framework project just added a new contrib.webdesign module with an amazingly simple, but incredibly handy first feature: a lorem ipsum generator. The idea is that a project’s base templates can include generated lorem ipsum for testing layout and page flow, but inheriting templates can override the generated text once real content is available.
The lorem tag is used like this (via the contrib.webdesign docs):
In practice, you might do this:
templates/template.html:
<html>
<head>
<title>{% block article_title %}{% lorem 5 w %}{% endblock %}</title>
</head>
<body>
<div class="article">
<div class="article_title">{% block article_title %}{% lorem 5 w %}{% endblock %}</div>
<div class="article_body">{% block article_body %}{% lorem 4 p %}{% endblock %}</div>
</div>
</body>
</html>
And then inherit when you’re ready:
templates/article.html:
{% extends "template.html" %}
{% if article %}
{% block article_title %}{{ article.title }}{% endblock %}
{% block article_body %}{{ article.body }}{% endblock %}
{% endif %}
Previously, I used to just paste lorem ipsum text directly into the main template (wrapped in block tags for overridding), but this new tag will let you skip the copy/paste routine. Very nice!
Even though most articles indicate that Ubuntu Edgy should have automatically patched itself with updated timezone files, my laptop (and apparently a few others didn’t get the update either.) With some googling, I found plenty of suggestions (including “sorry, mine worked”, and “just manually set your clock”), but none got to the core issue, which is that the timezone files themselves were wrong.
No doubt, by now, you know whether your machine updated correctly; but if it didn’t, you can verify your timezone files with this:
`zdump -v /etc/localtime | grep 2007`
If you see “April 1″ in there, the machine has old files (as mine did.)
The solution (for me), was to manually rebuild the timezone files (since the system thought it was fully patched.) Step 1: Go here: http://packages.ubuntu.com/edgy/libs/tzdata and download the latest file (for me, it was http://archive.ubuntu.com/ubuntu/pool/main/t/tzdata/tzdata_2006m.orig.tar.gz.)
Put the file somewhere (like /tmp/), ‘cd’ there, and un-tar it all. ‘cd’ into the uncompressed files until you find a file called ‘northamerica’. Now compile the timezone file like this:
`sudo zic northamerica`
Remove your previous file:
`sudo rm /etc/localtime`
And sym-link to the new one:
`sudo ln -sf /usr/share/zoneinfo/CST6CDT /etc/localtime` (substituting CST6CDT for your timezone.)
Now verify with:
`zdump -v /etc/localtime | grep 2007`
It should now read “Mar 11″ and “Nov 4″ instead of “April 1″ and “Oct 28″, and the machine should fix it’s clock shortly (it just took a few minutes for mine to correct itself.)
I have no idea what the long-term effects may be of having manually fixed this (as in, what happens when I update to Feisty Fawn), but for now, all is good with the system clock.
My previous post, “Passing JSON via the X-JSON HTTP header with Django and Prototype“, contained an example on writing custom HTTP headers from a Django-based web application. Continuing with that theme, here’s another header trick that I use in one of my apps to force the browser’s “Save As…” dialog box when viewing a particular URL.
The feature that I wanted was the ability to generate an XML file based on an HTTP GET request, but to have the browser open a “Save As…” dialog instead of attempting to render it (as would normally happen with XML in a modern browser.) The solution is to exploit the web browser behavior of not handling unknown mime types. A sample implementation (written in Python for the Django Web Framework) follows:
def save_as_xml(request):
import datetime
current_time = datetime.now()
response = HttpResponse('PUT THE XML HERE')
response['Content-Type'] = ‘application/x-generated-xml-backup’
response['Content-disposition'] = ‘Attachment; filename=export.%s.xml’ % (current_time.strftime(”%Y-%m-%d”))
return response
Setting the Content-Type header to a made-up type ensures that the browser will not attempt to render the file. The Content-disposition header provides the mechanism for suggesting the filename of the content to be saved on the viewer’s system. In this case, I’m using the standard `datetime` module to insert the date into the suggested filename.
One of the demo sites I was working on this week needed to pass a small amount of JSON back with it’s page results. There are a few ways to do this (and I’d suggest this post, “Loading Content with JSON” as a starting point if you’re looking for ideas), but for simplicity, I decided to take advantage of the automatic X-JSON HTTP Header parsing feature in Prototype 1.5.0. (The Ajax.Request docs address this capability.)
The sample code below demonstrates the use of the X-JSON header with an simple “sticky notes” web app. On the client-side, the JavaScript is quite simple. The second variable in the onSuccess callback handler will be automatically initialized using the data in the X-JSON header:
function display_note(id) {
new Ajax.Request('/api/note/' + id + '/', {
method: 'get',
onSuccess: function(transport, results) {
alert("Note(" + results['id'] + “) `” + results['title'] + “`: ” + results['body']);
},
}
);
}
To handle this request, I’m using Django on the server with the following URL pattern:
(r'^api/note/(?P
The `get_note` method implementation looks like this: [NOTE: For production use, you'll want some exception handling, but I removed the error handling to simplify the example.]
def get_note(request, id):
# Fetch the Note from the DB:
note = Note.objects.get(pk=id)
# Create the response object (with some dummy text for now):
response = HttpResponse('Check the X-JSON header.')
# Manually set the X-JSON header using the JSON generated from the Note record:
response['X-JSON'] = cjson.encode(note.__dict__)
# Return the response object:
return response
If you’d like to use this technique on your own sites, there are couple points to remember: