Posts Tagged ‘rants’

(on Technorati , Del.icio.us)

File List Applet – now with more autotools!

I decided that before I did any more work on the applet, I would improve its installation process to make it easier for people to try it out. So, the process to get and build the source now looks like this:

Download

  • Browse source here.
  • Download the source: bzr branch http://stevenbrown.ca/src/FileListApplet

Install

  1. Install dependencies (Ubuntu package names given): sudo apt-get install python-xdg python-gnome2-desktop python-gtk2 python-pyinotify
  2. Branch the source using the bzr command, above.
  3. cd into the directory.
  4. ./configure --prefix=/usr (the prefix is important!)
  5. make
  6. sudo make install
  7. If the applet does not show up in your Add to Panel menu, try restarting the bonobo-activation-server: killall bonobo-activation-server.

Autotools

Autotools is pretty much the standard in source package management on linux. Except for the name, there is nothing automatic about autotools. Every encounter I’ve had with autotools has usually defeated me and left me frustrated and leaving whatever I was working on to do something else. For me, because I had labeled it the next step, it basically stalled the entire project for a while. Most people tend to copy and paste other projects’ autotools setup, but I figured that was overkill for my purposes and I didn’t find anything that quite suited me. I looked at gnome-blog, but it seemed like some stuff wasn’t quite working properly and some was completely unnecessary… in fact, this seemed to be a trend when looking at the autotools stuff in projects. Why is this? Autotools is not simple and due to this simple fact, I think it fails completely on many levels. Developers massage it enough to get it working, but few actually understand it all – I know I sure don’t! So please forgive the sloppiness and feel free to send patches. ๐Ÿ™‚ I gave up doing a couple things, like getting the revision number (bzr revno) and including it in the version string (see configure.ac). I know it’s probably something super simple, but I couldn’t seem to pass a variable containing a string as the version….

I feel that GNOME, as a platform for development, could seriously benefit from some kind of frontend to autotools that handled GNOME development nicely and hid as much as possible from the developer (including all those nasty config files that pollute the package tree). Anyway, I did not have an enjoyable time grappling with autotools, but I’ll end this mini-rant here.

open-with for the command-line

Update 2008/11/18: Use xargs ๐Ÿ˜›

Here’s a bash script that you can pipe output into and tell it to run a specific program with the output as arguments. I’ve named it open-with and placed it in my personal script directory: /home/steve/bin/. Look within the script at a couple of the examples for how to use it.

#!/bin/bash
 
PROG=`basename $0`
 
DESC="Read arguments from standard input and run a specified program
with them.  Meant to be used as output for a pipe."
 
 
USAGE="OUTPUT | $PROG \"PROGRAM-NAME [OPTIONS AND ARGUMENTS]\""
 
EXAMPLES="
# List (with details), all the files that include \"downloads\" in their name:
  find /home/ -iname \"*downloads*\" | $PROG \"ls -l\"
 
# Queue all AVI files in current directory in vlc:
  ls *.avi | $PROG vlc
 
# View all time-related icons with eye-of-gnome:
  find /usr/share/icons/gnome/ -iregex \".*[^mul]time.*\" | open-with eog
"
 
function Usage() {
  echo "DESCRIPTION: $DESC" ; echo
  echo "USAGE: $USAGE" ; echo
  echo -n "EXAMPLES: $EXAMPLES"
}
 
# Quick check to see it's being called correctly, if not, print Usage and exit
if [ ${#@} -ne 1 ]
then
	Usage
	exit
fi
 
files=()						# empty array
while read -r					# read from stdin
do
	files+=( "$REPLY" )			# add result of read to array
done
 
# assume $1 is a valid program
$1 "${files[@]}"				# pass arguments to specified program

Motivation

You’re sitting at the command line and have a list of images (in different locations) that you would like to browse. Most image viewers let you iterate over a set of images, but only within the same directory. What would be great is if they accepted input from stdin through a pipe!

$ cat my_list_of_images | my_image_viewer

I didn’t find anything that did that, but using the open-with script, you can do something similar:

$ cat my_list_of_images | open-with my_image_viewer


Browsing a select list of images is actually kind of nice. It’s like a playlist for your image viewer – a viewlist. ๐Ÿ™‚ Anyway, I’m sure there’s some problems with this script. Feel free to provide suggestions in the comments. But I certainly don’t want to look at it for a while….

I hate shell scripting

With a passion. It’s not a great surprise… many programmers do. I’m willing to go on record and state that I hate it even more than PERL programming. I rarely do it, and when I decide to try something that seems like it would be simple, it turns out taking forever due mostly to quirks. The rest of this post is a bit about how I went about writing this script, which ended up being mostly given to me by some #bash gurus on IRC. And it’s a bit of a rant.

Although not many GUI programs seem to accept stdin as input, most accept filenames as arguments:

$ eog image1.jpg image2.jpg image3.jpg "/home/steve/image seven.jpg"

So I figured I would just have to convert the list of images into an acceptable format: quoted, absolute filenames, separated by space. Doing this depends entirely on the format the list is currently in, but it’s likely a list of unquoted filenames separated by newlines:

/home/steve/image1.jpg
/home/steve/my images/wow.jpg
/tmp/anotherimage.png

For me, my test list looked like this:

/usr/share/icons/gnome/48x48/stock/generic/stock_timezone.png
/usr/share/icons/gnome/16x16/stock/generic/stock_timezone.png
/usr/share/icons/gnome/16x16/stock/generic/stock_timer.png
/usr/share/icons/gnome/16x16/stock/generic/stock_timer_stopped.png
/usr/share/icons/gnome/16x16/stock/form/stock_form-time-field.png
/usr/share/icons/gnome/24x24/stock/generic/stock_timezone.png
/usr/share/icons/gnome/24x24/stock/generic/stock_timer.png
/usr/share/icons/gnome/24x24/stock/generic/stock_timer_stopped.png
/usr/share/icons/gnome/24x24/stock/form/stock_form-time-field.png

I was looking for icons of clocks or representations of time, and I obtained that list using find:

$ find /usr/share/icons/gnome/ -iregex ".*[^mul]time.*"

So I can’t pipe it into my image viewer, but I can use the output as the command-line arguments if I change the newlines to spaces. find has an option for formatting the output which is perfect:

$ find /usr/share/icons/gnome/ -iregex ".*[^mul]time.*" -printf "'%p' "
'/usr/share/icons/gnome/48x48/stock/generic/stock_timezone.png' '/usr/share/icons/gnome/16x16/stock/generic/stock_timezone.png' '/usr/share/icons/gnome/16x16/stock/generic/stock_timer.png' '/usr/share/icons/gnome/16x16/stock/generic/stock_timer_stopped.png' '/usr/share/icons/gnome/16x16/stock/form/stock_form-time-field.png' '/usr/share/icons/gnome/24x24/stock/generic/stock_timezone.png' '/usr/share/icons/gnome/24x24/stock/generic/stock_timer.png' '/usr/share/icons/gnome/24x24/stock/generic/stock_timer_stopped.png' '/usr/share/icons/gnome/24x24/stock/form/stock_form-time-field.png'

That’s great for me, because I’m using find. But not very useful if I’m not, so I wanted something more generic. Of course, there are many ways to do this, and again, I’m by no means a command-line guru. But here’s how I started:

$ find /usr/share/icons/gnome/ -iregex ".*[^mul]time.*" | sed -e 's/^/"/' | sed -e :a -e '$!N;s/\n/" /; ta' | tr '\n' '"'

This wrapped the lines in double-quotes and join them together with a space in between. The find command is the same as before, minus the formatting because that’s what I was trying to find an alternative to. The output of find is piped into sed, which adds a " at the beginning of each line. This output is then sent to another sed which replaces the newline character at the end of each line with a closing double-quote and a space, joining all lines into a single line. Finally, that output is piped into tr which replaces the one remaining newline with a final double-quote.

If the files don’t include spaces or other troublesome characters (mine didn’t), then you could get away with simply changing the newlines into spaces. But again, I wanted something generic.

$ find /usr/share/icons/gnome/ -iregex ".*[^mul]time.*" | tr '\n' ' '

Anyway, now that we have something that creates the desired input, we just have to wrap it in back-ticks and put the whole mess as the argument to the image viewer! In my case, I’m using eye-of-gnome (or eog).

$ eog `find /usr/share/icons/gnome/ -iregex ".*[^mul]time.*" | sed -e 's/^/"/' | sed -e :a -e '$!N;s/\n/" /; ta' | tr '\n' '"'`

Wait a second. That doesn’t actually work. Why not? Running the backtick contents by itself seemed to produce the correct output. Copying this output verbatim as arguments to eog worked as expected. The problem was that when the quoted arguments were manually entered on the command-line, bash (silently) escapes the filenames, removing the quotes, adding backslashes before space,s etc. But when the pipeline is wrapped in backticks, the result is not escaped, and eog complains about not being able to find files that begin with quotes. Fine. I was not about to write a bash “escape” script – something like that should already exist, right? And it should be built in to bash! Perhaps it’s even called “escape“. Well, if there exists such a built-in, I couldn’t find it. But I had to be going about this the wrong way. Heading over to IRC, it was kind of difficult to explain the problem, but ferret eventually gave me the meat of the script above:

files=(); while read -r; do files+=( "$REPLY" ); done < <(find /usr/share/icons/gnome/ -iregex ".*[^mul]time.*"); eog "${files[@]}"

It worked! I thanked him and began studying it. There were still a couple things I didn’t understand:

  • Why two angle brackets with a space between them? I understand the first one is probably redirecting input, but I don’t understand that one next to the opening parenthesis.
    Answer: The <(command) actually puts command‘s output in a temporary file and produces that filename. So <(command) becomes tempfile. (Thanks, kojiro.)
  • If I open some video or audio files in totem using open-with, there’s an odd delay. Using vlc doesn’t produce a delay, however.

And to think this was originally going to be a micro-blog post in Twitter and identi.ca. Wow. It’s safe to say I still hate shell scripting. ๐Ÿ™‚

Huge Piece of Crap

At my current job, my computer is a laptop which sits in a docking station is connected to an external monitor, keyboard, and mouse. If I wanted, I could take the laptop home with me. That would be great, but I have no desire to use this PC outside of work for a few reasons:

  1. It runs Windows.
  2. The image of Windows has been specially set up to be incredibly handicapped. An example of this I find most annoying: disabling the location bar in Explorer. WTF. It doesn’t even give a correct message… it gives a misleading and completely incorrect message! If I click the location bar in Windows Explorer and type in M: and push Enter, I get a dialog saying Access to the resource M: has being disabled. Huh? That’s total BS. I can click my way there…. I can’t even select history items, places I’ve clearly been to. This is the laziest blanket administration technique I’ve ever seen.
  3. I do not even have basic administrator privileges. To install something (anything) I would have to submit a request to the IT support department and wait for them to come over from a different building to click a couple buttons. I have doubts it could be done remotely… or with any haste.

Granted, my position has nothing to do with programming, and some users probably should be protected from themselves… but seriously, Thank you, IT department, for making my modern laptop nearly useless and actually getting in the way of me getting work done. Also, Lotus Notes is a terrible terrible experience, but Windows + Lotus Notes seems to be the standard virus infecting most large organizations.

I particularly enjoyed this bit from the latest LugRadio (they’ve changed their licence):

LR: “… having re-implemented it [the Windows API], you’ve got an idea of how the thing kind of works internally maybe, do you think Microsoft did a good job designing Windows?”
Wine Guy: “Oh no. Definitely not.”
*laughs*
Alexandre Juillard: No no, it’s a huge piece of crap and we find more crap every day.
*more laughs*
LR: Congratulations on having spent 15 years reimplementing it!
AJ: (laughing) That’s the beauty of it! We try to make something nice out of a piece of crap. That’s all the challenge.

Huge Piece of Crap - 30 sec audio clip of above conversation

(Audio clips are in OGG Vorbis format. I tried using Jokosher for audio editing – looks promising, but still young and lots of bugs.)

Phone Spam

Within the last 20 minutes, I have received two different phone calls with recordings saying I’ve won an all-inclusive vacation, and I just had to push a number on the keypad to accept it. Is it just a matter of time before an automatic filter can be applied to incoming calls? People shouldn’t be able to make unsolicited calls and email; it’s just wrong.