Archive for the ‘Open Source’ Category

jDCBot nearing its finale – The 1.0 milestone


2008
06.21

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.

Grep: The single most useful command of Linux.


2008
04.21

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!

Peach: Big Buck Bunny…. Coming Soon


2008
03.19


To download the trailer in HD and other resolutions or find several mirrors, click here


Hi Definition streaming version

This movie is coming soon near you, and what’s more this movie is completely FREE! You can also get the original source of the movie for free again. This is an Open Source Movie!!! Visit its site at www.bigbuckbunny.org and peach.blender.org.