Converting CHM file to html and pdf

From http://www.ubuntugeek.com/how-to-convert-chm-files-to-html-or-pdf-files.html


Microsoft Compiled HTML Help is a proprietary format for online help files, developed by Microsoft and first released in 1997 as a successor to the Microsoft WinHelp format. It was first introduced with the release of Windows 98, and is still supported and distributed through Windows XP platforms.
HTML Help files are made with help authoring tools. Microsoft ships the HTML Help Workshop with supported versions of Microsoft Windows and makes the tool available for free download. There are also a lot of third-party help authoring tools available.
CHM files, known as Microsoft Compressed HTML Help files, are a common format for eBooks and online documentation. They are basically a collection of HTML files stored in a compressed archive with the added benefit of an index.
Under Linux, you can view a CHM file with the xchm viewer. But sometimes that’s not enough. Suppose you want to edit, republish, or convert the CHM file into another format such as the Plucker eBook format for viewing on your Palm. To do so, you first need to extract the original HTML files from the CHM archive.
This can be done with the CHMLIB (CHM library) and its included helper application extract_chmLib.
Install Chmlib in Ubuntu
sudo apt-get install libchm-bin
Convert .chm files in to HTML files
If you want to convert .chm files in to HTML files use the following command
extract_chmLib book.chm outdir
where book.chm is the path to your CHM file and outdir is a new directory that will be created to contain the HTML extracted from the CHM file.
Convert .chm files in to PDF files
First you need to install htmldoc. HTML processor that generates indexed HTML, PS, and PDF.HTMLDOC is a program for writing documentation in HTML and producing indexed HTML, PostScript, or PDF output (with tables of contents). It supports most HTML 3.2 and some HTML 4.0 syntax, as well as GIF, JPEG, and PNG images.
sudo apt-get install htmldoc
If you want to use htmldoc type the following command in terminal
htmldoc

Threads in Java can outlive the thread that spawned it!

I often read in Java blogs that main thread is the last thread to die after all other threads die. This is obviously not what I experience. Main thread dies right after it finishes its business, leaving the threads that main spawned working alone. Moreover, if main spawns ThreadA, for example, and main joins ThreadA using Thread.join() method, then main only waits until ThreadA dies, then main dies. If in the process of running ThreadA spawns some other threads, then when ThreadA and main dies, those other threads will keep running if their business is not finished yet.

Interesting comment from this website:

The main() method must indeed have a void return type. From the Java Language Specification on "Execution - Virtual Machine Start-Up" (§12.1.4): The method main must be declared publicstatic, and void. It must accept a single argument that is an array of strings.



A program terminates all its activity and exits when one of two things happens:
  • All the threads that are not daemon threads terminate.
  • Some thread invokes the exit method of class Runtime or class System and the exit operation is not forbidden by the security manager.
In other words, the program may exit before or after the main method finishes; a return value frommain would therefore be meaningless. Therefore the return value of main is void.

main() method has no control over JVM. When JVM starts, it will run main() method, but when main() finishes, it doesn't mean that JVM terminaes. JVM continues to execute all threads until 1) Runtime.exit() is called OR 2) all normal (not daemon) threads have died. Daemon threads do not count for this second condition. In other words ... if main() method spawns some normal threads, JVM will notterminate when main() finishes. If main() doesn't spawn any threads, JVM will terminate. If main() spawns only daemon threads, JVM will also terminate when main() finishes.



Compile and run the following code:

package test;

import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

public class ThreadTest {

/**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub

System.out.println("The current main thread: "
+ Thread.currentThread().getName());

printAllThreads();

ThreadA tc = new ThreadA();
tc.start();

tc.join();
// Thread.sleep(5000);

System.out.println("Exiting main thread.");

}

static private void printAllThreads() {
Map stackTraces = Thread
.getAllStackTraces();
Set< Entry> entrySet = stackTraces
.entrySet();
for (Entry entry : entrySet) {
Thread t = entry.getKey();
System.out.println(">>>>>>>>>> " + t.getName());
}
}
}

----------------------------------------------------------

package test;

import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

public class ThreadA extends java.lang.Thread {

    private volatile int counterA = 0;
    
    public ThreadA(){
        setName("Threadcounter");
    }

    public void run() {

        while (counterA < 10) {
            System.out.println("Printing from within ThreadA: " + counterA++);
            printAllThreads();
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        ThreadB pt = new ThreadB();
        pt.start();
        
        System.out.println("Exiting ThreadA.");

    }

    private void printAllThreads() {
        Map stackTraces = Thread
                .getAllStackTraces();
        Set< Entry> entrySet = stackTraces
                .entrySet();
        for (Entry entry : entrySet) {
            Thread t = entry.getKey();
            System.out.println(">>>>>>>>>> Printing From ThreadCounter: "
                    + t.getName());
        }
    }

    private class ThreadB extends Thread {

        private volatile int counterB = 0;
        
        public ThreadB(){
            setName("Privatethread");
        }

        public void run() {
            while (counterB < 100) {
                System.out.println("Printing from within ThreadB: " + counterB++);
                printAllThreads();
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.println("Exiting ThreadB.");
        }
    }

}

Missing php-xml in standard Fedora installation

So I was developing a small php app which used DOM manipulation classes on my local Ubuntu machine. Everything went fine. Then I uploaded my app to the server which ran Fedora. My app would not work. The DOM classes were not recognized. It turned out that out of the box, php installation in Fedora did not include php-xml package which was needed for DOM manipulation. So, I had to install it.

su
yum install php-xml
yum install php-xmlrpc

First commit to SVN

So yesterday I set up SVN repo in my shared hosting. I have a project in my local computer that I want to get in there. I did "svn import". I did some modification. I did "svn commit". But then SVN threw a message "Skipped '.'" and nothing was committed.

It turns out that doing "svn import" does not make the imported directory a working svn directory. This is proven by the absence of .svn directory in the imported directory. This explains the Skipped '.' message.

The correct way to do it should be like this: after SVN repo is created, check it out into the would be imported directory using svn checkout. This will create .svn directory which makes the would be imported directory a svn working directory. After that, use svn add to add directories and files to the list of dir/files that will be committed, and then do svn commit.

New Eclipse. New Problems.

I got bored of my Eclipse Galileo for PHP. I no longer developed PHP and I used it to develop Java app, so I installed Java EE dev plugin and I thought it made the Galileo got rather bloated. I decided to download afresh Eclipse Helios for Java EE. I unzipped it and clicked the eclipse executable binary. Problems soon followed as I opened the projects I had previously worked on with my Eclipse Galileo.

  1. I no longer can connect to the SVN.
  2. I lost all of my run and debug configurations.
  3. Word completion does not work.
  4. I usually only needed to right click on a Java applet source code or Java code containing main class and choose run, and they ran, now I longer could do that.
I'll talk about all 4 points one by one. 

It turns out that Eclipse out of the box does not have Subversion (which is Eclipse plugin for SVN) installed. This is because installing Subversion is a 2 steps process: First you need to install Subversion plugin, which is provided by Eclipse, and then you have to install a separate connector which is provided by Polarion and not included in Eclipse due to licensing issue.

When I first tried to install Subversion, I did a stupid thing. I added subversion.tigris.org into the update address and then I installed the plugin provided by that address. After being installed, the plugin could not connect to SVN. The correct thing to install Subversion is as follows:
  1. Check for Helios update. Locate the "Collaboration" option. Install "SVN Team provider".
  2. After it is installed, try to connect to SVN repository or do something else SVN related. You will then be prompted to install Subversion connector from Polarion. Choose the latest SVNKit instead of the JavaHL option.
  3. Done!
Now you have "Team" menu when you right click on any Java file. 

But then on the 'Team" menu, I could not find "Update", "Synchronize" or "Commit" option as usual. It seemed that my newly installed Eclipse Helios did not recognize the SVN directories that were created by my previous Eclipse installation. I again did a stupid thing: I deleted all project on my disk and checked out all projects anew. 

I could have saved a lot of time by clicking "Team" and then "Share" instead. That would make my new Eclipse recognize the old SVN directories.

After I checked out all projects, I ran into new problems. I could not manipulate the source files like usual. The word completion did not work. It turns out that newly checked out projects are not recognized by Eclipse as Java project, that is why word completions do not work. So I had to delete the projects from workspace (but not from disk!) and then reopened them as Java projects.

One more tidbit, my projects came with Ant build files. I ran the ant. Failed. I fixed my project setting. I ran the ant. Successful. I tried to right click on my source file containing main class and chose run as Java application. Failed. It turns out I had to compile the project using Eclipse built in compiler in order to enable me to do that. So I cleaned the project (Project -> Clean) and then I could right click and run it. By the way, the option "Build automatically" in the Project menu means that the build will be executed automatically right after you clean the project.

Get the Mime Type from a File

I recently had to find the type of a file. I relied only on file extension, which as you can see, is unreliable. The following method is preferred:


Using javax.activation.MimetypesFileTypeMap

import javax.activation.MimetypesFileTypeMap;
import java.io.File;

class GetMimeType {
public static void main(String args[]) {
File f = new File("gumby.gif");
System.out.println("Mime Type of " + f.getName() + " is " +
new MimetypesFileTypeMap().getContentType(f));
// expected output :
// "Mime Type of gumby.gif is image/gif"
}
}
The built-in mime-type list is very limited but a mechanism is available to add very easily more Mime Types/extensions.The MimetypesFileTypeMap looks in various places in the user's system for MIME types file entries. When requests are made to search for MIME types in the MimetypesFileTypeMap, it searches MIME types files in the following order:
  1. Programmatically added entries to the MimetypesFileTypeMap instance.

  2. The file .mime.types in the user's home directory.

  3. The file /lib/mime.types.

  4. The file or resources named META-INF/mime.types.

  5. The file or resource named META-INF/mimetypes.default (usually found only in the activation.jar file).

This method is interesting when you need to deal with incoming files with the filenames normalized. The result is very fast because only the extension is used to guess the nature of a given file.

For a file read via URL, use the following method:

import java.net.FileNameMap;
import java.net.URLConnection;

public class FileUtils {

public static String getMimeType(String fileUrl)
throws java.io.IOException
{
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String type = fileNameMap.getContentTypeFor(fileUrl);

return type;
}

public static void main(String args[]) throws Exception {
System.out.println(FileUtils.getMimeType("file://c:/temp/test.TXT"));
// output : text/plain
}
}

Enabling webDAV in Apache running on Ubuntu

I found the following tutorial on: http://www.howtoforge.com/how-to-set-up-webdav-with-apache2-on-ubuntu-8.10

How To Set Up WebDAV With Apache2 On Ubuntu 8.10
Version 1.0
Author: Falko Timme
Last edited 01/20/2009

This guide explains how to set up WebDAV with Apache2 on an Ubuntu 8.10 server. WebDAV stands for Web-based Distributed Authoring and Versioning and is a set of extensions to the HTTP protocol that allow users to directly edit files on the Apache server so that they do not need to be downloaded/uploaded via FTP. Of course, WebDAV can also be used to upload and download files.

I do not issue any guarantee that this will work for you!



1 Preliminary Note
I'm using an Ubuntu 8.10 server with the IP address 192.168.0.100 here.

Because we must run all the steps from this tutorial with root privileges, we can either prepend all commands in this tutorial with the string sudo, or we become root right now by typing

sudo su



2 Installing WebDAV
If Apache is not already installed, install it as follows:

apt-get install apache2

Afterwards, enable the WebDAV modules:

a2enmod dav_fs
a2enmod dav

Restart Apache:

/etc/init.d/apache2 restart



3 Creating A Virtual Host
I will now create a default Apache vhost in the directory /var/www/web1/web. For this purpose, I will modify the default Apache vhost configuration in /etc/apache2/sites-available/default. If you already have a vhost for which you'd like to enable WebDAV, you must adjust this tutorial to your situation.

First, we create the directory /var/www/web1/web and make the Apache user (www-data) the owner of that directory:

mkdir -p /var/www/web1/web
chown www-data /var/www/web1/web

Then we back up the default Apache vhost configuration (/etc/apache2/sites-available/default) and create our own one:

mv /etc/apache2/sites-available/default /etc/apache2/sites-available/default_orig
vi /etc/apache2/sites-available/default

NameVirtualHost *

ServerAdmin webmaster@localhost

DocumentRoot /var/www/web1/web/

Options Indexes MultiViews
AllowOverride None
Order allow,deny
allow from all



Then reload Apache:

/etc/init.d/apache2 reload



4 Configure The Virtual Host For WebDAV
Now we create the WebDAV password file /var/www/web1/passwd.dav with the user test (the -c switch creates the file if it does not exist):




htpasswd -c /var/www/web1/passwd.dav test

You will be asked to type in a password for the user test.

(Please don't use the -c switch if /var/www/web1/passwd.dav is already existing because this will recreate the file from scratch, meaning you lose all users in that file!)

Now we change the permissions of the /var/www/web1/passwd.dav file so that only root and the members of the www-data group can access it:

chown root:www-data /var/www/web1/passwd.dav
chmod 640 /var/www/web1/passwd.dav

Now we modify our vhost in /etc/apache2/sites-available/default and add the following lines to it:

vi /etc/apache2/sites-available/default

[...]
Alias /webdav /var/www/web1/web


DAV On
AuthType Basic
AuthName "webdav"
AuthUserFile /var/www/web1/passwd.dav
Require valid-user

[...]
The Alias directive makes (together with ) that when you call /webdav, WebDAV is invoked, but you can still access the whole document root of the vhost. All other URLs of that vhost are still "normal" HTTP.

The final vhost should look like this:

NameVirtualHost *

ServerAdmin webmaster@localhost

DocumentRoot /var/www/web1/web/

Options Indexes MultiViews
AllowOverride None
Order allow,deny
allow from all


Alias /webdav /var/www/web1/web


DAV On
AuthType Basic
AuthName "webdav"
AuthUserFile /var/www/web1/passwd.dav
Require valid-user


Reload Apache afterwards:

/etc/init.d/apache2 reload



5 Testing WebDAV
We will now install cadaver, a command-line WebDAV client:

apt-get install cadaver

To test if WebDAV works, type:

cadaver http://localhost/webdav/

You should be prompted for a user name. Type in test and then the password for the user test. If all goes well, you should be granted access which means WebDAV is working ok. Type quit to leave the WebDAV shell:

root@server1:~# cadaver http://localhost/webdav/
Authentication required for webdav on server `localhost':
Username: test
Password:
dav:/webdav/> quit
Connection to `localhost' closed.
root@server1:~#