Thursday, June 30, 2005

systray sample app screenshots

I decided to post some screenies of the sample app included in the systray package source.


















1. The first shot identifies the sample app (its the 'S' icon).

2. The second shot showcases MenuOptions.

3. The third is me in the midst of selecting an option that will change the app icon.

4. The App icon has been changed (And the Hover Text as well). The current icon has a white 'S' the other one had a black 'S' with an outer glow.


Anyways... just a sample app. staty tuned... 'phiba' coming your way soon.

systray 0.2.1

The topic says it all. And as usual... i had to stay up... this time i think i just stayed till 1.00am... i'm getting lazy i guess :)

I have built up systray-0.2.1, and its looking good.

Here's the changelog so far.

0.2.1
=============
1. Make Menu() and MenuItem() have default values for 'title' in constructor, so they can be blank.

0.2.0
=============
1. Add MenuItem.add_submenu
2. implement the _App class inheriting from SysTrayIcon.SysTrayIcon
3. Added text and icon property to _App class which call refresh_icon, automatically
4. Modify App.start() to use _App() instead of SysTrayIcon.SysTrayIcon
5. Change App.start() to correctly set window_class_name of _App class
6. Refactor out MenuBase.
7. Reimplement MenuItem as a child of MenuBase, removing irrelevant attributes
8. Implement Menu as a chile of MenuBase, seperate from MenuItem.
9. Extend App to support both App.add_menu() and App.add_menuitem(), for unambigous usability
10. Modify App to have a default on_quit handler that does nothing, so it now always exits properly.
11. Rename default_onclick(s) to default_handler(s).
12. Create a module object DEFAULT_HANDLER to be the default_handler accessor object
13. Make App and MenuBase use DEFAULT_HANDLER as their default handlers for on_quit() and onclick() respecively
14. Added doc strings for _App and App, MenuBase, Menu, MenuItem.
15. Extend Menu to support SubMenus and MenuItems explicitly
16. Incoporate distutils framework for installation.


0.1.0
=============
1. Initial Release
2. Create systray module
3. Build App class
4. Build MenuItem class



The source comes with a sample application, here is the code:

#--------- systray sample ---------------
from systray import *
import time

mitem_txtchg = systray.MenuItem('Change Text')

def txtchg_onclick(s):
s.text = 'systray sample - ' + str(time.clock())

mitem_txtchg.onclick = txtchg_onclick


menuitem_published = systray.MenuItem()
menuitem_published.icon = 'published.ico'

def menuitem_published_onclick(s):
s.icon = 'published.ico'

menuitem_published.onclick = menuitem_published_onclick

menuitem_default = systray.MenuItem()
menuitem_default.icon = 'default.ico'

def menuitem_default_onclick(s):
s.icon = 'default.ico'

menuitem_default.onclick = menuitem_default_onclick



menu_icon = systray.Menu('Icon')
menu_icon.add_menuitem(menuitem_published)
menu_icon.add_menuitem(menuitem_default)


st_sample = systray.App('systray sample', 'default.ico')

st_sample.add_menuitem(mitem_txtchg)
st_sample.add_menu(menu_icon)

st_sample.start()


#--------------------------------------------------------#

at this stage, i think i've side tracked enough from 'phiba'. What is phiba? phiba was why i got looking for the SysTrayIcon.py module in the first place... its supposed to be a home brewed blogger butt... ooopss.. blogger bot :)

I'll start work on this sometime tonite i guess... i have the blogger API docs, and now i have 'systray'. I think that was the last missing piece. i think i should have something exciting soon :)

Wednesday, June 29, 2005

Eclipse, Python at Work and uhhh.. EMR

Today, I 'officially' had reason to work with Eclipse, PyDev and Python. :)

We were modifying the Hospice Backend, so i had to redo the import scripts which were crafted in Python. I had done this previously using PythonWin IDE, but since i've fallen inlove with Eclipse (yeah, now i admit it is cool, it has a rather high coolness factor too ;) ), I Decided to import the project into Eclipse and continue from there.

Yup... It turned out very painless and infact, very beneficial. I think that's it, Eclipse/PyDev has become my Python development Environment of choice. Now all that needs to be added is a way to access PyDoc easily, probably integration of all the docs that come with PythonWin into the Eclipse Help system, and I guess I won't open any other python Python IDE/IDLE/SHELL again ;)

woooo... exciting times.


Btw, today, I officially joined our EMR team. Phew! Everyone dreads that project, b/cos its so big, somewhat badly designed... and fixes keep coming in everyday.

Well today, I worked with Seun and did some fixes. One of the Refactorings I added today, was for implementing Warnings before closing forms with Changed data. I took one look at the stuff and told Seun... man... we can't be copying and pasting... Immedietly I went to work on an interface ISaveClose, and we integrated it first into the New Allergies form and the New Medications form. It works very nicely. Tmrw, we'll make all the other forms that need to do that, use it.

I'll actually like to go one step further, build a class that implements that inteface already, and all the what nots, so by making each of the forms just inherit from that class, we will be good to go.

Why this was never done before? hehe... that's the million dollar question :)

Boy... my back aches... my tummy rumbles... i really gtg.

Python and the Windows System Tray

Continuing with my exploration of small neat and usefull python hacks for windows, I went searching the web for how to use python to write an app that would run on the Windows System Tray.

Shift over... its Googlistic All The Way :)

I came across this from Simon Brunning : http://www.brunningonline.net/simon/blog/archives/SysTrayIcon.py.html

Quickly downloaded it, and yesternite (yup... i'm becoming a Pythonire - that's a poor vampire spin off :D ), I took it for a Test Drive.

After a quick understanding of how it works, I tried to write a small app, and in the process I quickly refactored out a small library, that makes using it a bit more Intuitive to me.

The module which i dubbed 'systray' looks like this:

import SysTrayIcon

def default_onclick(s):
return

class SysTrayApp:
def __init__(self, title, icon=None):
self.icon = icon
self.title = title
self.menu = []

def start(self):
SysTrayIcon.SysTrayIcon(self.icon, self.title, tuple(self.menu) ,default_menu_index=1)
return

def add_menuitem(self, m):
self.menu.append(tuple(m))
#print tuple(self.menu)
return


class MenuItem(list):
def __init__(self, title):
list.__init__(self)
self.append(title)
self.append(None)
self.append(default_onclick)

def __set_icon(self, icon):
self[1] = icon

def __set_onclick(self, handler):
self[2] = handler

icon = property(None, __set_icon, None, "Icon Property")
onclick = property(None, __set_onclick, None, "OnClick Event Handler")


Easily use this module, you can do the following:

#-------------------------------

import systray



mitem_sample = systray.MenuItem('Sample Menu')

st_sample = systray.SysTrayApp('systray sample', 'default.ico')
st_sample.add_menuitem(mitem_sample)
st_sample.start()

#--------------------------------------


To add icons and menu actions to those menu items, modify the code as follows:

import systray



mitem_sample = systray.MenuItem('Sample Menu')
mitem_sample.icon = 'default.ico'

def sample_onclick(systrayicon):
systrayicon.title = "I have been clicked"
return

mitem_sample.onclick = sample_onclick

st_sample = systray.SysTrayApp('systray sample', 'default.ico')
st_sample.add_menuitem(mitem_sample)
st_sample.start()

#---------------------------------------------

Well, that's it.

I want to use this for some nifty utils, like a network monitoring daemon, a monitor for pmserv, etc.

hmm... fun times ahead i say.

Tuesday, June 28, 2005

GNU GOATS on JAVA

Like i said earlier, these are exciting times. And if i hear anymore person say that lack of patents stiffles creativity, i'll personally truss em!


After crying about the Java Trap (http://www.gnu.org/philosophy/java-trap.html), the GNU community has been responding on many fronts, as a lot of Free software these days are written in Java. The result is GCJ and libgcj (which comes with GCC 4.0).

If you're a bit used to UNIXy nomenclature, libgcj may strike you as odd, b/cos its normally c/c++ libraries that are named like that, since they are compiled to native code. Well... GCJ can compile Java code to native code... Yes sir, you heard me well. In this manner, Java programs can run REALLY FAST.

libgcj is then the implementation of the Java library, and is currently a result of two GNU projects collaborating well (the original libgcj guys and the GNU Classpath hackers).

What does this mean for me as a coder, well, i now have a standard free platform to write Java code (uhh... i'm not exactly a Java freak tho). But most important to me, is that i can compile OpenOffice and Eclipse and run them as native binaries on Linux (and to some extent on windows using Ming). Now that is what i call innovation. You would wonder why Sun didn't do this? Or why .NET uses the same principle as Java (no native code). Well, they all tell you its compile once run everywhere, but in practice we know its not usually that straight forward, and its more true with Java than with .NET anyway, so why bother?

I personally don't know, and right now, i don't care :) Once I can run my Java programs that i NEED on my preferred platform, at native speeds, the bigwigs can go do what ever they like.

Business as we know it is changing fast, and innovations like this are the reason. Like I said earlier, these are exciting times.

Eclipse Weekend, pmutils - introducing pmserv

Last weekend, i decided to really take Eclipse for a drive. And i have one word. It is USEFULL. Note i didn't say cool. I'm yet to feel the coolness factor, though one plugin nearly got me there (the vim plugin - yeah... i'm a nerd so what? :) )

What I did was to install eclipse and setup the lattest version of PyDev, and then migrated my development of libpm and pmutils, to Eclipse.

My first really tripping moment was the Refactoring Functionality. It is really cool. What I ended up doing mostly is, all the places i know i want to factorize out a function, I use the Refactoring -> Extract Method. Then examine the resulting function to see if its good enough (sometimes, there are unnesseccarry arguments, etc). But, its really a time-shaver :)

I firstly cleaned up libpm and pmutils somemore, dealing with most of my todos, then started facing pmserv, which was intended as a windows service. i had layed out a basic service framework, but there was still work to be done, methods to extract from the existing pmutils, etc.

I did all of this in Eclipse, and last nite, i stayed up till 2.30am, to finish pmserv, and it works beautifully.

One of the things that really tripped me with eclipse was the External Tools feature. I added the python console (ofcourse), and a windows command prompt, which i used while developing the service (installing, starting, stoping). I really needed to include the windows Service Manager and Event Viewer too, and a PyDoc viewer, but didn't get around to doing those... I guess there's always latter, as i'm planning to write a blogging service too :)

All in all, i'll say, Eclipse is a really serious utility, and this is another boon for opensource development, and the ubiquitious J. Random Hacker. Thanks to tools like eclipse and all the budding tool smiths out there, anyone can start doing very usefull stuff, without paying a dime, and what's more... this things are actually industry standard.


Exciting Times are ahead i tell you, i'm really happy to be alive and coding in this era.

Eclipse Weekend, pmutils - introducing pmserv

Last weekend, i decided to really take Eclipse for a drive. And i have one word. It is USEFULL. Note i didn't say cool. I'm yet to feel the coolness factor, though one plugin nearly got me there (the vim plugin - yeah... i'm a nerd so what? :) )

What I did was to install eclipse and setup the lattest version of PyDev, and then migrated my development of libpm and pmutils, to Eclipse.

My first really tripping moment was the Refactoring Functionality. It is really cool. What I ended up doing mostly is, all the places i know i want to factorize out a function, I use the Refactoring -> Extract Method. Then examine the resulting function to see if its good enough (sometimes, there are unnesseccarry arguments, etc). But, its really a time-shaver :)

I firstly cleaned up libpm and pmutils somemore, dealing with most of my todos, then started facing pmserv, which was intended as a windows service. i had layed out a basic service framework, but there was still work to be done, methods to extract from the existing pmutils, etc.

I did all of this in Eclipse, and last nite, i stayed up till 2.30am, to finish pmserv, and it works beautifully.

One of the things that really tripped me with eclipse was the External Tools feature. I added the python console (ofcourse), and a windows command prompt, which i used in developing the service. I really needed to include the windows Service Manager and Event Viewer too, but didn't get around to doing those... I guess there's always latter, as i'm planning to write a blogging service too :)

All in all, i'll say, Eclipse is a really serious utility, and this is another boon for opensource development, and the ubiquitious J. Random Hacker. Thanks to tools like eclipse and all the budding tool smiths out there, anyone can start doing very usefull stuff, without paying a dime, and what's more... this things are actually industry standard.


Exciting Times are ahead i tell you, i'm really happy to be alive and coding in this era.

Saturday, June 25, 2005

Solution Layering

How many times have you actually felt that you were doing too much work while programming?

Hmmm... ok... i know we all feel overworked, and most of us derive a kind of sadistic pleasure just from the feeling of overworked pressurized must-meet-dealine kinda crap :) but sometimes, its plain unneccessary.

Actually, as you grow as a coder, you begin to relish 'elegant' solutions, that not just showcase how smart you are, but also reduce the number of keystrokes you hit and stuff like that (at least, i crave for that elegance in my solutions). What keeps hitting me everytime, is the importance of layering as an engineering art, and the importance of recognizing funcionality meant for those layers and keeping them there.

I'll give a couple of examples.

First of all, imagine you have a database table with two fields [id, name]. You also have this program that is putting data into the database. Supposing you're reading the data you have, from a couple of CSV files, collected from different secretaries in the same company. As you're about to start running your import script, you're suddenly alerted that there could be duplicate information in those CSV's and you have to ensure it doesn't mess up the database. What do you do?

I'm not sure what the no brainer answer is for a lot of ppl, but lets look at the alternatives.

1. Modify your script to (a) Hold the names in memory as it is reading, and compare new names with those already in memory to ensure duplicates don't occur (DONT LAUGH :) )

2. Before each insert, try to retrieve the same name from the database, just to see if its already there. If its not there (its UNIQUE), then insert.

3. Just make the stupid field in the database UNIQUE and don't touch you script at all.

Looking back at the three alternatives now, its almost a no-brainer see which is the most trivial and probably better (at least for me the programmer) solution.

Let's look at this solutions again before I finalize my point.

Solution 1.
===========

In solution 1, we were trying to do EVERYTHING in our code. Without basically, if we like it or not, or we realize it or not, we're going to need to replicate some functionality of a database (in memory data store). Once we commit to that solution, we're introducing a LOT of possible bugs, since our once simple import script will become an import script with an Embedded Database (albeit a poor man's database), and of course since its a poor man's database, our program and we the programmer will suffer from that decision. What will probably save us from this condition is if we realize this, and remember that usually, our programs should STRIVE to DO ONE THING, and DO IT WELL. Also, if there is ANOTHER program/library, that DOES WHAT WE WANT DONE, BETTER than we do it, WE OWE OURSELVES to TRY TO USE IT. Enough said. (Did i hear someone say Opensource?)

Solution 2
===========

In solution two, the change to our program is much simpler, because we're exploiting a property of our Database Server (querying for prior existence), before we insert. We can see that once we involve the Database System in anyway, our headaches automagically reduce to a very negligible minimum. This is almost acceptable, and in some cases of software layering is very ok. At least, we've pushed the real data manipulation to the system that was designed for data manipulation... the database itself.

Solution 3
============

The only reason why solution 2 is not the best solution is because Solution 3 is possible. Probably not in all cases, as there maybe some stripped down version of an embedded database to be used in a low resource application that will not have the ability we exploit in Solution 3, but as long as it exists, it is a preferred solution. Here, we totally shift EVERYTHING to the database layer. This is true layering. And our first advantage is ultimate simplicity... we DONT ALTER OUR CODE AT ALL. Now, that is a benefit i'm proud of. On the other hand, we have to be aware that this can be done, else we can't benefit from this. This brings to mind one of the nuggets i came across once about being a good programmer. It said to LEARN ABOUT THE ADVANCED FEATURES OF YOUR LANGUAGE(s). The idea being that most of those advanced features are easier ways of solving very real problems.

Now for a quick summary.

Its always beneficial for us everyone if we can properly design our solution systems to exploit designed-for strengths of various components of our systems. Infact, if we don't, we almost invariably build weaker systems. This is why working harder is not always a good thing, but working smarter usually translates as a problem solver.

Now, at times, it is not obvious that there is a better layer to handle your problem, so what do you do? Well, i usually think about my implementations, and everytime i find my self doing too much work, it *smells* wrong. I may not know the best solution immedietly, but i do leave TODO's and other kinds of hints in my code, so if a wiser me or a wiser someone else comes along, that code can be improved latter. Its usually better to roll-out a quick dirty solution within your time constraint than a better solution out of budget time. Your programming buddies may hail you for that, but your boss will chew you out, and you may have cost your company an actual job.

The key is to COMMIT TO IMPROVEMENT. If you identify a problem that you don't have the mental resources to solve now, not it down, and solve it latter. If on the other hand, you CAN solve it now, please do, or your head WILL Fly :)

Ok... now, repeat after me... "I am done reading this blog entry for today..."

More Python and Linux at work

Recently, i've been having more and more opportunity to use Python at work... mostly for scripting a lot of stuff for myself, as the needs were arising. Especially data analysis.

Well, i had another more "official" data transformation or more accurately data migration project recently. I had to migrate a very flat file database built in Access, to a more Relational Model solution, still built in Access. And it was to be a quick job. So here I was, itching to use Python (i mean... there was no way i was going to be doing that in C#... just plain old forget it... its too complicated and error prone.)

First thing i did to assuage my concience was to state the problem aloud, and ask if anyone had ANY MEANS that would solve this problem elegantly without my use of Python (Everyone knows Stan and I love Python), so well, we brainstormed for sometime, and honestly, there was no simpler faster solution (I knew that already, but i just wanted to be sure i wasn't being merely self-serving).

Long story short... I did the project in Python. To make things even more interesting, Dan Lash (one of the new consultants at Artemis, and most importantly the consultant on this project), is also a Pythonista, needless to say, we had real fun on this project, and NO BUGS, just suggested implementation changes. Nice wrap up.

On the case for Linux, i'm still keeping this underwraps a bit, but we've been pursuing a lot of OpenSource solutions for some new projects coming down the line, of which i can't really say much of at the moment. But I'm currently configuring E17 (Yup.. The new Enlightenment), for Dapo. The last week, we were setting up Eclipse/Java/Tomcat/MySql, the whole works on Linux and stuff like that...

Pretty interesting and cool. I'm getting to do more of what i really love i guess... could still be much more coming the next few weeks too.

Wednesday, June 22, 2005

Truce indeed.. who am i decieving?

ahh... i really don't feel too good.

i'm afraid i'll have to take at least one day off... arrgghh! There goes my stainless record.. anyways... my good friend Ugo put me in perspective, when he told me to stop playing Superman, and just go lie down and get better...

i think he's right...

Btw, just some random updates... i have been doing a full recon of website authoring recently... its been a while since i did that. And i'd been really growing tired of Table Kung-Fu (as Ryan neatly described that art!).

Anyways, DIVS, CSS, Ajax, the whole thing... i'm even thinking of picking up Ruby On Rails... ahh... anyways... this malaria fever thing is slowing me down... this is just why i hate to turn in sick :(

Bahh... i better just sign off now...

Tuesday, June 21, 2005

Malaria, Truce and libnetprog (What the heck!!!)

i'm feeling a bit under the weather...

Its like i have this running bet with Malaria, and every year, it tries to get me down at least once... there were times when i used to be gotten down... but these days... we sort of lock into a stale mate.

I keep going to work... being slightly affected with a nagging headache, and probably teary eyes that hurt. On my part.. i increase the intensity of my exercises, take more Vitamin C, drink lots of water... and work harder during the day than before.

This truce of convenience lasts for about 3 or 4 days, and eventually i'm back to normal. This is waaaaay much better than being enBEDDED for about 1wk. #:-s

Anyways... i'm in the middle of one now... started yesterday, and i still worked till 10.30pm yesterday, on one of those small and interesting utility projects.

In finishing that project, i had to dig up a library i had started work on a while back, and clean it up, extend it, and use it. I call it 'libnetprog', and was my way of 'pythonizing' or 'c-izing' .NET network programming. I TOTALLY HATE STREAMS!!! why Java, and .NET decide to NOT encapsulate if i will never know. Anyways..., libnetprog.NSTcpClient() [No Streams TcpClient()] is an encapsulation of System.Net.Sockets.TcpClient() but adds Send() and Recv() that allows more natural communication by abstracting the NetworkStream away from the user. That and the conversion that goes on with System.Text.Encoding.ASCII

libnetprog.SMTPClient() is another cool class. And it has a very usefull static function SendMail(), that is inspired by PHP's mail() function.

Anyways... lots of UnitTests in that library, and its looking good and stable. Its a 'driven-by-need' library, which i'm only extending as the need arises... i guess i should put this up on my website download area.

Ahh.... that reminds me... i've stumbled across a very nice way of layering GUI applications... its just a natural extension of Refactoring and Bottoms Up programming (Aggressive Unix Programming), applied to GUI's, and so far, all the stuff i'm building i'm building like that.

I *think* they're very stable (since i can trivially UnitTest the GUI using this method), and i end up having reusable components too... i'll blog about that latter... let me get the entire picture very clear :)

btw, good to be back.

Monday, June 13, 2005

Alive and Kicking

just a short note... i'm still alive and kicking... or well.. coding :)

fast blog updates coming soon.