Rick Spencer: More Quidgets … No More TreeViews

TreeViews (Not Easy and Fun)
If you have data that you want to display in a grid format in PyGtk is code intensive and inflexible. In Cognitive Dimensions speak we would say that the Work Step Units are too small, and the resulting code has high viscosity. It’s also quite hard to learn.

In order to take a dictionary of data and display it to a user in a grid in PyGtk, you use a combination of three object:

  • TreeView
  • ListModel
  • TreeViewColumn

Here’s some real code that I wrote while back for using the FogBugz XML API:

def __init__(self,session,data):
gtk.VBox.__init__( self, False, 3 )
child = gtk.ScrolledWindow()
#start time, end time, duration, case, title, category
store = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING, gobject.TYPE_INT,gobject.TYPE_STRING,gobject.TYPE_STRING)

total_time = None
for interval in data:
b = pyFogbugz.getbugs(session, [interval["case"]])[0]
store.append([interval["start"],interval["end"],interval["duration"],interval["case"],b["title"],b["category"]])
#see if this is the earliest date

#accumulate total time
if total_time == None:
total_time = interval["duration"]
else:
total_time += interval["duration"]

view = gtk.TreeView(store)

stcol = gtk.TreeViewColumn("Start", gtk.CellRendererText(), text=0)
stcol.set_sort_column_id(0)
view.append_column(stcol)

endcol = gtk.TreeViewColumn("End", gtk.CellRendererText(), text=1)
endcol.set_sort_column_id(1)
view.append_column(endcol)

durcol = gtk.TreeViewColumn("Duration", gtk.CellRendererText(), text=2)
durcol.set_sort_column_id(2)
view.append_column(durcol)

casecol = gtk.TreeViewColumn("Case", gtk.CellRendererText(), text=3)
casecol.set_sort_column_id(3)
view.append_column(casecol)

titlecol = gtk.TreeViewColumn("Case Title", gtk.CellRendererText(), text=4)
titlecol.set_sort_column_id(4)
titlecol.set_resizable(True)
view.append_column(titlecol)

catcol = gtk.TreeViewColumn("Case Category", gtk.CellRendererText(), text=5)
catcol.set_sort_column_id(5)
catcol.set_resizable(True)
view.append_column(catcol)

view.show()

Then in order to do anything with the TreeView, you need to manipulate:

  • The ListModel
  • Iters
  • Paths

So to remove all the selected rows, you do something like this:

#get the selected rows, and return if nothing is selected
model, rows = self.get_selection().get_selected_rows()
if len(rows) == 0:
return

#store the last selected row to reselect after removal
next_to_select = rows[-1][0] + 1 - len(rows)

#loop through and remove
iters = [model.get_iter(path) for path in rows]
for i in iters:
self.get_model().remove(i)

#select a row for the user, nicer that way
rows_remaining = len(self.get_model())

#don't try to select anything if there are no rows left
if rows_remaining < 1:
return

#select the next row down, unless it's out of range
#in which case just select the last row
if next_to_select < rows_remaining:
self.get_selection().select_path(next_to_select)
else:
self.get_selection().select_path(rows_remaining - 1)

Enter DictionaryGrid (Easy and Fun)
Last week I found that the TreeView code that I wrote for bughugger was not flexible enough to incorporate some new features. In Karmic I wrote a TreeView wrapper for Desktop Couch called CouchGrid, so I had recent experience in how I could do this better, and I determined that this would be the last time that I write this code. Thus, the quidget DictionaryGrid was born. To use it, simply hand the DictionaryGrid a list of dictionaries to display and it will do the work for you.

Here is what the test code for DictionaryGrid looks like:

    dicts = [{"ID": 0, "key2": 5, "tags": "aaa bbb ccc","_foo":"bar"},
{"ID": 1, "key2": 6, "tags": "bbb ccc ddd","_foo":"bar"},
{"ID": 2, "key2": 7, "tags": "ccc ddd eee","_foo":"bar"},
{"ID": 3, "key2": 8, "tags": "ddd eee fff","_foo":"bar"},
{"ID": 4, "key2": 9, "tags": "eee fff ggg","_foo":"bar"}]

grid = DictionaryGrid(dicts)
grid.show()

This produces this:

Seems to make more sense right? That is Easy and Fun! You just bind the TreeView to the dictionary. There are a couple of things to make DictionaryGrid a bit more flexible:

  1. If you use keys that start with underscores, they are hidden by default, thus the key “_foo” is not displayed
  2. You can determine which keys to display and in what order by passing in a list of keys, so this:
    dicts = [{"ID": 0, "key2": 5, "tags": "aaa bbb ccc","_foo":"bar"},
{"ID": 1, "key2": 6, "tags": "bbb ccc ddd","_foo":"bar"},
{"ID": 2, "key2": 7, "tags": "ccc ddd eee","_foo":"bar"},
{"ID": 3, "key2": 8, "tags": "ddd eee fff","_foo":"bar"},
{"ID": 4, "key2": 9, "tags": "eee fff ggg","_foo":"bar"}]

keys = ["ID","tags"]
grid = DictionaryGrid(dicts, keys)

grid.show()

produces this:

You can use underscores and or the keys property to store data along with the dictionary that you don’t want to display, and then retrieve the complete dictionary for the selected rows. If you’ve set the DictionaryGrid to be editable, the user can only edit the columns that are displayed, but all of the data that you passed along in the dictionaries is persisted. This is useful if you are persisting the data in a database or similar, and need to track something like the row id but don’t want to expose it to the user. The code simply looks like this:

for row in self.grid.selected_rows:
url = "http://bugs.launchpad.net/bugs/" + row["_id"]
webbrowser.open(url)

Finally, DictionaryGrid is just a subclass of gtk.TreeView, so you don’t have to sacrifice any of the power and flexibility of TreeView.

GridFilter
One of the coolest things about TreeViews is that they support lightening fast filtering. But building filters for them is onerous. In fact, so onerous, I don’t even want to discuss it in this posting, if you are interested, you can peruse the documentation.

However, I have created a Quidget that makes it very easy to create a filter. To cut to the chase, this code:

    dicts = [{"ID": 0, "key2": 5, "tags": "aaa bbb ccc"},
{"ID": 1, "key2": 6, "tags": "bbb ccc ddd"},
{"ID": 2, "key2": 7, "tags": "ccc ddd eee"},
{"ID": 3, "key2": 8, "tags": "ddd eee fff"},
{"ID": 4, "key2": 9, "tags": "eee fff ggg"}]
grid = DictionaryGrid(dicts)
grid.show()

filt = GridFilter(grid)
filt.show()

produces something the user can use the filters like this:

Note that:
1. There are built in filters for strings, numbers, and tags
2. a column with a key of “Id” (case insensitive) will default to using a number filter, a column with a key of “tags” (case insentitive) will default to using a tag filter, other columns will default to a string filter
3. You can create custom filters, but I don’t have a base class yet to make this easy, but the code is simple if you look at GridFilter.py. In fact, the tags filter was originally written by Loic Miner.

You can override the default filter by passing in a filter hint, like this:

    dicts = [{"ID": 0, "key2": 5, "tags": "aaa bbb ccc"},
{"ID": 1, "key2": 6, "tags": "bbb ccc ddd"},
{"ID": 2, "key2": 7, "tags": "ccc ddd eee"},
{"ID": 3, "key2": 8, "tags": "ddd eee fff"},
{"ID": 4, "key2": 9, "tags": "eee fff ggg"}]
hints = {"key2":NumericFilterCombo()}
grid = DictionaryGrid(dicts)
grid.show()

filt = GridFilter(grid,hints)
filt.show()

Which makes the key2 column use a number filter:

I’ve already started to pull these Quidgets into a branch of bughugger. I hope that other developers find them useful, and easy and fun.

Johnathon Mlady: sqlite, sqlite3, and CPAN equivalents in Ubuntu and Fedora

So I ran into an issue today, while working trying to port a program from Ubuntu to Fedora, involving Sqlite and Sqlite3 and CPAN.

sqlite (2.8)

Ubuntu:    sudo apt-get install sqlite
Fedora:    su -c 'yum install sqlite2'

sqlite3 (3.0+)

Ubuntu:    sudo apt-get install sqlite3
Fedora:    su -c 'yum install sqlite'

CPAN

Ubuntu:    Installed by default
Fedora:    su -c 'yum install perl-CPAN'

Ubuntu QA blog: Announcing the Next Ubuntu Hug Day! – Thursday 10 December 2009

Announcing the Next Ubuntu Bug Day! – Thursday 10 December 2009

Fellow Ubuntu Triagers!

This week’s Bug Day target is *drum roll please* Compiz!

* 120 New bugs need a hug
* 112 Incomplete bugs need a status check
* 61 Confirmed bugs need a review
* 2 bugs that need forward to upstream

Bookmark it, add it to your calendars, turn over those egg-timers!
* Thursday 10 December 2009
* https://wiki.ubuntu.com/UbuntuBugDay/20091210

Are you looking for a way to start giving some love back to your
adorable Ubuntu Project?
Did you ever wonder what Triage is? Want to learn about that?
This is a perfect time!, Everybody can help in a Bug Day!

open your IRC Client and go to #ubuntu-bugs (FreeNode)
the BugSquad will be happy to help you to start contributing!

Wanna be famous? Is easy! remember to use 5-A-day so if you do a good
work your name could be listed at the top 5-A-Day Contributors in the
Ubuntu Hall of Fame page!

We are always looking for new tasks or ideas for the Bug Days, if you have one
add it to the Planning page https://wiki.ubuntu.com/UbuntuBugDay/Planning

If you’re new to all this and you want to know more about
ubuntu?, head to
http://wiki.ubuntu.com/Bugs

Ubuntu Podcast from the UK LoCo: S02E19 – The Final Test

Ciemon Dunville, Alan Pope, Dave Walker and Tony Whitmore bring you a the penultimate episode of season two of the Ubuntu Podcast from the UK LoCo Team.

Subscribe:-

Hi-Fi Lo-Fi
Ogg Subscribe to the High Quality Ogg feed. Subscribe to the Low Quality Ogg feed.
Mp3 Subscribe to the High Quality MP3 feed. Subscribe to the High Quality MP3 feed via iTunes. Subscribe to the Low Quality MP3 feed. Subscribe to the Low Quality MP3 feed via iTunes.

In this week’s show:-

  • The Ecosphere Bit about Ubuntu has discussion of..
  • And finally we cover your emails, tweets and dents and voicemail since our last show
  • Comments and suggestions are welcomed to: podcast@ubuntu-uk.org
    Join us on IRC in #ubuntu-uk-podcast on Freenode
    Leave a voicemail via phone: +44 (0) 845 508 1986, sip: podcast@sip.ubuntu-uk.org and skype: ubuntuukpodcast
    Follow our twitter feed http://twitter.com/uupc
    Follow us on Identi.ca http://identi.ca/uupc
    Find our Facebook Fan Page
    Discuss this episode in the Forums

    Ciemon Dunville, Alan Pope, Dave Walker and Tony Whitmore bring you a the penultimate episode of season two of the Ubuntu Podcast from the UK LoCo Team.

    Subscribe:-

    Hi-Fi
    Lo-Fi

    Ogg

    Mp3

    In this week’s show:-

    What we’ve been doing this week including going to UDS, packaging Shellinabox and Inkscape 0.47, installing Android 2.1 on an HTC Hero, mapping minds with VYM and diffing files with meld, tweeting from the dentist and writing esays using OpenOffice.org.
    We get another chance to chat with Ubuntu Running Man Dustin Kirkland this time about his latest project, TestDrive
    In the News this week:-

    New VirtualBox supports live migrations
    Google announces Public-DNS
    Nokia reduces 2010 Linux smartphone plans
    The Open Learning Centre get vTiger CRM Partner status

    We announce some upcoming events:-

    OSSWatch are holding two workshops on Monday 7th December in Oxford, one on Open Source, Open Development, Open Innovation, the other on Building an Engaged Community.
    Camp KDE 2010 University of California, San Diego from January 15th-22nd, 2010
    FOSDEM – 6th – 7th February 2010 – University Libre Brussels

    Command line love

    $ w

    $ last

    We interview the well travelled and most relaxed Ubuntu forum moderator Matthew Helmke about his travels, writing books and the Ubuntu forums
    The Ecosphere Bit about Ubuntu has discussion of..

    Compulab Annouces FitPC2
    Toms Hardware give the Koala a kicking
    Chrome OS build for many netbooks

    And finally we cover your emails, tweets and dents and voicemail since our last show

    Comments and suggestions are welcomed to: podcast@ubuntu-uk.org
    Join us on IRC in #ubuntu-uk-podcast on Freenode
    Leave a voicemail via phone: +44 (0) 845 508 1986, sip: podcast@sip.ubuntu-uk.org and skype: ubuntuukpodcast
    Follow our twitter feed http://twitter.com/uupc
    Follow us on Identi.ca http://identi.ca/uupc
    Find our Facebook Fan Page
    Discuss this episode in the Forums

    Ubuntu Server blog: Server Team 20091209 meeting minutes

    Here are the minutes of the meeting. They can also be found online
    with the irc logs here.

    Scribe assignment

    In an effort to share the burden, the responsibility and the community visibility, the meeting minutes scribe role will rotate alphabetically every week between the server team engineers. ttx will write up the current minutes, and zul will write the ones for next week. The process to follow is detailed in the Server team knowledge base. mathiaz can give access to the ubuntuserver blog to those missing it.

    Review ACTION points from previous meeting

    • jos to find out the best time for the meeting: Server meeting time to stay the same for at least the next month or two

    Check blueprint status and progress for the week

    Everything is green so far. The Alpha2 burn down chart is positive. ScottK mentioned that his mail integration spec still needs approval.

    ACTION: jos to review/approve server-lucid-more-mail-integration

    Alpha1 ISO testing

    Lucid Alpha 1 candidates are now up on the ISO tracker. Everyone is encouraged to participate in testing them ! Cloud images should be up soon as well.

    ACTION: smoser to push cloud dailies to ISO tracker asap

    Assigned and to-be-assigned bugs

    Nothing assigned to team needing re-assignment. Some team members are still assigned to more bugs than they should be actively working on, so this might need more review. No red flag raised.

    Weekly Updates & Questions for the Kernel Team

    KSM has been turned on and should land in post-Alpha1 kernels. It requires user space to use the madise system call to mark pages for sharing. That’s expected to be part of soon-released qemu-kvm 0.12. jjohansen still has to go through and update the EC2 configs to be more like virtual. On the table is also ramdisk-less images, -virtual kernels with all reasonable disk drivers for root devices as built-in, and Hz. This will be tracked in a bug that smoser will open.

    ACTION: smoser to open bug for kernel team follow-up

    Development sponsorship

    Every server engineer with sponsorship capabilities is expected to spend one hour a week sponsoring stuff. The easiest way to track that is to do it every week at a fixed time, and combine it with Code reviews.

    ACTION: zul, kirkland, mathiaz to sign up for sponsoring time on https://wiki.ubuntu.com/UbuntuDevelopment/CodeReviews

    Developer communication

    Developer communication rules have been recently updated, please have a look at them and do the right thing.

    soren’s QA project for Alpha2

    Until Alpha-2, soren will be in the QA team, rather than the server team, working on automating a lot of the testing we are doing for servers. So far he has enabled a few test suites in package builds and set up kvm-autotest to do scripted, interactive testing.

    Open Discussion

    Instead of rewriting all Ubuntu Server python code in Perl, we plan to rewrite Jos in Python. Daviey encourages everyone to submit their Ubuntu Server tips to https://wiki.ubuntu.com/server-tips.

    Agree on next meeting date and time

    Next meeting will be on Wednesday, December 16th at 14:00 UTC in #ubuntu-meeting.

    Matthew Helmke: Interviewed for Ubuntu UK Podcast

    My friends at Ubuntu UK Podcast posted the most recent episode of season two on their site today. I was privileged to be interviewed by Alan Pope about my travels, writing books, and the Ubuntu Forums. Several friends get a mention including Benjamin “Mako” Hill and Ryan Troy. I did make one error in the interview. The Ubuntu Forums do not have about 850,000 users, we have more than 973,000 forum members!

    The interview appears in this podcast episode starting at about 36:45 and ends near 55:41.

    Share and Enjoy:

    StumbleUpon
    Facebook
    Twitter
    LinkedIn
    Google Bookmarks
    email
    Print
    RSS

    Steven Harms: Installing Play Framework on OpenBSD 4.6

    OpenBSD
    OpenBSD is a free, reliable and secure operating system. From a configuration standpoint it is both minimal and simple, which is great for those who want to get started quickly. For the purposes of this tutorial, it is assumed the user has already installed OpenBSD. If not, check out openbsd101.com for guides on installation etc.

    Play Framework
    The Play Framework is a java based web programming system, that includes the enterprise features of java with the methodology of Ruby on Rails or Django. You can view an introductory screencast at their website which shows just how easy and powerful it is.

    Allow your user to sudo
    Since this blog is aggregated on many Ubuntu sites, we will use the sudo facility to run commands instead of root. To enable sudo the same way Ubuntu does:

    1. su – # Get root
    2. visudo
    3. Uncomment the line “%wheel ALL=(ALL) SETENV: ALL”

    Install packages
    For the play framework the launch scripts are in python. Zsh is installed for a better shell, and vim is installed for a full featured editor.

    export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.6/packages/i386/
    sudo pkg_add zsh jre-1.7.0.00b59p0 wget python-2.6.2p0 vim-7.2.190p1-no_x11 unzip
    sudo ln -sf /usr/local/bin/python2.6 /usr/bin/python
    sudo ln -sf /usr/local/bin/python2.6-config /usr/bin/python-config
    sudo ln -sf /usr/local/bin/pydoc2.6  /usr/bin/pydoc
    

    Install Play Framework

    cd /usr/local
    sudo wget http://download.playframework.org/releases/play-1.0.zip
    sudo unzip play-1.0.zip
    

    Start your project

    cd /var
    sudo /usr/local/play-1.0/play new ourappname
    sudo chown -R ourusername ourappname
    cd ourappname
    # Set java home -- you can set this permanently in /etc/login.conf or in a startup script
    export JAVA_HOME="/usr/local/jre-1.7.0/"
    /usr/local/play-1.0/play run
    

    Done
    Your test app is now listening on port 9000 of the systems IP. That is all there is to it. Make sure to check out the excellent documentation available for the Play Framework.

    play

    Related posts:

    1. 64-bit Java browser plugin We now have flash and java in 64-bit browsers. What…
    2. Installing Groupwise 8 Client in Ubuntu Jaunty AMD64 Download the Groupwise 8 Linux Client Tarball from Novell:…
    3. Installing Bazaar Distributed Version Control on SLES 10 SP2 I chose to install from source, the process is (tested…

    Joe Barker: Chrome Beta

    OMG Chrome Beta for Linux is available!!11!!…………………….is all I saw on Twitter/identi.ca the other day. So I figured I’d give it a go, knowing it should be much different from Chromium.

    It seems that, somewhat surprisingly, I was wrong. I downloaded the 64 bit .deb file from the chrome site and installed it. Easy enough – there’s also RPM’s for any of you using Fedora etc. One thing I liked, though incredibly insignificant, was the Chrome logo – I just prefer the green, red & yellow to the Chromium blueness.

    From what I can gather from various bits of info online, and my own personal use of the browser, it’s very similar to the latest builds of Chromium, except it carries the official Google backing. One thing I did notice though, which is a deal clincher for me right now – is that flash (specifically YouTube & BBC iPlayer, I haven’t tried anything else really)….works! Now I have received a Flash Player update today, but it worked before that :)

    Another thing that seems to have been fixed is the double posting issue a lot of Linux/Chrome users were experiencing over on Ubuntu Forums – thankfully I haven’t had it happen yet, but I’m keeping an eye on it. I just have the privilege of being able to remove my double posts without having to report it first ;)

    All in all – I’d say it’s definitely worth looking into, especially if you’ve been put off trying Chromium

    Johnathon Mlady: Determining WHICH *nix distro is currently used

    So now I’m frustrated.  I’ve been trying to write a perl script that differentiates whether it’s running on an Ubuntu system or a Fedora system…The script is as follows:

    my($distro);
    
    # Determine if distro is Fedora or Ubuntu
    if ( -e "/etc/fedora-release" ) {
     $distro = "fedora";
    } else {
     $distro = "ubuntu";
    }
    
    sub test {
     &{$distro}();
    }
    
    sub ubuntu { # do something }
    sub fedora { # do something }
    

    Now there are a myriad of drawbacks to this method, especially if you want to expand out to any other distro.

    I think that it would be highly advisable for ALL linux distributions to implement a command such as uname (or even an argument within) that displays the current distribution and build of an operating system, so that writing code for specific distributions and or builds can be simplified, ensuring an accurate read as to what distro/build it is rather than having to try to guess, figure out, and worry about the user changing some file(s).

    Ultimately, I think having a command or parameter of a command would cut down on the user-error in the development realm.