K3b – How to ‘write’ CDs

K3b is as famous as Nero in the GNU/Linux world as a GUI for burning CDs. It works with both GNOME as well as in KDE (which is its native). I have been using it for more than 3 years now. Its another wonderful piece of software that makes life easier. But, since I got it on my Laptop I had not used it really to ‘burn’ CDs/DVDs because it failed to write.

Whenever I select an image/file to burn into a disk, and click the ‘burn’ button, it does something for sometime and then pops up a message saying I do not have enough permissions over cdrecord to write into the disk. So, cdrecord command had become my favourite.

A couple of days ago, I got determined to end this issue as I have to show them at the up coming GNU/Linux demo at a Coimbatore college. So, I sought the help of my buddies in KDE-In. Thankfuly floyd_n_milan came to my rescue. It was actually a problem of proper permission for the device to be writable. If you are facing the same problem this is what you have to do…

1. On the top menu, Settings –> k3b Setup. It opens up a window, where permissions on various devices are listed. Look for the device named cdrecord and its permissions. It should be ‘4710 root.burning’. If its not having ‘burning’ in it, then the burning group does not exists.

2. Now to add the burning group, open up a terminal and enter the following commands


$ groupadd burning
$ gpasswd -a username burning

3. Now we have a burning group. Check the top of the k3b setup window, where there will be a checkbox labelled ‘Use burning group’ and with a value ‘burning’. Check that one and press apply.

Thus, we have enabled a burning group and made it active. Now, try to burn a CD/DVD. Hurray! We would be able to 🙂

Qt4 from source

I had installed Qt4, Qt3-designer and Qt3-assistant from Ubuntu repos. I had been using Qt3-assistant examples and writing them in PyQt4, whole the document I was referring actually corresponds to Qt3.

Pradeepto was looking at my earlier blog post which had a PyQt4 code and pointed to me that I was rather working with PyQt3/Qt3. He was the one who suggested to make a source install of Qt4, as everything comes with it in one go. So here are the steps..

1. Download the source tar ball from the Qt’s home page which is Trolltech’s Qt Download site.

2. Untar the tar ball where ever you like to have it.

3. Like a typical source installation, with your current working directory pointing to the directory where you extracted the tar ball, run the following after one another in a terminal/console.


$ ./configure # check ./configure --help to know more options like -debug
$ make -j 4 # this may freeze your computer, do it if you have a powerful horse!

4. The ‘make’ command will build Qt4 from source. Generally, we run ‘make install’ also, which will install the built files in appropriate fixed locations. But, this is not mandatory, we can still run Qt4 from where we built it with a few additional things.

5. First, we need to add the files in /bin of Qt4 into the path; likewise the librariries and docs as well. We can sym link the files to existing path such as ‘/usr/bin’. Or else, we can set a few environment variables and proceed with out work. This can be done with a simple shell script, which needs to be executed before we start working with Qt4 everytime.


export QTDIR=/home/joe/qt-4.2.2
export PATH=$PATH:$QTDIR/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QTDIR/lib
export PKG_CONFIG_PATH=$QTDIR/lib:$PKG_CONFIG_PATH

6. When I openned up qt4-assistant, it showed me an error pop up stating that files were not found at a specific location. So, I had to copy these files to that specific location. I tried sym link but unfortunately it did not work, so I copied them rather.

Destination: /usr/share/qt4/doc/html/    Source: $QTDIR/doc/html/
assistant.dcf
designer.dcf
linguist.dcf
qmake.dcf
qt.dcf

The above files can either be sym linked (if it works for you) or copied by creating the destination directory. Now, open up the qt4-assistant and you should be able to see the contents.

7. I have a problem, rather a bug, which I suspect to be specific to Ubuntu Edgy. When I export the above paths and open up qt4-assistant or qt4-designer, as well sym link both to ‘/usr/bin’ or anywhere, the fonts on the window is not rendered properly. But, when I execute them from the place where I built them, which happens to be under ‘home’ directory, they get rendered properly. This is quite odd and till now I haven’t got a reason and solution to this.

This is just an account of my experience of installing Qt4 from source. But it was rather a very good experience. Installing from source is always fun, except when you get caught in a maze of dependencies 😀

Switching between Ubuntu/Kubuntu/Xubuntu uspalsh

When I installed Kubuntu desktop to try KDE in my laptop, it replaced my earlier Ubuntu usplash such that when I booted up it showed a kubuntu splash screen. I have been wondering how to change this back for almost a month now, having tried a few tricks which did not work.

Today, when trying to get something for ‘tuxplorer’s query, I got to see this ubuntu forum post which actually helped me in getting back my ubuntu usplash screen. Here is what you gotta do..

techno_freak@edgy:~$ sudo update-alternatives --config usplash-artwork.so
Password:

There are 2 alternatives which provide `usplash-artwork.so'.

Selection    Alternative
-----------------------------------------------
1    /usr/lib/usplash/usplash-theme-ubuntu.so
*+        2    /usr/lib/usplash/usplash-theme-kubuntu.so

Press enter to keep the default[*], or type selection number: 1
Using `/usr/lib/usplash/usplash-theme-ubuntu.so' to provide `usplash-artwork.so'.
techno_freak@edgy:~$ sudo dpkg-reconfigure usplash
update-initramfs: Generating /boot/initrd.img-2.6.17-10-386

Triggers in PostgreSQL – Quick Example!

I tried my first hand on PostgreSQL Triggers yesterday. Actually my current project needs some triggers, but I decided to try with a test table and create a trigger for it.

There are two tables, ‘addressbook’ and ‘phonebook’. The ‘addressbook’ is the main table in which data is to be entered. The structure of ‘addressbook’ is as follows.

Table "public.addressbook"
Column  |          Type          |                        Modifiers
----------+------------------------+----------------------------------------------------------
id       | integer                | not null default nextval('addressbook_id_seq'::regclass)
name     | character varying(100) |
address1 | character varying(100) |
address2 | character varying(100) |
address3 | character varying(100) |
phonenum | character varying(15)  |
Indexes:
"addressbook_pkey" PRIMARY KEY, btree (id)
"addressbook_name_key" UNIQUE, btree (name)

The ‘phonebook’ is another table with just stores ‘name’ and ‘phonenum’ fields of the ‘addressbook’. The structure of ‘phonebook’ table is,

Table "public.phonebook"
Column  |          Type          |                       Modifiers
----------+------------------------+--------------------------------------------------------
id       | integer                | not null default nextval('phonebook_id_seq'::regclass)
name     | character varying(100) |
phonenum | character varying(15)  |
Indexes:
"phonebook_pkey" PRIMARY KEY, btree (id)

Now, when a data is inserted into the ‘addressbook’ table, the ‘name’ and ‘phonebook’ values being inserted should also be inserted into the corresponding fields of ‘phonebook’ as well. For each insertion into the ‘addressbook’ table, there should be a corresponding insertion into the ‘phonebook’ table, which is accomplished using a trigger given below.


DROP TRIGGER phonebook on addressbook;
CREATE LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION add_to_phonebook() RETURNS TRIGGER AS $phonebook$
DECLARE
new_name varchar;
new_phonenum varchar;
BEGIN
IF(TG_OP='INSERT') THEN
INSERT INTO phonebook(name,phonenum) VALUES(NEW.name,NEW.phonenum);
END IF;
RETURN NEW;
END;
$phonebook$ LANGUAGE plpgsql;
CREATE TRIGGER phonebook AFTER INSERT ON addressbook FOR EACH ROW EXECUTE PROCEDURE add_to_phonebook();

This trigger function is named add_to_phonebook(). The SQL statement between BEGIN and END is the actual trigger code.

Let us now check the code by inserting data into the ‘addressbook’ table and check whether the data was inserted into the ‘phonebook’ table or not.

test=# INSERT INTO addressbook (name,address1,address2,address3,phonenum) VALUES ('Peter','Flat #2','3rd Street','Chennai','9842498424');
INSERT 0 1
test=# select * from phonebook;
id  |  name   |  phonenum
------+---------+------------
4025 | Peter | 9842498424
(1 row)

Yes, the trigger has worked. Now, an insertion of a row into ‘addressbook’ will cause insertion of corresponding data into the ‘phonebook’ as well. 🙂

PyProgram #3 – OOP in PyQt

Since foss.in 2006 I have got a special Interest in KDE and GUI development. Its up to such extent that I installed kubuntu-desktop in my laptop and started using it, at laeast when am home. I have also started learning PyQt, ultimately wish to learn PyKDE and contribute to KDE. I have started working with the Qt tuorial, which is in C++. So I have to write the change it to Python i.e. PyQt. Its not a much a problem, rather easy too. But, example 4 had some OOPs in it and I haven’t tried much OOPs in Python before. So, here goes my first OOP PyQt code, which I came up with a bit of struggle for some time.

The original Qt tutorial is here…


#include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h>
class MyWidget : public QWidget
{
public:
MyWidget( QWidget *parent=0, const char *name=0 );
};
MyWidget::MyWidget( QWidget *parent, const char *name )
: QWidget( parent, name )
{
setMinimumSize( 200, 120 );
setMaximumSize( 200, 120 );
QPushButton *quit = new QPushButton( "Quit", this, "quit" );
quit->setGeometry( 62, 40, 75, 30 );
quit->setFont( QFont( "Times", 18, QFont::Bold ) );
connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
MyWidget w;
w.setGeometry( 100, 100, 200, 120 );
a.setMainWidget( &w );
w.show();
return a.exec();
}

And here is my PyQt code…


#!/usr/bin/env python
import sys
from qt import *
class MyWidget(QWidget):
"""MyWidget is a custom widget to display a quit button.
This widget is inheritted from QWidget"""
def __init__(self, parent=None, name=None):
QWidget.__init__(self,parent,name)
self.setMinimumSize(200, 120)
self.setMaximumSize(200, 120)
quitbutton = QPushButton("Quit", self, "quitbutton")
quitbutton.setGeometry(62, 40, 75, 30)
quitbutton.setFont( QFont("Serif", 16, QFont.Bold))
self.connect( quitbutton, SIGNAL("clicked()"), qApp, SLOT("quit()"))
app = QApplication(sys.argv)
w = MyWidget()
w.setGeometry(100, 100, 200, 120)
app.setMainWidget(w)
w.show()
app.exec_loop()

The testing part of the code was how to transfer the ‘constructor’ in C++ to Python. Although Python is Object Oriented, we do not have constructor as in C++. We rather have a __init__ method, which can act as initializer, the job which the constructor does and the same reason for people to call __init__ to be the constructor in Python (which I found to be not the right way, from the Python Documentation and various other sources).

Actually, if you see the code it is pretty obvious that the Python code is easier to understand, easier to code and easier to maintain. Things are small and simple, but still your job gets done. And also, I realized that we can effectively transform (or port) an existing C++ code (or any of the many programing language) into Python code. Hope, I continue on this learning curve and learn things soon, end up writing cool Python Apps contributing to the community.

New Arrivals for December 2006

The month is born and I have got my salary. So, its time to buy a new load of books and I have. Went to Spencers yesterday for a birthday party and as I have landed there a bit early, I went to Landmark. This months new arrival are,

  • the genesis code by john case
  • The Holocraft Covenant by Robert Ludlum
  • The Google Story by David A. Vise
  • Python in a Nutshell by Alex Martelli

2 novels, one fiction and one thriller to quench my thirst this month. I saw some new arrivals under Robert Ludlum, hope I can get hold of a few next month. I have now completed the O’Reilly series for Python. The Google Story was one book I found in my lab and wanted to read very much. Now I have my very own copy. The reality is I haven’t read the books I got last time from LandMark, but everything is on my table and are occassionally brought to my notice 😉 .

PyProgram #2 – Validating start and end dates

Time for another n00b code in Python. My colleague was trying to validate start and end dates, where start date has to be earlier (or lesser) than end date. I always love coding for n00b stuffs like this, so I decided to have some fun.

Problem: Given start_date and end_date, validate the dates for start_date <= end_date and print a message whether date is accepted or rejected.

Solution:

Logic: I tried to use simple if-else-statements for the job, so I hit with the following logic.

check year1 < year2:
yes –> oK
no –> check year1 == year2:
no –> Quit
yes –> check month1 < month2:
yes –> OK
no –> check month1 == month2:
no –> Quit
yes –> check day1 < day2:
yes –> OK
no –> check day1 == day2:
yes –> OK
no = Quit

The start_date and end_date are split into the corresponding day, month and year values held in the arrays dd1 and dd2.

First the years are compred – if year2 is greater than year1, then the flag becomes 1. Else, equality of years is checked, if no then flag becomes 0.

For equal year values, months are compared – if month2 is greater than month1, flag becomes 1. Else, equality of months is checked, if no then flag becomes o.

For equal year and month values, days are compared. If day2 is greater than day1 or if the dates are equal, then flag becomes 1. Else the flag becomes 0.

Finally, if flag is 1 then the dates are accepted and if its 0 the dates are rejected.

Code:


def checker(date1,date2):
if int(dd1[2])def checker(date1,date2):
dd1=date1.split('-')
dd2=date2.split('-')
flag = 0
if int(dd1[2]) < int(dd2[2]):
flag = 1
elif int(dd1[2]) == int(dd2[2]):
if int(dd1[1]) < int(dd2[1]):
flag = 1
elif int(dd1[1]) == int(dd2[1]):
if int(dd1[0]) < int(dd2[0]):
flag = 1
elif int(dd1[0]) == int(dd2[0]):
flag = 1
else:
flag = 0
else:
flag = 0
else:
flag = 0
if flag == 1:
print 'Dates accepted'
else:
print 'Dates rejected'

Test: Now we can check the checker() function, with various possible date values. Here is the result..

>>> checker(’29-12-2006′,’01-01-2007′)
Dates accepted
>>> checker(’20-11-2006′,’20-12-2007′)
Dates accepted
>>> checker(’20-12-2006′,’22-12-2007′)
Dates accepted
>>> checker(’20-11-2006′,’20-12-2006′)
Dates accepted
>>> checker(’20-12-2006′,’22-12-2006′)
Dates accepted
>>> checker(’24-12-2006′,’22-12-2006′)
Dates rejected
>>> checker(’24-12-2006′,’24-12-2006′)
Dates accepted
>>> checker(’24-12-2007′,’24-12-2006′)
Dates rejected

Yay! Done!

Note: This code is to just show how to code in a plain way, for the proposed logic. But, this is not the best way to code in Python. The better way is to make use of built-in modules like ‘datetime’ module, which will help in doing the same stuff in a couple of lines or code, and also thats the Pythonic way of doing things. What I intend is to just show the transformation of a logic into expected result, using a simple python code using nested if-elif-else condition.