Shallow Thoughts

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

Fri, 29 Apr 2016

Vermillion Cliffs trip, and other distractions

[Red Toadstool, in the Paria Rimrocks] [Cobra Arch, in the Vermillion Cliffs] I haven't posted in a while. Partly I was busy preparing for, enjoying, then recovering from, a hiking trip to the Vermillion Cliffs, on the Colorado River near the Arizona/Utah border. We had no internet access there (no wi-fi at the hotel, and no data on the cellphone). But we had some great hikes, and I saw my first California Condors (they have a site where they release captive-bred birds). Photos (from the hikes, not the condors, which were too far away): Vermillion Cliffs trip.

I've also been having fun welding more critters, including a roadrunner, a puppy and a rattlesnake. I'm learning how to weld small items, like nail legs on spark plug dragonflies and scorpions, which tend to melt at the MIG welder's lowest setting.

[ Welded puppy \ [ Welded Roadrunner ] [ Welded rattlesnake ]

New Mexico's weather is being charmingly erratic (which is fairly usual): we went for a hike exploring some unmapped cavate ruins, shivering in the cold wind and occasionally getting lightly snowed upon. Then the next day was a gloriously sunny hike out Deer Trap Mesa with clear long-distance views of the mountains and mesas in all directions. Today we had graupel -- someone recently introduced me to that term for what Dave and I have been calling "snail" or "how" since it's a combination of snow and hail, soft balls of hail like tiny snowballs. They turned the back yard white for ten or fifteen minutes, but then the sun came out for a bit and melted all the little snowballs.

But since it looks like much of today will be cloudy, it's a perfect day to use up that leftover pork roast and fill the house with good smells by making a batch of slow-cooker green chile posole.

Tags: ,
[ 12:28 Apr 29, 2016    More travel | permalink to this entry | comments ]

Tue, 05 Apr 2016

Modifying a git repo so you can pull without a password

There's been a discussion in the GIMP community about setting up git repos to host contributed assets like scripts, plug-ins and brushes, to replace the long-stagnant GIMP Plug-in Repository. One of the suggestions involves having lots of tiny git repos rather than one that holds all the assets.

That got me to thinking about one annoyance I always have when setting up a new git repository on github: the repository is initially configured with an ssh URL, so I can push to it; but that means I can't pull from the repo without typing my ssh password (more accurately, the password to my ssh key).

Fortunately, there's a way to fix that: a git configuration can have one url for pulling source, and a different pushurl for pushing changes.

These are defined in the file .git/config inside each repository. So edit that file and take a look at the [remote "origin"] section.

For instance, in the GIMP source repositories, hosted on git.gnome.org, instead of the default of url = ssh://git.gnome.org/git/gimp I can set

pushurl = ssh://git.gnome.org/git/gimp
url = git://git.gnome.org/gimp
(disclaimer: I'm not sure this is still correct; my gnome git access stopped working -- I think it was during the Heartbleed security fire drill, or one of those -- and never got fixed.)

For GitHub the syntax is a little different. When I initially set up a repository, the url comes out something like url = git@github.com:username/reponame.git (sometimes the git@ part isn't included), and the password-free pull URL is something you can get from github's website. So you'll end up with something like this:

pushurl = git@github.com:username/reponame.git
url = https://github.com/username/reponame.git

Automating it

That's helpful, and I've made that change on all of my repos. But I just forked another repo on github, and as I went to edit .git/config I remembered what a pain this had been to do en masse on all my repos; and how it would be a much bigger pain to do it on a gazillion tiny GIMP asset repos if they end up going with that model and I ever want to help with the development. It's just the thing that should be scriptable.

However, the rules for what constitutes a valid git passwordless pull URL, and what constitutes a valid ssh writable URL, seem to encompass a lot of territory. So the quickie Python script I whipped up to modify .git/config doesn't claim to handle everything; it only handles the URLs I've encountered personally on Gnome and GitHub. Still, that should be useful if I ever have to add multiple repos at once. The script: repo-pullpush (yes, I know it's a terrible name) on GitHub.

Tags: , , ,
[ 12:28 Apr 05, 2016    More programming | permalink to this entry | comments ]

Sat, 26 Mar 2016

Debian: Holding packages you build from source, and rebuilding them easily

Recently I wrote about building the Debian hexchat package to correct a key binding bug.

I built my own version of the hexchat packages, then installed the ones I needed:

dpkg -i hexchat_2.10.2-1_i386.deb hexchat-common_2.10.2-1_all.deb hexchat-python_2.10.2-1_i386.deb hexchat-perl_2.10.2-1_i386.deb

That's fine, but of course, a few days later Debian had an update to the hexchat package that wiped out my changes.

The solution to that is to hold the packages so they won't be overwritten on the next apt-get upgrade:

aptitude hold hexchat hexchat-common hexchat-perl hexchat-python

If you forget which packages you've held, you can find out with aptitude:

aptitude search '~ahold'

Simplifying the rebuilding process

But now I wanted an easier way to build the package. I didn't want to have to search for my old blog post and paste the lines one by one every time there was an update -- then I'd get lazy and never update the package, and I'd never get security fixes.

I solved that with a zsh function:

newhexchat() {
    # Can't set errreturn yet, because that will cause mv and rm
    # (even with -f) to exit if there's nothing to remove.
    cd ~/outsrc/hexchat
    echo "Removing what was in old previously"
    rm -rf old
    echo "Moving everything here to old/"
    mkdir old
    mv *.* old/

    # Make sure this exits on errors from here on!
    setopt localoptions errreturn

    echo "Getting source ..."
    apt-get source hexchat
    cd hexchat-2*
    echo "Patching ..."
    patch -p0 < ~/outsrc/hexchat-2.10.2.patch
    echo "Building ..."
    debuild -b -uc -us
    echo
    echo 'Installing' ../hexchat{,-python,-perl}_2*.deb
    sudo dpkg -i ../hexchat{,-python,-perl}_2*.deb
}

Now I can type newhexchat and pull a new version of the source, build it, and install the new packages.

How do you know if you need to rebuild?

One more thing. How can I find out when there's a new version of hexchat, so I know I need to build new source in case there's a security fix?

One way is the Debian Package Tracking System. You can subscribe to a package and get emails when a new version is released. There's supposed to be a package tracker web interface, e.g. package tracker: hexchat with a form you can fill out to subscribe to updates -- but for some packages, including hexchat, there's no form. Clicking on the link for the new package tracker goes to a similar page that also doesn't have a form.

So I guess the only option is to subscribe by email. Send mail to pts@qa.debian.org containing this line:

subscribe hexchat [your-email-address]
You'll get a reply asking for confirmation.

This may turn out to generate too much mail: I've only just subscribed, so I don't know yet. There are supposedly keywords you can use to limit the subscription, such as upload-binary and upload-source, but the instructions aren't at all clear on how to include them in your subscription mail -- you say keyword, or keyword your-email, so where do you put the actual keywords you want to accept? They offer no examples.

Use apt to check whether your version is current

If you can't get the email interface to work or suspect it'll be too much email, you can use apt to check whether the current version in the repository is higher than the one you're running:

apt-cache policy hexchat

You might want to automate that, to make it easy to check on every package you've held to see if there's a new version. Here's a little shell function to do that:

# Check on status of all held packages:
check_holds() {
    for pkg in $( aptitude search '~ahold' | awk '{print $2}' ); do
        policy=$(apt-cache policy $pkg)
        installed=$(echo $policy | grep Installed: | awk '{print $2}' )
        candidate=$(echo $policy | grep Candidate: | awk '{print $2}' )
        if [[ "$installed" == "$candidate" ]]; then
            echo $pkg : nothing new
        else
            echo $pkg : new version $candidate available
        fi
    done
}

Tags: , , ,
[ 11:11 Mar 26, 2016    More linux | permalink to this entry | comments ]

Thu, 17 Mar 2016

Changing X brightness and gamma with xrandr

I switched a few weeks ago from unstable ("Sid") to testing ("Stretch") in the hope that my system, particularly X, would break less often. The very next day, I updated and discovered I couldn't use my system at night any more, because the program I use to reduce the screen brightness by tweaking X gamma no longer worked. Neither did other related programs, such as xgamma and xcalib.

The Dell monitor I use doesn't have reasonable hardware brightness controls: strangely, the brightness button works when the monitor is connected over VGA, but if I want to use the sharper HDMI connection, brightness adjustment no longer works. So I depend on software brightness adjustment in order to use my computer at night when the room is dim.

Fortunately, it turns out there's a workaround. xrandr has options for both brightness and gamma:

xrandr --output HDMI1 --brightness .5
xrandr --output HDMI1 --gamma .5:.5:.5

I've always put xbrightness on a key, so I can use a function key to adjust brightness interactively up and down according to conditions. So a command that sets brightness to .5 or .8 isn't what I need; I need to get the current brightness and set it a little brighter or a little dimmer. xrandr doesn't offer that, so I needed to script it.

You can get the current brightness with

xrandr --verbose | grep -i brightness

But I was hoping there would be a more straightforward way to get brightness from a program. I looked into Python bindings for xrandr; there are some, but with no documentation and no examples. After an hour of fiddling around, I concluded that I could waste the rest of the day poring through the source code and trying things hoping something would work; or I could spend fifteen minutes using subprocess.call() to wrap the command-line xrandr.

So subprocesses it was. It made for a nice short script, much simpler than the old xbrightness C program that used <X11/extensions/xf86vmode.h> and XF86VidModeGetGammaRampSize(): xbright on github.

Tags: , , ,
[ 11:01 Mar 17, 2016    More linux | permalink to this entry | comments ]

Tue, 08 Mar 2016

Juniper allergy season

It's spring, and that means it's the windy season in New Mexico -- and juniper allergy season.

When we were house-hunting here, talking to our realtor about things like local weather, she mentioned that spring tended to be windy and a lot of people got allergic. I shrugged it off -- oh, sure, people get allergic in spring in California too. Little did I know.

A month or two after we moved, I experienced the worst allergies of my life. (Just to be clear, by allergies I mean hay fever, sneezing, itchy eyes ... not anaphylaxis or anything life threatening, just misery and a morbid fear of ever opening a window no matter how nice the temperature outside might be.)

[Female (left) and male junipers in spring]
I was out checking the mail one morning, sneezing nonstop, when a couple of locals passed by on their morning walk. I introduced myself and we chatted a bit. They noticed my sneezing. "It's the junipers," they explained. "See how a lot of them are orange now? Those are the males, and that's the pollen."

I had read that juniper plants were either male or female, unlike most plants which have both male and female parts on every plant. I had never thought of junipers as something that could cause allergies -- they're a common ornamental plant in California, and also commonly encountered on trails throughout the southwest -- nor had I noticed the recent color change of half the junipers in our neighborhood.

But once it's pointed out, the color difference is striking. These two trees, growing right next to each other, are the same color most of the year, and it's hard to tell which is male and which is female. But in spring, suddenly one turns orange while the other remains its usual bright green. (The other season when it's easy to tell the difference is late fall, when the female will be covered with berries.)

Close up, the difference is even more striking. The male is dense with tiny orange pollen-laden cones.

[Female juniper closeup] [male juniper closeup showing pollen cones]

A few weeks after learning the source of my allergies, I happened to be looking out the window on a typically windy spring day when I saw an alarming sight -- it looked like the yard was on fire! There were dense clouds of smoke billowing up out of the trees. I grabbed binoculars and discovered that what looked like fire smoke was actually clouds of pollen blowing from a few junipers. Since then I've gotten used to seeing juniper "smoke" blowing through the canyons on windy spring days. Touching a juniper that's ready to go will produce similar clouds.

The good news is that there are treatments for juniper allergies. Flonase helps a lot, and a lot of people have told me that allergy shots are effective. My first spring here was a bit miserable, but I'm doing much better now, and can appreciate the fascinating biology of junipers and the amazing spectacle of the smoking junipers (not to mention the nice spring temperatures) without having to hide inside with the windows shut.

Tags: , ,
[ 20:20 Mar 08, 2016    More nature | permalink to this entry | comments ]

Fri, 04 Mar 2016

Recipe: Easy beef (or whatever) jerky

You don't need a special smoker or dehydrator to make great beef jerky.

Winter is the time to make beef jerky -- hopefully enough to last all summer, because in summer we try to avoid using the oven, cooking everything outside so as not to heat up the house. In winter, having the oven on for five hours is a good thing.

It took some tuning to get the flavor and the amount of saltiness right, but I'm happy with my recipe now.

Beef jerky

Ingredients

Directions

Heat water slightly (30-40 sec in microwave) to help dissolve salt. Mix all ingredients except beef.

Cut meat into small pieces, trimming fat as much as possible.

Marinate in warm salt solution for 15 min, stirring occasionally. (For pork, you might want a shorter marinating time. I haven't tried other meats.)

Set the oven on its lowest temperature (170F here).

Lay out beef on a rack, with pieces not touching or overlapping.
Nobody seems to sell actual cooking racks, but you can buy "cooling racks" for cooling cookies, which seem to work fine for jerky. They're small so you probably need two racks for a pound of beef.

Ideally, put the rack on one oven shelf with a layer of foil on the rack below to catch the drips.
You want as much air space as possible under the meat. You can put the rack on a cookie sheet, but it'll take longer to cook and you'll have to turn the meat halfway through. Don't lay the beef directly on cookie sheet or foil unless you absolutely can't find a rack.

Cook until sufficiently dry and getting hard, about 4 to 4-1/2 hours at 170F depending on how dry you like your jerky. Drier jerky will keep longer unrefrigerated, but it's not as tasty. I cook mine a little less and store it in the fridge when I'm not actually carrying it hiking or traveling.

If you're using a cookie sheet, turn the pieces once at around 2-3 hours when the tops start to look dry and dark.

Tip: if you're using a rack without a cookie sheet, a fork wedged between the bars of the rack makes it easy to remove a rack from the oven.

Tags:
[ 12:24 Mar 04, 2016    More recipes | permalink to this entry | comments ]

Sat, 27 Feb 2016

Learning to Weld

I'm learning to weld metal junk into art!

I've wanted to learn to weld since I was a teen-ager at an LAAS star party, lusting after somebody's beautiful homebuilt 10" telescope on a compact metal fork mount. But building something like that was utterly out of reach for a high school kid. (This was before John Dobson showed the world how to build excellent alt-azimuth mounts out of wood and cheap materials ... or at least before Dobsonians made it to my corner of LA.)

Later the welding bug cropped up again as I worked on modified suspension designs for my X1/9 autocross car, or fiddled with bicycles, or built telescopes. But it still seemed out of reach, too expensive and I had no idea how to get started, so I always found some other way of doing what I needed.

But recently I had the good fortune to hook up with Los Alamos's two excellent metal sculptors, David Trujillo and Richard Swenson. Mr. Trujillo was kind enough to offer to mentor me and let me use his equipment to learn to make sculptures like his. (Richard has also given me some pointers.)

[My first metal art piece] MIG welding is both easier and harder than I expected. David Trujillo showed me the basics and got me going welding a little face out of a gear and chain on my very first day. What a fun start!

In a lot of ways, MIG welding is actually easier than soldering. For one thing, you don't need three or four hands to hold everything together while also holding the iron and the solder. On the other hand, the craft of getting a good weld is something that's going to require a lot more practice.

Setting up a home workshop

I knew I wanted my own welder, so I could work at home on my own schedule without needing to pester my long-suffering mentors. I bought a MIG welder and a bottle of gas (and, of course, safety equipment like a helmet, leather apron and gloves), plus a small welding table. But then I found that was only the beginning.

[Metal art: Spoon cobra] Before you can weld a piece of steel you have to clean it. Rust, dirt, paint, oil and anti-rust coatings all get in the way of making a good weld. David and Richard use a sandblasting cabinet, but that requires a big air compressor, making it as big an investment as the welder itself.

At first I thought I could make do with a wire brush wheel on a drill. But it turned out to be remarkably difficult to hold the drill firmly enough while brushing a piece of steel -- that works for small areas but not for cleaning a large piece or for removing a thick coating of rust or paint.

A bench grinder worked much better, with a wire brush wheel on one side for easy cleaning jobs and a regular grinding stone on the other side for grinding off thick coats of paint or rust. The first bench grinder I bought at Harbor Freight had a crazy amount of vibration that made it unusable, and their wire brush wheel didn't center properly and added to the wobble problem. I returned both, and bought a Ryobi from Home Depot and a better wire brush wheel from the local Metzger's Hardware. The Ryobi has a lot of vibration too, but not so much that I can't use it, and it does a great job of getting rust and paint off.

[Metal art: grease-gun goony bird] Then I had to find a place to put the equipment. I tried a couple of different spots before finally settling on the garage. Pro tip: welding on a south-facing patio doesn't work: sunlight glints off the metal and makes the auto-darkening helmet flash frenetically, and any breeze from the south disrupts everything. And it's hard to get motivated to out outside and weld when it's snowing. The garage is working well, though it's a little cramped and I have to move the Miata out whenever I want to weld if I don't want to risk my baby's nice paint job to welding fumes. I can live with that for now.

All told, it was over a month after I bought the welder before I could make any progress on welding. But I'm having fun now. Finding good junk to use as raw materials is turning out to be challenging, but with the junk I've collected so far I've made some pieces I'm pretty happy with, I'm learning, and my welds are getting better all the time.

Earlier this week I made a goony bird out of a grease gun. Yesterday I picked up some chairs, a lawnmower and an old exercise bike from a friend, and just came in from disassembling them. I think I see some roadrunner, cow, and triceratops parts in there.

Photos of everything I've made so far: Metal art.

Tags: , ,
[ 14:02 Feb 27, 2016    More art | permalink to this entry | comments ]

Wed, 24 Feb 2016

Migrating from xchat: a couple of hexchat fixes

I decided recently to clean up my Debian "Sid" system, using apt-get autoclean, apt-get purge `deborphan`, aptitude purge ~c, and aptitude purge ~o. It gained me almost two gigabytes of space. On the other hand, it deleted several packages I had long depended on. One of them was xchat.

I installed hexchat, the fully open replacement for xchat. Mostly, it's the same program ... but a few things didn't work right.

Script fixes

The two xchat scripts I use weren't loading. Turns out hexchat wants to find its scripts in .config/hexchat/addons, so I moved them there. But xchat-inputcount.pl still didn't work; it was looking for a widget called "xchat-inputbox". That was fairly easy to patch: I added a line to print the name of each widget it saw, determined the name had changed in the obvious way, and changed

    if( $child->get( "name" ) eq 'xchat-inputbox' ) {
to
    if( $child->get( "name" ) eq 'xchat-inputbox' ||
        $child->get( "name" ) eq 'hexchat-inputbox' ) {
That solved the problem.

Notifying me if someone calls me

The next problem: when someone mentioned my nick in a channel, the channel tab highlighted; but when I switched to the channel, there was no highlight on the actual line of conversation so I could find out who was talking to me. (It was turning the nick of the person addressing me to a specific color, but since every nick is a different color anyway, that doesn't make the line stand out when you're scanning for it.)

The highlighting for message lines is set in a dialog you can configure: Settings→Text events...
Scroll down to Channel Msg Hilight and click on that elaborate code on the right: %C2<%C8%B$1%B%C2>%O$t$2%O
That's the code that controls how the line will be displayed.

Some of these codes are described in Hexchat: Appearance/Theming, and most of the rest are described in the dialog itself. $t is an exception: I'm not sure what it means (maybe I just missed it in the list).

I wanted hexchat to show the nick of whoever called me name in inverse video. (Xchat always made it bold, but sometimes that's subtle; inverse video would be a lot easier to find when scrolling through a busy channel.) %R is reverse video, %B is bold, and %O removes any decorations and sets the text back to normal text, so I set the code to: %R%B<$1>%O $t$2 That seemed to work, though after I exited hexchat and started it up the next morning it had magically changed to %R%B<$1>%O$t$2%O.

Hacking hexchat source to remove hardwired keybindings

But the big problem was the hardwired keybindings. In particular, Ctrl-F -- the longstanding key sequence that moves forward one character -- in hexchat, it brings up a search window. (Xchat had this problem for a little while, many years ago, but they fixed it, or at least made it sensitive to whether the GTK key theme is "Emacs".)

Ctrl-F doesn't appear in the list under Settings→Keyboard shortcuts, so I couldn't fix it that way. I guess they should rename that dialog to Some keyboard shortcuts. Turns out Ctrl-F is compiled in. So the only solution is to rebuild from source.

I decided to use the Debian package source:

apt-get source hexchat

The search for the Ctrl-F binding turned out to be harder than it had been back in the xchat days. I was confident the binding would be in one of the files in src/fe-gtk, but grepping for key, find and search all gave way too many hits. Combining them was the key:

egrep -i 'find|search' *.c | grep -i key

That gave a bunch of spurious hits in fkeys.c -- I had already examined that file and determined that it had to do with the Settings→Keyboard shortcuts dialog, not the compiled-in key bindings. But it also gave some lines from menu.c including the one I needed:

    {N_("Search Text..."), menu_search, GTK_STOCK_FIND, M_MENUSTOCK, 0, 0, 1, GDK_KEY_f},

Inspection of nearby lines showed that the last GDK_KEY_ argument is optional -- there were quite a few lines that didn't have a key binding specified. So all I needed to do was remove that GDK_KEY_f. Here's my patch:

--- src/fe-gtk/menu.c.orig      2016-02-23 12:13:55.910549105 -0700
+++ src/fe-gtk/menu.c   2016-02-23 12:07:21.670540110 -0700
@@ -1829,7 +1829,7 @@
        {N_("Save Text..."), menu_savebuffer, GTK_STOCK_SAVE, M_MENUSTOCK, 0, 0,
 1},
 #define SEARCH_OFFSET (70)
        {N_("Search"), 0, GTK_STOCK_JUSTIFY_LEFT, M_MENUSUB, 0, 0, 1},
-               {N_("Search Text..."), menu_search, GTK_STOCK_FIND, M_MENUSTOCK,
 0, 0, 1, GDK_KEY_f},
+               {N_("Search Text..."), menu_search, GTK_STOCK_FIND, M_MENUSTOCK,
 0, 0, 1},
                {N_("Search Next"   ), menu_search_next, GTK_STOCK_FIND, M_MENUS
TOCK, 0, 0, 1, GDK_KEY_g},
                {N_("Search Previous"   ), menu_search_prev, GTK_STOCK_FIND, M_M
ENUSTOCK, 0, 0, 1, GDK_KEY_G},
                {0, 0, 0, M_END, 0, 0, 0},

After making that change, I rebuilt the hexchat package and installed it:

sudo apt-get build-dep hexchat
sudo apt-get install devscripts
cd hexchat-2.10.2/
debuild -b -uc -us
sudo dpkg -i ../hexchat_2.10.2-1_i386.deb

Update: I later wrote about how to automate this here: Debian: Holding packages you build from source, and rebuilding them easily.

And the hardwired Ctrl-F key binding was gone, and the normal forward-character binding from my GTK key theme took over.

I still have a couple of minor things I'd like to fix, like the too-large font hexchat uses for its channel tabs, but those are minor. At least I'm back to where I was before foolishly deciding to clean up my system.

Tags: , ,
[ 19:00 Feb 24, 2016    More linux | permalink to this entry | comments ]