tag:blogger.com,1999:blog-19220110227822081212024-02-07T17:16:45.829-08:00Core Dump -- Godson Gera's BlogA Web-log on VoIP, CTI, Asterisk, FreeSWITCH & Python in India!Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-1922011022782208121.post-82353584220860824322015-11-22T12:16:00.000-08:002015-11-22T12:16:51.846-08:00Simple example using Jython and JPype<div dir="ltr" style="text-align: left;" trbidi="on">
In this post I am going to show you simple example of getting a random integer using java.util.Random in both JPype and Jython<br />
<br />
<b>Random.nextInt() using JPype : -</b><br />
<b><br /></b>
<b><br /></b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY2ev19cCwfn3mZagRhO8-REOHgvszdZIWoG1OlIoXoYxt6waV4ENVTx2on9oa5fnW8UfYdNgD_3kjcbMYM_r8Z8HR0Jq5iv8AT0DaJP6FG4yhoiMcyBhjAKWi3RhiP0h7N7CUPHatrerd/s1600/jpype.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhY2ev19cCwfn3mZagRhO8-REOHgvszdZIWoG1OlIoXoYxt6waV4ENVTx2on9oa5fnW8UfYdNgD_3kjcbMYM_r8Z8HR0Jq5iv8AT0DaJP6FG4yhoiMcyBhjAKWi3RhiP0h7N7CUPHatrerd/s1600/jpype.JPG" /></a></div>
<b><br /></b>
<b><br /></b>
The startJVM() call is important here. We need to invoke JVM before accessing any java functions. We need to supply java path to startJVM. The convenient function of getDefaultJVMPath() returns the path of default JVM installed on your machine.<br />
<br />
<b>Random.nextInt() using Jython:-</b><br />
<b><br /></b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo15_n8eCf_KELpTQaZ6fQnN-xD8yQtw1hTR-xlg2ohVnbIym2itfsIi3mrnBjjebEAZwRUfWSm2h_NcdHebWILdYBfj71XjcBv_DsueOyKfSEnv3EgHE_4sioywLpVteFrC4OIIWuiBHq/s1600/jython.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjo15_n8eCf_KELpTQaZ6fQnN-xD8yQtw1hTR-xlg2ohVnbIym2itfsIi3mrnBjjebEAZwRUfWSm2h_NcdHebWILdYBfj71XjcBv_DsueOyKfSEnv3EgHE_4sioywLpVteFrC4OIIWuiBHq/s1600/jython.JPG" /></a></div>
<b><br /></b>
<b><br /></b>
Unlike JPype you can import the java module using familiar Python import syntax.<br />
<br />
As shown in the above examples. Both JPype and Jython opens up access to rich set of java libraries to Python world in a simple and easy way. </div>
Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-83898771080629693012015-11-22T12:15:00.004-08:002015-11-22T12:15:53.440-08:00Taking advantage of Java libs using Python<div dir="ltr" style="text-align: left;" trbidi="on">
If you want to take advantage of rich set of java libraries but, without leaving your favorite language Python. You have couple of options.<br />
<br />
1. JPype - <a href="http://jpype.sourceforge.net/">http://jpype.sourceforge.net/</a><br />
2. Jython - <a href="http://www.jython.org/">http://www.jython.org/</a><br />
<br />
Both the above projects allow to call Java code using Python syntax. But, there is distinction how they achieve this.<br />
<br />
<b>How they are implemented ?</b>: -<br />
<br />
JPype is implemented as module in CPython. So all you need to do is install JPype package and you are ready to go. On the other hand Jython is a implementation of Python language syntax using Java. Both, have their advantages.<br />
<br />
<b>Which one should I pick ?</b> : -<br />
<br />
JPype is a suitable candidate if your application depends on lots of other external Python packages that are not available in Jython world. Like, for example you have an application built using PySide/PyQt and you want to call some java functions from within that application. Then, JPype is your best bet. This way JPype offers you best of the both worlds Python and Java.<br />
<br />
If you want to build your application purely using Java libraries but don't want to leave Python syntax , then Jython helps you out here. As Jython is implementation of Python language specification using Java. Often, it tends to lag behind in terms of features/standard library modules available in CPython implementation of Python. Another use of Jython is, if you have pure java application and you want to bring Python scripting features to it. Then, you can use jython.jar to embed in your program. This will help users to extend you program by writing scripts or plugins.<br />
<br />
<br />
<b>Show me the code</b> :-<br />
<br />
A simple helloworld program example is shown in next post - <a href="http://blog.godson.in/2015/11/simple-example-using-jython-and-jpype.html">Simple example using Jython and JPype </a></div>
Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-75877241107967837732013-01-05T03:12:00.000-08:002013-01-05T03:12:22.755-08:00Restore corrupted wubi boot on windows XP<div dir="ltr" style="text-align: left;" trbidi="on">
Problem - Unable to boot ubuntu installed using wubi due to accidental over writes or deletion of boot information required for doing multi boot in windows xp.<br />
<br />
Fix - If you have accidentally erased the boot file ( boot.ini , NTLDR.exe etc .. ) you'll be left with a computer which can't load the operating system that is present on disk. when you start computer if you are getting "NTLDR is missing" message you can fix that by following information that is available here <a href="http://tinyempire.com/notes/ntldrismissing.htm">fixntldr.exe</a><br />
<br />
Once you are able to boot back to your windows XP operating system, you will be able to access the partition where your ubuntu files are present, you have to copy \ubuntu\winboot\wubildr.mbr and wubildr back to C: drive where your boot.ini file is present. And the following line in boot.ini file<br />
<br />
C:\wubildr.mbr="Ubuntu"<br />
<br />
Make sure that there are not more than 10 entries in [operating systems] section of boot.ini file (fixntldr.exe creates 10 default entries in this section but you don't need all of them.) Save boot.ini file and reboot the machine, select ubuntu entry in boot menu to load grub.<br />
<br />
<br />
<br />
<br /></div>
Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-64675032805400629362012-08-07T02:53:00.001-07:002012-08-07T02:53:53.334-07:00How to fix start-stop-daemon: command not found error<div dir="ltr" style="text-align: left;" trbidi="on">
start-stop-daemon is not available in CentOS by default. However, you can easily install it using the following commands.<br />
<br />
<em>wget -c http://cloudman.rumahweb.com/wp-content/uploads/2011/10/dpkg_1.14.31.tar.gz</em><em><br /></em><em><br /></em><em>tar -zxvf dpkg_1.14.31.tar.gz</em><em><br /></em><em>cd dpkg-1.14.31/</em><em><br /></em><em>./configure</em><em><br /></em><em>make</em><em><br /></em><em>cd utils</em><br />
<em>make install</em></div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com1tag:blogger.com,1999:blog-1922011022782208121.post-58508282977576003692012-02-12T00:13:00.000-08:002012-02-12T02:12:36.677-08:00Whitney Houston and Python!<div dir="ltr" style="text-align: left;" trbidi="on">Back in 2004 or 05 (can't remember exactly) I have used "Heart break hotel" song of Whitney to test out the small mp3 music player I have built using Python (<a href="http://legacy.godson.in/downloads/index.htm" target="_blank">g2Dlite and NeverHeard</a>). During testing this song was played out countless times to add features and fix bugs in my program. Apart from this I have never really listened to any of her songs. I was saddened to learn about her death this morning, news reminded me of those special days. </div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-79454309088063917622011-06-17T06:43:00.000-07:002011-06-17T06:44:17.738-07:00Timers in Python<div dir="ltr" style="text-align: left;" trbidi="on">Often in computer programs there would be a requirement to execute a function/task after certain time has passed. And some times this task could be a repetitive one, that needs to be executed again and again after certain interval has elapsed. A simple example is, in VoIP applications a phone is required to send a voice packet every 20 milliseconds. In GUI application a clock needs to be displayed in which updates it self every second displaying time elapsed or current time. For all such cases a timer is best suited tool.<br />
<br />
Python standard library provides a <a href="http://docs.python.org/library/threading.html?highlight=timer#threading.Timer">Timer</a> class that is capable of executing task in single shot mode. However, thats a very basic functionality that a timer could provide. The external GUI and Network frameworks of python provide extensive timers with fancy provisions. I'll provide a list of timer APIs provided by vairous python libraries that I've come across.<br />
<ul style="text-align: left;"><li>after method of Tkinter librarie's mainwindow (ships with standard library on windows, again minimal functionality one) </li>
<li><a href="http://wxpython.org/docs/api/wx.Timer-class.html">wx.Timer</a><span id="goog_251959938"></span><span id="goog_251959939"></span> , <a href="http://wxpython.org/docs/api/wx.CallLater-class.html">wx.CallLater</a> , <a href="http://wxpython.org/docs/api/wx.PyTimer-class.html">wx.PyTimer</a> these are various timers provided by wxPython library. The CallLater and PyTimer are convenience functions built on top of wx.Timer </li>
<li><a href="http://www.pyside.org/docs/pyside/PySide/QtCore/QTimer.html">QTimer</a> is PySide's (PyQt) version of timer functionality. Its neat with various helper functions.</li>
<li><a href="http://twistedmatrix.com/documents/10.0.0/api/twisted.internet.interfaces.IReactorTime.html#callLater">callLater</a> , <a href="http://twistedmatrix.com/documents/10.1.0/api/twisted.internet.task.LoopingCall.html">LoopingCall</a> are the timer APIs provided by the network swiss army knife of python - Twisted library. </li>
</ul>Every asynchronous program comes with a main loop. Which dispatches the events (mouse, keyboard or network events) to target functions. The cardinal rule of such programs is not to block this main loop. Suppose if you block the main loop by calling long running function in your program, the main loop will no longer get a chance to dispatch any pending events until this long running function returns. <a href="http://docs.python.org/library/time.html?highlight=sleep#time.sleep">time.sleep</a>(100) in a function's body would certainly block whole program until those 100 seconds elapse. As a side effect, the program will freeze at that point. If its a GUI program it will no longer respond to user inputs and if its network program it will no longer read underlying sockets until this time.sleep returns. To avoid such awkward situation almost every frame work that comes with a main loop makes a provision for executing tasks at desired time with the help of timer functions. Timer tools are neat and useful. An in depth explanation of the way they are implemented and the problems that they solve will be the subject another post soon. <br />
</div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-54610114257027805432011-06-04T06:11:00.000-07:002011-06-04T06:12:55.564-07:00Pitfalls to avoid while using mod_xml_curl of FreeSWITCH<div dir="ltr" style="text-align: left;" trbidi="on">xml_curl is a great module of FreeSWITCH that simplifies user management (configuration management) . This module allows FreeSWITCH to fetch account details from a different server running HTTP service. The basic info of what is xml_curl and how to use it can be found on this <a href="http://wiki.freeswitch.org/wiki/Mod_xml_curl">wiki page of FS</a> . <br />
<br />
Now to the subject matter of this post. Current version of FS sofia profile can be paralyzed severely, if xml_curl is not carefully configured. If a request sent by xml_curl originated out of REGISTER request of some UA is never replied (situations that can trigger this is network issue or a bug in web service ), and connection is kept open like that. Any subsequent REGISTER requests sent by SIP UAs will not be replied back by mod_sofia, thus causing a situation where new SIP UAs can no longer register. To avoid this there is a timeout option in xml_curl's config file. <br />
<br />
<b><param name="timeout" value="10"/></b><br />
<br />
With this option in place it will safe guard FS sofia profile in question from becoming unresponsive. Also, it would be a good practice to use some sort of timeout functionality making sure that connection made by FS is not blocked indefinitely by web app.<br />
The reason this happens is because of the underlying <a href="http://sofia-sip.sourceforge.net/">sofia library</a> used by FS handles only one REGISTER request at a time. Anthony has some plans on enhancing this situation by making xml_curl not to come in way of sofia profiles working.<br />
<br />
Another tip is to use cacheable='true' attribute of user xml returned by web service. This will make FS to maintain a local cache of the account details. The details will stay in cache until cleared. This means that FS won't be hitting your web app for every REGISTER request that hoards of SIP UAs are sending, it will ask only once upon first request. The subsequent requests will be looked up from cache.</div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-56584710215607376502011-01-24T09:53:00.000-08:002011-01-24T09:53:53.880-08:00PySide and the GUI world of Python<div dir="ltr" style="text-align: left;" trbidi="on">For desktop GUI development Python has a long list of options that one can choose from . Here are more popular ones (Tkinter, <a href="http://wxpython.org/">wxPython</a>, <a href="http://www.riverbankcomputing.com/">PyQt</a>, <a href="http://pygtk.org/">PyGTK</a>) and many other infamous ones. Of all these libraries, PyQt a Python binding for Qt has wonderful docs and consitent API rich widget classes. This is mostly due to the licensing model that Qt and PyQt used. These libraries have made very good use of dual licensing, which helped their development. The people behind the libraries got paid thus they made sure that the crossplat-form experience is smooth , API is consistent and docs good.<br />
<br />
But, even with all these goodies, it hasn't seen a great use in opensource consulting arena because of the high price and viral GPL license. After Nokia's acquistion of <a href="http://qt.nokia.com/">Qt</a> situation has changed. Nokia released Qt under less restrictive license (LGPL ) . Which helped many devs looking for this day to go and embrace it. But on python side things were same quite for some time even after Nokia's acquisition of Qt. When Nokia and PyQt's Riverbank has failed to reach an agreement. Nokia has decided go ahead with making its own Python bidings, called <a href="http://pyside.org/">PySide</a>. Last october PySide has made a windows version release. With the PySide project really picking up, it will help more wide spread use of Qt. Nokia being hardware company has very little to loose by opening up Qt to public with less restrictive license. The very same step that Trolltech and Riverbank has restrained from doing because Qt is their bread and butter ! Nokia's decision has nice side effect that now all the python and opensource devs have a wonderful GUI library at their dispose. The sad thing being that Riverbank's PyQt libs will take a hit from the rise of PySide. <br />
</div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com4tag:blogger.com,1999:blog-1922011022782208121.post-43403686394003686682010-12-29T06:38:00.000-08:002010-12-29T06:38:33.030-08:00Inbound,Outbound EventSocket connections the beginner's confusionFor FreeSWITCH beginners and programmers coming from Asterisk world, these two terms Inbound,Outbound are very confusing. For developers who are familiar with Asterisk this is in short<br />
<ul><li>Inbound = AMI</li>
<li>Outbound = FastAGI</li>
</ul>For new comers - Inbound EventSocket connection can be used for controlling FreeSWITCH as a whole, can get information on any existing channel. We need to make these connections with FreeSWITCH from an external program.<br />
<br />
Outbound connections are generally tied up with a single channel, these connections are created by FreeSWITCH, whenever a socket (FastAGI in asterisk) application is encountered in dialplan. Generally meant to execute action on a single channel only and receiving events pertaining to that channel. <br />
<br />
However, FreeSWITCH is very flexible and this behavior can easily be changed as we can choose which Events our program can subscribe to. '<a href="http://wiki.freeswitch.org/wiki/Mod_event_socket#Special_Case_-_.27myevents.27">myevents</a>' command to FreeSWITCH will tie the socket connection to a particular channel. And <a href="http://wiki.freeswitch.org/wiki/Mod_event_socket#event">event</a> command will make the socket connections to receive all FreeSWITCH wide events related to every live channel in FreeSWITCH.<br />
<br />
<br />
These are named so by looking at them from a FreeSWITCH prespective. EventSocket connections that FreeSWITCH accepts are inbound to it and connections that FreeSWITCH makes to an external socket server is outbound to it.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-17825924977699455442010-12-18T10:02:00.000-08:002010-12-18T10:02:29.184-08:00FreeSWITCH EventSocket header lengthPython's email package is very useful for parsing and generating email messages. The messaging format used, is defined in <a href="http://www.faqs.org/rfcs/rfc822.html">RFC822</a> and RFC2822. This similar format is also used for many other protocols ( the one that I work with most often is SIP). FreeSWITCH also uses similar messaging format for communicating with applications over it's <a href="http://wiki.freeswitch.org/wiki/Event_List#Minimum_event_information">EventSocket</a> interface.<br />
<br />
The default python implementation adheres to line length recommendations specified in <a href="http://www.faqs.org/rfcs/rfc2822.html">RFC2822</a> 2.1.1 section so it wraps any header line beyond the length of 78 characters. However, this is bad for FreeSWITCH 1.0.6 as it ignores the wrapped part of the line. One good example is executing <a href="http://wiki.freeswitch.org/wiki/Misc._Dialplan_Tools_play_and_get_digits">play_and_get_digits</a> from EventSocket as it has more number of arguments the argument line length often exceeds 78 chars when all the argument values are provided. And, FreeSWITCH silently ignores the wrapped part of the arguments. To avoid this, you can override the <a href="http://docs.python.org/library/email.message.html#email.message.Message.as_string">as_string()</a> method of email.message.Message and set maxheaderlen=0 in email.generator.Generator() used by Message class. That will disable the line wrapping and your FreeSWITCH applications will work as expected.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-90463005781703112382010-12-15T14:08:00.000-08:002010-12-15T14:12:35.688-08:00Use of return_ring_ready originate variable in FreeSWITCHFreeSWITCH has easy API to originate calls. And this origination can be customized to great extent to meet various needs. By default the originate API command of FreeSWITCH will return only when the media starts flowing in like in the following situations<br />
<ul><li>'183 Session in progress' early media</li>
<li>'200 OK' when the call is answered. </li>
</ul>Different SIP providers have switches that behave differently when it comes to sending back session information. They may send '200 OK ' directly without any 180 codes. Or they may send fake ring back, by immediately sending '180 Ringing' back to FreeSWITCH. As mentioned above originate command only returns a result when origination is failed or when media starts flowing in. Now, if you want to make originate command to return when FreeSWITCH sees '180 Ringing' other end ringing thats when return_ring_ready variable comes in handy. You just need to set this to true during origination so FreeSWITCH returns immediately when it sees 180 saying that origination is successful.<br />
<br />
Why this is important ? There might be situations where you are using a outbound socket application to connect back to the originated call when it succeeds.<br />
<b>originate sofia/gateway/someprovider/919246461929 &socket(127.0.0.1:8082 async full)</b><br />
<br />
By default socket application only gets called when originate returns and originate won't return until it sees 183 or 200.<br />
<br />
<b>originate {return_ring_ready=true}sofia/gateway/someprovider/919246461929 &socket(127.0.0.1:8082 async full)</b><br />
If you execute the above command originate will return immediately and executes the outbound socket connection when it sees '180 Ringing' . This behavior allows you to read the channel information in outbound socket before the call is answered and also will allow you to catch CHANNEL_ANSWER event fired by FreeSWITCH when the other end answers the call(you can start playing your IVR at this point). In the default behavior you can you cannot capture CHANNEL_ANSWER if your SIP provider is sending signaling 200 after 180. As originate only return after it sees '200 OK' by the time your outbound socket gets invoked its too late to capture CHANNEL_ANSWER event. However, return_ring_ready is not required to achieve this if the provider is sending 183 before 200. Most of the SIP providers do send at least one 18X variant signal. So, its safe to have return_ring_ready set to true if you want outbound socket to be invoked before the channel is answered.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-25999734248739967172010-10-20T12:12:00.000-07:002010-10-20T12:12:10.224-07:00Asterisk Vs FreeSWITCH - Channel Tracking UniqueIDIf you have ever used Asterisk's <a href="http://blog.godson.in/2008/10/starpy-100a13-released-asterisk.html">AMI (Asterisk Manager Interface ).</a> You will know the pain of tracking a particular channel, especially when its getting originated or being bridged with some other channel. There is no easy way to do that cause in asterisk the Unique ID of a channel keeps changing over its life span. New Unique IDs are created through out a channel's lifespan when originated one Unique ID and when linked with other channel again a new Unique ID etc etc. All this gives jitters to programmer, and this kind of behaviour clearly shows some design mistakes in Asterisk. <br />
<br />
<br />
Asterisk uses unix timestamp appended by an incremental counter as a channel's uniqueid. <br />
<br />
A sample unique id of a channel used by asterisk - 1268129694.0<br />
<br />
This post is not about talking down Asterisk or any thing. Asterisk is a great milestone in opensource telephony evolution. <br />
<br />
That brings us to next beast in the evolution FreeSWITCH. FreeSWITCH is built by a person (<a href="http://www.cluecon.com/node/11"><strong>Anthony Minessale</strong> II</a> ) who has great understanding of Asterisk. So, he made sure that the short comings of Asterisk are addressed in a proper way. EventSocket interface of FreeSWITCH is more powerful and hooks into almost every aspect of FreeSWITCH. EventSocket is one single protocol for call control and switch control instead of two different protocols that Asterisk has FastAGI and AMI. <br />
<br />
FreeSWITCH tracks calls in a real neat way by hooking them up with <a href="http://en.wikipedia.org/wiki/Universally_unique_identifier">UUIDs</a>. Each leg or channel in FreeSWITCH is identified by a single UUID through out its lifespan. Which makes it a breeze for the programmer to deal with call events and control the calls. FreeSWITCH also allows you to specify your own UUID for a call leg while originating, that way you are given absolute control of what goes on with a leg. <br />
<br />
Before I end the post, here is a sample unique id of a channel used by FreeSWITCH - 60a3c6de-dc73-11df-9c62-00238b1dd454Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com2tag:blogger.com,1999:blog-1922011022782208121.post-69178495506347858662010-09-22T01:51:00.000-07:002010-09-22T02:18:51.988-07:00how to make python xmlrpclib client session awareManaging sessions in xmlrpclib client in the python standard library is not supported. If you are using xmlrpclib for serious work,sooner or later you are going to face this issue of managing authenticated sessions. Inspecting xmlrpclib.py reveals that it does all its HTTP communication using Transport class defined in xmlrpclib.py (Be ware that the current trunk version Transport is different from the one shipped with Python 2.5) The following code is implemented to work with Python2.5 version of xmlrpclib.<br /><br />You can get a clear description of HTTP session mechanics from the <a href="http://en.wikipedia.org/wiki/HTTP_cookie#Session_management">wikipedia page</a> . So to implement this in python2.5's xmlrpc client you need to subclass and override certain methods of Transport class as shown below.<br /><br /><br /><pre><br />class SessionTransport(Transport):<br /> def __init__(self):<br /> Transport.__init__(self, use_datetime=0)<br /> <br /> #def request(self, r):pass<br /> session = ''<br /> def request(self, host, handler, request_body, verbose=0):<br /> <br /> # issue XML-RPC request<br /><br /> h = self.make_connection(host)<br /> if verbose:<br /> h.set_debuglevel(1)<br /><br /> self.send_request(h, handler, request_body)<br /> self.send_host(h, host)<br /> self.send_user_agent(h)<br /> self.send_content(h, request_body)<br /><br /> errcode, errmsg, headers = h.getreply()<br /> <br /> self.session = headers.getheader("Set-Cookie", "").split(";")[0]<br /> <br /><br /><br /> if errcode != 200:<br /> raise ProtocolError(<br /> host + handler,<br /> errcode, errmsg,<br /> headers<br /> )<br /><br /> self.verbose = verbose<br /><br /> try:<br /> sock = h._conn.sock<br /> except AttributeError:<br /> sock = None<br /><br /> return self._parse_response(h.getfile(), sock)<br /><br /> <br /> def send_user_agent(self, connection):<br /> <br /> if self.session: <br /> connection.putheader("Cookie",self.session)<br /> return Transport.send_user_agent(self, connection)</pre><br />Now, you just need to pass the instance of SessionTransport to xmlrpclib.ServerProxy 's transport argument. I was using Twisted XML-RPC server on server side. When you create a session in twisted using <a href="http://twistedmatrix.com/documents/10.1.0/api/twisted.web.server.Request.html#getSession">request.getSession</a> it will send the Set-Cookie: TWISTED_SESSION:231123125usd ; Path=/ to client in HTTP headers. All that above code does, is to extract that Set-Cookie value and set it back in Cookie header on each subsequent request to server. This is fairly simple and should work with any other HTTP server.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com2tag:blogger.com,1999:blog-1922011022782208121.post-87598876569885379592010-07-01T15:46:00.000-07:002010-09-22T02:24:05.561-07:00Some notes on FreeSWITCH and Radius Integration<span style="font-size:100%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" style="FONT-FAMILY: trebuchet ms" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7DJUaIFYN9zkylmobOOMpmO-mEZHJn8ocDAKabHtQNj6FMXWMHqpE9QcLPuiTjQsHzgHvRelMe-Bev2goNsGTuor1LwKeG9Y9ocgknVZI8fHPhgxTk8Z8j1rbEtgN7Vyl4p2ViXtACooy/s1600/fsradius.png"><br /></a><br /></span><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><!--StartFragment--><span style="font-size:100%;">There are some decent modules out there that help us in tying up FreeSWITCH with Radius namely mod_rad_auth and mod_radius_cdr. However, they are pretty much limited and lack some of main features like dynamic routing that some radius servers can provide. Integrating FreeSWITCH with such radius server which can do routing and billing logic will allow us to deploy FreeSWITCH on a large scale, ideal for whole sale carriers kind of thing.<br /></span></p><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><span style="font-size:100%;"><br /></span></p><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><span style="font-size:100%;">This integration will give us the luxury of not having to configure any endpoint details that FreeSWITCH has to send calls to. We will have one centralized billing server which talks radius protocol. And NAS (name is debatable ) talking to many FreeSWITCH instances. The following image makes it clear.</span></p><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><span style="font-size:100%;"><br /></span></p><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><span style="font-size:100%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7DJUaIFYN9zkylmobOOMpmO-mEZHJn8ocDAKabHtQNj6FMXWMHqpE9QcLPuiTjQsHzgHvRelMe-Bev2goNsGTuor1LwKeG9Y9ocgknVZI8fHPhgxTk8Z8j1rbEtgN7Vyl4p2ViXtACooy/s1600/fsradius.png"><img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 320px; DISPLAY: block; HEIGHT: 269px; CURSOR: pointer" id="BLOGGER_PHOTO_ID_5489093050391153106" border="0" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7DJUaIFYN9zkylmobOOMpmO-mEZHJn8ocDAKabHtQNj6FMXWMHqpE9QcLPuiTjQsHzgHvRelMe-Bev2goNsGTuor1LwKeG9Y9ocgknVZI8fHPhgxTk8Z8j1rbEtgN7Vyl4p2ViXtACooy/s320/fsradius.png" /></a></span></p><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><span style="font-size:100%;">Now the challenge is to implement NAS that does the conversion of radius protocol to a language that FreeSWITCH understands. Luckily FreeSWITCH comes with numerous features and tools that offer hooks into every place of FreeSWTICH. I've implemented this NAS in python using Twisted's higly scalable network architecture. The major pain is understanding the cisco's radius dictionary attributes and how exactly they map to the FreeSWITCH variables. I've implemented all the important features of what VoIP radius protocol has to offer.</span></p><p style="TEXT-INDENT: 0px; MARGIN: 0pxfont-family:trebuchet ms;" ><span style="font-size:100%;"></span></p><ul style="MARGIN: 0px;font-family:trebuchet ms;" ><li style="font-family:'DejaVu Sans';font-size:9pt;"><span style="font-size:100%;">Endpioint Authorization (Digest and IP)</span></li><li style="font-family:'DejaVu Sans';font-size:9pt;"><span style="font-size:100%;">Route Autthorization (for Dynamic routing, limit call duration based on balance amount)</span></li><li style="font-family:'DejaVu Sans';font-size:9pt;"><span style="font-size:100%;">Accouting Requests (Radius CDR for billing ) </span><!--EndFragment--></li></ul>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com3tag:blogger.com,1999:blog-1922011022782208121.post-8495396590888836132010-04-20T00:38:00.000-07:002015-12-06T00:43:32.560-08:00Threads in Python GUIs<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-size: 100%;"><br /></span><span style="font-size: 100%;"> One easy way to crash GUIs built in python is to call any method that updates GUI ( causes to re-draw GUI ) from a thread other than the main thread! Most often people use threads to run long running tasks in background to keep the GUIs responsive how ever, ignorance of such a limitation like not to call GUI update methods from threads other than main thread will sure leave people scratching their head. In my experience this happens at least in Tkinter and wxPython.</span><br />
<span style="font-size: 100%;"><br /></span>
<span style="font-size: 100%;"> As a workaround wxPython provides wx.CallAfter method which can be used to invoke GUI update related methods from non main threads. However people also can device their own ways like creating custom events and binding them to a listener which gets fired from main thread. </span><br />
<span style="font-size: 100%;"><br /></span>
<span style="font-size: 100%;"> There is no such method for Tkinter, one easy way is to use python standard library Queue module. Queue module is thread safe. To update GUI from non main thread, put messages,flags, any thing you like in Queue (you can place any data type in Queue) and have watch dog timer checking for contents of this Queue, if it finds any contents take action to update accordingly.</span><br />
<span style="font-size: 100%;"><b><i><br /></i></b></span>
<span style="font-size: 100%;"><b><i>Note:main thread is the place where you call the main loop method of GUI framework</i></b></span></div>
Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-15602327213011103302010-04-08T00:51:00.000-07:002010-04-08T01:02:51.261-07:00Web woke up on StreamHarvester !<span style="font-size:100%;">Recently I've seen a sudden increase in my <a href="http://godson.in/">site's</a> traffic. Reason for this is after many months that I've published StreamHarvester-0.1 on <a href="http://code.google.com/p/streamharvester/">Google Code</a> web has started picking it up. StreamHarvester was reviewed on couple of websites. I am giving the links of the the sites that I was I able to find.<br /><br /><br /></span><ul><li><span style="font-size:100%;"><a href="http://www.ghacks.net/2010/04/04/record-internet-radio-streams-with-stream-harvester/">Ghacks</a></span></li><li><span style="font-size:100%;"><a href="http://www.softpedia.com/get/Internet/Other-Internet-Related/StreamHarvester.shtml">SoftPedia</a></span></li><li><span style="font-size:100%;">And scores of other sites that follow the above mentioned websites.<br /></span></li></ul><span style="font-size:100%;">Any way I am happy to see that people are trying it out. This is motivates me to work on it again and improve it more & more.<br /><br />If you have specific feature request, feel free to drop a mail to me.<br /><br /></span>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-57686838969644993172009-11-25T23:51:00.000-08:002009-11-26T00:30:53.792-08:00StreamHarvester-0.1<div id="wikicontent" style="padding: 0pt 3em 1.2em 0pt;"> <p>I've been working on StreamHarvester for the past one week. Last night I've created and made Streamharvester-0.1 available for windows. It is currently hosted google code.</p><p><a href="http://code.google.com/p/streamharvester/">http://code.google.com/p/streamharvester/</a><br /></p><p>StreamHarvester is a cross-platform internet radio and TV recoder.StreamHarverster works with Shoutcast and Icecast streams. You can record multiple streams simultaneously, also you can relay a stream locally while recording it. So that you can listen to the stream in an external media player like VLC , Windows media player.<br /></p><p>It can handle various media format and playlist formats.</p><p><span style="font-weight: bold;">Supported Media formats</span></p><ol><li><span style="font-weight: bold;"><span style="font-weight: bold;">mp3</span></span></li><li><span style="font-weight: bold;"><span style="font-weight: bold;">ogg</span></span></li><li><span style="font-weight: bold;"><span style="font-weight: bold;">nsv</span></span></li></ol><span style="font-weight: bold;"><span style="font-weight: bold;">Supported Playlist formats<br /><br /></span></span><ol><li><span style="font-weight: bold;">pls</span><br /></li><li><span style="font-weight: bold;">m3u</span></li></ol>which means while adding a job you can paste playlist URLs directly into the program. And it will automatically retrieve media from URLs available in playlist. Also StreamHarvester will automatically fallback to next available URL in a playlist<span style="font-weight: bold;"> </span>in case of any URL fails.<br /><br />Visit project page to know more about it and to freely download and try it.<br /> </div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-85389889852115779062008-10-10T03:45:00.000-07:002008-10-10T04:33:12.731-07:00starpy-1.0.0a13 Released (Asterisk protocols for twisted)Today I did a new release of <a href="http://starpy.sf.net">starpy</a>. (Asteirsk protocols for Twisted ) which can be downloaded from here <a href="https://sourceforge.net/project/showfiles.php?group_id=164040">https://sourceforge.net/project/showfiles.php?group_id=164040</a><br /><br />This release contains addition of many manager commands to manager API. Following is a list of newly added commands.<br /><br /><ol><li>agentLogoff</li><li>dbGet</li><li>dbPut</li><li>extensionState</li><li>getConfig</li><li>meetmeMute</li><li>meetmeUnmute</li><li>park</li><li>pauseMonitor</li><li>playDTMF</li><li>queuePause</li><li>sipShowPeers</li><li>unpauseMonitor</li><li>updateConfig (read AMI documentation before using this )</li><li>userEvent</li><li>waitEvent</li><li>zapDNDoff</li><li>zapDNDon</li><li>zapDialOffhook</li><li>zapHangup</li><li>zapRestart</li><li>zapShowChannels</li><li>zapTransfer</li></ol> Those are all the new manager Actions that were added. Queues action is there but it won't work cause AMI returns improperly formatted lines, same case with IAXPeers action, as AgentCallbackLogin is deprecated and is not functioning properly it was not included.<br /><br /> Bug fix in queueStatus manager api, in collectDeferred argument 'QueueStatusEnd' is changed to 'QueueStatusComplete'. Now the deferred fires properly.<br /><br /> Bug fix in fastagi playback (not a standard AGI command, was created by Mike as a workaround for buggy streamFile command back in Asterisk 1.2 days. Now streamFile is working properly so you might not be using this playback ).<br /><br />Those are all the changes that involved in this release if you find any bugs or hope for any features let me know.<br /><br />Have fun with starpy.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com1tag:blogger.com,1999:blog-1922011022782208121.post-75521094342010159052008-05-24T14:55:00.000-07:002008-05-24T15:01:45.338-07:00Zaptel to DHADIDue to trademark issues with the name Zaptel digium has announced change in the name,DHADI (Digium Asterisk Hardware Device Interface ) name sounds funny while trying to be serious<br /><br /><a href="http://blogs.digium.com/2008/05/19/zaptel-project-being-renamed">http://blogs.digium.com/2008/05/19/zaptel-project-being-renamed-to-dahdi/</a>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-68072035430531295872008-01-03T00:00:00.000-08:002008-01-03T00:20:59.864-08:00RoR - Rants on RailsToday there was a long long rant on rails & its community that got slashdotted. He got strong feelings against rails community and says when he hangs around with Django or other python related stuff people are nice to him!<br /><br />At least in my experience python and python related frameworks communities is been so nice.<br /><br />Here is the full rant<br /><br /><a href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html">http://www.zedshaw.com/rants/rails_is_a_ghetto.html</a><br /><br />And this is how I got the news from #twisted<br /><br /><span style="font-size:85%;"><span style="color: rgb(68, 95, 28);">(10:36:30 IST) </span></span><span style="color: rgb(68, 95, 28);"><span style="font-size:100%;">Jerub:</span></span><span style="font-size:100%;"> you know that rant about RoR that got on slashdot today?</span><br /><span style="font-size:85%;"><span style="color: rgb(68, 95, 28);">(10:36:35 IST) </span></span><span style="color: rgb(68, 95, 28);"><span style="font-size:100%;">Jerub:</span></span><span style="font-size:100%;"> the dude is in #python</span><br /><span style="font-size:85%;"><span style="color: rgb(132, 123, 95);">(10:37:21 IST) </span></span><span style="color: rgb(132, 123, 95);"><span style="font-size:100%;">glyph:</span></span><span style="font-size:100%;"> Jerub: Ask him if now that he's f***ed in the Ruby community he wants to maintain a Python webserver.</span><br /><span style="font-size:85%;"><span style="color: rgb(68, 95, 28);">(10:38:08 IST) </span></span><span style="color: rgb(68, 95, 28);"><span style="font-size:100%;">Jerub:</span></span><span style="font-size:100%;"> ask him yourself, slacker.</span><br /><span style="font-size:85%;"><span style="color: rgb(221, 109, 41);">(10:40:15 IST) </span></span><span style="color: rgb(221, 109, 41);"><span style="font-size:100%;">dash:</span></span><span style="font-size:100%;"> Jerub: yeah. I just got to that part :)</span><br /><span style="font-size:85%;"><span style="color: rgb(132, 123, 95);">(10:41:50 IST) </span></span><span style="color: rgb(132, 123, 95);"><span style="font-size:100%;">glyph:</span></span><span style="font-size:100%;"> Jerub: hey, you're my *connection* man; I don't know nothin about no #python no more</span><br /><span style="font-size:85%;"><span style="color: rgb(13, 40, 81);">(10:44:03 IST) </span></span><span style="color: rgb(13, 40, 81);"><span style="font-size:100%;">jml:</span></span><span style="font-size:100%;"> MFen: is that like DM of the Rings?</span><br /><span style="font-size:85%;"><span style="color: rgb(13, 40, 81);">(10:46:50 IST) </span></span><span style="color: rgb(13, 40, 81);"><span style="font-size:100%;">jml:</span></span><span style="font-size:100%;"> MFen: DM of the Rings is better</span><br /><span style="font-size:85%;"><span style="color: rgb(120, 160, 162);">(10:48:36 IST) </span></span><span style="color: rgb(120, 160, 162);"><span style="font-size:100%;">MFen:</span></span><span style="font-size:100%;"> i haven't seen DM of the rings, that sounds good</span><br /><span style="font-size:85%;"><span style="color: rgb(120, 160, 162);">(10:52:20 IST) </span></span><span style="color: rgb(120, 160, 162);"><span style="font-size:100%;">MFen:</span></span><span style="font-size:100%;"> Jerub: and asking about Django</span><br /><span style="font-size:85%;"><span style="color: rgb(68, 95, 28);">(10:52:22 IST) </span></span><span style="color: rgb(68, 95, 28);"><span style="font-size:100%;">Jerub:</span></span><span style="font-size:100%;"> glyph: which web server did you mean?</span><br /><span style="font-size:85%;"><span style="color: rgb(68, 95, 28);">(10:52:32 IST) </span></span><span style="color: rgb(68, 95, 28);"><span style="font-size:100%;">Jerub:</span></span><span style="font-size:100%;"> web, web2, or some divmod thing?</span><br /><span style="font-size:85%;"><span style="color: rgb(120, 160, 162);">(10:52:33 IST) </span></span><span style="color: rgb(120, 160, 162);"><span style="font-size:100%;">MFen:</span></span><span style="font-size:100%;"> just don't tell him about twisted, please</span><span style="font-size:85%;"><span style="color: rgb(120, 160, 162);"></span></span><br /><span style="font-size:85%;"><span style="color: rgb(68, 95, 28);">(10:52:55 IST) </span></span><span style="color: rgb(68, 95, 28);"><span style="font-size:100%;">Jerub:</span></span><span style="font-size:100%;"> dm of the rings is complete, which is nice.</span><br /><span style="font-size:85%;"><span style="color: rgb(132, 123, 95);">(10:52:58 IST) </span></span><span style="color: rgb(132, 123, 95);"><span style="font-size:100%;">glyph:</span></span><span style="font-size:100%;"> Jerub: all of the above</span><br /><span style="font-size:85%;"><span style="color: rgb(132, 123, 95);">(10:53:41 IST) </span></span><span style="color: rgb(132, 123, 95);"><span style="font-size:100%;">glyph:</span></span><span style="font-size:100%;"> Jerub: the problem being that "all of the above" is the answer, I need someone to make 2 of those options go away :)</span><br /><span style="font-size:85%;"><span style="color: rgb(120, 160, 162);">(10:54:26 IST) </span></span><span style="color: rgb(120, 160, 162);"><span style="font-size:100%;">MFen:</span></span><span style="font-size:100%;"> glyph: and some collateral damage to take out 6 or 7 other python web frameworks would be nice</span><br /><span style="font-size:85%;"><span style="color: rgb(132, 123, 95);">(10:54:36 IST) </span></span><span style="color: rgb(132, 123, 95);"><span style="font-size:100%;">glyph:</span></span><span style="font-size:100%;"> MFen: hehe<br /><br />Atleast people are not flaming each other here.<br /></span>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-5105909802439544232007-12-22T00:26:00.000-08:002007-12-22T00:46:02.189-08:00Tcl/Tk 8.5.0At last after a long long time, <a href="http://www.tcl.tk/software/tcltk/downloadnow85.html">Tcl/Tk8.5</a> was released. I am not a Tcl programmer! But what is in there for python programmers is the Tk8.5 with the theming engine Tile, which the Tkinter world is waiting for a long long time. Though some wrappers to Tile appeared on personal and sourceforge site, I was eager to see what is going to be there in final release. <br />Though I myself has started moving to <a href="http://wxpython.org">wxPython</a> . Whenever I look at Tkinter (Tk) I get that nostalgic feeling for it. Tkinter is the first GUI toolkit I've tried and I should say it made the GUI programming a lot of fun.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-47229987118255690622007-12-12T03:40:00.000-08:002007-12-12T06:35:17.076-08:00How to bulid Click2CallWith the advent of VoIP and computer telephony integration, one feature that have popped up is Click2Call. Its a convenient way to initiate a call with people whom you want to talk to by just clicking on their number in Outlook or on some webpage etc etc. <a href="http://vonage.com/">Vonage</a> has this feature for their service.<br /><br />Lets see how we can achieve this with Asterisk. Asterisk provides Originate AMI action for this. Just call the Originate action with the numbers you want to connect. Here is the <a href="http://twistedmatrix.com/">twisted</a> code on how you can do it ( You need <a href="http://starpy.sourceforge.net/">starpy</a> to do it). The following dirty example integrates http with AMI where by hitting the url some thing like http://localhost:8000?number=12322342345&ext=234 will do the magic needed. The same way you integrate this with any other protocol you think that it useful to you. After all twisted supports tons of those.<br /><br /><pre style="color: rgb(85, 119, 17);font:bold 9pt monospace"><br />#!/usr/bin/python<br /><br /><br />from starpy import manager<br />from starpy.manager import AMIFactory<br />from twisted.internet import reactor<br />from twisted.web import server,resource<br /><br />import logging<br /><br />logging.basicConfig()<br />log = logging.getLogger("Click2Call")<br />log.setLevel(logging.DEBUG)<br />manager.log.setLevel(logging.DEBUG)<br /><br />class Click2CallProtocol(object):<br /> def __init__(self):<br /> pass<br /> def onConnect(self,ami):<br /> log.info("Logged in successfully")<br /> self.ami = ami<br /> <br /> def dial(self,number,ext):<br /> try:<br /> self.ami.originate(channel='Local/'+number+"/n",context='mycontext',priority='1',exten=ext,async=True)<br /> return True<br /> except:<br /> return False<br /> <br /><br /> <br />class Click2CallFactory(AMIFactory):<br /><br /> def __init__(self):<br /> AMIFactory.__init__(self,"mark","mysecret")<br /> <br /> def connect(self):<br /> df = self.login("127.0.0.1")<br /> df.addCallback(c2cp.onConnect)<br /> <br /> def clientConnectionLost(self,connector,reason):<br /> log.info("We lost connection trying reconnect")<br /> reactor.callLater(1,self.connect)<br /> <br /> def clientConnectionFailed(self,connector,reason):<br /> log.info(reason)<br /> reactor.callLater(1,self.connect)<br /><br />class Click2CallResource(resource.Resource):<br /><br /> def render(self,request):<br /> try:<br /> number = request.args['number'][0]<br /> agent = request.args['ext'][0]<br /> except:<br /> return "Required arguments not found"<br /> if c2cp.dial(number,agent):<br /> return "OK"<br /> else:<br /> return "NOTOK"<br /><br />c2cp = Click2CallProtocol()<br />c2cf = Click2CallFactory()<br />c2cf.connect()<br /><br />root = Click2CallResource()<br />root.putChild("",root)<br />site = server.Site(root)<br /><br />reactor.listenTCP(8000,site,)<br />reactor.run()<br /><br /></pre>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-21167442141101768302007-12-12T03:22:00.000-08:002007-12-12T06:35:40.847-08:00Linux For LadiesGet the full story from here<br /><br /><a href="http://princessleia.com/journal/?p=1214">http://princessleia.com/journal/?p=1214</a><br /><br />Recently in my free time when I was reading some blogs I have stumbled upon the topic women in open source world. Amazingly I've found that lots of things are happening on that front. All most all the major projects are now having women's section.<br /><br /><a href="http://women.debian.org">http://women.debian.org</a><br /><a href="http://women.kde.org/">http://women.kde.org/</a><br /><a href="http://live.gnome.org/GnomeWomen">http://live.gnome.org/GnomeWomen</a><br /><a href="http://linuxchix.com">http://linuxchix.com</a><br /><br />Those are a few to quote. When I've read the document of debian women's site on whats the cause for so few women in opensource world is, I've found the document saying sexism to be the major force driving women away from the opensource. It suggests to keep mouth shut and pay no special attention to women in linux groups or mailing lists if possible you can help and encourage as you usually do with a male geek. What I think is for almost all of the guys its some thing they have to try, its not the default behavior.Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-62710290655567990682007-10-21T05:17:00.000-07:002007-12-12T06:35:59.725-08:00PyMOTW- Python Module of The Week<div style="text-align: justify;"> When I was collecting python related RSS feeds a few months back I came across this wonderful project called PyMOTW by Doug Hellmann<br /></div><br /><a href="http://www.doughellmann.com/projects/PyMOTW/">http://www.doughellmann.com/projects/PyMOTW</a><br /><br /><div style="text-align: justify;"> Though one such effort was made by <a href="http://effbot.org/zone/librarybook-index.htm">effbot</a> a long time back with a book called Python Standard Library it was on python2.0 after which a lot many changes happened in python standard library. PyMOTW fills this gap by coming up with articles mostly on new modules of python that were included in python2.3 onwards.<br /><br /></div><div style="text-align: justify;"> Having the through knowledge of what python distribution has by default saves you from reinventing the wheel most of the times. I found my self in such situations a lot many times :)<br /></div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0tag:blogger.com,1999:blog-1922011022782208121.post-21723769203186628642007-10-20T11:46:00.000-07:002007-12-12T06:36:14.355-08:00Dual Monitors on Ubuntu Gusty<div style="text-align: justify;"> Two days back I got my OS upgraded to the latest Ubuntu 7.10 Gusty. While reading the reviews of it I came across the Dual monitor support built into this distribution. In fact I've read that last night, since then I was hoping to try it, only now I got the chance to try it. I've plugged in the CRT monitor to my laptop VGA out let and had my laptop booted to GNOME, I found the application Screens and Resolution. After trying out a few configurations specs with it , I am finally here up and running with dual monitor. It takes away all the hard hand work of configuring xinerama and your X config files. Nice feature to have by default on laptops. Ubuntu is cool. Here is a screen shot.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrSU8LBOgw7sJqKyXned9K4D0VXJ2ixXqRoYc6tdWbG596m-rEio-Gqcwf84vKSxcrAK8c5L6uGwqRp9CDY1WeMKSVOL70EClGL2R666d61qujxQiv39sfhBNox6Iqg7Z3b8uiamlj54za/s1600-h/snapshot1.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrSU8LBOgw7sJqKyXned9K4D0VXJ2ixXqRoYc6tdWbG596m-rEio-Gqcwf84vKSxcrAK8c5L6uGwqRp9CDY1WeMKSVOL70EClGL2R666d61qujxQiv39sfhBNox6Iqg7Z3b8uiamlj54za/s320/snapshot1.png" alt="" id="BLOGGER_PHOTO_ID_5123495347241666402" border="0" /></a></div>Godson Gerahttp://www.blogger.com/profile/03937932928540142421noreply@blogger.com0