Experimenting with Glista on OS X

I haven’t blogged in a while, probably because I was too busy. I’ve been working, started to take some university classes (Philosophy & Computer Science), and… I’m doing most of my work on Mac OS X now. Don’t worry, I’m still a Linux guy - but mostly for work purposes (and out of curiosity) I decided to ask Zend for a Macbook when my Thinkpad was starting to die.

Unfortunately the negative side effect of this is that I had to put Glista on hold - since I didn’t have a Gtk+ based desktop anymore there wasn’t much point in actively working on it.

However, in the last couple of days (following some patches that came in from ananasik, for whom I immediately gave commit access) my fingers started itching, and I decided to play with porting Glista to OS X - and found this project.

After some hours of tinkering, crashing, building, rebuilding and breaking things again, I now have a somewhat working (albeit ugly, and not so OS X friendly) working Glista.app Application bundle running on my own 32 bit OS X 10.6:

Glista running on native OS X for the first time!

Glista running on native OS X for the first time!


Glista in the Dock!

Glista in the Dock!

If you’re really up for it, you can get a Disk Image here.

You can also build it from source by checking out http://glista.googlecode.com/svn/branches/osx-support and doing the following:

  1. Make sure you have all the nescesary build environment (XCode is usually a good start!)
  2. Install all the gtk-osx tools and libraries including ige-mac-builder and gtk-quartz
  3. cd into the source directory and run (in a jhbuild shell after installing osx-gtk) ./configure –prefix=$PREFIX
  4. Note that some things do not work on OS X yet (or will never work) like libunique integration, gtk-spell, libnotify integration etc. - that’s normal for now
  5. Run ‘make’, don’t (!!) run ‘make install’ (well you can, but there’s no need, you’ll just pollute your system
  6. cd into dist/mac/ and run ‘make dist-mac’. If everything is ok this should create Glista.app in that directory.
  7. Move that .app into /Applications (or anywhere else) and enjoy!

So far, it looks like it’s going to be a long time before Glista will work smoothly on Mac - and most of it is because Gtk+ is not really that portable, and making it use OS-native widgets and rendering seems to be quite a challenge. I also don’t feel I know enough about the internals of Gtk+, Quartz or OS X in general in order to help with that effort - but who knows, maybe I’ll be able to help somehow?

BTW I’m not sure if that binary will work on anything but OS X 10.6 on Intel 32 bit. If you try, let me know!

NetworkManager: Auto-HTTP login to a Wifi network

One of the cafés in my area where I frequently drink / work requires you to pass through an annoying web page forcing you to agree to some terms before allowing you to access the Internet through their Wifi network. It's free - but they still annoy you with this silly HTTP gateway. This is actually a frequent thing in Israel - most cafés offer free Wifi access, but some will require to to log-in nevertheless.

So today I figured out how to get NetworkManager to automatically work around this HTTP gateway for me whenever I connect to Arcaffe's Wifi network. Since it's super cool, and since I bet lots of people are annoyed by these sort of Wifi gateways, here's how to do it:

Apparently, NetworkManager allows you to create special post-connect or post-disconnect scripts that are executed when a network interface is brought up or down. Here is what I did:

I Created the following script and saved it at /etc/NetworkManager/dispatcher.d/100httpgateway.sh:

CODE:
  1. #!/bin/sh
  2.  
  3. IFACE="eth1"
  4.  
  5. if [ "x$1" = "x$IFACE" ] && [ "$2" = "up" ]; then
  6.     # Figure out the wifi SSID
  7.     SSID=$(/sbin/iwconfig $IFACE  | grep ESSID | cut -d: -f2 | sed 's/^\s*"\(.*\)"\s*$/\1/')
  8.  
  9.     case "$SSID" in
  10.         "012-ArCaffe")
  11.            URL='http://captive.012.net.il/user/refresh/home?confirmed=true&submitButton=+OK+&CPURL=http%3A%2F%2Fwww.arcaffe.co.il%2F&t=fsm3j5oe'
  12.            DATA='x=9&y=5&agree=on&username=arcaffe&password=arcaffe012'
  13.            COOKIE='Cookie: JSESSIONID=uc54121j305s; cookies=true'
  14.            REFERER='Referer: http://captive.012.net.il/home?confirmed=true&submitButton=+OK+&CPURL=http%3A%2F%2Fwww.arcaffe.co.il%2F&t=fsm3j5oe'
  15.  
  16.            curl -d "$DATA" -H "$COOKIE" -H "$REFERER" "$URL"> /tmp/arcaffe.last 2> /tmp/arcaffe.last.err
  17.         ;;
  18.     esac
  19. fi

Don't forget to make the file executable - I did it by running chmox +x /etc/NetworkManager/dispatcher.d/100httpgateway.sh.

Some things you should note:

  • "012-ArCaffe" is the ESSID of the network I'm logging in to. This of course work for ArCaffe in Israel, but you should change that with your network's ESSID.
  • Replace the value of IFACE with the name of your wireless interface
  • $1, the first parametter passed by NetworkManager to the script, is the network interface that was just connected or disconnected
  • $2, the second parameter, is "up" or "down" - the status of the interface.
  • The code I have inside the case block is where the magic happens. In this case, I send an HTTP POST with the correct parameters, Cookie and Referer headers and URL. This causes ArCaffe's gateway to log me in
  • I use curl - but I could have also used wget or any other tool to do the job
  • The -d flag sends the POST data, the -H flags set a header
  • I figured exactly what request to send using LiveHttpHeaders - but you can also use tcpflow or any other packet sniffing or HTTP sniffing tool
  • You can add more options to the 'case' statement for more networks that need that sort of treatment. With a little of bash-fu that should be no problem.

That's it! Man I love Linux today :D

Notify me when emerge is done

As a Gentoo user, I frequently install new software or update existing packages using emerge. Unlike binary package managers, building packages from source using emerge takes time, and I prefer running it inside a detached screen session, because (a) if I close the session it continues in the background and (b) it actually runs faster when it doesn't need to show all the compilation output in an X terminal.

This has an annoying side effect: I sometimes start a long update process and forget I did it. If things fail (or even if they succeed) I don't know about it.

Today, I solved this problem using notify-send, the libnotify binary client. I've created a short shell script wrapper to emerge which sends me a notification once emerge finishes, along with the original command line arguments and exit status code (0 = ok, failure otherwise):

CODE:
  1. #!/bin/sh
  2.  
  3. ARGS=$@
  4.  
  5. /usr/bin/emerge "$ARGS"
  6. STATUS=$?
  7. if [ "$STATUS" = "0" ]
  8. then
  9.         LEVEL="normal"
  10. else
  11.         LEVEL="critical"
  12. fi
  13.  
  14. /usr/bin/notify-send --expire-time=0 --urgency=$LEVEL "emerge finished" "Exit Code: $STATUS
  15. Emerge args: $ARGS"

If you save this code in a file named emerge-notify (and of course remember to chmod +x this file) you could then do this (from a GNOME terminal or any other X terminal):

CODE:
  1. $ ./emerge-notify -puD world

And you'll get a nice notification when it's done:

"emerge finished" notification

Of course, you need libnotify the notify-send binary and dbus for this.

Glista 0.3 Released

Thanks to the very good holiday layout this year*, I finally got to release the next preview release of Glista - my super simple Gtk+ based to-do list manager for your desktop.

The major improvement in this release is category support. For a while, I didn't want to add any features that will make the UI more complex than it is. Then I noticed that I tend to add ad-hoc categories to my tasks in order to sort them - that is instead of typing "Fix ZF bug #1234" I type "ZF: Fix bug #1234". This is a very natural way to organize your tasks for me, and I assume that it is for most people. So I decided to add category support by recognizing this colon-separated syntax and breaking any item typed in this way into a "cateogry: item" structure.
[more...]