resources

AVL Tree in Python

I’ve been teaching “Applied Algorithms and Programming Techniques” and we just reached the topic of AVL Trees. Having taught half of the AVL tree concept, I decided to code it in python — my newest adventure. Bear in mind that I have never actually coded an AVL tree before and I’m not particularly comfortable with python. I thought it would be a good idea to experiment with both of them at the same time. So, I started up my python IDE (that’s Aptana Studio, btw) and started coding.

For the newbie programmer, the code itself may not be very useful since you can find better code online. The benefit is in being able to look at the process. You can take a look at the commits I made along the way over here on github. You can take a look at how I structured the code when I began and how I added bits and pieces. This abstraction should help in solving other problems as well. The final code (along with a rigorous unit test file) can be seen here: https://github.com/recluze/python-avl-tree

How to Create a Beamer Template — A Newbie’s Tutorial

I started switching full-time to Ubuntu (once again) a couple of weeks ago. Turns out, it’s in much better condition than when I last tried it. Anyway, one of the problems was finding a replacement for Powerpoint. I hate creating presentations for classes — in fact, I think they’re counter-productive — but I have no choice for the moment. So, I decided to give LibreOffice Impress a chance. That was an hour of my life down the drain. Finally, I returned to beamer. Of course, I had to write my own theme because I couldn’t use the same theme used by all the rest of the world. To cut this long and boring story short, I tried very hard to find a tutorial on writing beamer themes, couldn’t do so, learned it through experiment and decided to write the tutorial myself. Here is that tutorial. Read more…

CS 303 Software Engineering (NU) Administrivia

Update Sep 08, 2011: Lectures are now available on the Lecture Server. Please get the updates there.

This is a (hopefully) temporary location for posting the contents that I want communicated to the students of CS303 Software Engineering course. These will be posted to the lecturer server as soon as I get access inshaallah. For the time being, bookmark this page and keep checking for updates.

CS303- Course Outline – Fall 2011
Slideset-01
Slideset-02

Varnish Cache for WordPress on cPanel

Varnish is an extremely easy to configure server cache software that can help you counter the ‘slashdot effect’ — high traffic over a small period of time. The way Varnish does this is by sitting between the client and the webserver and providing cached results to the client so that the server doesn’t have to process every page. It’s better than memcache etc because the request never gets to the webserver. You can avoid one of the bottlenecks this way. In this tutorial, we’ll cover how to setup Varnish on a VPS (or dedicated server) where you have root access and are running your site using cPanel/WHM. It also applies to situations where you don’t have cPanel/WHM. You can just skip the cPanel portion if that’s the case. So, let’s get started.

Read more…

Enabling Voicemail for A2billing

So you’ve setup a2billing and have everything working out, all the DIDs are forwarded to a2billing and all the call plans are set. All you’re missing is a voicemail system. Wait no more. Here’s how to enable voicemail for a2billing users.

First, you need to change the A2billing class to enable it to forward unavailable or unattended calls to the voicemail. For that, edit the [a2billing-home]/common/lib/Class.A2billing.php file file. The two functions that need changing are the call_did and call_sip_buddies. In version 1.8.5, the changes are around line 1160 and 1330. You can just search for the following code to reach there. (Remember, there are two instances that need changing.)

//# Ooh, something actually happend!
if ($dialstatus == "BUSY") {

Now, it needs to be changed so that the caller is redirected to the voicemail if the dialstatus is CHANUNAVAIL, CONGESTION or NOANSWER. Note that we need to get rid of the existing checks for these statuses and introduce our own code. The complete code would be as follows:

$answeredtime."-DIALSTATUS=".$dialstatus."]"); 
$lang = "en";
if (($dialstatus =="CHANUNAVAIL") || ($dialstatus == "CONGESTION") ||($dialstatus == "NOANSWER") || ($dialstatus =="BUSY") )
{
	// The following section will send the caller to VoiceMail with the unavailable priority.
	$did_ext_number = substr($this->destination, 4);
	// get the actual did 
	// BAD but a hack for now 
	$db_host = $this->config['database']['hostname']; 
	$db_user = $this->config['database']['user']; 
	$db_pass = $this->config['database']['password'];
	$db_sele = $this->config['database']['dbname'];
	
	mysql_connect($db_host, $db_user, $db_pass);
	@mysql_select_db($db_sele) or die( "Unable to access database");				
	$query = "select S.name, D.did, C.language from cc_sip_buddies S, cc_card C , cc_did_destination E, cc_did D 
				where S.id_cc_card =C.id and E.id_cc_card = C.id and E.id_cc_did = D.id and 
				S.name =  '$did_ext_number';";
				
	$result = mysql_query($query);
	$did_number = $did_ext_number; 
	if ($row = mysql_fetch_array($result)){		  
		if($dialstatus =="BUSY")
			$did_number = "b".$row["did"]; 
		else
			$did_number = "u".$row["did"]; 
		
		// set the language 
		$lang = $row["language"]; 
	}
	
	$this -> write_log("[STATUS] CHANNEL UNAVAILABLE - DIVERT TO VOICEMAIL ($did_number)");
	$lang_str = "LANGUAGE()=$lang";
	$agi->exec (Set, $lang_str); 
	$agi-> exec(VoiceMail,$did_number);
} 


// the old code for BUSY is commented out 
//# Ooh, something actually happend!
/* if ($dialstatus  == "BUSY") {
	$answeredtime = 0;
	if ($this->agiconfig['busy_timeout'] > 0)
		$res_busy = $agi->exec("Busy ".$this->agiconfig['busy_timeout']);
	$agi-> stream_file('prepaid-isbusy', '#');
} elseif ($this->dialstatus == "NOANSWER") {
	$answeredtime = 0;
	$agi-> stream_file('prepaid-noanswer', '#');
} else
*/ 

if ($dialstatus == "CANCEL") {
	$answeredtime = 0;
} elseif ($dialstatus == "ANSWER") {
	$this -> debug( DEBUG, $agi, __FILE__, __LINE__, "-> dialstatus : $dialstatus, answered time is ".$answeredtime." \n");
} elseif ($k+1 == $sip_buddies+$iax_buddies) {
	$prompt="prepaid-dest-unreachable";
	$agi-> stream_file($prompt, '#');
}

/* 
// AGAIN, the old code for the statuses is commented out 
if (($dialstatus  == "CHANUNAVAIL") || ($dialstatus  == "CONGESTION"))
	continue;
*/ 

Find the similar code in the other function and change that too.

Now, we need to change the asterisk voicemail configuration to recognize the DID as a mailbox. For that, first enable asterisk realtime. (It’s a simple matter of compiling asterisk and then compiling asterisk-addons.) After that is done, change the /etc/asterisk/res_mysql.conf file as follows:

[general]
dbhost = 127.0.0.1
dbname = a2billingdb
dbuser = [asteriskuser]
dbpass = [yourpassword]
dbport = 3306
dbsock = /tmp/mysql.sock

Also, in the /etc/asterisk/extconfig.conf add the following line:

voicemail =>mysql,a2billingdb,voicemail_users

This will make sure that the voicemail application tries to find the list of mailboxes in the voicemail_users table in the a2billingdb. Let’s create that table:

CREATE TABLE `voicemail_users` (
`uniqueid` int(11) NOT NULL auto_increment,
`customer_id` int(20) NOT NULL default '0',
`context` varchar(50) NOT NULL default '',
`mailbox` varchar(20) NOT NULL default '0',
`password` varchar(20) NOT NULL default '8888',
`fullname` varchar(50) NOT NULL default '',
`email` varchar(50) NOT NULL default '',
`pager` varchar(50) NOT NULL default '',
`stamp` timestamp(14) NOT NULL,
PRIMARY KEY (`uniqueid`),
KEY `mailbox_context` (`mailbox`,`context`)
) TYPE=MyISAM;

… and synchronize it with the rest of the a2billing database so that the users can use their DID and SIP secret for their mailboxes.

insert into voicemail_users(customer_id,context,mailbox, password, fullname, email)
select S.id_cc_card, 'default', D.did, S.secret, concat(C.lastname,' ',C.firstname) fullname, C.email
from cc_sip_buddies S, cc_card C , cc_did_destination E, cc_did D
where S.id_cc_card =C.id 
and E.id_cc_card = C.id 
and E.id_cc_did = D.id;

You might want to add the following cronjob to perform this synchronization automatically.

0 * * * * mysql -ua2billinguser -p[yourpassword] -D a2billingdb -e "truncate table voicemail_users; insert into voicemail_users(customer_id,context,mailbox, password, fullname, email) select S.id_cc_card, 'default', D.did, S.secret, concat(C.lastname,' ',C.firstname) fullname, C.email from cc_sip_buddies S, cc_card C , cc_did_destination E, cc_did D where S.id_cc_card =C.id  and E.id_cc_card = C.id  and E.id_cc_did = D.id ;"

That should fix the whole voicemail recording business. However, we still need to enable the voicemail interface provided by FreePBX. Since the ARI does not support asterisk realtime, we need to change the login.php file in /var/www/html/admin/includes folder. Search out the code where the authentication is being done. The code first tries to autenticate using the configuration file. It then tries SIP authentication (whatever that is). After that, we insert our own DB authentication like so:

// check database login:  recly 
if(!$auth){
	// BAD but a hack for now 
	$db_host = "localhost"; 
	$db_user = "a2billinguser"; 
	$db_pass = "[yourpassword]";
	$db_sele = "a2billingdb";

	mysql_connect($db_host, $db_user, $db_pass);
	@mysql_select_db($db_sele) or die( "Unable to access database");

	$query = "select * from `voicemail_users` where mailbox = '$username' and password= '$password'"; 
	$result = mysql_query($query);

	if ($row = mysql_fetch_array($result)){		  
		$auth = true; 
		$extension = $row["mailbox"]; 
		$outboundCID = "";
		$displayname = $row["fullname"];
		$vm_password = $row["password"];
		$category = "";
		$context = $row["context"]; 
		$voicemail_enabled = "1";
		$voicemail_email_address = $row["email"];
		$voicemail_pager_address = $row["pager"];
		$voicemail_email_enable = "yes";
		$voicemail_email = array('');
		$default_page = $ARI_DEFAULT_USER_PAGE;
	}
}
// the original login failure lines follow 

// let user know bad login
if (!$auth) {
	$_SESSION['ari_error'] = _("Incorrect Username or Password");
}

And that should enable you to login using your ARI. One final thing: You might also want to enable your users to check their mailbox. For that, change the dialplan in extensions_a2billing.conf:

[a2billing]
exten => 9999,1,VoicemailMain()
exten => _X.,1,Answer
exten => _X.,n,Wait(1)
exten => _X.,n,DeadAGI(a2billing.php|1)
exten => _X.,n,Hangup

Now your users can dial 9999 and check up on their voicemail.

Troubleshooting vTiger CRM Install on PHP 5.2

I recently had to deploy vTiger CRM 5 on a machine running PHP 5.2. Turned out that vTiger does not like PHP 5.2 because of some differences between PHP 5.0 and 5.2. As soon as you start the install script, you get the following error:

Cannot redeclare class DateTime

The problem is that vTiger defines its own DateTime class and so does PHP 5.2. The solution therefore (see vTiger wiki) was to rename the class in vTiger source. To do that, all you need to do is to run the following commands from the vtiger source root (e.g. /var/www/html/vtiger):

mv modules/Calendar/Date.php modules/Calendar/Date.php.back
sed s/\ DateTime/\ com_vtiger_DateTime/ < modules/Calendar/Date.php.back > modules/Calendar/Date.php
mv modules/Calendar/Appointment.php modules/Calendar/Appointment.php.back
sed s/\ DateTime/\ com_vtiger_DateTime/ < modules/Calendar/Appointment.php.back > modules/Calendar/Appointment.php
mv include/utils/RecurringType.php include/utils/RecurringType.php.back
sed s/\ DateTime/\ com_vtiger_DateTime/ < include/utils/RecurringType.php.back > include/utils/RecurringType.php

This script modifies the files Date.php, Appointment.php and RecurringType.php by first taking the backup of the file and then replacing all occurrences of ” DateTime” with ” com_vtiger_DateTime”. The backup is kept in the same location.

After that, you can run the install script and get to the login screen. When you login, you get a new error (something to this effect):

Catchable fatal error: Object of class <ClassName> could not be converted to string in /var/www/xxx on line yyy

The solution of this came from this great post. You need to create a custom error handler (called ErrorHandler.php) in the vtiger source root with the following content:

<?php
function compatibilityErrorHandler($errno, $errstr, $errfile, $errline)
{
  switch ($errno) {
  case  E_RECOVERABLE_ERROR:
    break;
  default:
    echo "Unknown error type: [$errno] $errstr \n";
    break;
  }
}

// set to the user defined error handler
$old_error_handler = set_error_handler("compatibilityErrorHandler", E_RECOVERABLE_ERROR);
?>

Finally, you need to include this error handler through the config.inc.php. For that, execute the following commands:

mv config.inc.php config.inc.php.back
sed "/include('vtigerversion.php');/ a\
require_once('ErrorHandler.php');" < config.inc.php.back > config.inc.php

Notice the line break after the a\. The first command makes a backup. The second inserts the require_once directive after the line with the include directive.

Web Fax for Asterisk

Over the past few weeks, I have been working with the popular telephony software asterisk and all the stack that stands on top of it. I have (in coordination with a friend) setup asterisk, FreePBX, a2billing, fax for asterisk and vicidial on several production servers. Combined, these provide a complete telephony solution for a wide range of commercial organizations. As a side note, I might be writing tutorials about some of these things in the future.

One of most problematic of these technologies was getting fax to work with asterisk. We tried many variations and finally found out that Digium’s Fax for Asterisk, or Free Fax for Asterisk (FFA) is currently the most stable and easy to set up. However, it does not provide an easy way to let your end users send faxes if they don’t have SIP enabled fax machines. What’s more, there is no software available that would allow you to do that! So, in one of our projects, we had to come up with a custom interface and we decided to open it up so that many others who need it can benefit from our efforts and hopefully build on it.

We call this PHP-based script Web Fax for Asterisk and are releasing it under GPLv3. For those of you who just want to get the code, you can get it from sourceforge.net. You can also get it from the SF SVN repo if you want to contribute. (In that case, gimme a shout and I’ll allow you to commit.)

For those of you who want to learn how it’s made, please read on.

Read more…

Auto Scale with Amazon Elastic Compute Cloud (EC2)

In this video, we talk about Auto Scale feature of the Elastic Compute Cloud (EC2). Auto Scale allows AWS to automatically start new instances of AMIs as more and more load is put on the instance. You can define triggers (policies) that define what the low and high limits are. Whenever these limits are breached, instances can be started or stopped depending on the policies. In this video, we start from scratch and setup the Auto Scale feature.

All comments are welcome.

Inserting Source Code and LaTeX in WordPress

A friend of mine asked me the other day how ‘pretty printed’ source code can be inserted into wordpress posts. Here’s how:

If you have a self-hosted wordpress server, get the plugin ‘SyntaxHighlighter Evolved’. Defaults work fine. If you have a wordpress.com account, the plugin is already. For LaTeX, you need the ‘WP-Latex’ plugin. After that, you can insert the source code using the syntax

[ sourcecode language="lang" ]
 ... code here (there is no space after the [ in the lines above and below).
[ / sourcecode]

You can get a list of supported languages here. Latex code can be inserted using the syntax:

$ latex 2^x $

Again, no space after the $ in the above code. There you go!

Venturing into Arabic Font Design

I started using Arabic (and Urdu) scripts quite a while ago. I came across the whole non-latin script problem when I was developing a software for a government agency related to land revenue. In the development of this software, I found myself learning about alternative keyboards and Asian language support in Windows. I also found out about the excellent research going on in FAST-NU Islamabad related to Urdu language support for computers. As an aside, I encourage all readers to go read about their work on CRULP and see the Naskh, Web Naskh and Nastaliq fonts they’ve developed and released free of charge. They’ve done a truly great job and none of my comments in the rest of the post should be taken as an offense to them or their work. Read more…