Agile or Fr"agile"
Abhang Rane
Adding openssl support to Python (the right way)
Recently I have been doing some Python stuff on Linux. For the most part, I am either using Windows for my job and Mac probably for the entertainment stuff. But whenever I get to do something on Linux, may it be installing something or working on it, I find one thing every time. Its not straight forward.
So what I wanted was to install Python, run my Python script which does some webservice calls, and go for my lunch. One caveat, the service needs to be accessed using https. So I need ssl support in Python. I am like, this is something that needs to be there by default. But its not. Argh!!!! Some mortals like me posted queries http://stackoverflow.com/questions/979551/adding-ssl-support-to-python-2-6. So I asked my friends to ahead with their lunch, its going to take a while!
Enough of my sarcasm, to get to the point, follow these steps to add ssl support on a box running RHEL. My box has RHEL5.
Download Python source, I was installing 2.7.2, http://python.org/ftp/python/2.7.2/Python-2.7.2.tgz
Extract it in a folder, say Python2.7.2. Do ./configure with any switches you need. In my case, I needed to add zlib support so, did this,
./configure –with-zlib=/usr/include
This creates a file called Setup and Setup.dist in Modules folder. To be safe, edit the Setup file. Locate the commented ssl section,
# Socket module helper for socket(2)
#_socket socketmodule.c
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
#SSL=/usr/local/ssl
#_ssl _ssl.c \
# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
# -L$(SSL)/lib -lssl –lcrypto
For those who have no clue what this file is, # means a commented line :). Uncomment few lines and change the SSL variable as below,
# Socket module helper for socket(2)
_socket socketmodule.c
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/usr/ssl
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
Save the file. Now do a make.
Now you might need to enter a root password. So do su – and then enter the root password. Once done, do make install. This should do it. At least it did for me and finally I had my lunch. Did you have your lunch yet!
Happy Programming!!!
Abhang Rane
Using Fiddler on Linux
If you are a web programmer, I am sure you would have come across a juncture where you needed some kind of tool that kept a steady eye on the network traffic. On Windows, a sexy tool that does this is Fiddler. You are using Windows, doing your programming, observing what requests flow in and out, all is well. Your boss asks you to write some kind of wise script that would some magic on the network like calling some webservice, ftp etc. You say, ‘huh… piece of cake’. Oh ya, the boss says, just one thing, this script runs on Linux.
Doh!!!!
Not really a “Doh” moment. Fiddler has a nice feature of remote connections. What you do is set the proxy on your Linux box, the proxy would have the ip address/computer name of a windows machine that is running Fiddler. That’s it, all the network traffic is routed to the Fiddler instance running on your beloved Windows machine. For those who understand in terms of some screenshots, here is the link from Fiddler website, http://www.fiddler2.com/fiddler/help/hookup.asp#Q-NonWindows
In my case, I had to put the IP address of my Windows machine and the port 8888 on which Fiddler was running. Computer names might not be searchable on all networks.
Happy Programming!!!
Abhang Rane
Did you wish the BackgroundWorker had a generic method?
We all love Generics. I love a little too much. It just makes me feel clean and tidy whenever I use it in my code. Awesome. Ok, enough of my incest for Generics.
It is quite common thing in a Windows desktop client application to have a user interface, which in response to some user actions performs certain tasks in the background. You certain would not want to make things like database/webservice calls on the UI thread. This could end up in showing the nice “Not Responding” message in your application title bar. If it is Vista you are running, it might be the Blue Screen of death who knows. In a normal Windows Forms application you would spawn a background thread and perform the tasks there. In a WPF application, well you could do the same but there is a BackgroundWorker available that does it for you. A straightforward usage of this class can be as below,
var backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += BackgroundWorkerDoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
The problem is, say you have 10 buttons on your UI and you want to make 10 different webservice calls one for each button click event. You would end up with 10 different BackgroundWorker objects each with their handlers scattered in some class. I think it can be made a little tidier, you would require 10 different BackgroundWorker objects for sure, but a Generic wrapper around this could make life a little easier. We can do this by using a generic class and a generic delegate in it. Enough words, lets see some code,
internal class ServiceHelper<T>
where T: class
{
private readonly BackgroundWorker backgroundWorker;
internal delegate void Completed(T result);
internal event Completed CompletedHandler;
internal ServiceHelper()
{
backgroundWorker = new BackgroundWorker();
}
internal void InvokeMethod(Func<T> method)
{
backgroundWorker.DoWork += BackgroundWorkerDoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorkerRunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
}
private void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e == null)
return;
var result = e.Result as T;
if (result == null)
throw new InvalidCastException("The result obtained is not of the requested type.");
if (CompletedHandler != null)
CompletedHandler(result);
}
private void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
if (e == null)
return;
var method = e.Argument as Func<T>;
if (method == null)
return;
e.Result = method();
}
}
All we have done is wrapped the BackgroundWorker inside a generic class and provided a generic event handler for clients to subscribe to.
Happy Programming!
Abhang Rane
Custom email with Hudson continuous integration
If you are using continuous integration for your project, you are cool. If you are using Hudson, you are uber cool. Anyways, regardless of the continuous integration (CI) tool you are using, sending emails via it is very useful. Hudson, certainly has a default Email Notification system. I was excited to see this feature, but once I saw the default email content, I was like, mmhhe!, this needs some revamp. There is a plugin available for custom email notification, http://wiki.hudson-ci.org/display/HUDSON/Email-ext+plugin. This plugin allows us to send HTML content in the email. Now we are talking. You would find tons of links in the cloud on how to setup this plugin to get things started. But, in my experience, the requirements for the contents of the email, its format etc. varies from team to team. Just to put be a little helpful here, below is the HTML content of the email I am using for a test project of mine,
<div class="panelMacro">
<table>
<tbody>
<tr>
<td class="noteMacro">
Hudson project, <a
href="${PROJECT_URL}">${PROJECT_NAME}</a>, is <b>${BUILD_STATUS}</b> for
build number <a href="${BUILD_URL}">${BUILD_NUMBER}</a>
</td>
</tr>
<tr>
<td class="infoMacro">
Build cause: ${CAUSE}
</td>
</tr>
<tr></tr>
<tr>
<td>
<div><b>Changes</b></div>
<br />
<div class="changesList">${CHANGES, showPaths=true, format="<div><b>[%a]</b> - %p</div><br />"}</div>
</td>
</tr>
<tr>
<td>
<div><b>Build Log</b></div>
<br />
<div style="font-size:13px;">${BUILD_LOG_REGEX, regex="Build FAILED*", linesAfter=100}</div>
</td>
</tr>
</tbody>
</table>
</div>
I have not included the stylesheet content used by this html. I have included the following things in the email,
- Project url, project name, build status and build url. These links obviously are not accessible if you are seeing this email outside your company network.
- Build cause says whether the build was triggered due to an SCM change, started manually by a user etc.
- Change list, displays a list of commits done since the last change. Each entry shows the user committing the change, and the name of the file checked in.
- Build log, shows the end of the log in case of a failure. This helps in knowing what were the build errors which caused the build failure. It is kind of important if you are not able to see the Console output as you are outside the company network and not able to access Hudson url. The way this works is, by doing a regex match on the “Build Failed” text in the Console output.
This is just a sample of how you could make your email notification really useful even when you or your team is not able to access Hudson dashboard.