Fun link

All of my coding lately has reminded me how important it is to exercise your coding skills on different types of problems so that you can become better. Being overwhelmed with homework sometimes helps you forget that.

Related to this, Dave Thomas of Pragmatic Programmer fame has been posting what he calls "Code Katas" on his blog. A kata is an exercise that someone does in Karate. He has a page with a link of all of them (except, it seems, the last two he has posted) here. Some of them seem geared a bit, at least in their descriptions, to solving problems with Ruby, his favorite language. The rest are fairly generic. The last sounds like a fun project to me. Writing a program to play klondike solitaire and explore strategies with it. He describes this here.

Perhaps someone else would find this interesting as well. I plan on trying this one, and perhaps others, after I finish the semester and can breathe a bit. Until then, my other coding is going to be limited to work on Informant.

Sleep!

After a few hours of hacking, I have tore Informant completely apart and put it back together again according to the new design. Things changed a bit from the design I posted, as they usually do when implementation starts. After I wake up, I will go over the code to see if there is anything I missed and see any possible bugs. Then it is on to the other major points I wished to cover in this release.

Somehow I have to fit this, work, working on my last computer science assignment, and all of the holiday related stuff in between now and Monday. I did want a new release by Monday. I don't code on Sundays, so that means by Saturday evening, I should have everything fairly stable with those items. Other than changing the icons to something from Gnome stock I won't be doing any other UI changes this release. I want to clean up the sources and make writing them a bit easier so I can still afford putting time into them and the UI improvements I am going to focus on for next release.

/me falls over into bed

Informant Design

Just a quick follow-up on what I wrote last night. I don't think it makes sense to split up the Informer Gnome UI into two Informers. What I will do, however, is make an object that implements IInformer which is composed of two distinct classes implementing the alerts window and the tray icon. I think that is the separation I was wanting, but was trying to make too complicated. As usual.

Sleepless in Logan

I hate not being able to sleep even though I am dog tired. Oh well. I will continue the saga of Informant development. I've been thinking about a redesign of it the last little while. When the code base is this small and the functionality is contained within just a few classes, it makes throwing the code out a lot easier. Not to mention that Python allows for this so easily as well.

I am trying my best to temper my own desires and plans for Informant with the view that this could be something that would be of general use in a project like Gnome. This design work I am doing now isn't so much necessary for Gnome, but it is very useful in my long term (and even immediate) plans for Informant. Therefore I shall press forward.

Hopefully this ASCII art thing will come out, diagramming the process:

         whisper(alertObj)                alert(alertObj
Source ----------------->  Listener      -------------->
                           (PBListener or 
                            DBusListener)


                          access alert info
--->  Informant            <-----------   
      - alertObjs = [...]               \ Informers
      - informers = [...]--\              - Tray Icon
                            \  newAlert() - Alert Window
                             \            - E-mail informer
                              \-------->  - IRC/IM bot Informer
                                          - Auto-Action Informer
                                          - Web display 

I hope this makes sense. This is how I see the system working. As always, there are any number of sources that provide notification of particular conditions, events, etc. Each of these sources will be able to talk to one of the Listeners in the particular protocol it understands. These Listeners are objects that "listen" for the alerts to be "whispered" to them and then pass it on to the main Informant object. This makes Informant at this level protocol agnostic. Each of the Listener objects, when initialized, is given a reference to the main Informant object. They call the alert method on this object. It stores a list of the available alert objects, which store thing such as the time sent, the message, the priority of the message, the source of the message, and the action to be taken. Registered with the Informant object are any number of Informers, objects that implement the IInformer interface. The Informant will call newAlert() method on each of the Informers that it has registered with it. Each then will take an appropriate action.

The Informers I envision are these: First, I am unsure of this separation, but I will leave it like this for now. There is the notification area icon. All this will do when receiving the newAlert message is increment the number of new alerts data member, and display itself in the notification area if not already. Otherwise, update the display. The second is the alertsWindow(). If the window is visible, it will ask the Informant for the information on the new alert and update itself accordingly. Otherwise, it will do nothing until displayed. At display time. it requests info on all alerts currently stored and displays them as proper. The part I am unsure about is the separation of these two objects. How do I tell the alerts window to display when the tray icon is clicked? Perhaps there can be a special kind of informer that is display only. The tray icon will call the display method on the Informant and it will call the corresponding method on the methods that implement IDisplayInformer.

There are other types that use the information right away. Another design decision is this: I can imagine for very high priority alerts -- such as a major error found by the log file watcher source -- I would want to be alerted if I am away from my computer. I can use SMTP to send an e-mail/text message to my phone. Or an IRC bot can alert someone in an IRC channel, etc. Do I automatically send all alerts notifications to all Informers, and let them decide what to do with them? Or do I have them tell the Informant "Only give me items that are above this priority or from this source." Add two more possible informers to the list. An auto-action informer would automatically perform the action associated with the alert. Back to the log file alert. A possible action would be to run a script that launches a terminal with an ssh session to the machine with the problem. That would force you to take care of it now. The last one would be a web viewer. The user could go to a web page and view the history of alerts.

I think this design allows for some flexibility and puts of the decision of how alerts are received and how they are given to the user until deployment time. A standard script could be written for standard configurations, with command line options to add others.

Does this sound reasonable or too much overhead? For the next release, I will only have the PB Listener and the Tray Icon and Alerts Window Informers. When Moshe finishes D-BUS in Twisted, I will add that listener. I hope to add other Informers, such as a gdesklets informer or a Windows System Tray or OS X menu bar Informer later. I want to get this all set up and going, work hard on the UI in the Alerts Window, and then get back to focusing on my sources and making them easy to write. They are the reason that I started this in the first place.

Man, I feel too verbose. I guess I take a risk in doing my design out in public. Oh well.

Python rocks

Python makes prototyping so quick. After changing Informant to work in the notification area, I put together a couple of ugly icons with The Gimp and then made it be just icons and then a number when there are new ones. I posted screenshots here.

Overanxious and Obsessed

I have this propensity to get anxious and obsessed with certain ideas. When I grasp onto something, I focus on it with minimal effort and keep talking about it and thinking about it. The problem is sometimes putting the "money where my mouth is", as it were.

Informant

Such is the case here with Informant. After getting it out on the net and talking with people about it, various people who use Gnome started telling me they wanted this sort of thing. I get on irc.gnome.org and start talking to people. I come to find out that Nat Friedman mentions something like this on one of the slides of a presentation at the Gnome Developer's summit. I realize how generally useful it may be. So I've talked about what I want and people have shown support for the ideas. I just hope that I haven't committed myself to an idea that is bigger than I can handle. But perhaps I can.

Right now Informant is written with Python and Twisted. In order for it to be generally useful for the Gnome project, it will probably need to be implemented in C and use D-BUS as the IPC mechanism instead of Twisted. I am not too excited about the C part, as this is the type of thing I can write so easily in Python. I don't know enough about D-BUS, but I agree that something that will be a standard for the desktop should be used. Ultimately, the only thing I want from this is to be able to easily "whisper" (to use my terminology) to the Informant from my Python scripts. There are (or will be) Python bindings for D-BUS, so that could be accomplished.

I feel like this is a big project. I'm not going to think about that end of things. At the very most, what I am doing now will serve as a good prototype for the "real" version in C and using D-BUS. I can quickly sort out interface issues and other things. I can test it with many different sources that I have written. Because of the way I wrote my sources, it will be easy to move to D-BUS. I just have to modify the BaseSource class to use D-BUS instead of Twisted's PB. They will work just fine out of the box. Since I am using Glade, moving the UI over will be trivial too.

I moved Informant from being a panel applet to be something that resides in the notification area. I like the way they have designed these things. An applet and a trayicon are just Gtk containers. I just dropped my main class in, passing in the container for the tray icon and it worked out of the box. The code to do this isn't in anything standard, so I used this excellent article by Ross Burton and the accompanying code to get access to the functions for this. I guess I'll have to get permission to distribute this little part with my code so people can install it. I am going to whip up a quick-n-dirty icon tonight that will take the place of the text. The notification will consist of an icon with a number next to it for the number of new alerts. I have some options to go with for the other cases. When there are no alerts available, nothing will show in the notification area. If this is the case, when there are only already read messages available, I can either have just the icon showing or have nothing at all.

The reason for having nothing at all is that the notification area should be meant for just new notifications. If this is the case, another button will have to be placed as a launcher or something on the panel to display the alerts window in other cases. Another option is to just have it there all of the time, using a different icon to indicate that there are no alerts at all sitting in the alerts window.

As you can see by how much I have gone on here, I have a tendency to get obsessed. I am excited that I am actually getting the energy and focus to hack on **something_ that is useful to me, and perhaps someone else. Unfortunately, the part I may spend a lot of work on upfront is the part that I initially didn't care as much about. The sources and making them work well and eventually get more advanced is the whole reason I did this. Isn't it funny how you get distracted by other things?

Afternoons and Informant

Afternoons Suck

Continuing on my quest for increased focus and productivity, I've become painfully aware this week that I get very little of worth accomplished during the afternoon hours. I've been tying to think of the reasons why and a solution. Well, I find I often am not feeling well during the afternoon hours. Lately I really haven't been eating that well, I only have a small meal in the morning and by the afternoon I'm dragging. Plus, after having a morning of classes -- and, usually, getting up late and not having the best of night's sleep the night before -- I really am fatigued.

It is probably in my best interest to stop attempting to be productive during these hours for the time being. I will only frustrate myself and allow myself to fall back into old patterns of behavior that I am attempting to leave. Solution part one is to stop trying to work or do homework during those hours. Get away from my computer. I am more productive in the evening and morning hours. Part two is to focus on eating and sleeping better so I am not so groggy and tired by the afternoon. Part three is the corallary to part one; I should find things to do in the afternoons that are just as productive but on other things. I haven't been exercising, and I don't seem to find time any other time of the day to do so. If I have to shower again in the middle of the day, oh well. I should probably take care of a growing list of to dos that don't require focus -- like errands, cleaning, etc. Part four is to just not get discouraged. I do that too much.

Informant

Did some more work on Informant today. I implemented the relative time display for the alerts window. As always, I attempted to do it the difficult way first. I was talking with a friend on IRC and I described the result of this algorithm. I was trying to use a fancy combination of a for loop and divmod(). My friend said, "Why don't you use a series of if-thens?" Duh! I should have learned from my Algorithms class by now that I should just code what is most obvious at first. Then, you see if that doesn't work well enough, try more advanced methods.

Talking with another friend brought up the issue that "No alerts" and "New alerts" are possibly not different enough visually. He suggested that perhaps I use different colored text or icons. I am wary of colored text because of color blind users, but perhaps different shapes or images for icons that are the different colors, and perhaps animated is enough of a visual indicator. I don't want to be extremely visually distracting, but anything that does make it easier to tell at a glance I have alerts is good.

Informant Todo notes

Things to do before I release new Informant code:

  • Move configuration into a central place - ~/.informant

  • Add support for configuration exceptions on the commandline - using twisted.python.usage

  • Per suggestion of Moshe, make Informant use Unix Domain Sockets by default instead of TCP. Advanced users can enable TCP/IP if they are having sources come from non-localhost

  • Somehow use something like ReconnectingClientFactory with Sources. Use case: since my desktop machine is always connected to the net, I move the website monitor to it. The source on my desktop would connect to the Informant on my laptop. Since my laptop is not always on the local network, it would be nice for it to attempt to send the alert periodically until it is able to send, when my laptop is back on the network.

  • Reimplement the time display in the "Your Alerts" window to show relative time: "10 minutes ago", "2 hours ago", "3 weeks ago".

  • Write a log file watcher. Support searching via regular expressions. Can I do what tail -f does with Twisted? Or should I just reopen the file every so often and get the bytes at the end that have changed? I wonder what is the best solution.

  • Regular Expression support for the header contents for the e-mail source. Also, have it watch for a key like BODY that will search the body of the message for a given regular expression as well.

  • Get a Debian package made for me.

Goal is to have this finished by the time I get back from Thanksgiving break. That leaves me until December 1st. 11 days. Should be enough time. I'll leave the UI improvements for after classes are over. Classes are over December 5th. Then I don't have my final for Computer Science until the 12th. I should have a little more free time that week to attack the GUI work.

That's the plan.

My sister is the coolest

Not much to say today, I'm almost ready to go to bed, but just a quick entry right now. I was very groggy and sleepy all day and had trouble focusing. I need more exercise and to eat better. I really haven't ate all that well lately. In those conditions, it sure it hard to focus and think or even do anything. I spent a lot of time at the library on campus, but didn't get a lot done. I talked with my sister on the phone and she could tell I wasn't feeling so well. She asked if I needed anything, and if I had ate. Sharalyn knows me too well. She offered and ended up bringing me a sandwich from Subway! She's the coolest and I love her. While I ate my sandwich, we talked and then she left so I could get back to homework.

I almost got my Computer Science homework done. I only have one more computer science assignment ever in my life after this one. Freaky. I need to interpret my graph comparing runtimes for methods of solving the Closest Pair problem and then a conclusion. Should be simple. If I can't sleep tonight, I'll do that.

Next on the agenda is to get focused on work. I need to figure out atop, a new persistence mechanism those crazy Divmod guys came up with. Plus, there are some bugs in the nvidia-glx drivers in Debian unstable and I'm waiting for them to get fixed so I can use one of the two graphics libraries I've been trying to compile and use. Work! Soon that's all I'll have!

Ended up being longer than I meant...

Focus

I just spent the last two and a half hours hacking on a couple of scripts with my roommate to keep SSH tunnels alive. It was quite fun and at the same time something very useful that I have been putting off for a while. I write of this because I was able to focus on this intently for that whole time, without any of the rapid context switches I normally do or even being unable to think. I was able to focus, concentrate on the task at hand, and come up with an elegant solution. The only problems I had thinking were related to the fact that I am tired. Why is this different than any other project I want to work on? Why is this different from work or school projects that I find interesting? Part of it is that for a lot of the time I was working on this my roommate was here talking to me about it. I have found with school projects I work so much better when I can work in a group. But that doesn't help these things that I have to do alone. Hrm.

<<  Page 2 of 4  >>