April 2005
Monthly Archive
Tue 26 Apr 2005
I finally booked my flight and saved a bit of money by having a 12 hour layover in London ($714 for the round trip from Boston). The cool thing is my flight arives in Heathrow at 8:30pm which gives me time to catch the 15 minute train ride into Paddington station where I can stash my luggage, go around London and finally park my keaster at some all night club if I can find one on a Thursday night (any ideas?) and catch the tube back some time after 5:00, preferably after I have had a propper helping of bangers and mash or a full english breakfast. My flight leaves at 8:00am on Friday for Stuttgart.
This all reminds me of my last semester of College spent running around London (and Europe) while trying to pack in as much fun as I could in a weekend on a budget. If anyone hasn’t gotten their tickets yet or will be in London at the same time and wants to come out for the fun drop me a line I will see if we can meet up.
What a great way to kick off what I am sure will be a productive conference.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Mon 25 Apr 2005
I have just released dbus-0.33 which include my update to the Python bindings. There is still a lot to be done in them but now everything else can remain behind the scenes as the API should remain stable baring anything I have forgotten. I perticularly like the clean soltuion to implementing the Introspectable interface:
class Object:
"""A base class for exporting your own Objects across the Bus.
Just inherit from Object and provide a list of methods to share
across the Bus. These will appear as member functions of your
ServiceObject.
"""
__metaclass__ = ObjectType
def __init__(self, object_path, service):
self._object_path = object_path
self._service = service
self._bus = service.get_bus()
self._connection = self._bus.get_connection()
self._connection.register_object_path(object_path, self._unregister_cb, self._message_cb)
def _unregister_cb(self, connection):
print ('Unregister')
def _message_cb(self, connection, message):
target_method_name = message.get_member()
target_methods = self._dbus_method_vtable[target_method_name]
args = message.get_args_list()
reply = _dispatch_dbus_method_call(target_methods, self, args, message)
self._connection.send(reply)
@method('org.freedesktop.DBus.Introspectable')
def Introspect(self):
reflection_data = '<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">n'
reflection_data = reflection_data + '<node name="%s">n'%(self._object_path)
reflection_data = reflection_data + self._dbus_reflection_data
reflection_data = reflection_data + '</node>n'
return reflection_data
Since every dbus object will inherit from the dbus.Object class, it will automaticly get the org.freedesktop.DBus.Introspectable interface without any fear of namespace clashing. Most of the reflection magic happens in the ObjectType metaclass and the method and signal decorators.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Mon 25 Apr 2005
I find myself in another season of aggressive inline skating and I think to myself, am I getting to old for this? I definitely am a lot less balanced than I used to be though I am in better shape than I have ever been (sans the time I was hiking for two months out in Colorado).
My feet hate me every time I land a jump but I think this was always true, just that I didn’t notice it as much back when. I think it is the thought that if I break a hand or wrist or god forbid my head I won’t be able to do my other passions in life. I still prefer not to wear pads though I keep them in my trunk on the off chance I end up at a skate park that requires them.
I’m not even part of the scene anymore. I used to watch the videos, salivate over the new tech coming out and even hang with some of the pros. Once in awhile I will peruse the message boards to see what is happening.
But there is something that keeps me coming back year after year. It may be a lonely sport but there is a feeling of freedom when hitting a trick. I’ll never be dropping two or three stories into a quarter pipe like some of the pros do. I’ll never be able to do anything more that an allyoop spin into a grind but I still can do a Lu Kang and Flying Fish with style. Besides, I skated pretty well today and that is all the incentive I need to keep playing.
This all brings me to some advocacy I want to do. You see I don’t do street skating anymore because well, the thought of running from cops for skating on public property doesn’t appeal to me these days. I stick to mostly parks. Well the parks in the Boston area mostly suck but there is a project to create a huge one in downtown Boston. The Charles River Conservancy Skatepark Project has already raised $641,153 but the building costs have been estimated at around $2 million dollors. Donations are needed and the cool thing is that according to the web site an anonymous donor has pledged to quadrupal any donation made by a skater or biker (which I assume to meen anyone donating directly to the skatepark and not just the Conservancy).
I know there are a few skaters in the Linux community who might be interested. I have even talk to a couple of inliners who use Fedora on their servers at school. Even if you are not a skater but live in the area, studies have been done on the effect that skate parks have and by in large they have shown to have a possitive effect on the community. I know I will be donating some money and perhaps some time to the effort. Even if it gets done after I have decided to hang up my skates for good at least it will be there for others to enjoy.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Sat 23 Apr 2005
Since the whole Just Works namespace is getting polluted with Linux ,Gnome, Apple, and now Microsoft wanting to get into the action I thought we should start thinking of better mantras. In the spirit of my ever more cynical outlook of things not being interesting until they are no longer exciting (because thats when the real fun starts), I present my entry:
GNOME: Software to let you get on with your life
or
GNOME: Stop computing and start doing
Perhaps there should be a contest. I don’t know. All I know is we are a much more creative group than what Just Works(tm) implies. So lets see those ideas posted to your blogs or as comments on mine.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Fri 22 Apr 2005
Posted by J5 under
Gnome ,
LinuxNo Comments
The bindings are almost to the point I where I want to commit them. Methods took me a bit to get right and I want to start moving some of the code from the helper function to the decorator itself. After figuring out the details of decorators I was able to whip up the signal stuff in five minutes at the end of the day. I need to get this stuff working with hal_device_manager and then I can commit. I can even implement the Introspection interface fairly quickly I think. Marshling with introspection data will take a bit longer but that is all internal stuff that developers don’t need to worry about.
The biggest problem right now is a bug in DBus which does not send messages over the bus if they have a NULL interface. For some reason this works fine with the org.freedesktop.DBus service but with every other service method calls just hang until they time out.
Here is the test class I have been using for your viewing pleasure:
import dbus
import gtk
class SomeObject(dbus.Object):
def __init__(self, service):
dbus.Object.__init__(self, '/SomeObject', service)
@dbus.method('org.designfu.SampleInterface')
def HelloWorld(self, hello_message):
print (str(hello_message))
return ['Hello', ' from example-service.py']
@dbus.method('org.designfu.SampleInterface')
def GetDict(self):
return {'first': 'Hello Dict', 'second': ' from example-service.py'}
class SomeInheritedObject(SomeObject):
@dbus.method('org.designfu.SampleInterface.Tuple')
def HelloWorld(self):
return ('Hello Tuple', ' from example-service.py')
@dbus.signal('org.designfu.SignalInterface')
def HelloSignal(self, msg):
pass
session_bus = dbus.SessionBus()
service = dbus.Service('org.designfu.SampleService', bus=session_bus)
object = SomeInheritedObject(service)
#emit the signal
object.HelloSignal("Well hello")
gtk.main()
And the test client:
import dbus
import gtk
bus = dbus.SessionBus()
sys_bus = dbus.SystemBus()
remote_object = bus.get_object('org.designfu.SampleService', '/SomeObject')
iface = dbus.Interface(remote_object, 'org.designfu.SampleInterface.Tuple')
dbus_obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
hal_obj = sys_bus.get_object('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
#this will timeout if we don't give it an interface
drives = hal_obj.FindDeviceByCapability('storage.cdrom', dbus_interface='org.freedesktop.Hal.Manager')
print str(drives)
#this will succeed even without the interface
print dbus_obj.ListNames()
def do_print(value):
print str(value)
def do_error(e):
print str(e)
hello_reply_tuple = iface.HelloWorld(reply_handler=do_print, error_handler=do_error)
hello_reply_list = remote_object.HelloWorld('Hello from example-client.py!', reply_handler=do_print, error_handler=do_error, dbus_interface='org.designfu.SampleInterface')
#this times out because of the bug
hello_reply_dict = remote_object.GetDict(reply_handler=do_print, error_handler=do_error)
gtk.main()
I know the examples were there just to test what I was writting and arn’t in the nicest form. Rest assured when I am done I will have a bunch of useful realworld examples for people to learn from. I am hoping to get the bindings to the point where writting dbus services and clients is a pleasurable experience. I know my work on these bindings have brought me back to my hacking roots where learning little tricks and solving problems in a clever way is almost like a game. It brings back the wonder and fun that got me into programming in the first place.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Thu 21 Apr 2005
Posted by J5 under
Gnome ,
Linux[4] Comments
Another thing I really like about python is the fact that the Gnome community has a wealth of brain power on the subject. I got a lot of good feedback from James and Johan and have been able to whip up a test case to brainstorm on how I am going to implement the methods and signal piece of the bindings. If anyone has any comments on ways I could do this stuff better please chime in. Here is the prototype:
class meta(type):
def __init__(cls, name, bases, dct):
print 'Init is called: ' + str(cls) + str(name) + str(bases) + str(dct)
method_list = []
for func in dct.values():
try:
method_name = func._dbus_method_name()
method_list.append(method_name)
except:
pass
print method_list
super(meta, cls).__init__(name, bases, dct)
def method(func):
def decorator(self, *args):
func(self, *args)
def _dbus_method_name():
return func.__name__
decorator._dbus_method_name = _dbus_method_name
return decorator
class bar:
__metaclass__ = meta
@method
def my_method(self):
print 'my_method'
x = bar()
x.my_method()
Ok so my main concerns is using the try/except block at top. While this works, is it cleaner to check for the _dbus_method_name member or is relying on the exception acceptibly pythonic? I could also just make it a property of the decorator object thereby avoiding the method call.
Perhaps I should explain what we are looking at here. I have created a method decorator that is used to tag methods as being exported. In that decorator I add a method that I can call on later to make a list of exported methods. At the top is a metaclass whoes purpose is to check all the decorators in classes that inherit from this metaclass. Upon the class bar being realized and its __metaclass__ being set to meta, the metaclass’ __init__ method gets called (__new__ gets called first but I don’t use it here). bar’s member dictionarty gets passed to init which we iterate over the values of. Upon finding an object with the member _dbus_method_name we add that to the list of exported methods. If this were the real bindings we would then attach this this as an attribute of the class which would then be used to bind the methods on the bus when the class is instantiated. The advantage here is that we don’t need to introspect every time an object is created but only when the class is first realized.
In the actual bindings I will be putting together a hash that points the interface and method objects so that we can have methods that overide each other. The code will also construct the dbus xml introspection format so that we can support the Introspectable interface. All of this will be hiddent to the user with the exception of having to use the @dbus.method and @dbus.signal decorators. It really is a nice solution.
As far as the backend structure goes I will be creating a dbus.MetaObject class which dbus.Object will use as its metaclass. The dbus.Object itself will use the decorators to implement DBus’ standard interfaces. Inheritting from dbus.Object will work almost the same way it does now except that one would use the decorators instead of the list in the constructor to export methods. I’m still debating if I should create class decorators for specifying classpaths or just leave it as is where we pass them into the constructor of dbus.Object. I don’t want to go overboard and make everything into a decorator even if I think they are pretty cool.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Wed 20 Apr 2005
Posted by J5 under
Gnome ,
Linux[2] Comments
So Johan Dahlin, PyGTK maintainer and Python guru extraordinaire, pointed me to some nice ideas for implementing the DBus bindings. While I didn’t quite like Twisted’s deffered stuff it did get me looking into some of the newer features of Python. After talking with Ray Strode I am thinking of doing things like this using decorators:
class my_object(dbus.Object):
@dbus_method('com.martianrock.MyInterface')
def my_exported_method(self, arg1, arg2, etc):
return 'you've called a method'
@dbus_signal('com.martianrock.MyInterface')
def my_exported_signal(self, arg1, arg2, etc):
pre_process()
emit()
post_process()
I don’t have a huge handle on decorators yet so I don’t know if the above is completely implementable but the idea is to decorate methods and signals one wants to export over the bus instead of passing in a list, as is done now, or register each member in the constructor.
The signal case is interesting because signals are emitted and not caught within a dbus.Object. The idea is the exported signal method is the emitter. In order to emit a signal the object just needs to call this method with the correct number of arguments it wants to send in the signal. Arbitrary code can be executed before and after the signal is emitted. An emit() function will be created local to the scope of the decorated method which does the actuall emittion. If no emit is called the signal is automaticly emitted at the end of the method. Again I don’t know if any of this is possible with decorators but it would be cool.
Another possible use of decorators is to use them to specify return types for methods and argument types for both methods and signals. Of course that would all be depricated once Python implement a more formal way to specify types.
P.S. To all you Ruby fans out there who are itching to post comments every time somone mentions the word Python, DON’T. XYZ language does it better this way, is just noise to me. I’m talking about DBus and Python and am not in the mood to start a language war. If I ever flame Ruby or XYZ flavor of the month project feel free to comment and flame back. I’m sure Ruby is a great language in its own right but it is way off topic here.
UPDATE: Ray just reminded me that signal emission is async and only happens when you go back to the main loop, so having an emit() call so you can do pre and post processing is useless. So now signals will be emitted after the decorated method returns.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Tue 19 Apr 2005
Because you solve problems like this cleanly:
def print_list(list):
print 'Here is your async list:'
print list
def async_error_handler(e):
print 'There was an async error:'
print e
obj.ListNames(reply_handler=print_list, error_handler=async_error_handler)
But where is the API for user data? How can I pass in variables I need to work on without making them global? Your API sucks because handlers are useless without external data!!!
class test:
def __init__(self, user_data):
self._user_data = user_data
obj.ListNames(reply_handler=self.print_list, error_handler=self.async_error_handler)
def print_list(self, list):
print self._user_data
print 'Here is your async list:'
print list
def async_error_handler(self, e):
print self._user_data
print 'There was an async error:'
print e
test('I can now work on userdata')
While this is not unique to python the ability to pass in methods that retain a refrence to an instance of their class means no added binding code for passing in user data. It just flows better when one can use a languages own constructs to obtain the desired functionality instead of each binding writter figuring out how to do it themselves. There are other ways to do this too in python but I won’t go into those.
I also like the whole keyword design. Without keywords it would have been harder or at least a bit more ugly for us to support async calling. API would have had to been added to register callbacks on individual methods. With keywords I was able to add what seems like extra parameters to the DBus calls making it cleaner in my opinion. Since DBus doesn’t support keywords as arguments there is no worries of clashes. I still have to worry about possible future namespace clashing with python itself (which is why we use dbus_interface instead of just interface) but I have a feeling it will not pose a problem.
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Tue 19 Apr 2005
Posted by J5 under
Gnome ,
LinuxNo Comments
I started on the rewrite of the python bindings this weekend. Well it is not a total rewrite since I am using the old code as a basis and just changing the interface quite a bit. I think once things are done the code is going to be a lot cleaner and using it will be a lot more fluid (though it is currently easy to use already). I’ve gotten rid of some useless objects to make the binding of dbus object a bit more terse and I have also implemented the dbus.Interface object as well as defaulting to no interfaces for default objects. A big change has been the addition of async calls to the highlevel API. My next step is to implement the Introspectable interface so that objects can export introspection data. Then it is off to parsing the introspection data so that clients can send data in the correct format and provide documentation of the interfaces. I also need to get together with David and add back some of the functionality I initially chopped like ObjectTree. None of this is in CVS yet since I want to finish it up before I commit. Rest assured there has been a version tuple added so programmers can do checks in their code. The initial release will point dbus.version to (0, 40, 0). In the meantime here is some test code to give you an idea of what it will be like working with the new API’s:
import dbus
import gtk
bus = dbus.Bus.get_system()
#bind the /org/freedesktop/DBus from the org.freedesktop.DBus service name
#this object does not have an interface so all methods are available
obj = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus')
#wrap the object in the org.freedesktop.DBus interface
#only methods from this interface are available
iface = dbus.Interface(obj, 'org.freedesktop.DBus')
#call ListNames on the org.freedesktop.DBus interface
print iface.ListNames()
#switch to the org.freedesktop.DBus interface for this call only
print obj.ListNames(dbus_interface='org.freedesktop.DBus')
#call ListNames on the object without an interface
#if two interfaces both implement ListNames the behavior is undefined
print obj.ListNames()
#examples of calls being made wich takes arguments
#in these cases the org.freedesktop.DBus name is being passed in
print iface.NameHasOwner('org.freedesktop.DBus')
#see you can still use the built in keywords even when passing arguments
print obj.NameHasOwner('org.freedesktop.DBus', dbus_interface='org.freedesktop.DBus')
#define a couple of callbacks
def print_list(list):
print 'Here is your async reply:'
print list
def async_error_handler(e):
print 'There was an async error:'
print e
#examples of async calls
#these should succeed
obj.ListNames(reply_handler=print_list, error_handler=async_error_handler)
obj.ListNames(reply_handler=print_list, error_handler=async_error_handler, dbus_interface='org.freedesktop.DBus')
#this will error out
obj.Fail(reply_handler=print_list, error_handler=async_error_handler)
gtk.main()
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Sun 10 Apr 2005
The party last night was a huge success. Thanks to all those who came. Props go out to Ray, Moe and Stef who brought a blender and a couple of drink shakers, Dan Willams for his Cran/Rasberry drink, Ed for his Lime Death drink, Diana for her Jello shots and Chris for bringing the Courvoisier. And though I haven’t tasted it yet I have to give props to Abby for bringing the Goats do Roam wine.
The party started at 8:00 but got into full swing around 10:00. It didn’t end until around 4:00 in the morning when I passed out. There was a constant stream of people coming and going and most of the party was centered in the kitchen next to the alcohol which ment people were having a good time. The floors did turn into sticky mess in there but the rest of the apartment stayed remarkably clean. We had a few people come back at 11:00am the next morning for breakfast.
I was busy being a host and getting drunk all night but I did manage to get a few pictures:
We had quite a bit of alcohol


Some people enjoyed the living room away from the hussle and bussle



Others enjoyed the kitchen




Peter enjoyed yoga

Breakfast was also served


And now we have a stocked bar

–
J5
[read this post in:
ar de es fr it ja ko pt ru zh-CN ]
Next Page »