summaryrefslogtreecommitdiffstats
path: root/src/utilities/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utilities/scripts')
-rw-r--r--src/utilities/scripts/Makefile.am4
-rw-r--r--src/utilities/scripts/digitaglinktree568
-rw-r--r--src/utilities/scripts/digitaglinktree.1182
3 files changed, 754 insertions, 0 deletions
diff --git a/src/utilities/scripts/Makefile.am b/src/utilities/scripts/Makefile.am
new file mode 100644
index 00000000..198f6c0d
--- /dev/null
+++ b/src/utilities/scripts/Makefile.am
@@ -0,0 +1,4 @@
+####### This script name should probably be more 'namespaced'. Think about distros putting everything in /usr/bin...
+bin_SCRIPTS = digitaglinktree
+man_MANS = digitaglinktree.1
+
diff --git a/src/utilities/scripts/digitaglinktree b/src/utilities/scripts/digitaglinktree
new file mode 100644
index 00000000..8d0d12c9
--- /dev/null
+++ b/src/utilities/scripts/digitaglinktree
@@ -0,0 +1,568 @@
+#!/usr/bin/perl
+
+$version="1.6.3";
+# Author: Rainer Krienke, [email protected]
+#
+# Description:
+#
+# This script will create a linktree for all photos in a digikam
+# database that have tags set on them. Tags are used in digikam to
+# create virtual folders containing images that all have one or more tags.
+# Since other programs do not know about these virtual folders this script
+# maps these virtual folders into the filesystem by creating a directory
+# for each tag name and then linking from the tag dir to the tagged image in the
+# digikam photo directory.
+#
+# Call this script like:
+# digitaglinktree -r /home/user/photos -l /home/user/photos/tags \
+# -d /home/user/photos/digikam.db
+
+
+# Changes
+#
+# 1.1->1.2:
+# Support for hierarchical tags was added. The script can either create
+# a hierarchical directory structure for these tags (default) or treat them
+# as tags beeing on the same level resulting in a flat dir structure (-f)
+#
+# 1.2->1.3
+# Added support for multiple tags assigned to one photo. Up to now only
+# one tag (the last one found) was used.
+#
+# 1.3->1.4
+# Bug fix, links with same name in one tag directory were no resolved
+# which led to "file exists" errors when trying to create the symbolic link.
+#
+# 1.4-> 1.6, 2006/08/03
+# Added an option (-A) to archive photos and tag structure in an extra directory
+# 1.6-> 1.6.1 2006/08/15
+# Added an option (-C) for archive mode (-A). Added more information to
+# the manual page.
+# 1.6.1-> 1.6.2 2008/11/24 (Peter Muehlenpfordt, [email protected])
+# Bug fix, subtags with the same name in different branches were merged
+# into one directory.
+# 1.6.2 -> 1.6.3 2008/11/25 Rainer Krienke, [email protected]
+# Fixed a bug that shows in some later perl interpreter versions when
+# accessing array references with $# operator. If $r is a ref to an array
+# then $#{@r} was ok in the past but now $#{r] is correct, perhaps it was
+# always correct and the fact that $#{@r} worked was just good luck ....
+#
+
+
+# ---------------------------------------------------------------------------
+# LICENSE:
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# ---------------------------------------------------------------------------
+
+
+use Getopt::Std;
+use File::Spec;
+use File::Path;
+
+# Please adapt the sqlite version to your digikam version.
+# Do not forget to also install the correct sqlite version:
+# Digikam 0.7x needs sqlite2
+# Digikam 0.8x needs sqlite3
+
+#$SQLITE="/usr/bin/sqlite";
+$SQLITE="/usr/bin/sqlite3";
+$archiveDirPhotos="Photos";
+$archiveDirLinks="Tags";
+
+#
+$scriptAuthor="[email protected]";
+
+#
+# check if sqlite can open the database
+#
+sub checkVersion{
+ my($database)=shift;
+ my(@data, $res);
+
+ if( ! -r $SQLITE ){
+ warn "Cannot start sqlite executable \"$SQLITE\". \n",
+ "Please check if the executable searched is really installed.\n",
+ "You should also check if the installed version is correct. The name\n",
+ "of the executable to search for can be set in the head of this script.\n\n";
+ exit(1);
+ }
+
+ @data=`$SQLITE $database .tables 2>&1`; # Try to get the tables information
+
+ if( $? != 0 || grep(/Error:\s*file is encrypted/i, @data) != 0 ){
+ warn "Cannot open database \"$database\". Have you installed a current\n",
+ "version of sqlite? Depending on you digikam version you have to \n",
+ "install and use sqlite2 (for digikam 0.7x) or sqlite3 (for digikam >= 0.8 )\n",
+ "Please install the correct version and set the SQLITE variable in the\n",
+ "script head accordingly \n\n";
+ exit(1);
+ }
+
+ $res=grep(/TagsTree/, @data);
+ if( $res==0 ){
+ return("7") # digikam version 0.7
+ }else{
+ return("8"); # digikam version 0.8
+ }
+}
+
+
+#
+# Get all images that have tags from digikam database
+# refPathNames will contain all photos including path having tags
+# The key in refPathNames is the path, value is photos name
+#
+sub getTaggedImages{
+ my($refImg, $database, $rootDir, $refPaths, $refPathNames)=@_;
+ my($i, $image, $path, $tag, $status, $id, $pid, $tmp);
+ my($sqliteCmd, @data, $vers, @tags, %tagPath, $tagCount, $refTag);
+
+ $vers=checkVersion($database); # Find out version of digikam
+
+ # Get tag information from database
+ $sqliteCmd="\"select id,pid,name from tags;\"";
+
+ @data=`$SQLITE $database $sqliteCmd`;
+ $status=$?;
+ if( $status == 0 ){
+ foreach $i ( @data ){
+ chomp($i);
+ ($id, $pid, $tag)=split(/\|/, $i);
+ # map tag id data into array
+ $tags[$id]->{"tag"}="$tag";
+ $tags[$id]->{"pid"}="$pid";
+ }
+
+ # Now build up the path for tags having parents
+ # Eg: a tag people might have a subtag friends: people
+ # |->friends
+ # We want to find out the complete path for the subtag. For friends this
+ # would be the path "people/friends". Images with tag friends would then be
+ # linked in the directory <tagsroot>/people/friends/
+ for($i=0; $i<=$#tags; $i++){
+ $pid=$tags[$i]->{"pid"}; # Get parent tag id of current tag
+ $tag=$tags[$i]->{"tag"}; # Start constructing tag path
+ if( $pid == 0 ){
+ $tagPath{$i}=$tag;
+ next;
+ }
+
+ while( $pid != 0){
+ $tag=$tags[$pid]->{"tag"} . "/$tag"; # add parents tag name to path
+ $pid=$tags[$pid]->{"pid"}; # look if parent has another parent
+ }
+ # Store path constructed
+ $tagPath{$i}=$tag;
+ #warn "+ $tag \n";
+ }
+ }else{
+ print "Error running SQL-Command \"$sqliteCmd\" on database \"$database\"\n";
+ }
+
+
+ if( $vers==7 ){
+ # SQL to get all tagged images from digikam DB with names of tags
+ $sqliteCmd="\"select ImageTags.name,Albums.Url,ImageTags.tagid from " .
+ " ImageTags, Albums,Tags " .
+ " where Albums.id = ImageTags.dirid; \"";
+
+ }elsif( $vers == 8 ){
+ # SQL to get all tagged images from digikam DB with names of tags
+ $sqliteCmd="\"select Images.name,Albums.url,ImageTags.tagid from" .
+ " Images,Albums,ImageTags where " .
+ " Images.dirid=Albums.id AND Images.id=ImageTags.imageid; \"";
+ }else{
+ warn "Unsupported digikam database version. Contact $scriptAuthor \n\n";
+ exit(1);
+ }
+
+ @data=`$SQLITE $database $sqliteCmd`;
+ $status=$?;
+ if( $status == 0 ){
+ foreach $i ( @data ){
+ chomp($i);
+ ($image, $path, $tag)=split(/\|/, $i);
+ $refPaths->{"$rootDir$path"}=1;
+ $refPathNames->{"$rootDir$path/$image"}=1;
+
+ $tmp=$path;
+ #warn "- $rootDir, $path, $image \n";
+ # Enter all subpaths in $path as defined too
+ do{
+ $tmp=~s/\/[^\/]+$//;
+ $refPaths->{"$rootDir$tmp"}=1;
+ } while (length($tmp));
+
+
+ $refImg->{"$path/$image"}->{"path"}=$path;
+ $refImg->{"$path/$image"}->{"image"}=$image;
+ $refTag=$refImg->{"$path/$image"}->{"tag"};
+ #
+ # One image can have several tags assigned. So we manage
+ # a list of tags for each image
+ $tagCount=$#{$refTag}+1;
+ # The tags name
+ $refImg->{"$path/$image"}->{"tag"}->[$tagCount]=$tag;
+ # tags path for sub(sub+)tags
+ $refImg->{"$path/$image"}->{"tagpath"}->[$tagCount]=$tagPath{$tag};
+ }
+ }else{
+ print "Error running SQL-Command \"$sqliteCmd\" on database \"$database\"\n";
+ }
+
+ return($status);
+}
+
+
+#
+# Create a directory with tag-subdirectories containing links to photos having
+# tags set. Links can be absolute or relative as well as hard or soft.
+#
+sub createLinkTree{
+ my($refImages)=shift;
+ my($photoRootDir, $linktreeRootDir, $opt_flat, $opt_absolute, $linkMode)=@_;
+ my( $i, $j, $cmd, $path, $image, $tag, $qpath, $qtag, $qimage, $linkName,
+ $tmp, $ret, $sourceDir, $destDir);
+ my($qtagPath, $relPath);
+
+ if( -d "$linktreeRootDir" ){
+ # Remove old backuplinktree
+ system("rm -rf ${linktreeRootDir}.bak");
+ if( $? ){
+ die "Cannot run \"rm -rf ${linktreeRootDir}.bak\"\n";
+ }
+
+ # rename current tree to .bak
+ $ret=rename("$linktreeRootDir", "${linktreeRootDir}.bak" );
+ if( !$ret ){
+ die "Cannot rename \"$linktreeRootDir\" to \"${linktreeRootDir}.bak\"\n";
+ }
+ }
+
+ # Create new to level directory to hold linktree
+ $ret=mkdir("$linktreeRootDir");
+ if( !$ret ){
+ die "Cannot mkdir \"$linktreeRootDir\"\n";
+ }
+ # Iterate over all tagged images and create links
+ foreach $i (keys(%$refImages)){
+ # Check that the images in the linktrees themselves are
+ # ignored in the process of link creation. If we do not do this
+ # we might get into trouble when the linktree root is inside the
+ # digikam root dir and so the image links inside the liktree directory
+ # are indexed by digikam.
+ next if( -l "${photoRootDir}$i" );
+
+ $path=$refImages->{$i}->{"path"};
+ $image=$refImages->{$i}->{"image"};
+ #$qimage=quotemeta($image);
+ #$qpath=quotemeta($path);
+
+ # Handle all of the tags for the current photo
+ for( $j=0; $j<=$#{$refImages->{$i}->{"tag"}}; $j++){
+ $tag=$refImages->{$i}->{"tagpath"}->[$j];
+ #$qtagPath=quotemeta($tagPath);
+
+ # For tags that have subtags there is a path defined in qtagPath
+ # describing the parentrelationship as directory path like "friends/family/brothers"
+ # If it is defined we want to use this path instead of the flat tag name like "brothers"
+ # Doing so results in a directory hirachy that maps the tags parent relationships
+ # into the filesystem.
+ if( $opt_flat ){
+ # For flat option just use the last subdirectory
+ $tag=~s/^.+\///;
+ }
+ # Create subdirectories needed
+ if( ! -d "${linktreeRootDir}/$tag" ){
+ $ret=mkpath("${linktreeRootDir}/$tag", 0, 0755);
+
+ if( !$ret ){
+ die "Cannot mkdir \"${linktreeRootDir}/$tag\"\n";
+ }
+ }
+ # Avoid conflicts for images with the same name in one tag directory
+ $linkName=$image;
+ $tmp=$image;
+ while( -r "${linktreeRootDir}/$tag/$tmp" ){
+ $linkName="_" . $linkName;
+ $tmp="_" . $tmp;
+ }
+
+ if(length($opt_absolute)){
+ # Create link
+ $sourceDir="${photoRootDir}$path/$image";
+ $destDir="${linktreeRootDir}/$tag/$linkName";
+ }else{
+ # Get relative path from absolute one
+ # $rel=File::Spec->abs2rel( $path, $base ) ;
+ $relPath="";
+ $relPath=File::Spec->abs2rel("${photoRootDir}$path", "${linktreeRootDir}/$tag" ) ;
+ if( !length($relPath)){
+ die "Cannot create relative path from \"${linktreeRootDir}/$tag\" to \"${photoRootDir}$path\" . Abort.\n";
+ }
+ # Create link
+ #print "-> $relPath\n";
+ $sourceDir="$relPath/$image";
+ $destDir="${linktreeRootDir}/$tag/$linkName";
+ }
+
+ if( $linkMode eq "symbolic" ){
+ $ret=symlink($sourceDir, $destDir);
+ if( !$ret ){
+ $ret="$!";
+ warn "Warning: Failed symbolic linking \"$sourceDir\" to \"$destDir\": ",
+ "\"$ret\"\n";
+ }
+ }elsif( $linkMode eq "hard" ){
+ $ret=link($sourceDir, $destDir);
+ if( !$ret ){
+ $ret="$!";
+ warn "Warning: Failed hard linking \"$sourceDir\" to \"$destDir\": ",
+ "\"$ret\"\n";
+ }
+ }else{
+ die "$0: Illegal linkMode: \"$linkMode\". Abort.\n";
+ }
+
+ }# for
+ }
+}
+
+
+
+#
+# Clone a directory into another directory.
+# source and destination have to exist
+# Files in $srcDir will symbolically or hard linked
+# to the $cloneDir according to $cloneMode which can
+# be symbolic for symbolic links or hard for hardlinks
+# refPathNames contains path for all photos having tags set
+#
+sub cloneDir{
+ local($srcDir, $cloneDir, $linkMode, $cloneMode, $refPaths, $refPathNames)=@_;
+ local(@entries, $ki, $path, $name, $ret);
+
+ # Read directory entries
+ opendir( DIR, $srcDir ) || warn "Cannot read directory $srcDir \n";
+ local(@entries)=readdir(DIR);
+ closedir(DIR);
+
+ foreach $k (@entries){
+ next if( $k eq '.' );
+ next if( $k eq '..');
+ next if( $k =~ /digikam.*\.db/o );
+
+ #warn "-> $srcDir, $k, $cloneDir\n";
+ # Recurse into directories
+ if( -d "$srcDir/$k" ){
+ # if cloneMode is "minimal" then only clone directories and files
+ # with photos that have tags set.
+ if( $cloneMode ne "minimal" ||
+ defined($refPaths->{"$srcDir/$k"}) ){
+ #warn "* $srcDir/$k defined \n";
+ mkdir("$cloneDir/$k", 0755);
+ if( $? ){
+ die "Cannot run \"mkdir $cloneDir/$k\"\n";
+ }
+ cloneDir("$srcDir/$k", "$cloneDir/$k", $linkMode,
+ $cloneMode, $refPaths, $refPathNames );
+ }
+ }else{
+ # if cloneMode is "minimal" then only clone directories and files
+ # with photos that have tags set.
+ if( $cloneMode ne "minimal" ||
+ defined($refPathNames->{"$srcDir/$k"}) ){
+ # link files
+ if( $linkMode eq "symbolic" ){
+ $ret=symlink( "$srcDir/$k", "$cloneDir/$k");
+ if( !$ret ){
+ $ret="$!";
+ warn "Warning: In cloning failed symbolic linking \"$srcDir/$k\" to \"$cloneDir/$k\": ",
+ "\"$ret\"\n";
+ }
+ }elsif( $linkMode eq "hard" ){
+ $ret=link( "$srcDir/$k", "$cloneDir/$k");
+ if( !$ret ){
+ $ret="$!";
+ warn "Warning: In cloning failed hard linking \"$srcDir/$k\" to \"$cloneDir/$k\": ",
+ "\"$ret\"\n";
+ }
+ }else{
+ die "$0: Illegal cloneLinkMode: $linkMode set. Aborting.\n";
+ }
+ }
+ }
+ }
+}
+
+
+#
+# Manage cloning of a complete directory. If the clone directory exists
+# a .bak will be created
+# Files will be linked (hard/symbolic) according to cloneLinkMode which
+# should be "symbolic" or "hard"
+# cloneMode can "minimal" or anything else. minimal means only to clone
+# those files and directories that have tags set. Anything else means
+# to clone the whole photo tree with all files
+#
+sub runClone{
+ my($rootDir, $cloneDir, $photoDir, $cloneMode, $cloneLinkMode,
+ $refPaths, $refPathNames)=@_;
+ my($ret);
+ my($dev_r,$dev_A, $ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks);
+
+ if( -d "$cloneDir" ){
+ # Remove old backuplinktree
+ system("rm -rf ${cloneDir}.bak");
+ if( $? ){
+ die "Cannot run \"rm -rf ${cloneDir}.bak\"\n";
+ }
+
+ # rename current tree to .bak
+ $ret=rename("$cloneDir", "${cloneDir}.bak" );
+ if( !$ret ){
+ die "Cannot rename \"$cloneDir\" to \"${cloneDir}.bak\"\n";
+ }
+ }
+ $ret=mkdir("$cloneDir", 0755);
+ if( !$ret ){
+ die "Cannot run \"mkdir $cloneDir\"\n";
+ }
+ $ret=mkdir("$cloneDir/$photoDir", 0755);
+ if( !$ret ){
+ die "Cannot run \"mkdir $cloneDir/$photoDir\"\n";
+ }
+
+ # Check if root and archive dir are on same filesystem
+ ($dev_r,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks) = stat($rootDir);
+ ($dev_A,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
+ $atime,$mtime,$ctime,$blksize,$blocks) = stat($cloneDir);
+ #
+ if( $dev_r != $dev_A ){
+ warn "Error: \"$rootDir\" and \"$cloneDir\" are not on the same filesystem. Please select ",
+ "an archive directory on the same filesystem like digikams root directory! Abort.\n";
+ exit 1;
+ }
+
+ # Create clone of all entries in $rootDir into $clonedir
+ cloneDir($rootDir, "$cloneDir/$photoDir", $cloneLinkMode,
+ $cloneMode, $refPaths, $refPathNames);
+}
+
+
+#
+# print out usage
+#
+sub usage{
+ print "$0 -r <photoroot> \n",
+ " -l <taglinkdir> | -A <archivedir> \n",
+ " -d <digikamdatabasefile> \n",
+ " [-H|-f|-a|-v|-C] \n",
+ " -r <rootdir> path to digikams root directory containing all photos\n",
+ " -l <tagdir> path to directory where the tag directory structure with \n",
+ " links to the original images should be created \n",
+ " -d <dbfile> full path to the digikam database file \n",
+ " -A <ardir> Create selfcontained archive of photos and tags in directory\n",
+ " ardir. rootdir and arDir have to be on the *same* filesystem!\n",
+ " -C If -A <archdir> was given this option will put hardlinks of all\n",
+ " photos in the \"$archiveDirPhotos\" directory not only of those with tags.\n",
+ " -a Create absolute symbolic links instead of relative ones \n",
+ " -H Use hard links instead of symbolic links in linktree. \n",
+ " -f If there are hierarchical tags (tags that have subtags) \n",
+ " create a flat tag directory hierarchy. So directories for\n",
+ " subtags are at the same directory level like their parent tags\n",
+ " -h Print this help \n",
+ " -v Print scripts version number \n";
+
+ print "Exit.\n\n";
+ exit 1;
+}
+
+
+# ------------------------------------------------------------------
+# main
+# ------------------------------------------------------------------
+$ret=getopts('HhCar:l:d:A:fv');
+
+if( defined($opt_h) ){
+ usage(0);
+}
+
+if( defined($opt_v) ){
+ print "Version: $version\n";
+ exit 0;
+}
+
+usage if( !length($opt_r) || (!length($opt_l) && ! length($opt_A))
+ || !length($opt_d) );
+
+$opt_f=0 if( ! length($opt_f) );
+
+if( ! -d $opt_r ){
+ print "Invalid digikam photoroot directory \"$opt_r\". Exit.\n";
+ exit 1;
+}
+if( ! -f $opt_d ){
+ print "Digikam database \"$opt_d\" not found. Exit.\n";
+ exit 1;
+}
+
+# Remove trailing /
+$opt_r=~s/\/$//;
+$opt_l=~s/\/$//;
+#
+$rootDir=$opt_r;
+$linkDir=$opt_l;
+
+if( length($opt_C) ){
+ $cloneMode="full"; # Clone all files/dirs
+}else{
+ $cloneMode="minimal"; # Only clone dirs and files haviong tags not all files
+}
+
+if( length($opt_H) ){
+ $linkMode="hard"; # type of link from linktree to phototree
+}else{
+ $linkMode="symbolic"; # type of link from linktree to phototree
+}
+
+# Extract data needed from database
+$ret=getTaggedImages(\%images, $opt_d, $opt_r, \%paths, \%pathNames);
+
+# Handle Archiving photos and tag structure
+# digikams photo dir will be clone as a whole by using
+# either soft or hard links ($cloneMode)
+if( length($opt_A) ){
+ #
+ runClone($opt_r, $opt_A, $archiveDirPhotos, $cloneMode, "hard", \%paths, \%pathNames);
+ $rootDir="$opt_A/$archiveDirPhotos";
+ $linkDir="$opt_A/$archiveDirLinks";
+}
+
+if( !$ret && ( length($opt_l) || length($opt_A)) ){
+ # When doing hard links we always use absolute linking
+ if( $linkMode eq "hard" ){
+ warn "Will use absolute hard links for linktree in archive mode...\n" if( !length($opt_a) );
+ $opt_a="1";
+ }
+
+ # Create the link trees for all tagged images
+ createLinkTree(\%images, $rootDir, $linkDir, $opt_f, $opt_a, $linkMode);
+}
diff --git a/src/utilities/scripts/digitaglinktree.1 b/src/utilities/scripts/digitaglinktree.1
new file mode 100644
index 00000000..fdfe9e09
--- /dev/null
+++ b/src/utilities/scripts/digitaglinktree.1
@@ -0,0 +1,182 @@
+.\" -*-Nroff-*-
+.\"
+.TH digitaglinktree 1 "16 Aug 2006 " " " "Linux User's Manual"
+.SH NAME
+digitaglinktree \- Export tag structure of photos in digikam to the filesystem.
+.SH SYNOPSIS
+.B digitaglinktree
+.B -r\fI rootdir\fR
+
+.B -l\fI taglinkdir\fR
+|
+.B -A\fI archivedir\fR
+
+.B -d\fI database\fR
+
+.B [-H|-f|-a|-v|-C]
+
+.SH DESCRIPTION
+.B "digitaglinktree "
+will create a linktree for all photos in a digikam database that have tags set
+on them. Tags (like eg. "family", "events", ...) are used in digikam to create
+virtual folders containing images that all have one or more tags assigned.
+Please note: Photos that have no tags at all assigned are silently ignored by
+this script. The program will not modify or even touch your original photos
+managed by digikam.
+
+
+The script can be used in two ways: If you call it using
+Option -l \fItaglinkdir\fR the script will create the user specified
+directory \fItaglinkdir\fR and inside this directory it will create sub
+directories for digikam tags set on the photos. Inside these subdirectories it
+will finally place symbolic or hard links (see -H) to photos having the tags
+in question. As a result you will see the tags of your photos as folders and in
+these folders you will find links to your original photos.
+
+
+In this way you can access the collection of all images that share a certain tag
+by changing directory to the folder with the tags name created by this script.
+This allows you e.g. to run JAlbum a photo album software that needs to find the
+pictures to be put into a web album in the filesystem because JAlbum cannot
+access digikams virtual folders directly.
+
+
+The second way of calling this script is the so called archive-mode by setting
+option -A \fIarchiveDir\fR.
+
+Archive mode is thought for people who want to archive tagged photos
+independently of digikams root directories and the photos therein. This way you
+can put your photos and their tag structure in eg. a tar archive and send it to
+a friend, who can look at the photos via their tag structure. In this mode the
+script creates the directory given as parameter to -A and in this directory two
+more subdirectories. One named Photos and a second named Tags. The Photos
+directory contains hard links to your original photos, and the Tags directory
+contains a subdirectory for each Tag used by any of your photos. Inside this
+subdirectory there are links (either symbolic or hard links) to the files in the
+Photos directory. This way the archive directory needs nearly no additional
+space on your harddisk and you have an archive that allows you or a friend to
+easily look at the photos tag structure.
+
+Another benefit from using this script is that you have kind of a backup of your
+tag settings for all of your photos. The backup is simply the directory
+structure containing links to the original images that wear the tags.
+This could become important if
+for whatever reason the digikam.db file gets corrupted or even lost.
+
+.PP
+.SH "COMMAND\-LINE OPTIONS"
+.TP
+\fB \-r \fIrootdir\fR
+\fIrootdir\fR denotes the digikam base directory containing all your photos.
+
+.TP
+\fB \-l\fI taglinkdir\fR
+Parameter \fI taglinkdir\fR denotes a directory in which the tag structure of
+all your photos stored in
+rootdir will be exported to by creating subdirectories for each tag and placing
+symbolic links in these subdirectories that point to the original photo wearing
+the tags. If calling the script with option -l\fI taglinkDir\fR you also have
+to specify options -r \fIrootdir\fR as well as -d \fIdatabase\fR.
+
+.TP
+\fB \-A \fIarchivedirectory\fR
+\fIarchivedirectory\fR denotes a directory into which the script will export the photos and their tag
+structure. -A has to be used together with option -r \fIrootdir\fR as well as
+-d\fI database\fR else the script will terminate. Inside the archive directory
+the script will create a Photos and a Tags directory. It will put hard links in
+the Photos directory that point to your original photos. By using hard links
+you are independent of changes in your digikam root directory but on the other
+hand you are limited to one filesystem. So the directory given by
+-r \fIrootdir\fR and the directory specified for -A \fIarchivedir\fR have to be one
+the same filesystem. The Tags subdirectory will contain links to the files in
+the Photos directory. This way you have one archive directory that is completely
+self contained. You can tar it, send it to a friend or just put it somewhere
+for archivel or backup purposes. Usually only those photos will be archived that
+have a digikam tag set on them. By using option -C however you can perform a
+complete archive. See -C for more infos.
+
+.TP
+\fB \-d \fIdatabase\fR
+\fIdatabase\fR is the complete path including the filename to digikams photo database which
+usually can be found in digikams root directory. The files name is usually
+digikam.db .
+
+.TP
+\fB \-C\fR
+When the script is called with option -A \fIarchivedir\fR only those photos
+will be archived (by placing links) in the Photos subdirectory of
+\fIarchivedir\fR that have at least one digikam tag set. By setting option -C all
+photos will be archived to \fIarchivedir\fR no matter if they have a tag set
+or not. Note: This only changes the contents of the Photos subdirectory not of
+the Tags subdirectory in the \fIarchivedir\fR directory.
+
+.TP
+\fB \-a \fR
+By default the script will try to create relative symbolic links from the
+directory \fItaglinkdir\fR set by option -l to the photo files under
+\fIrootdir\fR given by option -r. Using this option will result in absolute symbolic
+links beeing created instead of relative ones.
+
+.TP
+\fB \-H \fR
+By default the script will create soft (symbolic) links from the Tag-Tree to the
+photos. By setting option -H the script will use hard links instead. Please note
+that hard links can only be created inside one filesystem. So your photos and the Tag tree
+have to be one the same filesystem. If not you will see a warning about this problem and the script
+will not run.
+
+.TP
+\fB \-f \fR
+In digikam photos can have hierachical tags (tags that have subtags). In this case
+digitaglinktree would by default add a directory for the tag and a subdirectory for
+each of the subtags of this tag. By setting \fB \-f \fR a subtag is treated like a
+regular tag just as its parent tag so digitaglinktree will create all subdirectories
+for tags and subtags at the same level independent of the tag - subtag hierarchy.
+
+.TP
+\fB \-v \fR
+Prints the scripts version number and exits.
+
+
+.SH CONFIGURATION
+
+The script has to know which version of database is beeing used by digikam.
+The script needs this information to find the correct sqlite binary to
+start queries to the database.
+.sp
+You have to configure the script by setting the path to the sqlite binary that
+is used by the script to query the digikam database digikam.db. Since older
+digikam version use sqlite in version 2, but later digikam 0.80 versions
+needs sqlite version 3 you have to take care to install the correct version of
+sqlite for the installed digikam version and to set the path to the correct
+sqlite executable in the scripts head:
+.sp
+Choose
+
+$SQLITE="/usr/bin/sqlite3";
+
+for digikam version 0.8x and 0.9x and
+
+$SQLITE="/usr/bin/sqlite";
+
+for digikam version 0.7x.
+
+.SH EXAMPLE
+
+A call to digitaglinktree is shown below:
+
+digiTagLinktree -r /home/user/photos -l /home/user/photos/tags \
+ -d /home/user/photos/digikam.db
+
+In this example digikams photo root denoted by -r is /home/user/photos where all of the photos
+can be found that are managed by digikam. The option -l /home/user/photos/tags
+tells the script that all the subdirectories and symbolic links will be placed in
+the directory /home/user/photos/tags. Because the link directory is
+below digikams root directory in this example, you will see a new album in digikam
+after running the script that contains the exported tag structure with all the photos inside.
+Since only links are used here this tag structure does hardly need any additional space on your
+harddisk.
+
+.SH AUTHORS
+.B digitaglinktree
+was written by Rainer Krienke <krienke at uni-koblenz.de>