Remove duplicate files

December 3rd, 2008

This is a slightly modified version of the script published here. It allows you to scan files for duplicates based on md5 checksums.


#!/bin/bash
# rd - remove dupliactes

# find the files using the specified 'find arguments'
find "$@" -type f -print0 |

# calculate checksum for each file
xargs -0 -n1 md5sum |

# sort on the checksum
sort --key=1,32 |

# show remove command for each duplicate file
awk 'dup[$1]++{print "rm -f " $2}'

exit 0

The script is safe to use, it it not able to actually delete files itself. Instead, it generates a script that does the risky stuff.

Usage
To see what files are marked as duplicate in the current working directory:


$ rd .
rm -f ./config_backup_2008-11-06_11.30.01.tar.bz2
rm -f ./config_backup_2008-11-07_11.30.01.tar.bz2
rm -f ./config_backup_2008-11-08_11.30.01.tar.bz2

If you like the result, you can execute the generated commands. This can by piping the output to the shell:


$ rd . | sh

Processing the rd command might take some time. So you can also copy and paste the output in the terminal when there are a lot of (big) files.
Since the script passes all arguments to the find command. It’s also possible to fine tune the find command. For example, you only want to remove duplicates in the current directory, without searching in sub directories:


#  rd . -maxdepth 1

I’m using the script to remove duplicate backup sets.

Cool simple CMS: Pluck!

December 1st, 2008

Recently I’ve put a simple cms driven website online (ik-zie-je.nl). I’ts using Pluck. Pluck is easy to install (doesn’t need a database) and easy to use. It can be extended with custom modules and themes.

Combining Modalbox & CakePHP

February 28th, 2008

demo included!I’m pretty sure this can be implemented more elegantly, but I’ll describe my attempt to unite Modalbox with CakePHP 1.2.

First example - a modal box view
This example shows the steps I’ve taken to flavour a freshly baked cake app with modalbox. The starting point is a customer model, a controller and some basic index, view and edit views.
Showing a cakephp view in a modalbox, is just a few snippets away. Just make sure you include prototype, scriptaculous and the modalbox javascript and the modalbox css file in the default layout…


/app/views/layouts/default.ctp:
echo $html->css('modalbox');
echo $javascript->link('prototype');
echo $javascript->link('scriptaculous.js?load=effects');
echo $javascript->link('modalbox');

Then create the appropiate link to the view you want to load inside the modalbox. For example, if you want to show customer details from the customers/index.ctp view:


# ...somewhere in the loop that lists customers:
echo $html->link('View', array('action' => 'view', $customer['Customer']['id']), array('title' => 'Customer details', 'onclick' => "Modalbox.show(this.href, {title: this.title, width: 400}); return false;"));

Make sure you use the RequestHandler component so that the customer view is displayed in the ajax.ctp instead of the default.ctp layout. You can do this by making sure the following line is in /app/app_controller.php:


var $components = array('RequestHandler');

And… there you go! When you click the view link, the modalbox slides in, while the rest of the page dims to gray. When you hit the escape button, click the little ‘X’ or click anywhere in the gray area, the modal box slides back where it came from.

Ok, now forms!
Read the rest of this entry »

CD sleeves on-the-fly!

February 27th, 2008

A while ago, I’ve written a simple web interface around cdlablegen. Cdlabelgen is a perl script that allows you to automatically generate cd and dvd sleeves.
It’s installed on a closed network and my colleagues use it to label their scientific data archive. This is public version is now available on special request of a remote co-worker (company logo removed!).
hoesje.nerdnotes.org

vmcp

December 10th, 2007

Vmcp (vm-copy) is a simple script that allows you to copy/clone a VMware virtual computer image. Just specify the source directory and the destination directory. It will first just copy the wmware directory recursively en then change the configuration option ‘displayName’ in the vmx file.


#!/bin/sh

source=$1
dest=$2

echo copying virtual machine
cp -rv $source $dest

vmxsourcefile=`ls $source/*.vmx`
vmxdestfile=`ls $dest/*.vmx`

grep -v displayName $vmxsourcefile > $vmxdestfile
echo displayName = \"$dest\" >> $vmxdestfile

exit 0

Howto start your CakePHP project in Subversion

December 6th, 2007

This howto will demonstrate how to start your cakephp project from scratch, taking advantage of subversions “externals definition”. The result will be a basic CakePHP directory structure with only the “/app” part under your svn control and the other directories linked to a specified revision of cakephp. Once setup, if you do a ’svn chekout’ of your project, you will get all the files at the right location, so no need to merge your ‘/app ‘ with the contents of a tarbal which you downloaded from the CakePHP website.

Let’s get started!

First, we create a temporary directory structure, just for the purpose of importing it:


$ mkdir temp
$ mkdir temp/mynewproject
$ mkdir temp/mynewproject
$ svn import -m "New import" temp file:///home/me/subversion/
# remove the temporary directory structure
$ rm -rf temp

Now, we checkout a working copy:


$ cd ~/src
$ svn checkout file:///home/me/subversion/mynewproject

Ok, this just bought us an empty directory managed by subversion!! Let’s fill it with the use of some magic: Externals. We will create an externals definition for the directory. It will point to the current cakephp1.2 release, which is 5875 at time of writing.


$ cd mynewproject
$ svn propedit svn:externals .

This will fire up your text editor with an empty text file. Type the following line, save and quit:


third-party/cake_1.2.0.5875 -r 5875 https://svn.cakephp.org/repo/trunk/cake/1.2.x.x/

Since this is an actual change to the current directory, we should commit it back to the repository:


$ svn commit -m "Added externals definition for CakePHP 1.2 rev. 5875"

By updating our working copy, the cakephp files will be downloaded to the in the property specified directory:


$ svn update

Wow, that’s nice, isn’t it! Oh… and btw, don’t forget to donate some change to the project!

Let’s go and make some symlinks and a copy of the ‘app’ directory:


$ ln -s third-party/cake_1.2.0.5875/.htaccess
$ ln -s third-party/cake_1.2.0.5875/cake
$ ln -s third-party/cake_1.2.0.5875/index.php
# now create your own copy of the app directory
$ cp -r third-party/cake_1.2.0.5875/app .

Since we don’t need the .svn directories from the cakephp svn checkout. We find and delete them:


$ find app -type d | grep \.svn | sort -r | xargs rm -rf

Finally, add the ‘/app’ directory and the simlinks to our own subversion repository


$ svn add .htaccess app cake index.php
$ svn commit

That should be it!

Remember, when you want to upgrade your CakePHP version. It should be a matter of (a) editing the externals definition on the myproject directory. And (b) re-linking the symbolic links.

Preparing plogger thumbnails

October 12th, 2007

I recently started to use Plogger to publish family pictures. The photo blogger package is nice, but still in beta stage. The latter doesn’t go unnoticed when setting it up.

One of the things that has been bothering me is the fact that thumbnails are not only generated during import, but also during the first visit of the new albums. Especially on my very slow web host, it can take up to minutes to view a single picture that hasn’t been processed before.

A solution is a shell script that finds out what pages to download after adding a new set of pictures. It will then download those pages, forcing Plogger to generate all the necessary cache files. The script should be executed form the web server itself. It requires 3 lines (upper part of the script) of configuration: the url and filesystem path to the plogger installation and a log file that keeps track of the url’s already downloaded. If you want to redo the downloading, just remove this log file.

Reminder: Local documentation!

September 21st, 2007

I’ve been searching for some ‘getopt’ examples on the internet. Many tutorials show the same basic tricks. I completely looked over the local documentation, which in fact has very nice examles for bash and tcsh:


#!/bin/bash

# A small example program for using the new getopt(1) program.
# This program will only work with bash(1)
# An similar program using the tcsh(1) script language can be found
# as parse.tcsh

# Example input and output (from the bash prompt):
# ./parse.bash -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "
# Option a
# Option c, no argument
# Option c, argument `more'
# Option b, argument ` very long '
# Remaining arguments:
# --> `par1'
# --> `another arg'
# --> `wow!*\?'

# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
     -n 'example.bash' -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
        case "$1" in
                -a|--a-long) echo "Option a" ; shift ;;
                -b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;
                -c|--c-long)
                        # c has an optional argument. As we are in quoted mode,
                        # an empty parameter will be generated if its optional
                        # argument is not found.
                        case "$2" in
                                "") echo "Option c, no argument"; shift 2 ;;
                                *)  echo "Option c, argument \`$2'" ; shift 2 ;;
                        esac ;;
                --) shift ; break ;;
                *) echo "Internal error!" ; exit 1 ;;
        esac
done
echo "Remaining arguments:"
for arg do echo '--> '"\`$arg'" ; done