woensdag 3 december 2008

How I organize my gmail

Since I first started using gmail, I started using labels for everything. Every time I start a new project or subscribe to some mailing list I created a new label (mostly with a corresponding filter) without thinking too much about how I ordered them. At first this was no real problem, but after a while I had too much unordered labels. You can Imagine the clutter. The moment gmail introduced labs and with it, the quick links feature, I rejoiced. I started saving links for all my most used labels.
But this was definitely no solution for the problem. So I recently decided it was time to think about a real solution.
I started reading blogs about how other people organize their mail. Soon I came to the conclusion that all those solutions are good in a certain way, but they didn't suffice for me.
So In this post I'll explain what I do want, how my labels look now and what gmail still lacks.

What do I want?

I want to organize my mail so that I don't need to spend much time organizing it (apart from spending quite a lot of time with this now). This means that I have to be able to quickly process and search mail.

The most important things are these:
  • I need to be able to access my most accessed labels fastest.
Quick search is a bit of a solution for this, but only a partial solution, it can still take some time to give a label to a mail if you have to search the label way down on the list. So my labels need a good and logical order.
  • I don't want an inbox full of mails.
This means that I need to be able to label mail or to archive it the moment I read it.
  • Things I don't need may not clutter my mail.
Archive/delete those messages at once. (I almost never delete mail)
  • I don't want to spend my time on mail I don't need.
There are three things you can do here: If this is a message from something you can unsubscribe easily, do that, if not mark it is as spam and if that doesn't work, create a filter to mark the message as read and archive it.
  • Be able to decide whether a message is important to read now or if it can wait.

Organizing my labels

I use a prefix to create a first ordering.
Things I am working on now, and thus have to access often have a _ as prefix so it's on top of the list:
_/study/project
If I'm finished with the project or task, I label them with a P (for processed and it doesn't clutter my first labels):
P/study/project.
When you rename this task, you can also add a timestamp for projects that return every year or every month, or you can sort the label more fine grained.
Things I always need like personal or important mails, those I label with an A (for always and just below the _)
A/important
A/notes
If you have many labels that are only for personal use, you could create a secondary ordering for example A/me/important.
Other labels I use
things I almost never need: Z (way down)
If you create a label Z/unimportant you should delete that label and archive those mails as they are unimportant anyway! I use the Z label for backups of old mail, or for my starred messages as sometimes desktop mail clients delete all the stars.
The important remark here is that you should only label those messages with a Z that you want to find later, mail that you'll never need again needs to be archived.

mailing lists: L
You should make a filter for mailing lists. If you make the filter so that you never look at the mail anymore, you should unsubscribe from the list
You can use as many prefix as you want but a rule that I like is to keep most used labels on top with _ and A!
Things you can filter and don't need to access often doesn't matter much, make sure they don't get on top though.

Things that don't need a label
- all mail coming from one person, you can perfectly fine search for all that mail (from:person) and if typing that is too much, you can still create a quick link.
- unimportant mail.

What with new mail?

I try to process all incoming mail at the moment I read it. If you do have to defer it, for example when you have too much mail and don't have the time to read them all now, make a label for mail that you should access later, something like __/reply or __/waiting. I personally don't have those labels. If I label them like that, I just forget about that mail most of the time.

I think it's more useful to distinguish between important unread mails and other unread mails. That's why I have always two quick links: "important unread" and "unread". When I don't have much time I only read the important unread messages, and I can always come back to the other unread messages.

If there are then still mails that cannot be processed right away, I keep those mails in my inbox, so that they are always there when I open my mail. But that are the only mails in my inbox.

If you have mail that you don't need it anymore, archive it.


Some tips

  • For abbreviations I use all caps, other words with all small letters. (it doesn't matter what you use, but be sure to use it everywhere to keep things clean).
  • I use simple and short names for labels.
  • I write drafts of notes/text to myself and mail them to myemail+note@gmail.com. You can use the +note to create a filter and label those mails like this: A/notes. If I want to write nicely formatted text, I use google docs, and reply it to my note (the google docs gadget in labs makes drag and drop possible)
  • I also have a filter for unwanted mail to mark the as read and archive/delete them, I use 1 filter for that, so I don't clutter my filters to much (this has the disadvantage that this filter becomes harder to edit if it becomes bigger).
  • I don't keep a todo list in gmail because I forget to do those items, I use remember the milk for my todo list which you can integrate in gmail.

What gmail still lacks

Not much! that's for sure, it's becoming more and more feature complete with support for gadgets like google docs, calendar and remember the milk, quick links.
But 2 more things would be great:
- Search labels with wild cards, so you can do something like this: search for "l:L-*" to search for all emails from mailing lists.
- Support for folders in the labels (there are plugins for this though, but official support would be great as the plugins don't always seem to work)
There is one more thing, but I don't think this is really a gmail thing. It would be great if desktop mail clients would now when an email has a double label. Not having to mark those messages as read twice would be great.

Conclusion

I've been using this scheme now for some days and I haven't yet found any issues with it. One small thing is that you manually have to change the prefix _ to P for projects that are finished.
This sort of scheme will probably not work for everybody but for me it's great so far!

Now it's time to sort my google reader subscriptions.

woensdag 6 februari 2008

My kde svn account

I applied today for an svn account and already have it :) so I just commited my first patch. It's a simple patch to the Picture Frame applet and also some refactorings. I'll sure be commiting more patches to plasma and kde.

I also made a techbase page with all the current known plasmoids. (I still need to add those from playground) you can see the page here: http://techbase.kde.org/index.php?title=Projects/Plasma/Plasmoids

vrijdag 18 januari 2008

I wanted an easy way of following some matches on the australian open.  But since I couldn't get the IBM scoreboard working under linux1 I wanted to try write something myself.

So I've come up with something really simple.

I've just made a python script and with urllib2 I pull the results and format them simply.

Here is the script.

#!/usr/bin/python


#The players you want to follow.
players =["Roger Federer", "Justine Henin", "Andy Roddick", "Rafael Nadal", "Maria Sharapova", "Lleyton Hewitt", "David Nalbandian", "Amelie Mauresmo"]
#The maximum width of the display (maximum chars)
max_width= 14

#Only change below this if you know what you're doing.
import urllib2
import urllib


url = 'http://www.australianopen.com/en_AU/scores/index2.html'



def find_player_in_data(player, data):
startString = '<table width="440" height="100" border="0" cellspacing="0" cellpadding="0" background="/images/scores/ao_sc_0000g5.gif"'
endString = '<sup></sup></td><td width="5"><spacer type="block" height="1" width="1"></td></tr><tr><td colspan="16" height="4">'
index = data.find(player)
if index != -1:
index = data.find(startString, index-200)
endIndex = data.find(endString, index)
return data[index: endIndex+len(endString)]
else:
return ""

def find_numbers(data):
lineBegin = '<td width="1"><spacer type="block" height="1" width="1"></td><td width="19" valign="middle">'
lineEnd = '</sup></td>'

first = 0
numbers = []
last = 0
while (first != (-1+len(lineBegin))):
first = data.find(lineBegin)+len(lineBegin)
last = data.find(lineEnd,first)
numbers.append(getNumber(data[first:last]))
data = data[last:]
return numbers

def find_game_number(data):
firstLine = '<td width="21" valign="middle">'
vet = "<b><b>"
first = data.find(firstLine)
if (data.find(vet) != -1):
return data[first+len(firstLine):2]
else:
return data[first+len(firstLine)+len(vet):2]

def is_serving(data):
""" returns if the player is serving or not"""
firstLine = '<td width="21" valign="middle">'
vet = "<b><b>"
first = data.find(firstLine)
return (data.find(vet) != -1)

def player(data):
start = '<td width="264" align="left" valign="middle">&nbsp;&nbsp;<a href='
startNext = 'class="blue">'
end = "</a>"
winner_start = '<b>'
winner_end = '</b>'
first = data.find(start)
next = data.find(startNext,first)
end = data.find(end,next)
player_name = data[next+len(startNext):end]
if player_name.find(winner_start) != -1:
player_name = player_name[len(winner_start):-len(winner_end)]
win = True
else:
win = False

if len(player_name) > max_width:
player_name_list = player_name.split(" ")
first_len = max_width - (len(player_name_list[1])+1)
result = player_name_list[0][0:first_len] + " " + player_name_list[1]
return [result, win]

def getNumber(char):
if char[0].isdigit():
return char[0]
else:
return ""

def do(data):
if data == "":
return

lastBlock = '<td width="5"><spacer type="block" height="1" width="1"></td></tr><tr>'
firstBlockLastIndex = data.find(lastBlock)
first = data[0:firstBlockLastIndex]
last = data[firstBlockLastIndex:]
first_player = player(first)
last_player = player(last)
message = ""
if (first_player[1] == True | last_player[1] == True):
message += "Completed\nWinner:\n"
if (first_player[1] == True):
winner = first_player
else:
winner = last_player
message += winner[0]
else:
serving_1 = is_serving(first)
serving_2 = is_serving(last)
message = join_results(first_player[0], find_numbers(first), serving_1)
message += "\n"
message += join_results(last_player[0], find_numbers(last), serving_2)
return message

def join_results(player, numbers, serving):
result = player + "\n"
if serving == True:
result+= "* "
else:
result += " "
result += " ".join(numbers)
return result


data = urllib2.urlopen(url)
stringData = data.read()



for p in players:
data = find_player_in_data(p, stringData)
result = do(data)
if result != None:
print result



features:
show who's serving
truncate for maximum width (edit max_width in the script)
choose which players to follow (edit players in the script)
show the match winners

bugs/missing:
cannot show 15,30,40,AD,De (this should be simple to add, so maybe I'll add this later)
This script won't probably work for the double matches and if two
players in your list play against each other it will display the match
twice

how to use:
you can choose yourself but I use it in conky. (just add this line in conkyrc2: "${texeci 90 python ~/path/to/script.py}") (screenshot)
other possible use would be: a cron script and terminal, a superkaramba widget, a plasmoid,...


I know this is only a really simple script.  There are probably better ways of doing this but it works and it was written fast.
If you have request, you can always ask, I'll see if I have the time for it (exams for now).
You can change the script as you like but if you made improvments it would always be cool if you shared them.

1Didn't work in konqueror, firefox nor opera (I have flash 9 installed),  I wrote them an email about this but haven't yet received a response.
2To get conky working in kde I have installed feh and added this line to my conkyrc: "${exec feh --bg-scale `dcop kdesktop KBackgroundIface currentWallpaper 1`}" (source: http://briancarper.net/2006/08/25/transparent-conky-in-kde-part-2/ )