Thiago Bellini's homepage Free software development, Open source software, Linux – by Thiago Bellini

28Mar/120

Gnome-shell Notifications Alert Extension

If there is anything that I dislike on gnome-shell are the notifications...wait, not the notifications itself, I really like the whole bottom hot corner concept and stuff. But it's very easy for me, specially at my work that I use dual monitors, to miss an im message that way.

I then started to search for a shell extension that provides something to alert me of the existence of an unread notification. I found the Pidgin Persistent Notification's concept very good and decided to try to do a generic one (since it's pidgin specific). This is the result:

2ce634507b438acb5c35a3d40adf4e08 Gnome shell Notifications Alert Extension

Without unread notifications / With unread notifications

It supports any shell version >= 3.2. You can download it on extensions.gnome at the link: Gnome-Shell Notifications Alert

The source code is on github <https://github.com/hackedbellini/Gnome-Shell-Notifications-Alert> and licensed at GPLv2. Fell free to fork it! Just don't forget to send me a pull request, so I can merge your improvements into the official code ;D

10Aug/112

Writing asynchronous Python code with Twisted using inlineCallbacks

A few weeks ago, I started using Twisted for developing a plugin for synchronization between Stoq and Magento.

Twisted is really a great tool, and it makes it very easy to write asynchronous code. The only problem is that your code has a high probability of becoming Spaghetti code icon razz Writing asynchronous Python code with Twisted using inlineCallbacks . And anyone who knows me knows that I'm crazy when it comes to code organization.

Well, those days, specially after a hint by a work mate, Johan Dahlin, I started to take a look on inlineCallbacks decorator. It's just beautiful and solve all my problems icon smile Writing asynchronous Python code with Twisted using inlineCallbacks .

Since I found the documentation a lot hard to understand, and little examples on the web, I decided to try to make one of my own. Hope you will enjoy!

Now, consider the following piece of code (utilizing the classic Twisted way):

from twisted.internet import reactor
 
def on_failure(err):
    print "Error:", err
    reactor.stop()
 
def on_success(*args):
    print "Success. Shutting down"
    reactor.stop()
 
def print_file(file_):
    d = async_print_file(file_) # This will return a Deferred
 
    d.addCallback(on_success)
    d.addErrback(on_failure)
 
def get_file():
    d = async_get_file() # This will return a Deferred
 
    d.addCallback(print_file)
    d.addErrback(on_failure)
 
if __name__ == '__main__':
    get_file()
    reactor.run()

On this example, we want to get a file, print it, and then shutdown the application. Yeah, it's ugly, a little spaghetti (could be a lot more if the code wasn't a simple example)...but it works.

Just for a fast explanation, the async_*() functions are fictitious functions that will return a Deferred. When it's fired, it'll call the function added by addCallback, or, in case of failure, the one added by addErrback. If more than one callback (or errback) is added, when the first one returns, that return value will be passed to the second function, and so on, as a chain of callbacks.

Now, take a look at the following piece of code (utilizing the inlineCallbacks way):

from twisted.internet import defer, reactor
 
@defer.inlineCallbacks
def print_file():
    try:
        file_ = yield async_get_file() # This will return a Deferred
        yield async_print_file(file_)
        print "Success."
    except Exception as err:
        print "Error", err
    finally:
        print "Shutting down"
        reactor.stop()
 
if __name__ == '__main__':
    print_file()
    reactor.run()

Beautiful, isn't it? What does all the magic is the yield statement (without using it, file_ would still be a Deferred)

When the code inside a function decorated by the inlineCallbacks decorator yields a Deferred (in that case, a function that returns a Deferred), the code goes on and the reactor will come back after the Deferred fires. It's return value will be returned on the yield statement, and, if any errors occurred, the exception will be raised (that's why I yielded inside a try/except clause).

Note that, because yield is captured by inlineCallbacks, there's no way to use that function as an iterator generator.

And if we need to call another function decorated by inlineCallbacks? How to get it's return value, as the return statement won't work? Well, that's why there is a function called returnValue. Take a look at the following piece of code:

from twisted.internet import defer, reactor
 
@defer.inlineCallbacks
def get_arg():
    retval = yield another_sync_func()
    defer.returnValue(retval)
 
@defer.inlineCallbacks
def print_file():
    try:
        arg = yield get_arg()
    except Exception as err:
        arg = None
 
    try:
        file_ = yield async_get_file(arg)
        yield async_print_file(file_)
        print "Success."
    except Exception as err:
        print "Error", err
    finally:
        print "Shutting down"
        reactor.stop()
 
if __name__ == '__main__':
    print_file()
    reactor.run()

In this example, we assumed that async_get_file neeeded an expecific argument, that needs to be retrieved asynchronous too. By doing returnValue(arg), we make anyone who yields get_arg() to receive arg, or raise an exception if an error occour.

 

A little complicated but, after a while you get used to it! icon wink Writing asynchronous Python code with Twisted using inlineCallbacks

Any doughs?

20Oct/100

A simple script to help with simple “Test Cases”

Just here to share a simple script I wrote to help with some test cases on university.

  • What it does:

1- It takes all ".in" files it finds recursively on the folder and show how much time your algorithm takes to process each one.

2- For each ".in" file, it tries to find another one with the same name but with the ".out" extension. If it finds, it'll diff both that file and the output of the ".in" file and show if your algorithm is correct. If not, it shows the diff.

  • The script:

Download it at: http://gist.github.com/631593. Name it as you wish! (In the explanations bellow I'll assume the default name "TestCases")

  • How to use:

You can put the script anywhere and call it using it's absolute/relative path. If you want to call it just by it's name, make sure it's on your $PATH. To do so, add this to the end of your .bashrc:

export PATH="PATH/TO/SCRIPT":"${PATH}"

Make sure the ".in" and ".out" (if any) files are in the same folder (or in a sub-folder) of the executable you will test. Lets suppose the executable is called "EXECUTABLE" and you are on it's working directory...you can run the script like this:

TestCases EXECUTABLE

Watch the output and enjoy! ;D

The script is a Gist, so, if you want to improve the script, fork it! After you made the changes don't forget to tell me so I can pull your changes.