Shallow Thoughts : : Aug

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sun, 26 Aug 2012

We've taken care of our supplier problems ...

[3 adjacent stores: Scales 'n' Tails, Aquarium supplies, and Sushi Dake]

I love these three storefronts right next to each other.

At least it reduces any freshness problems the one on the right might have had with its previous suppliers.

Tags: , ,
[ 22:29 Aug 26, 2012    More humor | permalink to this entry | ]

Tue, 21 Aug 2012

GIMP: Re-uniting Save and Export

In GIMP 2.8, the developers changed the way you save files. "Save" is now used only for GIMP's native format, XCF (and compressed variants like .xcf.gz and .xcf.bz2). Other formats that may lose information on layers, fonts and other aspects of the edited image must be "Exported" rather than saved.

This has caused much consternation and flameage on the gimp-user mailing list, especially from people who use GIMP primarily for simple edits to JPEG or PNG files.

I don't particularly like the new model myself. Sometimes I use GIMP in the way the developers are encouraging, adding dozens of layers, fonts, layer masks and other effects. Much more often, I use GIMP to crop and rescale a handful of JPG photos I took with my camera on a hike. While I found it easy enough to adapt to using Ctrl-E (Export) instead of Ctrl-S (Save), it was annoying that when I exited the app, I'd always get am "Unsaved images" warning, and it was impossible to tell from the warning dialog which images were safely exported and which might not have been saved or exported at all.

But flaming on the mailing lists, much as some people seem to enjoy it (500 messages on the subject and still counting!) wasn't the answer. The developers have stated very clearly that they're not going to change the model back. So is there another solution?

Yes -- a very simple solution, in fact. Write a plug-in that saves or exports the current image back to its current file name, then marks it as clean so GIMP won't warn about it when you quit.

It turned out to be extremely easy to write, and you can get it here: GIMP: Save/export clean plug-in. If it suits your GIMP workflow, you can even bind it to Ctrl-S ... or any other key you like.

Warning: I deliberately did not add any "Are you sure you want to overwrite?" confirmation dialogs. This plug-in will overwrite your current file, without asking for permission. After all, that's its job. So be aware of that.

How it's written

Here are some details about how it works. Non software geeks can skip the rest of this article.

When I first looked into writing this, I was amazed at how simple it was: really just two lines of Python (plus the usual plug-in registration boilerplate).

    pdb.gimp_file_save(img, drawable, img.filename, img.filename)
    pdb.gimp_image_clean_all(img)

The first line saves the image back to its current filename. (The gimp-file-save PDB call still handles all types, not just XCF.) The second line marks the image as clean.

Both of those are PDB calls, which means that people who don't have GIMP Python could write script-fu to do this part.

So why didn't I use script-fu? Because I quickly found that if I bound the plug-in to Ctrl-S, I'd want to use it for new images -- images that don't have a filename yet. And for that, you need to pop up some sort of "Save as" dialog -- something Python can do easily, and Script-fu can't do at all.

A Save-as dialog with smart directory default

I couldn't use the standard GIMP save-as dialog: as far as I can tell, there's no way to call that dialog from a plug-in. But it turned out the GTK save-as dialog has no default directory to start in: you have to set the starting directory every time. So I needed a reasonable initial directory.

I didn't want to come up with some desktop twaddle like ~/My Pictures or whatever -- is there really anyone that model fits? Certainly not me. I debated maintaining a preference you could set, or saving the last used directory as a preference, but that complicates things and I wasn't sure it's really that helpful for most people anyway.

So I thought about where I usually want to save images in a GIMP session. Usually, I want to save them to the same directory where I've been saving other images in the same session, right?

I can figure that out by looping through all currently open images with for img in gimp.image_list() : and checking os.path.dirname(img.filename) for each one. Keep track of how many times each directory is being used; whichever is used the most times is probably where the user wants to store the next image.

Keeping count in Python

Looping through is easy, but what's the cleanest, most Pythonic way of maintaining the count for each directory and finding the most popular one? Naturally, Python has a class for that, collections.Counter.

Once I've counted everything, I can ask for the most common path. The code looks a bit complicated because most_common(1) returns a one-item list of a tuple of the single most common path and the number of times it's been used -- for instance, [ ('/home/akkana/public_html/images/birds', 5) ]. So the path is the first element of the first element, or most_common(1)[0][0]. Put it together:

    counts = collections.Counter()
    for img in gimp.image_list() :
        if img.filename :
            counts[os.path.dirname(img.filename)] += 1
    try :
        return counts.most_common(1)[0][0]
    except :
        return None

So that's the only tricky part of this plug-in. The rest is straightforward, and you can read the code on GitHub: save-export-clean.py.

Tags: , ,
[ 12:26 Aug 21, 2012    More gimp | permalink to this entry | ]

Sun, 19 Aug 2012

They put handicapped parking in the darndest places ...

[Handicapped people, park in the bushes] In my rambles, I've sometimes noticed that handicapped parking isn't always as convenient as it ought to be.

For instance, in one vista point up on Skyline Blvd, there's a handicapped parking sign way off in the bushes and down the hillside, far away from the parking lot where everybody else parks. Makes me wonder how you'd get a wheelchair through all that coyote brush.

[Handicapped people, watch out for the slope]

Or this sign, in the Verdugo mountains. I'm not sure I'd want to park in a spot that needed a warning sign like that!

Tags:
[ 16:34 Aug 19, 2012    More humor | permalink to this entry | ]

Wed, 15 Aug 2012

Getting ls to show symlinks (and stripping terminal slashes in shells)

The Linux file listing program, ls, has been frustrating me for some time with its ever-changing behavior on symbolic links.

For instance, suppose I have a symlink named Maps that points to a directory on another disk called /data/Maps. If I say ls ~/Maps, I might want to see where the link points:

lrwxrwxrwx   1 akkana users              12 Jun 17  2009 Maps -> /data/Maps/
or I might equally want to see the contents of the /data/Maps directory.

Many years ago, the Unix ls program magically seemed to infer when I wanted to see the link and what it points to, versus when I wanted to see the contents of the directory the link points to. I'm not even sure any more what the rule was; just that I was always pleasantly surprised that it did what I wanted. Now, in modern Linux, it usually manages to do the opposite of what I want. But the behavior has changed several times until, I confess, I'm no longer even sure of what I want it to do.

So if I'm not sure whether I usually want it to show the symlink or follow it ... why not make it do both?

There's no ls flag that will do that. But that's okay -- I can make a shell function to do what I want..

Current ls flags

First let's review man ls to see the relevant flags we do have, searching for the string "deref".

I find three different flags to tell ls to dereference a link: -H (dereference any link explicitly mentioned on the command line -- even though ls does that by default); --dereference-command-line-symlink-to-dir (do the same if it's a directory -- even though -H already does that, and even though ls without any flags also already does that); and -L (dereference links even if they aren't mentioned on the command line). The GNU ls maintainers are clearly enamored with dereferencing symlinks.

In contrast, there's one flag, -d, that says not to dereference links (when used in combination with -l). And -d isn't useful in general (you can't make it part of a normal ls alias) because -d also has another, more primary meaning: it also prevents you from listing the contents of normal, non-symlinked directories.

Solution: a shell function

Let's move on to the problem of how to show both the link information and the dereferenced file.

Since there's no ls flag to do it, I'll have to do it by looping over the arguments of my shell function. In a shell test, you can use -h to tell if a file is a symlink. So my first approach was to call ls -ld on all the symlinks to show what the point to:

ll() {
    /bin/ls -laFH $*
    for f in $*; do
        if [[ -h $f ]]; then
            echo -n Symlink:
            /bin/ls -ld $f
        fi
    done
}

Terminally slashed

That worked on a few simple tests. But when I tried to use it for real I hit another snag: terminal slashes.

In real life, I normally run this with autocompletion. I don't type ll ~/Maps -- I'm more likely to type like ll Ma<tab> -- the tab looks for files beginning with Ma and obligingly completes it as Maps/ -- note the slash at the end.

And, well, it turns out /bin/ls -ld Maps/ no longer shows the symlink, but derefernces it instead -- yes, never mind that the man page says -d won't dereference symlinks. As I said, those ls maintainers really love dereferencing.

Okay, so if I want to not dereference, since there's no ls flag that means really don't dereference, I mean it -- my little zsh function needs to find a way of stripping any terminal slash on each directory name. Of course, I could do it with sed:

        f=`echo $f | sed 's/\/$//'`
and that works fine, but ... ick. Surely zsh has a better way?

In fact, there's a better way that even works in bash (thanks to zsh wizard Mikachu for this gem):

        f=${f%/}

That "remove terminal slash" trick has already come in handy in a couple of other shell functions I use -- definitely a useful trick if you use autocompletion a lot.

Making the link line more readable

But wait: one more tweak, as long as I'm tweaking. That long ls -ld line,

lrwxrwxrwx   1 akkana users              12 Jun 17  2009 Maps -> /data/Maps/
is way too long and full of things I don't really care about (the permissions, ownership and last-modified date on a symlink aren't very interesting). I really only want the last three words,
Maps -> /data/Maps/

Of course I could use something like awk to get that. But zsh has everything -- I bet it has a clever way to separate words.

And indeed it does: arrays. The documentation isn't very clear and not all the array functions worked as the docs implied, but here's what ended up working: you can set an array variable by using parentheses after the equals sign in a normal variable-setting statement, and after that, you can refer to it using square brackets. You can even use negative indices, like in python, to count back from the end of an array. That made it easy to do what I wanted:

            line=( $(/bin/ls -ld $f ) )
            echo -E Symlink: $line[-3,-1]

Hooray zsh! Though it turned out that -3 didn't work for directories with spaces in the name, so I had to use [9, -1] instead. The echo -E is to prevent strange things happening if there are things like backslashes in the filename.

The completed shell function

I moved the symlink-showing function into a separate function, so I can call it from several different ls aliases, and here's the final result:

show_symlinks() {
    for f in $*; do
        # Remove terminal slash.
        f=${f%/}
        if [[ -h $f ]]; then
            line=( $(/bin/ls -ld $f ) )
            echo -E Symlink: $line[9,-1]
        fi
    done
}

ll() {
    /bin/ls -laFH $*
    show_symlinks $*
}

Bash doesn't have arrays like zsh, so replace those two lines with

            echo -n 'Symlink: '
            /bin/ls -ld $f | cut -d ' ' -f 10-
and the rest of the function should work just fine.

Tags: , , ,
[ 20:22 Aug 15, 2012    More linux/cmdline | permalink to this entry | ]

Sun, 12 Aug 2012

A daytime Venus occultation

Tomorrow -- Monday, August 13th -- starting a little after 1 pm PDT (20 UT), the moon passes in front of Venus. That's during the day for those of us in the US, but don't worry -- both Venus and the moon are easily visible during the daytime.

The RASC handbook lists the time as exactly 1pm, but XEphem and some web sources show Venus disappearing at more like 1:30. The time isn't critical, because the most interesting part of this occultation is the lead-up, where you can see both Venus and the moon at once. The nearness of the moon will make it easy to locate Venus during the day, something that's usually a bit challenging even with this bright magnitude -4 planet.

Binoculars should show both objects just fine, though a telescope is even better. In a telescope, you'll be able to compare the phases of the two objects: the slim crescent of the moon contrasted with the half Venus.

If you've never seen a Venus occultation before, you'll be amazed at the difference between the brightness of Venus and the dimness of the moon's limb. We think of the moon as bright, but it's actually dark grey, about the same albedo (reflectivity) as asphalt; whereas Venus is covered with brightly reflective clouds.

It's a great excuse to set up a telescope or binoculars for a late lunchtime observing session and share some photons with your co-workers or anyone else who happens by. I've heard an amazing number of adults express amazement at the idea of seeing the moon during the daytime (even though they've undoubtedly seen it themselves at some point, and just don't remember it). So seeing both objects, and their phases, should be a great conversation starter outside the cafeteria or local coffeehouse.

I'd suggest setting up no later than 12:30, and earlier works fine. Even before 11, a low power eyepiece should show both the moon and Venus in the same field. Watch out for the sun! Try to find a place where you're shaded from the sun but can still see the moon. That way, not only do you stay cooler, but you're protected against accidentally swinging binoculars toward the sun and blinding yourself.

Of course, what goes behind must come out again: Venus should re-emerge from behind the dark side of the moon around 2:30 to 3 pm.

[Daytime Venus occultation] And now it's over. A fun event! It disappeared at about 1:35pm. You can see my low-tech photos here: Daytime Venus occultation, 2012-8-13.

Tags:
[ 13:27 Aug 12, 2012    More science/astro | permalink to this entry | ]

Thu, 09 Aug 2012

Tool sanity! Who knew they had tool rolls?

I have an old tool bag I bought at a surplus store a zillion years ago to carry tools in the trunk of my Fiat X1/9, while I was learning to work on cars. It's reasonably compact, with two pockets, which I designated as "wrenches" and "everything else", and it carried nearly all my tools for over a decade.

But over that time, it's been getting progressively shabbier and dirtier -- funny thing about something that gets tossed on roadsides and parking lots. And I've been getting tired of the way, when I need to find that 10mm wrench, I have to dump everything in the "wrenches" pocket out on the garage floor and sort through them. Then the last straw was the zipper breaking.

Lately, every time I have to find a tool, an idle thought flits through the back of my mind, like ... wouldn't it be nice if I had some flat thing that held all the tools in some sort of order, which then rolled up into a compact bag?

It took an embarrassingly long time before it occurred to me that if I was thinking this, maybe someone else had had the same idea ... and to go to Amazon and search for "tool roll". And discover that there were dozens of these things, and they're not even expensive. Under $20 for a nice one. So I ordered one. [Tool roll, open]

When it arrived, I took all my tools out of the old bag, washed and dried them, and sorted them. (What ever happened to my 14mm socket? Or the short 3/8-inch extension?) Then I laid out the tool roll and started choosing pockets.

I was glad I'd chosen the 25-pocket model instead of one of the smaller ones. I didn't have any problem filling out the pockets, and I'm still not sure what to do with my set of deep sockets. Maybe I should get an even bigger roll!

[Tool roll, closed] But I'm very happy with my tool roll for now. I'm jazzed about how organized the tools are now and how easy it'll be to find things, and to pack up after a repair job. And it rolls up much smaller than the old tool bag, so it'll be easy to store in the Miata's trunk. Not that I expect to need to carry tools with the Miata, like I sometimes needed for the Fiats ... but it never hurts to be prepared. And having my tools in one compact place will also it easy to toss them in the back of the Rav4 when we go on desert trips.

(And no, I don't know how the large Vice-Grips got so rusty. They never got wet.)

Tags: , ,
[ 16:10 Aug 09, 2012    More hardware | permalink to this entry | ]

Tue, 07 Aug 2012

Extended comments in XML

Quite a few programs these days use XML for their configuration files -- for example, my favorite window manager, Openbox.

But one problem with XML is that you can't comment out big sections. The XML comment sequence is the same as HTML's: <!-- Here is a comment --> But XML parsers can be very picky about what they accept inside a comment section.

For instance, suppose I'm testing suspend commands, and I'm trying two ways of doing it inside Openbox's menu.xml file:

  <item label="Sleep">
    <action name="Execute"><execute>sudo pm-suspend --auto-quirks</execute></action>
  </item>
  <item label="Sleep">
    <action name="Execute"><execute>sudo /etc/acpi/sleep.sh</execute></action>
  </item>

Let's say I decide the second option is working better for now. But that sometimes varies among distros; I might need to go back to using pm-suspend after the next time I upgrade, or on a different computer. So I'd like to keep it around, commented out, just in case.

Okay, let's comment it out with an XML comment:

<!-- Comment out the pm-suspend version:
  <item label="Sleep">
    <action name="Execute"><execute>sudo pm-suspend --auto-quirks</execute></action>
  </item>
 -->
  <item label="Sleep">
    <action name="Execute"><execute>sudo /etc/acpi/sleep.sh</execute></action>
  </item>

Reconfigure Openbox to see the new menu.xml, and I get a "parser error : Comment not terminated". It turns out that you can't include double dashes inside XML comments, ever. (A web search on xml comments dashes will show some other amusing problems this causes in various programs.)

So what to do? An Openbox friend had a great suggestion: use a CDATA section. Basically, CDATA means an unparsed string, one which might include newlines, quotes, or anything else besides the cdata end tag, which is ]]>. So add such a string in the middle of the configuration file, and hope that it's ignored.

So I tried it:

<![CDATA[  Comment out the pm-suspend version:
  <item label="Sleep">
    <action name="Execute"><execute>sudo pm-suspend --auto-quirks</execute></action>
  </item>
]]>
  <item label="Sleep">
    <action name="Execute"><execute>sudo /etc/acpi/sleep.sh</execute></action>
  </item>

Worked fine!

Then I had the bright idea that I wanted to wrap it inside regular HTML comments, so editors like Emacs would recognize it as a commented section and color it differently:

<!-- WARNING: THIS DOESN'T WORK:
<![CDATA[
  <item label="Sleep">
    <action name="Execute"><execute>sudo pm-suspend --auto-quirks</execute></action>
  </item>
]]> -->
  <item label="Sleep">
    <action name="Execute"><execute>sudo /etc/acpi/sleep.sh</execute></action>
  </item>

That, sadly, did not work. Apparently XML's hatred of double-dashes inside a comment extends even when they're inside a CDATA section. But that's okay -- colorizing the comments inside my editor is less important than being able to comment things out in the first place.

Tags: ,
[ 20:20 Aug 07, 2012    More tech/web | permalink to this entry | ]

Sat, 04 Aug 2012

Sing-along machismo

Wired last week reported on a British study on songs people are most likely to sing along to in pubs.

The study concluded that the most popular songs were the ones with "a male vocalist with a loud, clear high-chest voice, without many vocal embellishments."

As to why that was, the lead researcher

suggested that singing along to these songs promotes a kind of "neotribal bonding" among participants. As for why female vocalists' songs weren't popular, Pawley speculated that, whereas women will happily sing along to men, men may feel that voicing a woman's words threatens their masculinity.

So what was the number one singable tune found in this study?

...

Queen's "We are the Champions".

I wish Freddie Mercury, that rugged bastion of straight he-man masculinity, was still around to read that. Bet he would have died laughing.

Now excuse me while I go belt out some "Bohemian Rhapsody" while no one's listening.

Tags:
[ 18:47 Aug 04, 2012    More humor | permalink to this entry | ]