Archive for best practises

Using WGET to download whole website

Recently, I came about some e-books that are html only (sucks yeah), but they are good books and I want to really have them locally. So I need to download ’em.

I know. There are GUI tools for it. But what if you are stuck in a terminal only server? I am behind a very strict proxy, but I have a server that I can FTP into and the server is not behind the proxy. But the server is terminal only, hence the wget option.

wget can download the whole internet if you so wish. and it’s simple

wget -r url

Now before you go there are a few caveats.

The sites will be downloaded, but will not be really suitable for offline viewing. To enable relative links do

wget -rk url

The above will convert the files to be suitable for offline viewing as necessary. You might want wget to keep the original files.

wget -rkK url

Also another caveat. This option will only download the html file. To tell wget to download all files necessary to display the page properly (images, sounds, linked css etc) use

wget -rkp url

Again, don’t go yet. The default level of links to follow is 5. This might be too much (or too small in case your plan is to download the whole internets). you can specify the link level thus

wget -rkpl 5 url

Finally, you might want wget to do all the hard work of downloading the internet and delete the files immediately after.

wget -r –delete-after url

man wget

is also a good place to start learning more about the things that wget can do.

That’s it. Happy interwebs downloading.


Leave a Comment

From Zero To Profit – The NaLyrics Story.

Let me start by saying that I am programmer. What I am about to share with you is lessons learnt by running a business for one year. A programmer can also run a business if he put half as much energy into running the business that he put into coding.

NaLyrics is a platform for distributing and promoting songs via lyrics. It is run by myself and two other people (Not programmers). We have built a mobile app, website and wap site (mobile web). We have some unique idea on how to distribute and promote songs and we believe it will work. Our major concern is if one of our bigger competitors get a whiff of our idea, we are basically dead in the waters. So how did we manage to operate under the radar and yet go from zero to start making profit?

Let me also say that we didn’t have funding from anywhere (well, more like we didn’t want funding). First the reason why we didn’t want funding is because we are afraid the sudden fame that comes with funding might actually be the death of us. If we display our trump card too soon, they (competitors) have the money and resources to just swallow us up.

We also didn’t make any money in the first 9 months. So how did we survive? We had an initial funding of about 300, 000 naira. What we did was maximize the use of that money. For example we didn’t spend money advertising. We also found a way to run the business without borrowing. The lessons I am about to share might not work exactly for your startup, but what I learnt is if you spend time thinking about it properly, you will find a way.

We needed to advertise, without advertisement this project won’t get anywhere, like someone said, having a product without advertising is like winking in the dark. You know what you are doing but no one else does. The problem with advertisement is that it costs money and it puts you kind of in the spotlight. If we start advertising, competitors will notice us and we might be gone the next day. So what did we do? Our major market are the blackberry users, Blackberry smartphones are still the most used in Nigeria, so it makes sense to target the blackberry users. I personally scouted the web until I found two facebook groups where Nigerians post their BBM pins. The idea is to invite the people via their pins and tell them about the app. A major challenge is blackberry BBM doesn’t allow for bulk invitation. I quickly wrote a blackberry app that can do bulk invitation.

Another decision we made that paid off was, we didn’t send BBM broadcasts, because some people find it annoying. So after adding someone new to BBM, we chat with them one on one, telling them about our platform and how they can get use it. The one on one chat paid off. We have made a beautiful app and so even those that don’t like music, after downloading the app recommends it to their friends. This way we are doing advertising without being noticed by the big shots who can swallow us up.

We faced some challenges when we started. The main one is where do we get lyrics of Nigerian songs. There are a couple of websites that post lyrics of Nigerian songs, but about 80% of those lyrics are from less-known artists. Our aim is to post the lyrics of the big shots, and our major challenge is, will they give us the lyrics? Of course the answer is NO! I can remember I was able to setup a meeting with just two known artists during the early days, Vector and Mode 9. I met Mode 9 at an event and I quickly used the opportunity to tell me about my cool new app. Of course he was happy to lend any help he could. At the time he has licensed his lyrics to some other site. But after some cajoling, the site allowed us to use the lyrics on our platform as ling as we give them credit. The lessons I learnt here is, if you wait until all the conditions are right (for us, we need the artists to send us their lyrics), you might never get anything done. We need to find a way around this.

First we made the app a wiki, meaning you can register and post lyrics on the app. But after a lot of spamming, we disabled the wiki feature. We got someone who can listen to songs and write the lyrics. After posting the lyrics, we have an automated system that tweets and post the lyrics on facebook, 4 times a day for 7 days. In the posts and tweets, we copy the artist and other people related to the song, like the producer, record label etc. This gave us credibility with the artist because in a way we are helping to promote their songs via lyrics. After a while we can now count a couple artists who sent us the lyrics of their songs.

We also made some mistakes. One of them I believe now is starting with a mobile app only. We should have launched both the mobile app and the mobile web the same time. We are making some money from adverts on the app, but it is not comparable to the money we are making from the mobile web site. The mobile web site now generates about 90% of all our income and it is growing on a daily basis. If we had started with the mobile web, we would have broken even a long time ago. The lesson here is, Nigerians seldom click ads in mobile apps, but they will gladly click same ads on a web or wap site. The second mistake is we launched with blackberry app. It makes sense at the time. Our major market is Nigeria, and most Nigerians don’t use anything except blackberries and j2me devices. We had over 300K downloads from RIM appstore and another 100K from (for J2ME devices) and almost zero income from ads. Those two platforms (Blackberry and J2ME) are the most difficult to monetize.

We also learnt that analytics is good. We found out that we are getting loads of downloads from Cameroon. We couldn’t spend the needed money to translate the app. Remember we are making almost zero income. So I got a Cameroonian friend who assisted us in translating the app to French. We now have the app in two languages. Also we have to launch the Android app (It makes sense, android is becoming very popular).

To make sure we don’t run into debt, we decided to spend the 300K initial funding we had very wisely.

1. We can not get salaries
2. We can not afford to spend more that 20, 000 naira per month (this will keep us running for about 15 months).
3. We refused all forms of grants and investment opportunities less that a certain amount of money. (Sorry I won’t disclose). Because the amount we are asking for is huge, no one invested. I think it did us good, because if we have gotten the grant or small investments, maybe we would have ended up like Tiketmobile (No offence please). Although we didn’t have the opportunity to turn down 25K, but I am sure we would not have turned it down. The reason is that if an investor think there’s a market in what we are doing, we better accept his offer, especially if it is 25K and loads of experience, else he will just take his money, influence and experience elsewhere.

About a month after we launched the mobile site, we started getting some trickles from advertisements and we added two more people to our lyrics writers. Today, about a year after, we have 5 people writing lyrics of Nigerian songs, 1 person writing Gospel lyrics, 3 people writing lyrics of Ghanian songs, 2 managers (one per country) and we are in the advanced stage of starting South African Lyrics.

So in conclusion, our most important decision is to have a wap site for those who couldn’t use the app for any reason. The wap site adverts picked up faster than the mobile apps and today, we have expanded to 2 other african countries, the third one in progress, funded exclusively from the money made from the ads on the wap site.

I believe Nigeria is a big market and soon, apps will start to do well, but for startups, my advice is to build a web/wap site. If you think you have a chance of winning 25K in google app challenge, then please do build a app (case study? AfriNolly), else focus your energy on the web/wap. Then build an app. Also build an app for Android and iOS, they are the easiest to monetize in terms of Ads. Studies have also shown that iOS users tend to even pay for stuff (in app purchases) more than Android users and finally, Blackberry might be dying a slow death in the west, it is still very popular around here, build an app for Blackberry, you might not be able to monetize it, but it will give you the necessary stats you need to pitch if you need to.


Website –
Mobile – (auto detect mobile sites)
Blackberry –
Android –

Comments (2)

Simple Sorting Algorithms Implementations – Part 1

In the below, I will be presenting java source code of popular sorting algorithms. The problem with so many books I have read is that they don’t provide the simplest of solutions. I always consider myself an Hello World programmer. If I pick a new language, the first thing I look for is hello world, if I pick a concept, the first thing I look for is the simplest implementation, not the most optimized solution. NO. So when I look for implementations of algorithms, even if you are going to present me the most optimized algorithm, let me see the simplest, non-optimized implementation first.

When someone asked me why am I using for example, java.util.logging instead of log4j, I tell them, so far java.util.logging is working and I am yet to see a case I can not easily handle with it. So it is with these algorithms, let the reader/student see the simple solution and then present him with the problems with the simple solution, and then the optimized, more difficult to implement solution. If he likes, he can go with the simple implementation, when he finally discovered the problems with the simple implementation himself, it will be easier to understand the complex ones.

The programs below are very simple. Non of them have been optimized, they are meant to introduce to you these algorithms. You can take the code and optimize all you want. I also take care to use only simple data structures, no Lists, or Sets or any class in the collections package.

The below code are just segments of the full code. The important segments. The full source code is publicly hosted on Github

Finally if you want to read-up on these algorithms, please head to wikipedia

The algorithm below is based on the assumption that after every run through the array, the last element is already sorted.

for run1, the nth element is sorted,
for run2, the n-1th element is sorted,
for run3, the n-2th element is sorted, etc

	public void sortList(int n) {
		boolean swapped = true;
		while(swapped) {
			swapped = false;
			for(int i = 1; i < n; i++) {
				if (toSort[i] < toSort[i - 1]) {
					swap(i, i - 1);
					swapped = true;
			n = n -1;


	public void algorithm() {
		for(int i = 1; i < toSort.length; i++) {
			int key = toSort[i];
			int k = i - 1;
			while(k >= 0 && toSort[k] > key) {
				toSort[k + 1] = toSort[k];
			toSort[k + 1] = key;


	private void sortList(int startIndex) {
		int minIndex = findMinimum(startIndex);
		if(minIndex != startIndex) {
			int temp = toSort[minIndex];
			toSort[minIndex] = toSort[startIndex];
			toSort[startIndex] = temp;
		if(startIndex < toSort.length) {
			//recursively call sortList

	public int findMinimum(int startIndex) {
		int min = toSort[startIndex];
		int minIndex = startIndex;

		for(int i = (startIndex + 1); i < toSort.length; i++) {
			if(min > toSort[i]) {
				min = toSort[i];
				minIndex = i;
		return minIndex;

In the Part 2 of this post, I will show codes for MergeSort, QuickSort and HeapSort.

Source Code: Github

Comments (2)

Codename One Dynamic Ads Component

Codename One (CN1) really took off with a blast. Although still in beta, but loads of people are already using it for various apps, from banking to a mobile front for this. What is commendable is the ease with with you can build mobile apps that are truly cross platform without having to install tools for each platform.

If you are still wondering what CN1 is, please head to CN1 Website and read up about it for yourself.

I am going to be doing a series of tutorials or useful code snippets for CN1. Today we are looking at the ads component.

To use codename one ads, you need to register and have an account on inner active

Here are the steps to getting your ads on your CN1 app

  1. Create an account on inner active
  2. After login in, click the Add App tab and provide details for your app. The trick is to create different apps for different platforms so that inner active don’t go displaying a download app link on the appstore to blackberry users. You can also profile by age group and/or location.
  3. For every App you added like this, inner active will generate a unique key for you. Key this key.
  4. Now in your code, create an hash table that holds all the keys mapped to the specific platform and populate it. Then write a method as in below to add the ads component to the form.
    public static final Hashtable adKeys = new Hashtable();
    adKeys.put("rim", "[inner_active_rim_ad_key]);
    adKeys.put("and", "[inner_active_android_ad_key]");
    adKeys.put("me", "[inner_active_others_ad_key]]");
    public static void showAds(Form f) {
        Ads ads = new Ads(adKeys.get(Display.getInstance().getPlatformName()).toString());
        if (!f.contains(ads)) {
            f.addComponent(BorderLayout.NORTH, ads);

Now for every page where I want to show the ad, I just call the above method and pass the form instance. Notice however that all my forms are BorderLayout and the North part is reserved for ads.

If you want to however use any type of layout other than border layout, you can use this code to add the ads component to the top of the page

Ads ads = new Ads(Helpers.adKeys.get(Display.getInstance().getPlatformName()).toString());
if (!f.contains(ads)) {
f.addComponent(0, ads);

That’s it, you now have Ads. You can visit your inneractive dashboard to see how your App is doing.

Comments (6)

CodenameOne: Another Java Promise Delivered

Back in 2001 when I started reading about this new programming language  called Java, I have only being a programmer for a few months and I see nothing serious about the mantra, “write once, run anywhere“. Don’t blame me, I have just learnt how to make a div jump using javascript and wrote a few arithmetic functions in pascal.

Fast forward to 2003, I have read about C/C++ and I have done more than my fare share of pascal, I never really got the hang of web programming, so I really suck at javascript then, but once again I started reading about Java and this time around something really caught my attention: The book I was reading said “Java can run on anything that has a memory and a microprocessor“. The author said,

soon your fridge will be able to determine when you are low on say milk and automatically make an order using you predefined credit card, soon, you TV will be able to send emails, soon, your credit card will be able to store more information that your account number, and these will be made possible by java.

Now those are pretty big claims to make in 2003, now? not anymore, even though your fridge can’t yet make orders, but the possibility is there and is not really something very difficult to do. But I digress, last week I was installing JRE for a client and Oracle said on the installer that Java runs on 2.5 billion devices! Great numbers right? but no, those numbers meant nothing to me if Java can’t run on iOS. iOS is the biggest mobile operating system out there and powers millions (if not billions) of devices and yet, Java can’t run on them. Those iOS devices are actually in every home right now (maybe not), but the point is Java could run on a gazillion devices, but they meant nothing if it isn’t running where it matters. One can argue that Java powers Android devices, yes, but that doesn’t dispute the fact that iOS devices are actually very important if you are an app developer.

Another place where Java is failing in it’s promises is the write once, run everywhere mantra, no it doesn’t work for mobile devices. There’s no way your can write once and run everywhere in mobile space, you write and write and write and hope and pray it runs on a few devices.

But all that is about to change. Enter Codename One. I don’t even know how to define what Codename One is, all I know is

  1. Now you can write once and run on every mobile platform.
  2. Your Java code can finally be made to run on iOS devices.

You can head to the Codename One Website to learn more about the goodies that it has to offer. I have successfully tested and seen a single code base running on Android (ICS), Blackberry (OS 4.2 and above) and Java ME feature phones (MIDP 2.0 and CLDC 1.0 and above). I didn’t have to make any changes to the codebase, and believe me the UI looks pretty cool.

Development is also easy, all you need is Netbeans. It comes with a GUI builder and a Simulator. One thing you will notice again is that the Simulator is fast. Very fast! Have you tried to develop for Android and Blackberry? Then you will notice that the Codename One Simulator is order of magnitude fast.

If you’ve been following the mobile app development space for a while, you would have heard of LWUIT, Codename One is built on LWUIT but is far more than that, the GUI Builder generates one of the most efficient code I have seen a GUI Builder generate. It throws away most of the fluff GUI Builders add to your code. It also builds your GUI as a state machine, such that you can think of your application as a series of states.

I can go on and on.

Codename One is currently in private beta and I believe beta is not far out (I am not speaking on behalf of the developers, but based on my perceived success of the private beta). I recommend you give it a try, you’ll be amazed.

Below are some sample screen shots from the application I built using Codename One private beta

And here is a live application

J2ME and RIM:



Comments (2)

Book Review: Java the Complete Reference, 8th Edition

Java, the Complete Reference, 8th Edition has been updated according to changes in Java 7. For those not willing to read the whole review, I will say my conclusion is, be you a beginner or an expert Java developer, you need to read this book.

This book is an in-depth guide to the Java language. A very large portion of the core Java APIs are discussed comprehensively. The book has four parts, plus appendix and index.

PART 1: The Java Language

This part has 14 chapters and comprises discussions ranging from the simplest to the fairly complex. It starts with a history of Java and ends with a discussion on Generics, touching topics like Annotations, IO, Threading and Exceptions along the way. I particularly like the part that talks about C programming language, extolling the virtues of the language. Of course no Java book is complete without talking about OOP (Object oriented Programming) and chapter 2 of part 1 did justice to this. One good thing for beginners is that you start writing code straight from chapter 2. If you are an experienced programmer, you can safely skip to chapter 10. Although I recommend reading everything.

Chapter 1: The Introduction and Evolution of Java

Chapter: 2: An Overview of Java

Chapter: 3: Data Types, Variables and Arrays

Chapter: 4: Operators

Chapter: 5: Control Statements

Chapter: 6: Introducing Classes

Chapter: 7: A closer look at methods and classes

Chapter: 8: Inheritance

Chapter: 9: Packages and Interfaces

Chapter: 10: Exception Handling

Chapter: 11: Multithreaded Programming

Chapter 12: Enumerations, Autoboxing, and Annotations (metadata)

Chapter 13: I/O, Applets and Other topics

Chapter 14: Generics


PART 2: The Java Library

This part also has 14 chapters, taking the chapters count to 28. Here the book discusses the core Java Library; which includes Strings, NIO, Networking, java.util package, AWT, concurrency and Regular Expressions. This is the chapter for you if you are an experienced developer. Here, the book discusses the new Java 7 Features and more. I’ll advice beginners to read the Part 1 at least twice before diving into Part 2.

Chapter 15: String Handling

Chapter: 16: Exploring java.lang

Chapter: 17: java.util Part 1: The collections framework

Chapter: 18: java.util Part 2: More Utility Classes

Chapter: 19: Input/Output: Exploring

Chapter: 20: Exploring NIO

Chapter: 21: Networking

Chapter: 22: The Applet Class

Chapter: 23: Event Handling

Chapter: 24: Introducing the AWT: Working with Windows, Graphics and Text

Chapter: 25: Using AWT Controls: Layout Managers and Menus

Chapter 26: Images

Chapter 27: The Concurrent Utilities

Chapter 28: Regular Expressions and Other Packages


PART 3:  Software Development Using Java

This part discusses some really very import ant Java concepts. It contains just 4 fully packed chapters, recommended for both beginners and experts alike

Chapter 29: Java Beans

Chapter 30: Introducing Swing

Chapter 31: Exploring Swing

Chapter 32: Servlets


PART 4: Applying Java

In this part, we have two chapters. Each chapter picks a real world Java application. describes and implemented it. A note to beginners here, because of the volume of code you will be required to type, you might want to do copy-and-paste, but I strongly recommended against that. Doing the typing will definitely help you in more ways than one. This chapter concludes this book, bringing the number of chapters to 34.

Chapter 33: Financial Applets and Servlets

Chapter 34: Creating a download manager in Java


Appendix and Index.

In the appendix, javadoc is discussed. I particularly like and recommend this part to all. Documenting code is very important and should be embraced by all.


In summary, this is a good book, read it, study it, use it as a reference, whatever you decided to do with this book, you will find out it is more than equal to the task.

Great thanks to Faltermeier Bettina for providing me the preview copy.

Comments (2)

Defying the Odds: Setting up Oracle NoSQL DB on MAC, using VMs for replication

I have a Macbook Pro, 2010 Model with 8GB of RAM. While reading the Admin Guide for the Oracle BigData release, it says that only linux and Solaris OSes are supported for now. I hissed and went ahead anyway. Next It said I shouldn’t setup multiple nodes using a Virtual Machine, another hiss.

The reason why I hissed was I was pissed, why Linux and Solaris, and now I couldn’t use VM? I went back to the Guide to see why, but the reasons given wasn’t convincing, so I went ahead and started the deployment on my mac. My disobedience paid off, not only did it work on a Mac, I was able to setup other Nodes using VM running on the same Box.

I have two VMs running headless. The type of Networking is Bridged. I have a wireless router that also has ethernet port, I hooked my Mac up on both the wireless and the LAN. I use the LAN for the Brigded networking on the VMs and the WIFI for my MAC.

This is all the setup you will need. Note that of you have read the Admin guide, you will see things like node1, node2 etc used to name the systems on which the different instances of the NoSQL DB is running, to avoid having to go into naming and hosts file and that, we will just use the IP addresses, they also work.

I am going to assume that my MAC ip address is, and the VMs are and respectively.

After installing the NoSQL DB on all three machines (My MAC and the two VMs.), I run the below commands in the same directory as where the NoSQL DB is installed.

mkdir Data
./bin/kvctl makebootconfig -root Data -port 5000 -admin 5001 -host 192.168.1.[4,5 or 6] -harange 5010,5020
./bin/kvctl start -host 192.168.1.[4,5 or 6] -root Data

The above will create a config in /Data and start the NoSQL DB.

Next, you need to run the below command on only

./bin/kvctl runadmin -port 5000 -host -script script.plan.txt

The content of script.plan.txt is

configure mystore
plan -execute -name "Deploy Boston DC" deploy-datacenter "Boston" "Savvis"
plan -execute -name "Deploy Node1" deploy-sn 1 5000
plan -execute -name "Deploy Admin" deploy-admin 1 5001
addpool BostonPool
joinpool BostonPool 1
plan -execute -name "Deploy Node2" deploy-sn 1 5000
joinpool BostonPool 2
plan -execute -name "Deploy Node3" deploy-sn 1 5000
joinpool BostonPool 3
plan -execute -name "Deploy the Store" deploy-store BostonPool 3 300

If all went well, visit from you browser and click on topology.

For a description of the commands in the script.plan.txt see the Adming Guide.

Comments (1)

Older Posts »