jDCBot nearing its finale – The 1.0 milestone

The open source project DC client framework jDCBot (http://jdcbot.sourceforge.net) I have been working on is now nearing its 1.0 milestone. Version 1.0 means that it will have all the required features that a DC client framework should have, like – managing shared files, hashing them, creating file lists, queuing downloads and resuming them when the source is available, multi-source downloading, etc.

This framework has been created from scratch, so unlike other DC clients which share DC++‘s code for the core functionality and hence provide similar features, jDCBot will provided unorthodox features. For example DC++ clients and its derivatives allow users only to provide different user names and passwords for different hubs. jDCBot on the other hand allows you to be passive or active in different hubs. So you can be passive and active both at the same time. This is useful in situations when say you are inside your college LAN and you want to connect to hubs inside the LAN and outside on the Internet too. In this case DC++ and derivatives will force you to be passive, but in jDCBot you can be active for inside your LAN and passive for outside the LAN. Well, you also get to set different descriptions, email addresses and connection types too.

There some other cool features too which are not present in other clients like allowing you to set different upload speeds for different users (this way you can give your friends a boost), blocking upload to particular users (could be misused but we are giving the power and it is upto the clients who will use jDCBot to make the decisions), using the virtual file list concept which allows the users to organize their share into virtual directories without actually reorganizing the files, the file names in file list can even be different from the original allowing the user to rename the file in the file list without rehashing or allowing the user to re-associate the virtual file with the actual file after the original file name/path changes so that rehashing is not required, and many more. Last but not the least it is pure JAVA framework and hence is platform independent and is very modular.

Rush Hour 3 – Review


Yesterday I saw Rush Hour 3. I know it was released long ago, in fact one year ago, but I have much less time or rather I love to do others tasks more and so movie watching takes a back seat. Anyway back to the movie. This is one of the most ridiculous movies I ever have seen, yes there are some, much more ridiculous, but its one scene broke all limits and forced me to actually blog about it!

Warning story spoiler (huh! as if it has any story)

This movie uses numerous well known formulae to create its plot. This movie has a typical protagonist (Jackie Chan) who has an evil brother – the villain. The protagonist tries to shrug off any fact that he actually still cares about his evil brother, but he indeed does care about him. The evil brother in question doesn’t give a damn about his protagonist brother, but he is very much aware about his brother’s weakness for him. So much so that the evil brother doesn’t fear a gun at his temple when pointed by his protagonist brother, after all the writer of the story has given him his word. The movie’s focal point was that a criminal secret society has (again) a secret ridiculous ritual. Because of the only reason that they
want it to remain secret that they rough-up and kill people. The same old story. Yawn!

The movie starts with a scene with a traffic cop (Chris Tucker), iPod in his ears, guiding the traffic or shall we say just dancing. Here we get to meet the typical black side-kick that many movies have. Oh, yes, by-the-way the evil brother – the villain, is not the main villain, as it can very well be assumed when a villain is shown in the very first 15 mins of the movie. Another typical formula, make an old, caring and father figure the main villain. I had a gut feeling who was the main villain from the very beginning, so much so, when I saw the protagonist trusting him so much I felt like going through the screen and pull Jackie Chan’s ears and tell him – You fool, can’t you see he is the real villain, haven’t you seen enough movies? The movie is peppered with ridiculous moments, I am still coming to the biggest of such moments. In one scene when Jackie and his associate reach the hospital where the shot ambassador was kept, they find not a single security personnel. During this time the villainous gang attack but our heroes save the day, as expected. Later nowhere in the movie they raise question about it. As if they had an amnesia and now none of them remember that they were just now attacked and mysteriously there was no one else to cover.

Now the biggest ridiculous moment of all. This is the only scene that actually forced me write this blog – This is my first movie review. This was so so (double ‘so’ was intended) ridiculous. In the climax of the movie it was shown that the mafia has control over the Eiffel Tower! Not even that, they even happen to have a plush apartment up there, and nobody in France seems to be bothered about it or maybe they don’t know about it – Ah the might of the writer’s pen, they can make anything possible. The last scene too was kinda funny. When the old, caring and father figure main villain, points his caring gun at our protagonists, a shot is fired, and (here we go again) as always he gets the shot, but from a cab driver who wanted to kill someone without reason (‘to become a true American’), and as this was not a ‘no reason’ hence his dreams were shattered. Poor driver. Then happens the funny part. The dying old, caring and father figure main villain walks up to the pool to take his eternal plunge. In many movies the villains take plunge into the near-by pools when they are shot (during the climax), as if to hide their shameful faces, but never before I had ever seen them walk for meters for the plunge. He didn’t looked like he was shot, rather he looked like a tired person lost in the desert and seeking water. Brett Ratner you could have made him walk up close to the pool when he was alive and then he could have just fallen into it without the walking stuff. Anyway this last part did really give me the laughs.

Conclusion

What can I conclude? You have nothing else to do and have no other options then, well, you have no other options, so see this movie, else recommend this movie to your enemy.

Get my Javadoc StyleSheet – Red N Black Theme

I recentry created the brand new site for jDCBot (http://jdcbot.sourceforge.net ). For the Javadoc section I wanted the Javadoc to match the site’s red and black theme. Below is its screenshot. Click on it for a better view, or even better visit jDCBot’s site (link is above) and goto to the Javadoc section.

Well anyway, below is the script.
The code
License: GNU Public License version 3.

/* Javadoc style sheet theme - Red N Black - by Nirupam Biswas (AppleGrew)*/

/* Define colors, fonts and other style attributes here to override the defaults */

/* Page background color */
body { background-color: #FFFFFF; color:#000000 }

/* Headings */
h1, h2, h3 {
font-family: Arial, Helvetica, sans-serif;
color: #555555;
}
h1 {font-size: 145%;}

a:link {
line-height: 14px;
font-weight: bold;
text-decoration: none;
color: #444444;
}
a:visited {
color: #777777;
text-decoration: none;
font-weight: bold;
}
a:hover {
border-bottom: 2px solid #666666;
}
hr{
color: #666666;
background-color: #666666;
text-align: left;
border: 0;
text-align: left;/*this will align it for IE*/
margin-left: 0; /*this will align it left for Mozilla*/
}

/* Table colors */
.TableHeadingColor     { background-image:url(javadoc.jpg); background-repeat:repeat-x; color:#FFFFFF;}
.TableHeadingColor a:link, .TableHeadingColor a:visited {
color: #bbbbbb;
}
.TableHeadingColor a:hover {
border: none;
background-color:#666666;
}
.TableSubHeadingColor  { background: #EEEEEE; color:#000000 }
.TableRowColor         { background: #FFFFFF; color:#000000 }

/* Font used in left-hand frame lists */
.FrameTitleFont   { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
.FrameHeadingFont { font-size:  90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
.FrameItemFont    { font-size:  90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }

/* Navigation bar fonts and colors */
.NavBarCell1    { background-image:url(javadoc.jpg);}
.NavBarCell1 a:hover {
border: none;
background-color:#666666;
}
.NavBarCell1Rev { background-color:#666666; color:#FFFFFF}
.NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}

.NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
.NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}

Also please save the following image and save it in the same directory with the style sheet above.

Make the top bar (navbar) disappear.

I once made a similar post. That trick no longer works since blogger.com’s upgrade. Now I have a new cleaner and better trick to make the top banner disappear. Add a new HTML/Javascript widget to your template. Now in this template add the following code.

<!--exclusively BY APPLEGREW (applegrew.blogspot.com),
HIDES Navbar -->
<style type="text/css">
div#navbar { display: none; }
</style>
<!--end of HIDE Navbar-->

Now save the widget and reload the page.

A tip. The navbar won’t disappear until this code gets loaded, hence make it gets loaded faster. Simply put it in head portion of your template.

My first GreaseMonkey script: Blogspot Post PrintView

My first GreaseMonkey script. It provides print option for your posts hosted in blogspot.com. When this script is running a ‘Print’ option will appear next to post’s date header. It depends heavily on the internal code of the template, hence it can very well not work on many non-stock themes and some stock themes.

You can install this from here. I highly recommend that you install it from there.

Anyway I am also providing the code below.
The code
License: GNU Public License version 3.

[code lang=”javascript”]
// Show Posts in Blogspot in Print View
// version 0.1 beta
// 2005-05-02
// Copyright (c) 2008, AppleGrew
// Released under the GPL license
// http://www.gnu.org/copyleft/gpl.html
//
// ——————————————————————–
//
// This is a Greasemonkey user script. To install it, you need
// Greasemonkey 0.3 or later: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "Access Bar", and click Uninstall.
//
// Usage: When using this script then a new word ‘Print’ will appear
// beside every post’s posting date header.
// ——————————————————————–
//
// ==UserScript==
// @name Blogspot Post PrintView
// @namespace http://applegrew.blogspot.com/search/label/Greasemonkey%20Scripts/
// @description Show Posts in Blogspot in Print View
// @include http://*.blogspot.com/*
// @include file:///home/apple/Desktop/AppleGrew’s%20Mind.html*
// ==/UserScript==

var head, js;
head = document.getElementsByTagName(‘head’)[0];
if (!head) { return; }
js = document.createElement(‘script’);
js.type = ‘text/javascript’;
js.innerHTML =’function printview(id){location.href =location.href + "?print=1&id="+id+""; return;}’;
head.appendChild(js);

var isPrintMode = false;
var qs;
var ID=-1, postClass="post";
if (qs=location.href.match(/\?print=1&id=(\d+)&postclass=(\S+)/i)){
if(qs[1] && qs[2]){
isPrintMode = true;
ID = qs[1];
postClass = unescape(qs[2]);
}
}

var allDates, allPosts;

var postDiv = document.evaluate(
"//div[@class=’blog-posts hfeed’]",
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null);

var postDivChildren;
if(postDiv && postDiv.singleNodeValue)
postDivChildren = postDiv.singleNodeValue.childNodes;

if(postDivChildren){
for (var i = 0; i < thisdate =" postDivChildren[i++];" thisdate="postDivChildren[i++];" var="" thispost="postDivChildren[i++];" tagname="" i="" thispost="postDivChildren[i++];" thisdate="" id="" postid="" posttimestamp="thisDate.textContent;" newdiv="document.createElement(‘div’);" var="" divhtml=">h2dateid" href="http://www.blogger.com/post-edit.g?print=1&id=%27+i+%27&postclass=%27+thisPost.getAttribute%28" innerhtml =" DivHTML;" dateid = "dateid" postid = "postid" newbody = "<div\">"+document.getElementById(dateid).innerHTML+
"</h2><div"+postClass+"\"">"+document.getElementById(postid).innerHTML+"</div></div>";
document.body.innerHTML = newbody;

}
[/code]

Grep: The single most useful command of Linux.

I love Linux. Why? Because it has so many cool cool cool … commands like grep, sed, find, etc. Of all the commands, I use grep the most. If grep is taken out of Linux then I will be severely crippled. Almost everyday I need to use it.

I will give you a recent case where I fixed a bug in LinuxDCpp in just 15 mins even when I had never looked into its code before and I had absolutely no experience building GUI applications in C++ or using GTK libraries.

I am using LinuxDCpp 1.0.1 which has a problem of not beeping when private messages are received even when I have configured it to do so. Because of this I had to repeatedly open the window of LinuxDCpp to check for new private messages. Then, one fine day I decided to fix this. The only problem was how and where. To answer my these questions I needed a starting point to start searching from. I had an idea; I realized that the best place to start searching from is the text – “Beep every time a private message is received“, this is the text that is displayed in the Preferences dialog of LinuxDCpp. I then un-tared the the source code of LinuxDCpp and opened the console in that directory, then I ran the command

$ grep -Rl "Beep every time a private message is received" .

Which yielded the result

./glade/settingsdialog.glade

I then opened that file and located the message. The code there read as following.

<child>
<widget class="GtkCheckButton" id="soundPMReceivedCheckButton">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="label" translatable="yes">
             Beep every time a private message is received</property>
        <property name="use_underline">True</property>
        <property name="draw_indicator">True</property>
</widget>
<packing>
        <property name="expand">False</property>
        <property name="fill">False</property>
</packing>
</child>


From my experience of HTML and common sense, I knew that soundPMReceivedCheckButton is the text that need to search for next. Hence I ran the command

$ grep -Rl "soundPMReceivedCheckButton" .

Which yielded the output

./linux/settingsdialog.cc
./glade/settingsdialog.glade

The second line was expected, but the first line contained the destination I must head to next. The code in that file read

// Sounds
sm->set(SettingsManager::PRIVATE_MESSAGE_BEEP, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(getWidget(
  "soundPMReceivedCheckButton"))));
sm->set(SettingsManager::PRIVATE_MESSAGE_BEEP_OPEN, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
  getWidget("soundPMWindowCheckButton"))));

From here on knowledge of C++ was required, but still grep was helpful. The lines spoke to me that there is a an object ‘sm’ which has a method ‘set’ which allows to set the properties of the program. PRIVATE_MESSAGE_BEEP is a constant which means that LinuxDCpp must beep on receiving the private message. From common sense, I concluded that the part of the program which actually generated the beep too must check for whether the property is SettingsManager::PRIVATE_MESSAGE_BEEP or not; in other words, that part of the program too must have the text PRIVATE_MESSAGE_BEEP. Hence my next command

$ grep -Rl "PRIVATE_MESSAGE_BEEP" .

I got the following outputs.

./client/SettingsManager.cpp
./client/SettingsManager.h
./linux/settingsdialog.cc
./linux/privatemessage.cc

As we already have seen the definition SettingsManager::PRIVATE_MESSAGE_BEEP, which clearly meant that PRIVATE_MESSAGE_BEEP must have been defined in the file SettingsManager.h. The only interesting result among them is privatemessage.cc. There I at last found what I was looking for. The code read

if (BOOLSETTING(PRIVATE_MESSAGE_BEEP_OPEN))
  gdk_beep();

In that very file the searched for gdk_beep() which took me to the code

if ((state & GDK_WINDOW_STATE_ICONIFIED) || mw->currentPage_gui() != getContainer())
  gdk_beep();

This is the code which was actually triggered on receiving private message and the code above that is activated when the private message window is opened.

The clear culprit was gdk_beep(). From Goggling out I found that it is part of GTK/GDK library and it is supposed to produce a beep from the internal speaker of the computer, but as per the many posts I saw on the various forums, it usually didn’t work. The only solution was to replace that with some other code. The easiest I could think of was using an external command to play a sound file. I opted for aplay which is usually installed on all current Linux computers. Also, I coded it such that user can configure LinuxDCpp to use any other commands by setting LINUX_DCPP_SND environment variable to the command to execute on receiving private message. For that I replaced

if (BOOLSETTING(PRIVATE_MESSAGE_BEEP_OPEN))
  gdk_beep();

with

if (BOOLSETTING(PRIVATE_MESSAGE_BEEP_OPEN))
{
//Added by AppleGrew
const char *sndCmd = getenv("LINUX_DCPP_SND");
if(!sndCmd) {
        string cmd = "aplay \"/usr/local/linuxdcpp/ping.wav\"";
        system(cmd.data());
}else{
        system(sndCmd);
}

I then edited the SConstruct file to automate the copying of the ping.wav file. For that added th following codes.

snd_file = ['ping.wav']
env.Alias('install', env.Install(dir = env['FAKE_ROOT'] + env['PREFIX'] + '/share/linuxdcpp', source = snd_file))

But, there was still a big problem. The SConstruct allowed the user to install it in /usr directory (the default is /usr/local). That meant I somehow needed to find out during runtime the location of the files. LinuxDCpp was already able to locate its pixmap (graphics) files, which are stored in the location – prefix_loc/pixmaps (prefix_loc is either /usr or /usr/local), I just needed to locate that code. It was clear that whatever mechanism LinuxDCpp was using, it will undoubtedly return the location /usr or /usr/local, and hence the code that accessed the pixmap files then would have to create the pixmap location as

string pixmap_location = function_or_method_that_gives_the_prefix_location + "/pixmaps"

Hence I ‘grepped’ for pixmaps.

$ grep -Rl "pixmaps" .

Which yielded

./Changelog.txt
./Readme.txt
./linux/hub.cc
./linux/mainwindow.cc
./SConstruct

And then and there I found what I was seeking.

// Load icons. We need to do this in the code and not in the .glade file,
// otherwise we won't always find the images.
string file, path = WulforManager::get()->getPath() + "/pixmaps/";

WulforManager::get()->getPath() was the method I needed. Now the new code in privatemessage.cc read

if (BOOLSETTING(PRIVATE_MESSAGE_BEEP_OPEN)){
//Added by AppleGrew
const char *sndCmd = getenv("LINUX_DCPP_SND");
if(!sndCmd) {
        string cmd = "aplay \"" + WulforManager::get()->getPath() + "/ping.wav\"";
        system(cmd.data());
}else{
        system(sndCmd);
}[/code]

This was it. Nice and smooth. I still don't know anything about WulforManager or SettingsManager declarations or the GTK libraries, yet I could finish this up fast and smoothly. All thanks to grep!