Lookit 0.3 hits Beta

Just the other day, I pushed out the first beta of version 0.3 of my screenshot utility, Lookit. Just a few minutes ago, I pushed out the second.

Lookit is a tool inspired by TinyGrab for quickly uploading and sharing screenshots. This new version brings a couple of new features that the previous version lacked, in particular, compatibility with older, non-compositing window managers, and a selection rectangle to more clearly see the area of the screen that you’re selecting.

Beta 2 includes just a couple bugfixes over beta 1, which are KDE compatibility (at least the beginnings of it, I still need some testers for this) and properly saving and restoring the save directory, if you choose to not delete images after upload.

A look at Lookit 0.3

Well, maybe “look” isn’t quite the right word, there’s not a lot of GUI to look at. However, I’ve spent a large portion of the day figuring out how to get around two of the more annoying issues in the current version, specifically, non-compositing window manager support and drawing the selection rectangle.

The new solution involves grabbing the mouse directly rather than letting the input be grabbed by an invisible window. That alone improves the application dramatically by allowing it to run without a compositing manager. With some luck, this will help with multimon support as well. Drawing the rectangle requires some lower level code, though, specifically using Xlib instead of GDK.

If there’s anything that you want to see implemented in the next release, make sure it’s mentioned on the Bug Tracker.

Generating Gnome Rotating Backgrounds

The version of Gnome in Ubuntu 10.04 has the ability to automatically change through a defined set of files. Unfortunately, there’s no simple way to do this via the gui (I originally assumed that you just assigned a folder to be your background) so I whipped up a quick Python script. This could probably have been done in bash, but I took the lazy way out. I’m also sure I could have used some existing XML library, but the file is fairly simple, so I just used file.write(). If any glaring errors are pointed out, or if I feel like implementing XML properly, I’m sure I’ll post a revised version sometime soon, but for now, here’s the program:

Here’s a link to the source, in case WordPress fubars Python’s indentation.

#!/usr/bin/python

import os, os.path, sys, optparse

IMG_FILETYPES = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg']

def gen_bg_xml(directory, duration=1795.0, transition=5.0):
    if not os.path.isdir(directory):
        print “Error: {0} is not a valid directory”.format(directory)
        sys.exit(2)

    xmlfile = os.path.join(directory, “background.xml”)
    xml = open(xmlfile, mode=’w')

    xml.write(“<background>\n”)
    xml.write(“  <starttime>\n”)
    xml.write(“    <year>2010</year>\n”)
    xml.write(“    <month>01</month>\n”)
    xml.write(“    <day>01</day>\n”)
    xml.write(“    <hour>00</hour>\n”)
    xml.write(“    <minute>00</minute>\n”)
    xml.write(“    <second>00</second>\n”)
    xml.write(“  </starttime>\n”)

    files = os.listdir(directory)
    l = files[:] # Copy the list so we have something to iterate through
    for f in l:
        name, ext = os.path.splitext(f)
        if not ext in IMG_FILETYPES:
            files.remove(f)
            continue

    for f in files:
        absf = os.path.join(directory, f)
        if not files.index(f) == 0:
            xml.write(“    <to>{0}</to>\n”.format(absf))
            xml.write(“  </transition>\n”)
        xml.write(“  <static>\n”)
        xml.write(“    <duration>{0}</duration>\n”.format(duration))
        xml.write(“    <file>{0}</file>\n”.format(absf))
        xml.write(“  </static>\n”)
        xml.write(“  <transition>\n”)
        xml.write(“    <duration>{0}</duration>\n”.format(transition))
        xml.write(“    <from>{0}</from>\n”.format(absf))
        if files.index(f) == len(files) – 1:
            xml.write(“    <to>{0}</to>\n”.format(
                      os.path.join(directory, files[0])))
            xml.write(“  </transition>\n”)
    xml.write(“</background>”)
    xml.flush()
    xml.close()

if __name__==”__main__”:
    p = optparse.OptionParser(usage=”usage: %prog [options] directory”)
    p.add_option(‘–duration’, ‘-d’, default=”1795.0″)
    p.add_option(‘–transition’, ‘-t’, default=”5.0″)
    options, arguments = p.parse_args()
    if not len(arguments) == 1:
        p.error(“incorrect number of arguments”)
    sys.exit(1)
    gen_bg_xml(arguments[0], options.duration, options.transition)

Whew, escaping all those tabs was annoying.

Fast screenshot sharing in Linux, Part 2

So, thanks to a post on twitter, I’ve found a better way to snag screenshots by using scrot instead of compiz. This doesn’t give the graphical corruption that imagemagick does while compiz is running, and has the added bonus a being able to single-click a window to grab the entire window quickly.

So, here’s my revised source:

#!/bin/bash

user=
server=
destdir=
httpstr=

filename=`scrot -s -b -e ‘echo $f’`

md5=`md5sum $filename`
if [ "$?" -ne 0 ]; then
    notify-send “Error” “Could not generate md5sum” -i error
    exit
fi

md5=${md5/ */}

scp $filename “$user@$server:$destdir${md5}.png”
if [ "$?" -ne 0 ]; then
    notify-send “Error” “Failed upload” -i error
    exit
fi

longurl=$httpstr$md5.png

shorturl=`wget http://is.gd/api.php?longurl=$longurl -O-`
if [ "$?" -ne 0 ]; then
    notify-send “Error” “Failed to shorten URL” -i error
    $shorturl=$longurl
fi

echo $shorturl | xclip -selection clipboard

notify-send “Upload Complete” $shorturl

rm $filename

Save it and bind the script to a hotkey and you should be good to go.

See the original post for the rest of the setup.

Fast screenshot sharing in Linux

When I’m using Windows or OS X, I use a utility called Tinygrab to quickly share screenshots over the internet, whether it’s via Twitter, IM, email, etc. The concept is simple: you press a key combination, select a region of your screen, and it uploads a screenshot of that area and gives you a URL for sharing. Unfortunately, they don’t (currently) support Linux, and so I decided to create my own version.

Since this was the result of an hour or two of bash scripting, it’s somewhat limited in what it can do. I’m planning on expanding it in the near future to support GUI configuration and not rely on Compiz in order to take the screenshot. Since Compiz causes some wackyness when it comes to grabbing screens, I’m using Compiz’s Screenshot plugin, which you can enable in CompizConfigSettingsManager.  By default, the shortcut is to hold Super (aka, the Windows key) and drag your mouse button to select an area to grab. You’ll need to set two options in order for my script to work. First, the directory to save the images to. I used ~/Desktop, since the script deletes the image after it has been uploaded, however you could also use something like /tmp if you like. Second, the command to be run on the screenshot after it has been saved, which is the script you see below. I saved it to ~/bin/upload_image, but again, you can call it whatever you like, just be sure to make the file executable.

The next step is to install the necessary dependencies. Since I’m reply on a few applications, you’ll have to have the following packages installed (this is on Ubuntu 10.04), but again, I’m hoping to change this in the near future: libnotify-bin and xclip.

The script also assumes you have passwordless ssh set up with your server (yes, you do need your own server for the moment, I’m hoping I can change this in future versions) You can easily do this in Ubuntu via the “Password and Encryption Keys” item under Accessories.

Now that all that is in place, it’s time for the script. You’ll notice there are a few values you need to fill in:

#!/bin/bash

user=
server=
destdir=
httpstr=

if [ ! -e $1 ]; then
    notify-send “Error” “File does not exist” -i error
    exit
fi

md5=`md5sum $1`
if [ "$?" -ne 0 ]; then
    notify-send “Error” “Could not generate md5sum” -i error
    exit
fi

md5=${md5/ */}

scp $1 “$user@$server:$destdir${md5}.png”
if [ "$?" -ne 0 ]; then
    notify-send “Error” “Failed upload” -i error
    exit
fi

longurl=$httpstr$md5.png

shorturl=`wget http://is.gd/api.php?longurl=$longurl -O-`
if [ "$?" -ne 0 ]; then
    notify-send “Error” “Failed to shorten URL” -i error
    $shorturl=$longurl
fi

echo $shorturl | xclip -selection clipboard

notify-send “Upload Complete” $shorturl

rm $1

Those values that you need to fill in are:

user: your username on the server

server: the address of the server you’re uploading your images to

destdir: a directory on that server that’s accessible via the web, such as /var/www/screengrabs/

httpstr: the url to that directory, for example: http://www.mysite.com/screengrabs/

Once all that’s set up, try it out. Hold Super and drag your mouse to select an image on your screen. Wait a few seconds and you should either get an “Update Complete” notification, or an error with what went wrong. If the upload was a success, you’ll have a url on your clipboard shortened with is.gd, ready for the pasting.

Enjoy

Update: Bonus: Here’s how you can make use of my script without needing Compiz. I haven’t tested it yet, but it should work. You’ll need Imagemagick installed.

#!/bin/bash

import /tmp/screenshot.png

/path/to/other/script /tmp/screenshot.png

Save that and bind it to a hotkey and you should be good to go.

More Server Consideration

I discovered a positive development for both server options today: First, the Q9400s, a lower power version of the Q9400 which would work better in the SFF case.  Secondly, I learned that I can boot to a software RAID1 setup, which makes the Atom route more appealing, which I’m now leaning towards.  The Atom should have enough power for a basic web and file server, while running cooler and using less power as well.

A Question of Power

By now, Cervantes (my webserver) is starting to get pretty old. While it still performs it’s basic functions decently, I’m wanting to move to a RAID setup to prevent data loss due to a hard drive crash.  While I do have nightly backups of the most important data on Cervantes (my posts) the rest of the data could still be lost at any moment.

I’ve found a couple of nice Mini-ITX cases for server use, both made by a company named Chenbro.  One has two hot-swappable drive bays and a 150W power supply, and the other has four bays with a 180W PSU.  Besides the number of bays, the cases are otherwise very similar. What type of RAID I decide will influence the case selection.

When I first started putting this build together, my plan was to use the Intel Atom board with the 330 dual core processor.  Unfortunately, that board does not support hardware RAID, so I’d have to do RAID in software.  While the Atom should be able to handle that ok, it does mean that I’d need a separate boot disk.  The Atom board only has two SATA ports, so that boot disk would have to be on either IDE or USB, and I have found online some small flash-memory modules that can plug directly into those connectors on the motherboard.

When I ran into the hardware RAID issue on the Atom board, I also began to look at other Mini-ITX boards that DID support hardware RAID.  If I want to stick to an Atom CPU, I can get an ION board, which pairs the Atom CPU with an Nvidia chipset.  While I’d gain hardware RAID, the ION boards are considerably more expensive than the Intel boards, and most of the multimedia features of the board would go to waste.

The second alternative was to use a Mini-ITX Socket LGA 775 board, which are available with either a Q45 or G45 chipset.  The board feature four SATA ports as well as hardware RAID support on the motherboard.  I’d also be able to use a much more powerful CPU, though it brings up the question of whether the smaller power supplies in these cases would support them (In fact, a quick calculation confirms that the system would pull around 160W, just over the power provided by the smaller case, and a little close for confort on the larger).  I’d like to have a Core 2 Quad processor, as I do sometimes SSH into my server for development purposes.  The power issue could be remedied by replacing the included PSU with a larger one.  The two bay case uses a FLEX ATX power supply, and a quick Google turns up a 270W for sale, which would provide plenty of power.

Overall, I’m leaning towards the higher end build, due to both the hardware RAID and the better CPU for development, as well as the possibility of running virtual machines on top of it.

Wacom Bamboo in Ubuntu 9.04

Today I got my Wacom Bamboo USB Tablet in from Newegg.  Installation in Jaunty was incredibly easy, I just plugged it in and the Wacom drivers were already installed and ready to go.  The corners of the tablet automatically mapped to the corners of the screen, which in some previous Ubuntu releases required a bit of editing to Xorg.conf.

I’ve really only messed with two apps so far, Gimp and Evernote.  Gimp is, of course, preinstalled in Ubuntu and allows pen input just fine, although it doesn’t automatically map the eraser to the Erase tool.

Evernote doesn’t have a native Linux version, but it runs quite well in Wine.  The only issue I’ve come across so far is that I cannot drag and drop files from Nautilus into a notebook.  My plan is to use this to handwrite notes for school, and I’ve already been typing my notes into Evernote for the last few days.  Evernote is nice because it automatically keeps your notes synced between multiple installations (for me, that’s Evernote/Wine Evernote/VistaVM and Evernote/W7) and also has a web interface for when I’m not at one of my computers.  This syncing allows me to drag files to Evernote either by opening a VM or remoting to my desktop and then they will automatically be synced back to the copy of Evernote I’m running in Wine.

Ubuntu Netbook Remix

There’s been a fair amount of news online about Canonical’s specialized version of Ubuntu for Atom based laptops, but the current word on it is that Canonical will only be licensing it directly to OEMs.  However, there is a PPA that you can use to turn an Ubuntu Hardy install into UNR.

Just add the repository and install the applications that it contains, then log out and in and set up your new desktop.

I have mine configured as close as I can to what the default layout seems to be from the screenshots I’ve seen online.

UNR makes good use of available screen real estate (my screenshots are running at 800×600) by putting each application in a “Tab.”  I installed a couple of extra apps, Deluge 1.0rc2 and Banshee 1.0, and sure enough, they automatically conformed to the layout.

UNR places it’s launchers and menus on the desktop, which is quickly accessible from the “Go Home” button in the upper-left corner (it looks like an Ubuntu logo).

I’m not crazy about the look and feel.  The desktop has a nice, new, polished look to it while the applications themselves use the standard Human theme.  Either are nice on their own, but they seem to clash when used together.  The interface was also a little slow, but that may be due to running it inside a virtual machine, as I’ve heard that the interface makes some use of OpenGL.

Overall, it’s a nice product and most tasks are accomplished easily.  This will make a great OS for the Eee PC or any other subnotebook.

Easy SSH Tunneling

Whenever I work out of the San Francisco office, I have to tunnel back to my workstation in Palo Alto in order to do any development.  The way I do this is with an SSH Tunnel.  While I used to just fire it up manually, the other day I hacked up some shell scripts to automatically connect and start up my most used apps on the remote machine, and I thought I’d share them here.

First, on the local machine:

/usr/local/bin/tunnel:

#!/bin/sh
$IPADDR=0.0.0.0 # IP Address of the remote machine
$LOGON=usrname # Your username on the remote machine
$STARTUP=/usr/local/bin/startup
ssh -X $IPADDR -l $LOGON $STARTUP

and, on the remote machine:

/usr/local/bin/startup:

#!/bin/sh
gnome-terminal &
nautilus &
firefox &
pidgin &
xchat &

Essentially, a list of programs to start up. Don’t forget the & on each line, or else they won’t all start at the same time.

Make sure that both files are executable (chmod +x), then you can add a launcher to /usr/local/bin/tunnel and you’re good to go.

It’s a pretty simple trick, but it saves me several seconds each time I connect to the network.  Also, as there’s no terminal needed to keep the ssh session open, I don’t accidentally lose my session.