Posts for Sunday, November 22, 2009

Kensington SlimType Keyboard (64365) Review


“Let your fingers do the walking”.

That old Yellow Pages slogan applies good to us that are on the keyboard often. We learn pretty quickly that a good tool makes all the difference. I learned this previously when I got a bargain keyboard that had broken keys originally, and later one had a shift key that quickly became very picky on how it was to be pressed, and then failed resume from sleep (which was a killer to debug). Since I am on the keyboard quite a bit, this was something I began to think about over and over.

The Kensington Slimtype keyboard has a laptop-like keyboard feel. There are two types of keyboards: low-profile, and those that have the high key presses. The best keyboard I use is on an old iBook G3 clamshell. It allows quick keypresses with a soft response that never bunch or conflict. When I saw Brians’ keyboard, I was a bit surprised people still used them. Seemed like a lot of extra work to press the key another half inch. I’m guessing a lot of this is about what a person is used to. People that use the Happy Hacking Keyboard have told me that they have a less likely chance of accidental keypresses using these keyboards. This isn’t true to me, but can accept that each has their own. If you like low profile keyboards, the SlimType does very well.

On the SlimType, the keypresses are nice and responsive. Not quite as low profile as on most laptops but actually the difference provides a good feel. The keys provide obvious click feedback and there is no doubt to when the key has been pressed. However, the bounce response a little too obvious. When I first started typing it felt like it was fighting me – the clicks a little too pronounced and bounces too springy. I found I had to run my hands over the keys a several hundred times (might be a bit of an exaggeration) and I got the feel I like. After I did this I found the typing to be fast and could closely replicate the speed I do on the iBook.

The gripping on the keys is subtle and useful. Kensington puts a nice texture on the keys that prevents slidding and it gives it a good tactile feel. This is my favorite feature on the keyboard but that perspective may be a bit skewed because I never had it before.

The keyboard layout makes the SlimType considerably narrower than a normal keyboard. This is very useful for desktops that have limited space. The reduced width mainly comes from how the keys are laid out, but the keys are a bit slimmer too (about a 1/16th of an inch from A to ;). This isn’t a big difference but I do find myself doing an awkward keypress on a rare occasion. The rest of the keyboard layout does take a bit of time to get used to. The numbers are layered a bit different and the function keys are slim. The Home, PgUp, PgDn are the most difficult to get used to and are on a single column right next the the Enter, Backspace… keys. And when I say right next to them, I mean it. There is no gap between them and I am still trying to get use to them after two weeks – old habits die hard :). If you were pretty loose about the space on the right side of the keyboard before (i.e. the gap between the Enter, Backspace.. and Home, PgUp…) you might find yourself accidentally pushing these keys from time to time. Also the arrow keys are taking some re-learning too being shifted to the left as well.

There are seven multi-media keys on the keyboard that cover the basic uses, unfortunately they don’t have the same quality as the other keys (they click awkwardly and and roll a little). Since they don’t get used often I don’t consider them a huge minus.

The keyboard profile is thin, not even a half-inch high. And allows those of us that rest our wrists on the desktops a lot more comfort. Not the proper position, I know :).

The footing grips very good and the keyboard is a bit heavier than other keyboards I’ve used that helps typing by keeping the keyboard in place.

Pluses

  • Low profile keys, can type fast
  • Textured keys
  • Weight and footing
  • 5 year warranty from a company that are good about their warranties
  • Thin and narrow
  • All the keys work in Linux and suspend! (ok, haven’t tried the Windows key)

Minuses

  • Keypositions take some getting used to.
  • Arrow keys to the left of what you usually expect.
  • Chrome border – ugly and takes up extra space.

Conclusion

Absolutely great for normal typing after the spring had been taken out of them. If you like the laptop keyboard profile, you will very probably like this keyboard. It’s quick, responsive, and has a good tactile feel. For $30 I can’t really be too rough, without the Chrome border and no space between the Enter,Backspace… and Home, PgUp… it would have gotten a 4.5.

4/5 stars.

Posts for Saturday, November 21, 2009

SpiderOak referral

I've already mentioned before that I chose SpiderOak as my backup utility and provider.

The problem is that although I would be prepared to pay for the package, I can't because I don't have a credit card. This means that I only get the complementary 2 GiB and the possibility to upgrade to max. 5 GiB by friend referrals.

I normally wouldn't do this, but with my laptop dead and my whole data residing on an aging external disk, those three extra gibibytes would mean I can at least have all my documents and the whole inbox backed up.

So, if you have already thought of trying out SpiderOak and would like to do me a favour, please use my referral link when downloading SpiderOak.

hook out >> with terror wathcing the progress bar in SpiderOak slowly, but surely crawling to the end of the free space
<!--break-->

openresolv imported into NetBSD

 openresolv has been imported into NetBSD, which allows more than one daemon to update /etc/resolv.conf sanely and configure local nameservers for enhanced DNS, especially if running on a VPN.  dhcpcd already uses resolvconf when available and dhclient in NetBSD has been patched to use it.

This is important for NetBSD, as many packages support resolvconf, but only when /sbin/resolvconf exists. This meant that a lot of packages that supported resolvconf, failed to work with any resolvconf implementation from pkgsrc.

PPP users who maintain their own scripts are encouraged to try it out :)

Posts for Friday, November 20, 2009

linux love, gentoo love!


recently i updated my gentoo box. the computer is a c2c processor with a fast nvidia graphics card. but what is cool about that “you” wonder?

gentoo linux logo (copied from commons.wikipedia.org)

gentoo

actually the new portage kde 4.3.3 seems to be very stable (read usable) for me. the proprietary graphics driver nvidia.ko is doing great! i use suspend2ram about 10 times a day. i leave the pc in suspend2ram for days and it only needs 3W of power! suspend2ram needs 2-3 secs for going down and about 7 secs to come back up! plasma is now at a point that i see it is going to be useful. the expose clone of the kde folks is very very nice to use. dragon player seems to get stable so i can use it with the smb:// kio plugin to watch films from my server. firefox64 selfcompiled now uses a 64bit flash plugin. and finally nearly all applications i’m using regularly work like a charm, which include:

  • firefox (even watching flash films, fullscreen still stutters but then usually once can do: mplayer -fs /tmp/FlashAVE3 (name is somehow similar)
  • very fast 3d support (nvidia i love you!) in kde and in fullscreen games as well as normal 2d acceleration for movies
  • that said, the new kde desktop effects are the best user experience i’ve had for years now (i didn’t test vista/win7) but mac os x
  • sound seems to be working now. to be honest i don’t understand why (didn’t test skype tough)
  • the game ’spring’ runs with 280fps on my computer (that is a peak value of course) but then with medium details on a map with 5on5 (10 kaik ais) it still seems to be no problem to get decent 60fps!

to conclude: i’m very happy especially since this suspend2ram thing now works. both pcs (i just cloned the gentoo image from the first pc) did work with the same settings altough both use different hardware.

that is really really cool!

currently i’m looking forward getting:

  • into kdevelop 3.9.95
  • akonadi: using a backend !google for pim (i don’t have a google calender nor do i use google mail)
  • getting rid of my laptop with this awful radeon r300 card, i’ll probably buy a “hp elite” with a nvidia card and a 6mb L2 cache (c2c cpu)

to all gentoo readers out there: i love this distribution so much since portage is doing well and the update (although taking long) was a great success.

UPDATE: i forgot to feature the graphics card i use: it is a ‘Gigabyte GeForce 9600 GT Passiv 512MB for 83,90 euro’ (20 nov 2009) which is as silent as you can imagine: 0 dB

avatar

The making of Perspective

Perspective is my school’s magazine of which I’ve been the designer last year. Though the old team has moved on and I’m no longer associated much with it, such releases have remained as an archive online. Mainly because I like the open-source ideology I’ve produced the magazine primarily using FOSS tools – such practice is quite rare in the publishing industry due to Adobe’s dominance. However -especially noticeable in the latest release- the quality of results have truly been quite astounding. So of course I was pleased to recently receive an email about it:

Hi Dion,

I was blown away by the layout you did for Perspective using scribus, and I was wondering if you could offer a COMPLETE newbie to scribus some tips on how to layout a simple greeting card. I would really appreciate your help.

Everybody loves seeing their work being appreciated, and so I crafted a reply, and whether or not it helps anybody else, I thought it’d be good to share.

Hello,

Why thank you! I assume you’re talking about the July 09 edition, where I took the time and effort to actually design each page instead of simply lump text and boxes around.

The first step was to use Scribus to split the page into a grid using the rulers. As a magazine, I split the page into three, then created more rulers to allow for padding. I also put rulers at each of the borders to give ample space for page margins. Once this was done I now have a clear idea of what space I have allocated for my content.

I have to admit that the main crux of the design process was done in the GIMP. I would export a blank canvas and then mirror the rulers with GIMP’s rulers to make it so that my designs also were within those borders. The entire page layout was created in GIMP – I would guess how much space an article might take, and then create it in GIMP. Putting the entire article’s text in The GIMP along the side of one column allowed me to get a pretty good guess at how much space it would take – a screenshot showing this can be seen here:

If you look at that screenshot you’d also notice that all of the pictures – eg: the page template as well as the pictures for the article and fancy font used for the title – were done on The GIMP and NOT on Scribus. The problem I found was that because printer’s were unreliable, when given to them in a format that separated text and many images being overlayed above one another, the colours would run and many artifacts would be seen. So what I did was to create all non-text items in one single image, then export that and use it as a background for the page in Scribus. This keeps all the images together and greatly reduces the number of artifacts – it worked so well, in fact that I would be confident to say that there were almost no artifacts at all!

At the same time, when dealing with such a potentially complex document this technique would keep Scribus running extremely fast yet still benefit from a well designed and with pages full-of-effects (eg: shadow, interesting overlays and rotations). Of course this also meant I could use cool fonts for titles and not be worried on whether or not the printer also had those fonts! Another benefit is that it keeps the final file small and extremely fast to export. Less chances of crashes and easy portability!

The final step once all the non-text were finished in The GIMP was to fire up Scribus and put text on top- so on each page, there was only one image, no more, no less. This also made it a lot easier to manage and edit text. I could still make text flow around images by inserting invisible shapes then selecting Shape -> Text flows around image in the properties window (F2). With line and bezier shapes this really gave me the precise control I needed.

The title page was made almost last – I find this helps as firstly you don’t sit around wasting time thinking of a design because you’re doing the easier and repetitive inner pages. Over time you gather a feel of the document’s style and creating the title just flows out.

On this issue I chose a “small” text font size. This does actually make it seem more professional as you really notice the flow around images. Previous issues I refrained from doing this as my editor told me it would strain people’s eyes. Turns out that they were wrong (well, nobody complained).

Release early, release often – share your work’s in progress with your friends. They’ll help point out things that don’t look nice. If at anytime you’re unsure of how to layout a page, stop what you’re doing on the computer, print it out, and start throwing down ideas with a pen(cil).

So in short – basic layout started in Scribus, design and playing around with ideas done in GIMP, inserting and arranging text done in Scribus, and that’s it. I hope that helped – if you’re unsure on the actual design, searching google images and especially design blogs such as SmashingMagazine can really give you some inspiration.

In other news, things are starting to calm down a bit so within a week or so I should be able to continue development on WIPUP and perhaps even do a few small creative projects.

Related posts:

  1. Perspective July 2009 Released
  2. Perspective Failure
  3. Perspective in progress

Posts for Thursday, November 19, 2009

Changes in Microsoft Windows EULA

My friend Peter Toft just blogged about an important change in the Windows EULA that could very well affect a large part of us. His original blog post (in danish) is available here.

But the short story is that Windows Vista allowed you to contact the manufacturer for a refund for the software if you didn't accept the EULA and Windows 7 appears to have removed that option. You can know contact the manufacturer to cancel the entire order or have them tell you which rights you no longer have because you didn't accept the EULA. Given how stubborn manufacturers are about refunding the windows license here in Denmark and several other countries I guess the Microsoft tax is pretty much impossible to escape now. The way I understand it this EULA change practically makes it mandatory paying for Microsoft Windows if you want a laptop for professionel use at least.

The exact part of the Windows Vista EULA mentioned by Peter is:
By using the software, you accept these terms. If you do not accept them, do not use the
software. Instead, contact the manufacturer or installer to determine their return policy for
a refund or credit..

The same part from the Windows 7 EULA is now:
By using the software, you accept these terms. If you do not accept them, do not use the
software. Instead, contact the manufacturer or installer to determine its return policy. You
must comply with that policy, which might limit your rights or require you to return the
entire system on which the software is installed.

I know of two current cases where Lenovo refuses to follow the Vista EULA and refund the Windows license. One being in Denmark where FreeBSD developer Poul-Henning Kamp is suing Lenovo and the other being in Hong Kong.

I'm curious how people think this EULA change will affect future refunds in different countries and how it relates to the different court cases in the european union and elsewhere that have already taken steps to limit Microsofts abuse of it's de-facto monopoly and secure free competition.

Please comment if you know of other current cases or have any information that can help keep open source operating systems an option when buying laptops.

Making a Django form field using aggregated values

So another Django post for those who like that sort of thing. In this post we will dynamically create the choices argument for the forms.ChoiceField.

Often you will be making a search form where the objects to be searched have common but dynamic field values. The Django admin app does this kind of thing when you use list_filter, but I haven't yet found an official function in the API for doing this (but Django adds new functions all the time).

To take a simple hypothetical example of a web application for a pet shop, you have a model 'Fish' which has a field called 'species' which is just a normal CharField that the staff enter when they get new stock.

Here is my made up Fish model:

from django.db import models
class Fish(models.Model):
    name = models.CharField(max_length=255)
    species = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=7,
                                decimal_places=2,
                                null = True)
    sold = models.BooleanField(default = False)
    record_created = models.DateTimeField(auto_now_add = True)
    record_updated = models.DateTimeField(auto_now = True)

You want to allow the customers to search fish by species.

How do you do this?

Well the most obvious yet drastic solution would be to completly change the workflow to create a species model that the staff fill in every time they add a new kind of fish. Then you can make the form as follows:

class FishSearchForm(forms.Form):
    species = forms.ModelChoiceField(Species.objects.all())

This is not a complete solution however, as your form will have every species name the shop has ever stocked, not necessarily what they have now. Allowing the customer to search for a south american aquarama when you cannot get them anymore is not giving a good experience, it is just raising expectations and then dashing them straight away. So then you have to make a backwards lookup from the species to the fish and filter out the species that are not in stock and so on.

Instead, the way I have been solving this problem is by dynamically creating the 'choices' field based on what is in the database:

class FishSearchForm(forms.Form):
    species = forms.ChoiceField(choices = valuechoices(Fish, 'species'))

My valuechoices function is below:

def valuechoices(model_name, field_name):
    """Return a choices list based on aggregated values of a model.
    Like the list_filter in the admin.
    (For unaggregated objects, just use a ModelChoiceField)

    For example:
    class FishSearchForm(forms.Form):
        species = forms.ChoiceField(choices = valuechoices(Fish, 'species'))

    """
    from django.template.defaultfilters import slugify
    choice_list = model_name.objects.values_list(field_name).distinct()
    choices = [(slugify(choice[0]), choice[0]) for choice in choice_list]
    choices.sort()
    return choices

It is easy to add a none value, e.g. for advanced forms where there are lots of optional ways to search:

species_choices = valuechoices(Fish, 'species')
species_choices.insert(0, (None, u'All'))
class FishSearchForm(forms.Form):
    species = forms.ChoiceField(choices = species_choices)

Be careful when setting an initially selected value, since obviously the initial value needs to exist in the database for it to work.

if you did set the initial value to a something that is not in 'choices', the current version of Django would probably let you off and display the form anyway, but it is best not to rely on undocumented behaviour. It is quite easy just to check whether the initial value is in the database:

initial_fish_species = 'koi' if Fish.objects.filter(species = 'koi').count() else None
class FishSearchForm(forms.Form):
    species = forms.ChoiceField(choices = valuechoices(Fish, 'species'),
                                        initial = initial_fish_species)

Happy hacking and all that jazz.

Discuss this post - Leave a comment

Posts for Wednesday, November 18, 2009

Command Line Dictionary Update


I do alot of work from the terminal so I like to have a dictionary available there. Previously if you read about my command line dictionary post you know that I used some html parsing with curl to do this, lately though I’ve learned about Sdcv and it’s absolutely great. Since I’m not always on the internet this option works alot better with the same results. I also added a thesaurus too. You can find it here.

avatar

They’re Back! Amarok Finally Reimplements Its Killer Feature!

https://bugs.kde.org/show_bug.cgi?id=168781

--- Comment #13 from Daniel Dewald <TheCrasher gmx de>  2009-11-18 02:56:25 ---
Labels support was added and is available in the GIT Version. First stable
release with label support will be 2.2.2.

Woot!

Nostalgiarama

On a whim today, I decided to dust off a bit of my Jpop (Ayumi Hamasaki, to be precise) and give it a listen. It is amazing what memories are invoked from just the first few tracks off of LOVEppears, which I first started listening to in 2000 — my first total immersion dives into computing (nay, computer appreciation), fleeting loves, the Milwaukee School of Engineering, Gentoo Linux, compiling Gentoo Linux, breaking all of my computers at least once.

Lonely nights in a warm bedroom, surrounded by computers, Ayu blasting through XMMS, heralding my first great interest shift. The daily commutes to MSOE punctuated with long sessions before and after class in the student center, tasting for the first time the sweet nectar of broadband, filling my belly with Japanese culture. My last serious interest in anime, my first serious appreciation for the potpourri of the Internet.

The whiteness of an Ayu wallpaper. My rust bucket truck. The couches in the Cudahy Student Center. The cheeseburgers they served there. Windows file sharing clients, their names long lost, from an age before the luxury of BitTorrent. A certain kind of orange present in my Trillian IM client. Shit, Trillian itself. Conversations never saved, never remembered, no longer the highlight of a lazy afternoon between classes. People not seen in years. Quiet conversations outside, in the cold, revisiting the high school roof.

All from Ayu’s “Trauma". If I had one hope, it was that I never lost these memories. If I had one fear, it would be losing the ability of music to invoke them.

avatar

Portage 2.2 and License Management

Portage 2.2 has recently introduced a new feature that allows users to select what licenses they want to allow on their install. The interface still needs some work (for example, Portage needs to explain when it has “ignored” packages due to license during updates) so that users don’t, for example, get confused as to why their system suddenly wants icedtea instead of sun-jdk. Other than these fairly minor issues, it seems to be working well so far.

There’s an article on Gentoo Wiki that explains this new feature from a users point of view and how to tailor it to your individual tastes.

Posts for Tuesday, November 17, 2009

avatar

msmtp queueing for offline use

muttWhen you start using a small and slow laptop over an unreliable GPRS connection (say while travelling in an ICE at 300km/h) you start noticing certain things that are missing from your current shell-setup. One of these problems manifests itself when you want to send the mail you just typed in mutt. Fortunately there is an easy and elegant fix (if you use mutt with msmtp): msmtpqueue. This gives you three little scripts to enqueue, list and send messages which would otherwise have gone directly into msmtp. Just put them somewhere and then add this to your .muttrc:set sendmail="$HOME/local/bin/msmtp-enqueue -i"
macro index \Cy "!$HOME/local/bin/msmtp-runqueue<enter>"</enter>
Now “sending” mail from mutt happens instantly and you can manually push the batch of mails out to your smtp once the train has stopped in a station and your reception is stable ;). msmtp-listqueue shows you the queued mails while msmtp-runqueue mails them (using msmtp of course!). For the downstream-direction of offline mutt-usage there’s offlineimap, but I feel like this deserves an extra post ;)

avatar

Get adblocking back for archivum.info

If you have adblock enabled and you try to visit any url of www.archivum.info you will get a really nasty alert saying:

You Are Using Adblock Plus or some other advert blocking software! Archivum.info relies on advertising for revenue. Please add www.archivum.info to your ad blocking whitelist or disable ad blocking when you visit www.archivum.info.

When I first saw this I laughed…and then I tried to find a way to bypass it.
I used curl to see the sites html code:

<code2>$ curl -v www.archivum.info
curl -v www.archivum.info 
* About to connect() to www.archivum.info port 80 (#0)
*   Trying 69.147.224.162... connected
* Connected to www.archivum.info (69.147.224.162) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.5 (i486-pc-linux-gnu) libcurl/7.19.5 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15 libssh2/1.2
> Host: www.archivum.info
> Accept: */*
> 
< HTTP/1.1 200 OK
< Date: Tue, 17 Nov 2009 11:24:22 GMT
< Server: Apache
< Last-Modified: Mon, 16 Nov 2009 08:41:17 GMT
< Accept-Ranges: bytes
< Content-Length: 9392
< Vary: Accept-Encoding
< Content-Type: text/html
< 
<html>
<head>
<title>archivum.info - The Internet archive.</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">var disabled = false;</script><script type="text/javascript" src="http://www.archivum.info/js/adblocker_probe.js?
site=http://googlead.foobar.tld/"></script><script type="text/javascript">if (disabled == false) { location.replace("http://www.archivum.info/denied");
alert("You Are Using Adblock Plus or some other advert blocking software! Archivum.info relies on advertising
for revenue. Please add www.archivum.info to your ad blocking whitelist or disable ad blocking when you visit
www.archivum.info.");}</script></head>

[snip]</code2>

Here’s how this site blocks Adblockplus: there’s a variable called disabled set to “false” then if a js (http://www.archivum.info/js/adblocker_probe.js) runs it sets disabled to “true” . The hint is that adblockplus blocks urls starting with “googlead.” so it won’t visit “http://www.archivum.info/js/adblocker_probe.js?site=http://googlead.foobar.tld/” and the variable will remain “false“. Then the alert pops up.

The solution is very simple, just add an exception to your local AdblockPlus rules, AdblockPlus Preferences -> Add Filter:
@@|http://www.archivum.info/js/adblocker_probe.js?site=http://googlead.foobar.tld/

So firefox, visits the js url, disabled becomes “true” you are allowed to continue browsing the site and AdblockPlus continues blocking all blockable items.

Countries in Django

Django is my preferred web framework. If you don't know what I am talking about, then you can read my previous posts, e.g. here and here and so on.

Anyway, for the people who do like Django, it comes with a nice set of local field types for inputting post codes and zip codes in different countries as well as Peruvian national identity numbers, Australian territories, Romanian Bank Account Numbers, Icelandic phone numbers and lots of other stuff. This saves you the hassle of implementing fields for these types of data yourself.

Somewhat bizarrely however, Django does not currently contain a field for what country the person or thing is in, which is often a very basic yet important piece of data to collect.

Fortunately, people have started work on this and on a LanguageField, however the patches have been languishing on the bug tracker for some time.

I wanted the CountryField now, so I copied and pasted from the patches and put it in a module, this is on my code page (direct link is here).

It is pretty obvious how you use it, import the field into your models file:

from whatever.countries import CountryField

Then you can add it to a model:

class Whatever(models.Model):
    country_based_in = CountryField(blank = True)

Here the field is shown in the automatically generated admin:

http://commandline.org.uk/images/posts/django/django_countries_field.png

It seems to have all of the countries that one is ever likely to encounter on the web. The module lists countries alphabetically, however lots of online forms put the United States and perhaps the United Kingdom and other large Internet using countries at the top. If you want to do this, then just arrange the tuple in the order that you want, and delete everything from line 276 onwards (i.e. def sorted_countries etc)

This module is beautifully simple, yet it probably saved me 30 to 60 minutes of fiddling about. This is the joy of programming in a friendly open source community, someone has already done the hard work for you already, you just need to dig it out of some bug tracker and adapt it to your needs.

Happy hacking and all that jazz.

Discuss this post - Leave a comment

Posts for Monday, November 16, 2009

Fluxbox, we meet again

I'm sort of tired of KDE4 crashing left and right and Plasma barfing all over me all day. So I decided to check out the current state of lightweight window managers.

Lo and behold, Fluxbox is still going strong. It was the first WM I used way back in 2000-something when I started using Linux full-time. Last time I tried, there were always weird compatibility problems with system tray icons and pagers working properly when running a mix of KDE and Gnome and other apps, but those seem to have cleared up nicely; I have yet to hit any snags. Here's a screenshot.

Fluxbox

This took very minimal effort to install and set up. Maybe a couple hours total. I'm using ipager and conky. The wallpaper comes from the UniQ KDE theme. Vim and Emacs themes are my own.

The Fluxbox style is mydefcon_4 from tenr.de which is probably the largest and most thorough set of themes created by one person that I've witnessed. That fellow is motivated.

For all the bells and whistles of KDE4, what features did I actually use regularly?

  1. A menu of apps
  2. Taskbar + System tray + Clock
  3. KWin's good window management.
  4. Global keyboard shortcuts galore
  5. One widget: current CPU/RAM/Network usage
  6. Mouse/keyboard management, background-setting, etc.

Fluxbox gives me all but number 5, and Conky gives me that. Number 6 you can do with xset and feh and such.

And I like being motivated to use keyboard shortcuts for more things. I'm already halfway there. Maybe I can take the plunge eventually and try a tiling window manager. Not sure I've reached that level of nerditude yet though.

And now I can move and resize windows without my graphics card bursting into flames. Maybe when I can afford a few more cores worth of CPU I'll try KDE4 again. Honestly I think I have too much monitor real-estate for my ancient computer to handle smoothly in KDE4.

Not to knock KDE4; it's awesome and I'll probably go back someday. But everyone needs a break now and then.

Posts for Sunday, November 15, 2009

This Week in Python Stupidity: os.stat, os.utime and Sub-Second Timestamps


The primary design principle behind the Python programming language is to take everything that’s horrible and wrong with Perl and get it horrible and wrong in a completely different and even more hideous way. Today, however, we shall be looking at a particularly egregious case of stupidity the likes of which not even PHP has managed to replicate.

On Unix, timestamps have traditionally been held as an integer number of seconds since the epoch. The modification time for a file is one place such a timestamp has been used. Two groups of system calls are of interest to us here.

First, stat (and its fstat and lstat variants). The stat system call places information about a file into a struct also named stat (which is possible thanks to a lesser case of brain damage in C’s design). To get the mtime of a file, historically we would have used the st_mtime field, which is of type time_t, which is an integer of some kind:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char * argv[])
{
    struct stat s;
    if (-1 == stat("timmy", &s))
        return EXIT_FAILURE;

    printf("stat.st_mtime for timmy is %ld\n", s.st_mtime);
    return EXIT_SUCCESS;
}

Sometimes we might want to modify a file, but not affect its mtime. Thus, we need a way to set a file’s mtime to a given value, and to do this we would historically have used a function from the utime family:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <utime.h>
#include <fcntl.h>

int main(int argc, char * argv[])
{
    struct stat s;
    if (-1 == stat("timmy", &s))
        return EXIT_FAILURE;

    int fd;
    fd = open("timmy", O_WRONLY, O_TRUNC | O_CREAT);
    if (-1 == fd)
        return EXIT_FAILURE;
    if (0 != close(fd))
        return EXIT_FAILURE;

    struct utimbuf times = { .actime = s.st_atime, .modtime = s.st_mtime };
    if (-1 == utime("timmy", &times))
        return EXIT_FAILURE;

    return EXIT_SUCCESS;
}

(Sidenote: the above almost certainly should be using fstat and futimes instead to avoid race conditions, but this is irrelevant for our examples.)

But all of this operates only on a second-precision basis. For many applications this is no longer sufficient. Fortunately, some kernels and filesystems now support nanosecond-resolution timestamps.

First, for the stat family: rather than using st_mtime, we now use st_mtim, which is a struct timespec:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char * argv[])
{
    struct stat s;
    if (-1 == stat("timmy", &s))
        return EXIT_FAILURE;

    printf("stat.st_mtim for timmy is %lds %ldns\n",
            s.st_mtim.tv_sec, s.st_mtim.tv_nsec);
    return EXIT_SUCCESS;
}

And if our filesystem supports it, we get something like:

$ ./mtimens
stat.st_mtim for timmy is 1258321672s 173919603ns

As we can see, running our old utime-using code preserves the seconds but not the nanoseconds:

$ touch timmy
$ ./mtimens
stat.st_mtim for timmy is 1258321978s 62671870ns
$ ./utime
$ ./mtimens
stat.st_mtim for timmy is 1258321978s 0ns

To modify preserving nanoseconds, we use either utimensat or futimens:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <utime.h>
#include <fcntl.h>

int main(int argc, char * argv[])
{
    struct stat s;
    if (-1 == stat("timmy", &s))
        return EXIT_FAILURE;

    int fd;
    fd = open("timmy", O_WRONLY, O_TRUNC | O_CREAT);
    if (-1 == fd)
        return EXIT_FAILURE;
    if (0 != close(fd))
        return EXIT_FAILURE;

    struct timespec times[2] = { s.st_atim, s.st_mtim };
    if (-1 == utimensat(AT_FDCWD, "timmy", times, 0))
        return EXIT_FAILURE;

    return EXIT_SUCCESS;
}

And now it works as expected:

$ touch timmy
$ ./mtimens
stat.st_mtim for timmy is 1258322326s 852774523ns
$ ./utimens
$ ./mtimens
stat.st_mtim for timmy is 1258322326s 852774523ns

Incidentally, POSIX.1-2008 considers the non-nanosecond-resolution functions and members to be deprecated, although since the nanosecond resolution functions aren’t universally available yet, a certain amount of autovoodoo is generally required…

Now we shall look at some Python. First, the old way:

import os

s = os.stat("timmy")

f = open("timmy", "w+")
f.close()

os.utime("timmy", (s.st_atime, s.st_mtime))

Now, to see if we can guess how the new way works:

>>> import os
>>> os.stat("timmy").st_mtim
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'posix.stat_result' object has no attribute 'st_mtim'

Mmm, nope. Time to consult the documentation. Nothing under stat, but there’s something interesting called stat_float_times:

stat_float_times([newvalue])

Determine whether stat_result represents time stamps as float objects. If newvalue is True, future calls to stat() return floats, if it is False, future calls return ints. If newvalue is omitted, return the current setting.

Uh oh. This can’t be good. Let’s look more closely at what happens when we run our code that uses stat.st_mtime and os.utime:

$ touch timmy
$ ./mtimens
stat.st_mtim for timmy is 1258324320s 762942258ns
$ python utime.py
$ ./mtimens
stat.st_mtim for timmy is 1258324320s 762942000ns
$ ./utimens 12345678901 111111111
$ ./mtimens
stat.st_mtim for timmy is 12345678901s 111111111ns
$ python utime.py
$ ./mtimens
stat.st_mtim for timmy is 12345678901s 111110000ns

What’s that, Lassie? Timmy has lost several significant digits of its sub-second mtime? Oh noes!

Yup, that’s right, Python’s underlying type for floats is an IEEE 754 double, which is only good for about sixteen decimal digits. With ten digits before the decimal point, that leaves six for sub-second resolutions, which is three short of the range required to preserve POSIX nanosecond-resolution timestamps. With dates after the year 2300 or so, that leaves only five accurate digits, which isn’t even enough to deal with microseconds correctly. Brilliant.

Posted in python Tagged: python

Migrated to Sabayon, in need of a EvroKorpus plasmoid

What I would give for a EvroTerm/EvroKorpus plasmoid right now!!! XD

Also, the stability of the Jamendo plugin in Amarok leaves a lot to be desired.

Sabayon is cool (for a temporary replacement for Gentoo).

hook out >> legal counciling, translating and sipping tea...
<!--break-->

links for 2009-11-15

avatar

A lovely little emoticon set from KDE.

I am of the opinion that the default emoticons on KDE are disgusting. Over time I’ve grown accustomed to them but lately I decided to do something once and for all. My solution was in the KDE forums – which had a different iconset (shouldn’t they be the same?) Sure, they didn’t have as many emoticons but I’m not an avid user. Anyways, here is a picture for those unaquainted with those iconsets:

… and of course you can download it here. KDE users can install it from System Settings, or even through Get Hot New Stuff. Users on other operating systems, it’s just a regular .tar.gz file so uncompress it and get the pictures inside and import it your own way.

Related posts:

  1. What is FTP?

It's Been Awhile...

Wow... It's been a long, long time since I updated anything about my life on here.  Mostly because stuff got really busy, and really interesting about April of this year.  I've documented all the crud that we've gone through, so no need to rehash that.

What I would like to say is that music is more a part of my life now than it ever has been.  I play my drums an average of about 30 minutes per day now, whereas before six months ago, I played them more like 30 minutes per month.  I've been spending a large amount of time learning how to properly track, mix, and master audio.  I've created a site for my studio, and am in the process of creating a site for something which I hadn't really seriously considered until two people started paying me to play my drums for their songs.

It's sort of a "remote drummer" type of thing.  Basically, musicians write their songs, record them the best they can, and then send them to me to play and record the drums for them.  Evidently, people think I can play much better than I think I can, and right now, we can certainly use the money.

So...  That's what's up.

Well...  Almost...    I've got a Christmas-based project I'm working on with a friend which is turning out to be one of the funnest and most professional projects I've ever worked on.  Talk about trial by fire.

Anyway...  As the project progresses, I'll let ya more in to what exactly is going on, but for now, I'm having the time of my life with it.

And that's about it for this time of the morning.  I've gotta go to choir in a few hours!

Posts for Saturday, November 14, 2009

Installing Go in Ubuntu Jaunty

Processor: x86
Operating System: Ubuntu Linux 9.04 Jaunty Jackalope

1. CONFIGURE THE ENVIRONMENT
Set the necessary variables in your .bashrc that is if you are using bash. Assuming you have a 386-descendant processor and you want to keep the installation clean in an external disk (/media/disk).

# Google Go Programming Language Settings
export GOROOT=/media/disk/go
export GOARCH=386
export GOOS=linux
export GOBIN=/media/disk/go/bin

2. INSTALL MERCURIAL.
Easy.

$ sudo easy_install mercurial

Install process,

Searching for mercurial
Reading http://pypi.python.org/simple/mercurial/
Reading http://www.selenic.com/mercurial
Best match: mercurial 1.3.1
Downloading http://mercurial.selenic.com/release/mercurial-1.3.1.tar.gz
Processing mercurial-1.3.1.tar.gz
Running mercurial-1.3.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-a3YaRd/mercurial-1.3.1/egg-dist-tmp-VyNqd2
zip_safe flag not set; analyzing archive contents...
mercurial.lsprof: module references __file__
mercurial.templater: module references __file__
mercurial.extensions: module references __file__
mercurial.i18n: module references __file__
Adding mercurial 1.3.1 to easy-install.pth file
Installing hg script to /usr/local/bin
	
Installed /usr/local/lib/python2.6/dist-packages/mercurial-1.3.1-py2.6-linux-i686.egg
Processing dependencies for mercurial
Finished processing dependencies for mercurial


3. CHECKOUT GO USING MERCURIAL

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

Checkout process,

requesting all changes
adding changesets
adding manifests
adding file changes
added 4016 changesets with 16888 changes to 2931 files
updating working directory
1640 files updated, 0 files merged, 0 files removed, 0 files unresolved

4. BUILD GO

$ cd $GOROOT/src
$ ./all.bash

Build process,

--- cd pkg/exp/ogle
rm -rf *.[568vqo] *.a [568vq].out *.cgo[12].go *.cgo[34].c *.so _obj _test _testmain.go ogle
8g -o _go_.8 abort.go arch.go cmd.go event.go frame.go goroutine.go rruntime.go rtype.go rvalue.go process.go vars.go
rm -f _obj/exp/ogle.a
gopack grc _obj/exp/ogle.a _go_.8
8g -I_obj main.go
8l -L_obj -o ogle main.8
	
real	0m2.264s
user	0m1.496s
sys	0m0.136s
	
--- cd ../doc/progs
	
real	0m4.430s
user	0m3.144s
sys	0m0.444s
	
--- cd ../test/bench
fasta
reverse-complement
nbody
binary-tree
binary-tree-freelist
fannkuch
regex-dna
spectral-norm
k-nucleotide
mandelbrot
meteor-contest
pidigits
threadring
chameneosredux

It should end with the following lines,

--- cd ../test
0 known bugs; 0 unexpected bugs

5. ENJOY!

avatar

Aspire One / X.org screen blanking

When using X on my Acer Aspire One (110L) and playing videos with mplayer, X would occasionally blank the screen after a few minutes without any way out but to suspend/resume to get your X back. This didn’t only happen with mplayer, and it didn’t have anything to do with xscreensaver.Anyway, after some digging I found that adding Option "FramebufferCompression" "off"to the Device-section of my xorg.conf resolved the problem.
Another cool thing I found out while going through ssh manpages is that you can silence the motd on login simply by touching ~/.hushlogin.

I'm turning into a Lisp snob

Reddit and StackOverflow and other websites I frequent are filled to the brim with discussion of Google's Go. The code snippet on the front page is:

package main

import "fmt"

func main() {
  fmt.Printf("Hello, 世界\n")
}

First thoughts that ran through my head as I looked over the site:

  • Ugh, look at all that syntax.
  • Nice(r) type system (than C++ and Java). I'll stick with multimethods though.
  • Concurrency semantics, hmmm... Shared mutable memory between threads? I think I'll stick with Clojure for now thanks.
  • Where are the macros?
  • It has anonymous functions and closures and sort-of first-class functions? Good. Welcome to the 1960's.
  • len is a special operator? Sigh. (Programming language quality is usually inversely proportional to the number of special forms.)
  • Cool that they used Japanese in the example though. (That word is sekai, "world", obviously.)

Compared to a Lisp, this language looks indistinguishable to C, Perl, Python, Java etc. It looks like such a small incremental improvement (if it even is an improvement). Yet another imperative, for-loop-wielding, curly-brace-using, pointer-mangling, state-mutating, OOP language.

In fact via Reddit today I read this awesome post to a mailing list which compares Go with ALGOL68, and it gave me a would-you-look-at-that moment. Once you learn a few languages that are significantly different from ALGOL derivatives, all ALGOLish languages start to look eerily similar. Are we really stuck with ALGOL-derived languages being the only viable mainstream languages for all time? How much polish can we possibly apply to the same turd?

Then I realized, I'm turning into a Lisp snob. : ( Learning a Lisp apparently does spoil you for the rest of time. I am without a basis to judge whether this language will be a successful replacement of anything. All I know is I probably won't use it. Honestly I'm much more excited about new things on the horizon in Clojure. And I still have getting better at Haskell on my TODO list.

Posts for Friday, November 13, 2009

avatar

Gentoo Wallpaper

I just found this wallpaper I seem to have made in ‘06 (around August) and posted to the Gentoo Forums. It never went anywhere, but it would be a shame to let it go to waste, so here you go. Don’t ask for any higher resolutions though ;)

Download it in 800×600, 1024×768 or 1280×1024.

Linux audio player comparison (nit-picking)

Given my inability to use Amarok 1.4 and my lack of desire to use Amarok 2.0, I tried loads of music players and for now I've landed on aTunes.

It's not perfect. It's far from perfect. But it's the best of the bunch. These are the features I MUST HAVE for a media player and which aTunes possesses.

  1. Last.fm integration. aTunes has probably the best integration I've seen in a player, without going over-the-top and stuffing a whole web browser into the app.
  2. System tray icon, right-clickable with song controls in the menu.
  3. Commandline interface.
  4. Able to display CJK fonts. In Arch (or in Gentoo using the icedtea6-bin VM) CJK fonts are displayed as empty boxes, but in Gentoo using Sun JVM, it works fine.
  5. Tag editing. aTunes has a pretty nice tag editor for single songs or multiple at once.
  6. Amarok-like tree of albums/artists/genres/whatever I want. I want a single expandable and collapsable tree-list, not 3 panes I have to click between.
  7. Equalizer.
  8. Skins are nice; aTunes has these.
  9. "Collection" support and folder-watching/auto-updating when I dump music into ~/music. aTunes does this very well. Scanned a few thousand files fairly quickly, and does updates very fast.
  10. Amarok-1.4-like spreadsheetish playlist layout.
  11. Lightweight build process. No gstreamer. aTunes provides Mplayer and Xine backends and has few to no other dependencies (besides Java). The Mplayer backend didn't work out very well for me, but Xine works beautifully.

It also has some other nice bonuses, like the elegant way it uses the Album Artist tag for albums with multiple artists, the interesting statistics and bar graphs it can produce from your song listening history, playlist tabs, and so on.

Things I dislike about aTunes... well it's a Java app, so it takes a decade to start up. It also has horrid fonts and the widgets are clunky. But it's responsive once it's running, and I don't care how it looks as much as how sane the layout is. Searching is also clunky. But these aren't show-stoppers.

Here's a list of other players I tried, and why I didn't use them.

Amarok 1.4

  • I'd use this if I could. :( It compiles and runs on my Gentoo box but too much stuff is broken due to bit-rot.

Amarok 2

Banshee

  • It wanted to pull in about a billion and a half Gnome dependencies. This is not fun for a KDE user.

Songbird

So close. This is probably second place behind aTunes. It has a great plugin system, it's skinnable, the layout is extremely functional and compact and easy to use and customizable. But...

  • No system tray icon in Linux! This is a show-stopper. There's alltray but it doesn't let me right-click and have song controls.
  • It has a clumsy commandline interface which makes setting global KDE keyboard shortcuts annoying.
  • Bloat. Do you really need a full-fledged web browser in your media player?
  • XUL, ew.

gmusicbrowser

This is very customizable (almost absurdly so) and looks promising. However...

  • Still a bit beta-quality.
  • Crashed on me a couple times in the short time I used it.
  • Interface has a kitchen-sink feel to it. Too many tabs and widgets all over the place. I couldn't find a layout I liked.
  • Looks pretty good, but no real compelling reason to use this.
  • Written in Perl?

amaroq

  • Alpha-quality PyQt4 clone of Amarok 1.4. Looks promising. I will keep an eye on this.

MPD

Last time I tried MPD was years ago. If aTunes doesn't work out, I'll try this next. But aTunes has kept me going for a week now, and I have very few complaints.

If they do a complete rewrite for aTunes 2.0 and destroy the interface, I'll jump off a bridge.

Planet Larry is not officially affiliated with Gentoo Linux. Original artwork and logos copyright Gentoo Foundation. Yadda, yadda, yadda.