Sunday, 29 November 2009

"Modifiers" in KRename

Andi Clemens did some amazing work on the batch renamer included and integrated into digiKam. I really like the simple UI and some of the features he included. I think I can get some inspiration from him for KRename (e.g. syntax highlighting).

Lately he posted over the topic of "Modifiers" in the digiKam rename tool, which he added to digiKams renamer and was not able to find in KRename. Modifiers are a way to convert a token, let's say the name of a directory or the artist of a mp3 in some way before inserting it. For example if you insert the name of the directory into the new filename and the directory name is in all uppercase and to match the look of the new filename, you want it to be inserted in lowercase. In digiKam's renamer it is achieved by the token:
[dir.]{lower}

In KRename you would use:
[%dirname.]

So contrary to Andi's post, KRename has modifiers, too. You can add a modifier before any token (after the opening bracket and before the actual name of the token). The modifierst are those used to insert filename's and convert there case. To list the most important ones:





$No conversion, insert the token as it is
%Convert to lowercase
&Convert to uppercase
*Convert every first letter in a word to uppercase
##Format a number with leading zeros


So you can even use modifierst to format numbers for tokens that return number. For example [##tagTrack] will insert the track number of a MP3 formatted with one leading zero if the track number is less than 10.

It is true that KRename does not have a really readable syntax for modifiers here, I think appending {upper} or {lower} like digiKam does it, is a good idea. But there are several other places, too, where the KRename syntax could be improved. I hope that this post will help a few people that also did not know about this feature.

Modifiers in action

Tuesday, 11 November 2008

KRename on Windows

Some time ago - during a longer trip by train - I booted the Windows XP installed on my Eee PC and tried to port KRename to Windows. Thanks to the efforts of the KDE on Windows team it was only a matter of about 1-2 hours.

You don't believe it? Well see the screenshots:





I am really impressed how easy it is to get KDE on Windows installed and start compiling using Visual Studio. The only changes necessary were related to some Unix syscalls in the Permissions and Date&Time plugin. To try KRename out, it is best to get a current snapshot from SVN (I justed checked in the changes necessary for compilation on Win32).
A pre-compiled binary can be found here. It requires a working installation of KDE 4.1 for Windows. Simply copy it to %KDEDIR%/bin and it should work. If there is interest I might try to provide a real setup for Windows or create more regularly SVN builds.

Saturday, 4 October 2008

PoDoFoBrowser updates

I had finally sometime to work on PoDoFoBrowser again.

Most notably, I added finally a hex widget so that binary streams can be viewed directly from within PoDoFoBrowser:



Credits for the QHexView widget goes to Evan Teran.


Other changes include an implementation for Find and Replace in text streams and a new Goto Page feature. Both will safe you a lot of time when you have to work with content streams.

To try the changes, get PoDoFoBrowser from SVN.

Tuesday, 26 February 2008

KRename Video

Peter Upfold from fosswire.com has posted a great video on how to use KRename.

I think this video is great to show how KRename (or any other application) is working. I love the way he made the video: easy to understand and very well commented! Great work Peter!

You can find his article including the links to the video here. The video is available as flash for viewing online or as OGG for download.

Thursday, 21 February 2008

Visualize dependencies of binaries and libraries on Linux

Update2: pfee made some more fixes. The script parses now the dependcies tree correctly using readelf and ldd so that only direct dependencies apear in the graph. The updated version can also be found at dependencies.sh



Update: Thanks to the feedback from pfee, I made some fixes to the script. The script is now also available for direct download dependencies.sh



Sometimes it is useful to know the library dependencies of an application or a library on Linux (or Unix). Especially OpenSource applications depend on lot's of libraries which in turn depend on other libraries again. So it is not always quite clear which dependencies your software has.



Imagine you want to package up your software for a customer and need to know on which libraries your software depends. Usually you know which libraries were used during development, but what are the dependencies of these libraries? You have to package all dependencies so that the customer can use and/or install your software.



I created a bash-script which uses ldd to find the dependencies of a binary on Linux and Graphviz to create a dependency graph out of this information. Benedikt Hauptmann had the idea to show dependencies as a graph - so I cannot take credits for that. Using this script I created the depency graph of TFORMer, the report generator we are developing at TEC-IT. The result is a nice graph showing all the dependencies a user has to have installed before using TFORMer.





Another beautiful graph is the one of PoDoFo. See below the graph of PoDoFo.





The dependencies of Firefox are way more complex than the examples shown above...





If you want to create a graph of your favorite application or library your self, get the script from here. I pulished the simple source code below. Graphviz is the only requirement. Usage is very simple, just pass an application or library as first parameter and the output image as second argument. The script will always create a PNG image:


./dependencies.sh /usr/bin/emacs emacs.png
./dependencies.sh /usr/local/lib/libpodofo.so \
podofo.png



The code of the script is as follows: (Warning: the style sheet cuts of some lines, so better download the script from dependencies.sh)




#!/bin/bash

# This is the maximum depth to which dependencies are resolved
MAXDEPTH=14

# analyze a given file on its
# dependecies using ldd and write
# the results to a given temporary file
#
# Usage: analyze [OUTPUTFILE] [INPUTFILE]
function analyze
{
local OUT=$1
local IN=$2
local NAME=$(basename $IN)

for i in $LIST
do
if [ "$i" == "$NAME" ];
then
# This file was already parsed
return
fi
done
# Put the file in the list of all files
LIST="$LIST $NAME"

DEPTH=$[$DEPTH + 1]
if [ $DEPTH -ge $MAXDEPTH ];
then
echo "MAXDEPTH of $MAXDEPTH reached at file $IN."
echo "Continuing with next file..."
return
fi

echo "Parsing file: $IN"

$READELF $IN &> $READELFTMPFILE
ELFRET=$?

if [ $ELFRET != 0 ];
then
echo "ERROR: ELF reader returned error code $RET"
echo "ERROR:"
cat $TMPFILE
echo "Aborting..."
rm $TMPFILE
rm $READELFTMPFILE
rm $LDDTMPFILE
exit 1
fi

DEPENDENCIES=$(cat $READELFTMPFILE | grep NEEDED | awk '{if (substr($NF,1,1) == "[") print substr($NF, 2, length($NF) - 2); else print $NF}')

for DEP in $DEPENDENCIES;
do
if [ -n "$DEP" ];
then

ldd $IN &> $LDDTMPFILE
LDDRET=$?

if [ $LDDRET != 0 ];
then
echo "ERROR: ldd returned error code $RET"
echo "ERROR:"
cat $TMPFILE
echo "Aborting..."
rm $TMPFILE
rm $READELFTMPFILE
rm $LDDTMPFILE
exit 1
fi

DEPPATH=$(grep $DEP $LDDTMPFILE | awk '{print $3}')
if [ -n "$DEPPATH" ];
then
echo -e " \"$NAME\" -> \"$DEP\";" >> $OUT
analyze $OUT $DEPPATH
fi
fi
done

DEPTH=$[$DEPTH - 1]
}

########################################
# main #
########################################

if [ $# != 2 ];
then
echo "Usage:"
echo " $0 [filename] [outputimage]"
echo ""
echo "This tools analyses a shared library or an executable"
echo "and generates a dependency graph as an image."
echo ""
echo "GraphViz must be installed for this tool to work."
echo ""
exit 1
fi

DEPTH=0
INPUT=$1
OUTPUT=$2
TMPFILE=$(mktemp -t)
LDDTMPFILE=$(mktemp -t)
READELFTMPFILE=$(mktemp -t)
LIST=""

if [ ! -e $INPUT ];
then
echo "ERROR: File not found: $INPUT"
echo "Aborting..."
exit 2
fi

# Use either readelf or dump
# Linux has readelf, Solaris has dump
READELF=$(type readelf 2> /dev/null)
if [ $? != 0 ]; then
READELF=$(type dump 2> /dev/null)
if [ $? != 0 ]; then
echo Unable to find ELF reader
exit 1
fi
READELF="dump -Lv"
else
READELF="readelf -d"
fi



echo "Analyzing dependencies of: $INPUT"
echo "Creating output as: $OUTPUT"
echo ""

echo "digraph DependencyTree {" > $TMPFILE
echo " \"$(basename $INPUT)\" [shape=box];" >> $TMPFILE
analyze $TMPFILE "$INPUT"
echo "}" >> $TMPFILE

#cat $TMPFILE # output generated dotfile for debugging purposses
dot -Tpng $TMPFILE -o$OUTPUT

rm $LDDTMPFILE
rm $TMPFILE

exit 0

Tuesday, 14 August 2007

Encrypting PDF documents and setting document permissions

Nowadays many applications are able to create PDF files. Most of them do not support advanced PDF features like encrypting PDF files or setting document permissions.


Document permissions are settings that configure what the user is allowed to do with a PDF file (let's say you can forbid the user to print the PDF file or to extract images from the PDF).


PoDoFo includes now a nice commandline utility in its SVN version (and in the next relase 0.6.0) called podofoencrypt.


podofoencrypt can be used to encrypt any existing PDF file and set document permissions on the file. You can select between weak rc4v1 encryption and strong rc4v2 encryption. An owner password has always to be set. The owner password is only used internally by PDF processing applications. The optional user password can be used if you want the user to have to enter a password before he can view the PDF in a user application.


Let's see a small example on howto use podofoencrypt to encrypt a PDF file with a user password which allows the user to print the PDF but not to extract text or images from it.


./podofoencrypt -o dominik -u user --print example.pdf output.pdf

A quick look at the document properties dialog in Adobe Reader shows that you are allowed to print the PDF but do nothing else with it.



I would like to get some feedback on the new encryption feature of PoDoFo and especially on the new podofoencrypt tool. So please get it from svn and try it out.

Dom

Wednesday, 4 July 2007

TFORMer 5.0.0 released


Besides developing OpenSourceSoftware I do also work for TEC-IT Datenverarbeitung GmbH. Last week we finally released TFORMer 5.0.0. A cross platform, easy to use and very powerful report printing framework.


I worked over the last 3 years on this version and we all put a lot of work into this release. Most importantly, the source is completely portable over a broad range of platforms and architectures. The Linux version is relased for several RPM based distributions and as deb for Ubuntu. AIX, HPUX and Solaris builds are available on request. Please note that the same source is also compiled on Windows (from which we ported it to all these platforms).


TFORMer can print to PDF, PostScript and HTML files and of course to any system printer using CUPS. More output formats will be available with TFORMer 5.1 :) The PDF and PostScript output are really highquality and were the two projects you got me to learn both output formats.


I am proud of the quality of the Linux version. We ship with an easy to use installer, which installs either an RPM or a DEB. The software is installed, with documentation (PDF format and man page), several templates, demo reports, sample code for C and .Net and of course development libraries for C and C#. After the software has been installed and report is printed automatically (if the users agrees to do so) and everything works - I can't imagine reporting has ever been easier on Linux.


The C API is great and powerful, but the new .Net API is sexy! First of all, the wrapper is portable between Mono on Linux and .Net on Windows. We load the TFORMer.dll when run on Windows and we load libTFORMer.so on Linux when we are executed on Unix.


Have you ever created a PDF report so easy?



// Create a TFORMer Job
Job job = new Job();

// Load a predefined form layout
job.RepositoryName = "MyForm.tff"M

// create an in-memory data-source
DataSourceRecordSet datasource = new DataSourceRecordSet();

// Set some datafields
job.DataSource = datasource;
Record record = new Record();
record.Data.Add("Email", "support@tec-it.com");
record.Data.Add("JobTitle", "Support Engineer");
record.Data.Add("Name", "Mr. Harald Backoffice");
datasource.Records.Add(record);

// Set the output file name and type
job.OutputName = "out.pdf";
job.PrinterType = PrinterType.PdfFile;

// Print
job.Print();


Easy - Ja??!


A free demo version is available (for Windows and several Linux versions). So give it a try.