Building desktop Linux applications with JavaScript

During his keynote presentation at OSCON last year, Ubuntu founder Mark Shuttleworth described application extensibility as an important enabler of innovation and user empowerment. Citing the Firefox web browser and its rich ecosystem of add-ons as an example, Shuttleworth suggested that the Linux community could deliver a lot of extra value by making scriptable automation and plugin capabilities available pervasively across the entire desktop stack.

Mark Shuttleworth also described his strategy for accelerating the adoption of Linux. He discussed the importance of extensibility in open platforms, contemplated the challenges of adapting conventional software methodologies so that they can be used for community-driven development, and contended that the open source software community has the potential to deliver a user experience which exceeds that of Apple’s Mac OS X platform.

Ryan Paul: Building desktop Linux apps with JavaScript

Running Quercus in Jetty Web Server

Jetty Web server can be invoked and installed as a stand alone application server. It has a flexible component based architecture that allows it to be easily deployed and integrated in a diverse range of instances. The project is supported by a growing community and a team with a history of being responsive to innovations and changing requirements. More info here.

Installing Jetty

First you need to download Jetty. It’s distributed as a platform independent zip file containing source, javadocs and binaries. The most recent distro can be downloaded from Codehaus:

$ wget http://dist.codehaus.org/jetty/jetty-6.1.14/jetty-6.1.14.zip
$ unzip jetty-6.1.14.zip
$ cp -R jetty-6.1.14 /opt/
$ cd /opt
$ ln -s /opt/jetty-6.1.14 jetty

Problems installing Jetty? More info here.

Running Jetty

Running jetty is as simple as going to your jetty installation directory and typing:

$ cd /opt/jetty
$ java -jar start.jar etc/jetty.xml

This will start jetty and deploy a demo application available at:

http://localhost:8080/test

That’s it. Now stop Jetty with cntrl-c in the same terminal window as you started it.

Installing Quercus

Quercus is a complete implementation of the PHP language and libraries in Java. It gives both Java and PHP developers a fast, safe, and powerful alternative to the standard PHP interpreter. Quercus is available for download as a WAR file which can be easily deployed on Jetty:

$ wget -P ~/quercus http://quercus.caucho.com/download/quercus-3.2.1.war
$ jar xf ~/quercus/quercus-3.2.1.war

Unpack the WAR file and copy all the jars to Jetty’s global library directory:

$ cp ~/quercus/WEB-INF/lib/* /opt/jetty/lib

Configuring Jetty

Edit the web.xml file:

$ vi /opt/jetty/webapps/test/WEB-INF/web.xml

Add the following between the web-app tags:

<servlet>
    <servlet-name>Quercus Servlet</servlet-name>
    <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Quercus Servlet</servlet-name>
    <url-pattern>*.php</url-pattern>
</servlet-mapping>
<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.php</welcome-file>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

Create a PHP file inside the test application:

$ cat /opt/jetty/webapps/test/index.php
<?php phpinfo(); ?>

This file will be available at:

http://localhost:8080/index.php

It works! You are now ready to:

Instantiate objects by class name

<?php
$a = new Java("java.util.Date", 123);
print $a->time;

Import classes

<?php
import java.util.Date;

$a = new Date(123);
print $a->time;

Call Java methods

<?php
import java.util.Date;

$a = new Date(123);
print $a->getTime();
print $a->setTime(456);

print $a->time;
$a->time = 456;

And much, much more.

NautilusSVN: Linux TortoiseSVN Equivalent

Based on Stuart Langridge’s original script, Jason Field and Bruce van der Kooij created a set of Python scripts which integrate a load of Subversion functionality into the Gnome Nautilus browser. It’s basically a clone of the TortoiseSVN project on Windows.

NautilusSVN currently supports the following functionality:

  • Checkout
  • Commit
  • Revert
  • Diff (using Meld or gvimdiff)
  • Log Viewer
  • Revision and SVN User as columns in Nautilus views
  • Emblems to show file status (though buggy)
  • SSL authentication (buggy)
  • Username and password entry dialog
  • Editing Properties

NautilusSVN Project

Netbooks: Microsoft’s biggest worry

Netbooks will account for about a third of all PC growth this year, according to Citigroup. They are a real threat to Microsoft. Clearly, the future is in netbooks and that has Microsoft worried. Microsoft isn’t just worried about ceding 30% of the netbook market to Linux, it’s also worried that if people get used to running Linux on netbooks, they’ll consider buying Linux on desktop PCs as well.

According to Dickie Chang, this gives users a chance to see and try something new, showing them there is an alternative.

Happy New Year!

Cloning your Ubuntu Installation

It’s always handy to have a complete list of packages installed, specially if you want to create a system that is similar to a different system you have already set up. In this post I’ll cover how you can export a list of installed packages on one Ubuntu system, and import them into another to build a duplicate system.

Make a copy of the system’s repositories

Copy the /etc/apt/sources.list text file to the destination system over the network.

Export the list of installed packages

$ dpkg --get-selections | grep '[[:space:]]install$' | \\
awk '{print $1}' > ~/package.list

Copy the package.list text file to the destination system over the network.

Prepare the destination system

Update your package list to make sure you get the latest version of the packages:

$ apt-get update

Import the package list

$ cat ~/package.list | xargs apt-get install

That’s it! All of the files from the package list will have been imported into the new system. This doesn’t mean that all of the settings have transferred over. To do that, you will likely need to copy settings from the /etc directory.

Meet Intrepid Ibex, also known as Kubuntu 8.10

Intrepid Ibex is the codename for Kubuntu 8.10, due to be released October 30 2008.

The focus for 8.10 for the Kubuntu community will be transitioning to a KDE 4 desktop. The plan is to integrate the existing Kubuntu software while at the same time offering the best out-of-the-box KDE 4 experience around. Intrepid Ibex is a whole new revolution for the open-source community, Intrepidly going where no Kubuntu release has gone before.

The key improvements in Kubuntu 8.10 are:

  • The KDE-PIM suite is back
  • Plasma matures
  • Many new and improved applications and frameworks

KWin

KWin’s desktopgrid visualizes the concept of virtual desktops and makes it easier to remember where you left that window you’re looking for.

Plasma

The new folderview applet lets you display the content of arbitrary directories on your desktop. Drop a directory onto your unlocked desktop to create a new folderview. A folderview can not only display local directories, but can also cope with locations on the network.

More info here

What’s free, looks like a Mac and is actually Linux?

The answer is gOS, a lightweight, web-heavy operating system that anyone can use.

The emphasis in gOS is on web apps and everyday tasks like browsing the web and checking e-mail. Under the hood, gOS is based on the solid Linux distribution base of Ubuntu 8.04.1, but aside from that familiar startup sound, you’re unlikely to notice the Ubuntu underpinnings.

gOS instantly launches Google Gadgets for Linux on startup, introducing over 100,000 possible iGoogle and Google Gadgets to the desktop. Google Documents, Calendar, and Mail launch in Mozilla Prism windows to closer resemble desktop applications. The newest release of WINE 1.0 is included to now support thousands of Windows software.

http://www.thinkgos.com/

FileSyncTask: Using Phing to synchronize files and directories

I needed to automate the task of synchronizing files from one server to another, so I wrote a Phing task. Finally today I found some time to finish writing the documentation.

Overview

FileSyncTask is a Phing extension for Unix systems which synchronizes files and directories from one location to another while minimizing data transfer. FileSyncTask can copy or display directory contents and copy files, optionally using compression and recursion.

Rather than using FTP or some other form of file transfer, FileSyncTask uses rsync to copy only the diffs of files that have actually changed. Only actual changed pieces of files are transferred, rather than the whole file, which results in transferring only a small amount of data and are very fast. FTP, for example, would transfer the entire file, even if only one byte changed. The tiny pieces of diffs are then compressed on the fly, further saving you file transfer time and reducing the load on the network.

FileSyncTask can be used to synchronize Website trees from staging to production servers and to backup key areas of the filesystems.

Usage

There are 4 different ways of using FileSyncTask:

  1. For copying local files.
  2. For copying from the local machine to a remote machine using a remote shell program as the transport (ssh).
  3. For copying from a remote machine to the local machine using a remote shell program.
  4. For listing files on a remote machine.

The SSH client called by FileSyncTask uses settings from the build.properties file:

sync.source.projectdir=/home/development.com/public
sync.destination.projectdir=/home/staging.com
sync.remote.host=server.com
sync.remote.user=user
sync.destination.backupdir=/home/staging.com/backup
sync.exclude.file=/home/development.com/build/sync.exclude

Listing files

The “listonly” option will cause the modified files to be listed instead of transferred. You must specify a source and a destination, one of which may be remote.

<taskdef name="sync" classname="phing.tasks.ext.FileSyncTask" />
<sync
    sourcedir="${sync.source.projectdir}"
    destinationdir="${sync.destination.projectdir}"
    listonly="true"
    verbose="true" />

Excluding irrelevant files

To exclude files from synchronizations, open and edit the sync.exclude file under the build/ directory. Each line can contain a file, a directory, or a pattern:

*~
.svn
.htaccess
public/index.development.php
public/images/uploads/*
build/*
log/*
tmp/*

Copying files to a remote machine

The following task definition will transfer files from a local source to a remote destination:

<taskdef name="sync" classname="phing.tasks.ext.FileSyncTask" />
<sync
    sourcedir="${sync.source.projectdir}"
    destinationdir="${sync.remote.user}@${sync.remote.host}:${sync.destination.projectdir}"
    excludefile="${sync.exclude.file}"
    verbose="true" />

Example

Directory structure

In order to separate the sync settings from the main build file, I’ve created a file called sync.properties:

development.com
|-- build
|   |-- build.properties
|   |-- build.xml
|   |-- sync.exclude
|   `-- sync.properties
`-- public
    `-- index.php

XML build file

Phing uses XML build files that contain a description of the things to do. The build file is structured into targets that contain the actual commands to perform:

<?xml version="1.0" ?>
<project name="example" basedir="." default="build">
<property name="version" value="1.0" />

<!-- Public targets -->
<target name="sync:list" description="List files">
  <phingcall target="-sync-execute-task">
    <property name="listonly" value="true" />
  </phingcall>
</target>

<target name="sync" description="Copy files">
  <phingcall target="-sync-execute-task">
    <property name="listonly" value="false" />
  </phingcall>
</target>

<!-- Private targets -->
<target name="-init" description="Load main settings">
  <tstamp />
  <property file="build.properties" />
</target>

<target name="-sync-execute-task" depends="-init">
  <property file="sync.properties" />
  <if>
    <not>
      <isset property="sync.verbose" />
    </not>
    <then>
      <property name="sync.verbose" value="true" override="true" />
      <echo message="The value of sync.verbose has been set to true" />
    </then>
  </if>
  <property name="sync.remote.auth" value="${sync.remote.user}@${sync.remote.host}" />
  <taskdef name="sync" classname="phing.tasks.ext.FileSyncTask" />
  <sync
    sourcedir="${sync.source.projectdir}"
    destinationdir="${sync.remote.auth}:${sync.destination.projectdir}"
    backupdir="${sync.remote.auth}:${sync.destination.backupdir}"
    excludefile="${sync.exclude.file}"
    listonly="${listonly}"
    verbose="${sync.verbose}" />
</target>
</project>

Execute task

$ phing sync:list

Outputs:

Buildfile: /home/development.com/build/build.xml

example > sync:list:
[phingcall] Calling Buildfile '/home/development.com/build/build.xml'
            with target '-sync-execute-task'

example > -init:
[property] Loading /home/development.com/build/build.properties

example > -sync-execute-task:
[property] Loading /home/development.com/build/sync.properties
[echo] The value of sync.verbose has been set to true

Execute Command
----------------------------------------
rsync -razv --list-only -b --backup-dir

Sync files to remote server
----------------------------------------
Source:        /home/development.com/public
Destination:   user@server.com:/home/staging.com
Backup:        user@server.com:/home/staging.com/backup

Exclude patterns
----------------------------------------
*~
.svn
.htaccess
public/index.development.php
public/images/uploads/*
build/*
log/*
tmp/*

(list of files that have changed)

BUILD FINISHED
Total time: 1.9763 second

More information

Related Articles

The easiest way to search and replace in files

The “find” command is one of the most powerful and useful Unix commands, you can use it to locate files, and then perform some type of action on the files after they’ve been located. With this capability, you can locate files using powerful search criteria, and then run any Unix command you want on the files you locate.

Find Strings

In the following example I’ll recursively search a directory for files containing the ‘test’ string and output the name of the files and the line number:

$ grep -in -e 'test' `find -type f`

This command will search in the current directory and all sub directories. All files containing the string ‘test’ will have their path printed to standard output:

./build/build.properties:4:project.name=test
./build/build.xml:12:<target name="sync:test">

Count Strings

If you only want to count the matching lines for each file, then you can use the following command:

$ grep -inc -e 'test' `find -type f` | grep -v :0

This will output:

./build/build.properties:1
./build/build.xml:2

Replace Strings

And finally, if you want to replace all occurrences of the search string with the replacement string:

$ sed -i 's/search/replace/' `find -type f`

Linux Commands

Learn more about these commands:

Cygwin, a Linux-like environment for Windows

If you are an experienced Linux user who misses a powerful command-line environment in Windows, you will enjoy Cygwin.

What is Cygwin?

Cygwin is a set of powerful tools to assist developers in migrating applications from Linux to the Windows platform. Cygwin delivers the open source standard Red Hat GNU gcc compiler and gdb debugger on Windows. In addition, it provides for a standard Linux development environment on Windows including APIs and command shells.

What can Cygwin do?

With Cygwin, Windows users can easily run shell command scripts, ls, cat, grep, sed, awk, etc. Standard Windows command line tools can even be intermixed within the Linux shell script environment to administer the Windows system. Over the years, Linux system administrators have developed a large toolbox set of management scripts for their Linux machines. Cygwin provides the ability to continue using these scripts on Windows machines.

Why use Cygwin?

One of the largest problems developers face today is supporting their applications on disparate platforms. Windows workstations continue to be added to an environment already populated by Linux and other UNIX-based Operating Systems. Using Cygwin, developers can manage heterogeneous environments in a consistent, efficient way.

Installing Cygwin

First go to Cygwin’s site and select Install or update now. This will download their online installer, setup.exe. The rest will be downloaded by the installer itself.

  1. Start the installer. Click Next.
  2. Choose Install from Internet. Next.
  3. Choose root directory, keep it as it is. Next.
  4. Choose local package directory, should be the desktop as default. Next.
  5. Choose connection. If you are behind a firewall, change the settings. Next.
  6. Choose location.
  7. Choose packages.
  8. The files are now downloaded from Internet and installed.
  9. When done click the finish button.
  10. To see that the installation works, click the shortcut that was made on the desktop.
  11. A console window is opened, showing some text.
  12. Close the console window.

Tutorials

An introduction to Cygwin
Cygwin, changing the face of Windows
Cygwin Website