<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Advogato blog for henrique</title>
    <link>http://www.advogato.org/person/henrique/</link>
    <description>Advogato blog for henrique</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Sat, 30 Aug 2008 14:59:03 GMT</pubDate>
    <item>
      <pubDate>Wed, 13 Aug 2008 00:14:03 GMT</pubDate>
      <title>13 Aug 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=6</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=6</guid>
      <description>&lt;b&gt;Please, don't be a &lt;big&gt;WANNABE!&lt;/big&gt;&lt;/b&gt;&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; I'm working a lot and I'm very tired, but no, it is not completely &#xD;
related &#xD;
to the &#xD;
work itself, but to the people I have to work together... these people should &#xD;
stop relying on its crap courses or background at university, nobody is better &#xD;
than anyone just because the clothes that she/he is using or because the SUN &#xD;
certification that was paid by him/her in the last summer (IMO these are the &#xD;
same thing, you are free to disagree however :)&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; Certifications are &lt;b&gt;CRAP&lt;/b&gt;, in the sense that it is used to &#xD;
call &#xD;
yourself &#xD;
a good &#xD;
engineer or developer. You can be good without certification or you can be a &#xD;
total shit with it... you must &lt;big&gt;die with fire&lt;/big&gt; if you think you are &#xD;
good just because the certification... &lt;i&gt;no pain, no gain&lt;/i&gt; bitch, there is &#xD;
no miracle.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; OK, this post can be as bored as the people I'm describing, but it is &#xD;
good to &#xD;
write about this now, so I can understand better why I leaved the work or the &#xD;
reason why I fired someone or then the reason why I kicked somebody ass.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; Anyway, the guys behind the projects BRisa, easy and pluthon &#xD;
rocks! Thank you &#xD;
guys for the introduction in these projects.&#xD;
&#xD;
</description>
    </item>
    <item>
      <pubDate>Sat, 7 Jun 2008 00:08:27 GMT</pubDate>
      <title>7 Jun 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=5</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=5</guid>
      <description>Lets say you work on a company which has an employee&#xD;
working at home 'cause currently he is not at company's city&#xD;
(and will note be for the next 2 months). That's all fine,&#xD;
but it got complicated to ask the "sysadmin" to give him&#xD;
access to our server, his response takes so long and even&#xD;
this way the response propably will be a "no-no, sorry".&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; Well, at least some things got available to our&#xD;
employee and&#xD;
he can do its work.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; It is raining and it is cold in the city and another&#xD;
employee would like to work at home; asking the sysadmin for&#xD;
access is not an option, so this employee explains the other&#xD;
employee that there is an option if he agrees to give access&#xD;
to your machine through SSH, so he could try some port&#xD;
forwarding through SSH and access the servers freely.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; The slack employee then runs the following command&#xD;
on your&#xD;
machine:&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;code&gt;&#xD;
ssh -L 8888:XXX.XXX.XXX.XXX:YYY&#xD;
slackuser@ofirst_employee_host -N&#xD;
&lt;/code&gt;&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; Where &lt;cite&gt;XXX.XXX.XXX.XXX&lt;/cite&gt; is the IP address of&#xD;
the company's server you want to access, the "8888" is the&#xD;
port number at your machine which you access the company's&#xD;
services (you access the services through&#xD;
&lt;cite&gt;localhost:8888&lt;/cite&gt; and it will be forwarded&#xD;
to &lt;cite&gt;"XXX.XXX.XXX.XXX:YYY"&lt;/cite&gt;) and &lt;cite&gt;YYY&lt;/cite&gt;,&#xD;
obviously, is the port. With that, you can access the&#xD;
services at&#xD;
company normally (actually, it should be a pretty slow, but&#xD;
it is better than rain and cold).&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; (For reference and pictures, please visit &lt;a href="http://www.linuxhorizon.ro/ssh-tunnel.html" &gt;this site&lt;/a&gt;)&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; All the story was just to put that tip in a context, the&#xD;
slack employee will be at the office in the next monday :) &#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; So long!&#xD;
</description>
    </item>
    <item>
      <pubDate>Thu, 5 Jun 2008 00:09:35 GMT</pubDate>
      <title>5 Jun 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=4</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=4</guid>
      <description>Currently it is being hard to find a good job. About one&#xD;
month ago I went to a new company to work with smart people&#xD;
and interesting projects, but life is strange and no much&#xD;
time was required to make me think about the future and if I&#xD;
really had make the right choice...&#xD;
&#xD;
&lt;p&gt; There are some things that I consider essential to classify&#xD;
a good job. First, the most important, is how interesting is&#xD;
the project to develop... that is very important, even if&#xD;
the needed tools are not the ones you use every day and&#xD;
"want to use forever". Currently, there are tools for&#xD;
everything (or almost everything) you need to do, so you can&#xD;
just "join the points" and start appreciating the system to&#xD;
work, i.e, your own design.&#xD;
&#xD;
&lt;p&gt; Second, and this may sounds strange, is the language (or&#xD;
tool) used to develop. If the project is not very good,&#xD;
there is a chance that you enjoy the development, since you&#xD;
are improving your knowledge on the language that you like&#xD;
to write (or being in contact with new tools you didn't&#xD;
known before)...&#xD;
&#xD;
&lt;p&gt; If neither the project nor the tool are good, well.. you can&#xD;
talk to colleagues and see what they think about the&#xD;
projects and if there is some possibility to change the way&#xD;
things are done; if it doesn't work, something is wrong and&#xD;
it can be you!&#xD;
&#xD;
&lt;p&gt; ...or it can be the company, in both cases it is worth to&#xD;
try finding a new job. That is exactly what I'm going to do&#xD;
now and I think this time things will be better; the project&#xD;
is good and the language is "perfect", but the people are&#xD;
not that good... (should I write about this combination later?)&#xD;
</description>
    </item>
    <item>
      <pubDate>Sat, 29 Mar 2008 00:54:25 GMT</pubDate>
      <title>29 Mar 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=3</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=3</guid>
      <description>Well, finally we have found a way to get the accounts for a&#xD;
contact on maemo.  We need this to be able to identify the&#xD;
contact which the user has called through "Internet Call".&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; As you may have read in the post about "watching for&#xD;
calls&#xD;
through telepathy", you can have noted that all the contact&#xD;
information available was just an URI, kind of&#xD;
"sip:1234@192.168.1.55". However, this info is only enough&#xD;
to supply a way to search for contacts which has this URI as&#xD;
account "specification".&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; So the question over this week was: &lt;b&gt;How maemo&#xD;
store the&#xD;
accounts available for a contact?&lt;/b&gt;. Basically, how do you&#xD;
can get the list of accounts by which you can make a&#xD;
conversation with the contact?&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; We've looked at the APIs available (ebook, abook,&#xD;
mission-control, ...) and nothing seemed to supply the&#xD;
list... so I went to the database file and the first attempt&#xD;
was to try open it and investigate tables structure or&#xD;
something similar that could give me some information. No&#xD;
way there, the db is a Berkeley DB and there is no python&#xD;
modules to manage this kind of database (python for maemo&#xD;
seems to have removed this standard module of the&#xD;
distribution) and I wasn't disposed to try it in C (to work&#xD;
with a "mysterious" DB &lt;b&gt;in C&lt;/b&gt; was not the kind of fun&#xD;
that I would like to play at the moment, at least with&#xD;
python this could be a bit easier).&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Then I had the idea to try get the VCARD info for a&#xD;
contact&#xD;
and... WELL, the information was there. One thing that I&#xD;
forgot to say is that through the APIs I could get each&#xD;
information (named "fields" there) for the contact (first&#xD;
name, last name, email and so forth), but the accounts&#xD;
wasn't available through "fields", since you can have an&#xD;
variable number of accounts and the function to get a&#xD;
contact field expects a well defined constant (note, the&#xD;
"vcard" &lt;b&gt;is&lt;/b&gt; a "well defined constant").&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Through the vcard, you get things like:&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;pre&gt;&#xD;
X-SIP;X-OSSO-BOUND:your-account-on-device@host:the-contact-account@host&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; The "X-SIP" value is the user account which the&#xD;
&lt;b&gt;contact&lt;/b&gt; account is mapped to. For example: I've two&#xD;
accounts on the device: gtalk and SIP. I've the contact X&#xD;
which I can talk through gtalk, the contact Y I can talk &#xD;
through gtalk and SIP... so you need a way to say what is&#xD;
the &lt;b&gt;user&lt;/b&gt; account the &lt;b&gt;contact&lt;/b&gt; account is&#xD;
bounded to (in the example, for the contact Y you could ask&#xD;
if his account is a "gtalk" or "sip" account), it servers as&#xD;
an "account type" identifier.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Given this, you can now map your "sip uri" available&#xD;
through&#xD;
the "calls watcher" to a real contact on the system. If you&#xD;
can do this, you can get all the other contact info, like the&#xD;
general ones available on most of the softwares (like name,&#xD;
email, web address, phone and &lt;b&gt;another ways&lt;/b&gt; to contact&#xD;
the same person :)&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Also note that there is a python package for vcard&#xD;
management, it is named vobject and is available on &lt;a href="http://vobject.skyhouseconsulting.com/" &gt;the project&#xD;
page&lt;/a&gt;&#xD;
 and &lt;a href="http://pypi.python.org/pypi/vobject" &gt;Python&#xD;
Package&#xD;
Index (Pypi)&lt;/a&gt;.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Hope this information can help some people having to&#xD;
do this&#xD;
 kind of interaction with maemo's rtcomm.&#xD;
</description>
    </item>
    <item>
      <pubDate>Mon, 24 Mar 2008 23:39:57 GMT</pubDate>
      <title>24 Mar 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=2</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=2</guid>
      <description>&lt;pre&gt;&#xD;
I want something good to die for&#xD;
To make it beautiful to live&#xD;
I want a new mistake&#xD;
Loose is more than hesitate&#xD;
You believe it in your head&#xD;
&lt;p&gt;&#xD;
I can go with the flow&#xD;
Don't say it doesn't matter anymore&#xD;
I can go with the flow&#xD;
You believe it in your head?&#xD;
&lt;p&gt;&#xD;
     - Go with the flow, Queens of the Stone Age&#xD;
&lt;/pre&gt;</description>
    </item>
    <item>
      <pubDate>Fri, 21 Mar 2008 02:55:15 GMT</pubDate>
      <title>21 Mar 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=1</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=1</guid>
      <description>Telepathy rocks, and it rocks a lot! First, let me explain&#xD;
our  problem: we need a way to watch outgoing voip calls on&#xD;
maemo and since maemo is, fortunately, using telepathy for&#xD;
its communication software subsystem (named rtcomm), we&#xD;
finish having to use telepathy to do this job.&#xD;
&#xD;
&lt;p&gt; In the begining, things were obscure, we didn't know the way&#xD;
to follow, but the folks on the telepathy IRC channel&#xD;
(#telepathy @ irc.freenode.net) were &lt;b&gt;very&lt;/b&gt; cool... and so,&#xD;
we got the problem fixed before the expected, this motivated&#xD;
to write about the solution here.&#xD;
&#xD;
&lt;p&gt; The first step was to watch for new connections made to a&#xD;
connection manager, it is quite simple, we just need to&#xD;
connect a callback to the "NewConnection" event, the initial&#xD;
block of code follows:&#xD;
&#xD;
&lt;p&gt; &lt;pre&gt;&#xD;
import dbus&#xD;
bus = dbus.SessionBus()&#xD;
&lt;p&gt;&#xD;
cm = bus.get_object(&#xD;
    "org.freedesktop.Telepathy.ConnectionManager.sofiasip",&#xD;
    "/org/freedesktop/Telepathy/ConnectionManager/sofiasip")&#xD;
iface = dbus.Interface(cm,&#xD;
    "org.freedesktop.Telepathy.ConnectionManager.sofiasip")&#xD;
iface.connect_to_signal("NewConnection", on_new_connection)&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; When a connection is created, we need to watch for new&#xD;
channels being created (which can be read as "a&#xD;
communication channel with some of the contacts was&#xD;
created"), this way:&#xD;
&#xD;
&lt;p&gt; &lt;pre&gt;&#xD;
def on_new_connection(bus_name, object_path, protocol):&#xD;
    conn = bus.get_object(bus_name, object_path)&#xD;
    iface = dbus.Interface(conn,&#xD;
        "org.freedesktop.Telepathy.Connection")&#xD;
    iface.connect_to_signal("NewChannel", on_new_channel)&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; So when a channel is created, you got the channel type, if&#xD;
it is a text conversation, the channel_type parameter would&#xD;
be something like&#xD;
"org.freedesktop.Telepathy.Channel.Type.Text". For our case,&#xD;
we need to filter "streamed-media" conversation, so&#xD;
channel_type must be&#xD;
"org.freedesktop.Telepathy.Channel.Type.StreamedMedia". If&#xD;
it is satisfied, we need then attach a new callback for the&#xD;
"StreamAdded" event -- this callback will be fired when a&#xD;
voice or video data transfer has began.&#xD;
&#xD;
&lt;p&gt; &lt;pre&gt;&#xD;
def on_new_channel(object_path, channel_type, handle_type,&#xD;
                   handle, supress_handler):&#xD;
    if channel_type.split(".")[-1] == "StreamedMedia":&#xD;
        channel = bus.get_object(conn.bus_name, object_path)&#xD;
        iface = dbus.Interface(channel, channel_type)&#xD;
        iface.connect_to_signal("StreamAdded",&#xD;
                                on_stream_added)&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; Finally, on &lt;code&gt;on_stream_added&lt;/code&gt; callback, we filter&#xD;
out voice channels, and get the person the user is trying to&#xD;
speak with:&#xD;
&#xD;
&lt;p&gt; &lt;pre&gt;&#xD;
def on_stream_added(stream_id, contact_handle, stream_type):&#xD;
    # discard video channels&#xD;
    if stream_type == 1:&#xD;
        return&#xD;
    iface = dbus.Interface(conn,&#xD;
        "org.freedesktop.Telepathy.Connection")&#xD;
    contact_data = iface.InspectHandles(1, [contact_handle])&#xD;
    uri = filter(lambda d: d.startswith("sip"),&#xD;
                 contact_data[0].split(";"))[0]&#xD;
    print "new call: %s" % uri&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; Shazam! It works! There is two things to note, though. If&#xD;
you just copy-and-paste the code, it'll not work -- as you&#xD;
can have noticed, some callbacks needs the connection&#xD;
object... you have two choices here: to use lambdas to proxy&#xD;
the real handler passing the connection object among all the&#xD;
handlers until &lt;code&gt;on_stream_added&lt;/code&gt; or you can&#xD;
encapsulate all these handlers in a class and define the&#xD;
connection object as an attribute of it, it is up to you.&#xD;
&#xD;
&lt;p&gt; The other thing is that it can seem not too simple as&#xD;
&lt;code&gt;watch_for_voip_connections()&lt;/code&gt;, but you must to&#xD;
note that telepathy doesn't have something specific to do&#xD;
what we needed here, but even in this case the framework&#xD;
seems to be so well designed that it gives to you the power&#xD;
needed to do your work.&#xD;
&#xD;
&lt;p&gt; I loved telepathy since the moment I start working with it,&#xD;
and I expect to contribute with the project as soon as&#xD;
possible. Hope you like it too :)&#xD;
</description>
    </item>
    <item>
      <pubDate>Wed, 5 Mar 2008 02:30:25 GMT</pubDate>
      <title>5 Mar 2008</title>
      <link>http://www.advogato.org/person/henrique/diary.html?start=0</link>
      <guid>http://www.advogato.org/person/henrique/diary.html?start=0</guid>
      <description>I was implementing a distutils' setup script when I got a&#xD;
problem to define permissions to the so called data files.&#xD;
As I hadn't found anything in the documentation about this,&#xD;
the remaining alternative was to look at the source code (in&#xD;
distutils.command.install_data and distutils.cmd modules) to&#xD;
see how these things were expected to work.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; For my surprise, permissions seemed not to be&#xD;
supported by&#xD;
distutils and all data files always were being installed in&#xD;
a non-restricted mode, i.e, 0777. So good, this liberal mode&#xD;
could be my solution, although I don't like the idea to be&#xD;
so limited in this way.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; So the question was: although the mode 0777 was&#xD;
being used&#xD;
as default, the data files still being wrote with mode 0755&#xD;
(actually, it depends on the umask of the user running the&#xD;
installer)... then, my last attempt was to look in depth to&#xD;
the remaining related modules and I found out that distutils&#xD;
implements its own "makedirs" on distutils.dir_utils.mkpath&#xD;
module and this function was ignoring completely its "mode"&#xD;
parameter (the one which defaults to 0777)! Finally I've&#xD;
found the culprit. I moved ahead and create a patch and&#xD;
report an issue on python's bug tracking system:&#xD;
&lt;a href="http://bugs.python.org/issue2236" &gt;http://bugs.python.org/issue2236&lt;/a&gt;.&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Hmm, but the problem hadn't been fixed, even&#xD;
with mkpath&#xD;
using its mode parameter now, the files/directories were&#xD;
still being save with modes other than 0777; but the problem&#xD;
here is more complicated, it seems it is related to how&#xD;
python is using the mkdir system call: depending on the &#xD;
compiler directives, it doesn't specify the mode parameter&#xD;
to mkdir... I don't known why it is this way and I think we&#xD;
moved too down - the python core developers should have some&#xD;
good reason and it is out of the scope of this post).&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; So I go to the less attractive solution (IMO): to&#xD;
extend the&#xD;
distutils' install_data command. To do this we need to known&#xD;
a bit how the commands are structured and executed. The idea&#xD;
is quite simple, every distutils' command is a python module&#xD;
available through distutils.command dir. In this directory,&#xD;
there is a module for each command, and each module has a&#xD;
class with the same name, so we do:&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;pre&gt;&#xD;
from distutils.commands.install_data import install_data&#xD;
&lt;p&gt; class MyInstallData(install_data):&#xD;
    pass&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; Each class must implement a method run(), which is&#xD;
the place&#xD;
to look to see how the command does its work. For the&#xD;
install_data command, the operations are closed to copy&#xD;
files and create directories (through copy_file() and&#xD;
mkpath() methods of the Command superclass). The mkpath()&#xD;
was the problem, so it is what needs to be extended:&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;p&gt; &lt;pre&gt;&#xD;
class MyInstallData(install_data):&#xD;
    def mkpath(self, name, mode=0777, verbose=0, dry_run=0):&#xD;
        rv = Command.mkpath(self, name, mode, verbose, dry_run)&#xD;
        os.chmod(name, mode) &#xD;
        return rv&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;p&gt; When a path is created, I force the chmod to fix the&#xD;
permissions. Problem fixed. Not so good solution, but "it&#xD;
works" (tm). Ah! to use our custom install_data command with&#xD;
setup, we just specify the cmdclass parameter:&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; &lt;pre&gt;&#xD;
setup(&#xD;
    name="package name",&#xD;
    author="foo",&#xD;
    ...&#xD;
    cmdclass={"install_data": MyInstallData,}&#xD;
)&#xD;
&lt;/pre&gt;&#xD;
&#xD;
&lt;p&gt; &lt;p&gt; that's it.&#xD;
</description>
    </item>
  </channel>
</rss>
