You are not logged in.

#1 2008-04-17 15:42:08

Arkane
Member
From: Switzerland
Registered: 2008-02-18
Posts: 263

Rox Application directory generator

Edited 04/18/08:
Renamed a few things, corrected some typos/stupid bugs.


Usage: makeroxapp [OPTIONS] APPLICATION
       makeroxapp -a [OPTIONS]
       makeroxapp -m [OPTIONS] COMMAND [ICON]
    -a: process all .desktop files in the default applications directory
    -h, --help: print this message
    -v: verbose output
    -q: silent
    -l LANGUAGE: try to use names and information in this language
    -m: manually provide a command and an (optional) icon
    -i DIR: look for .desktop files in the directory DIR instead
            of the default
    -d DIR: create application directories in DIR instead of the
            default
    -f: overwrite the application directory if it already exists
    -k: asks whether to overwrite the app dir if it already exists

Here's a script which creates ROX app dirs from .desktop files. I think I finally got it pretty bulletproof, but I can't be sure it won't wreck something ^^'. It will create a directory named after the "Name=" field of the .desktop file, with the AppRun file, AppInfo.xml (with additional comments to make completing it by hand easy), and .DirIcon if an icon was found.


General usage notes:

- The scripts supports alternate languages, specify one with the -l flag, or by changing the LANGUAGE variable at the beginning of the script.

- Applications needing to be run in a terminal are also correctly handled, you will need to set the TERMCOMMAND variable at the beginning of the script to the correct command line for your terminal emulator.

- Both the directory where the .desktop files are searched for (default: /usr/share/applications) and the one where app dirs are created (default: ~/ROXApps) can be changed inside the script, or with the -i and -d flags, respectively.

- The -a flag will process all .desktop files in the APPSDIR folder.


Configure it by editing the variables at the beginning, run makeroxapp -h, and you'll know how to use it. A single makeroxapp -a is all you need to fill a folder with all available applications so you can use it as an application menu.



#!/bin/dash

# Configuration

APPSDIR=/usr/share/applications/
ROXDIR=~/ROXApps/
ROXCONFIG=~/.config/rox.sourceforge.net/

# leave blank for the default language (en_US)
LANGUAGE=""
# if you want another, then for example
# LANGUAGE=fr

# command line to run an application in a terminal
TERMCOMMAND="xterm -e"

# acceptable icon sizes, by decreasing preference
ICONSIZES="scalable 256x256 128x128 64x64 48x48 32x32 24x24 22x22 16x16"

# End configuration

makeapp () {
    if [ -e "$DESTDIR" ]; then
        if [ "$FORCE" ]; then 
            rm -r "$DESTDIR" && echo "Removed already existing directory: $DESTDIR" > $OUT || return 1
        elif [ $ASK ]; then
            read -p "$DESTDIR: An application directory with this name already exists. Overwrite? (y/n) [n] " answer
            [ ! "y" =  "$answer" ] && echo "Skipping $APP" && return 1
            rm -r "$DESTDIR" || return 1
            echo "Removed $DESTDIR" > $OUT
        else
            echo "$DESTDIR: Directory exists, skipping" > /dev/stderr
            return 1
        fi
    fi
    mkdir "$DESTDIR" || return 1
    echo "Created $DESTDIR" > $OUT
    
    echo "#!/bin/dash" > "${DESTDIR}AppRun"
    if [ "`echo $COMMAND | grep "%u"`" ]; then
        echo 'if [ "$1" ]; then' >> "${DESTDIR}AppRun"
        echo "    `echo $COMMAND | sed -e 's/%u/\"\$@\"/'`" >> "${DESTDIR}AppRun"
        echo 'else' >> "${DESTDIR}AppRun"
        echo "    `echo $COMMAND | sed -e 's/%u/ /'`" >> "${DESTDIR}AppRun"
        echo 'fi' >> "${DESTDIR}AppRun"
    else
        echo 'if [ "$1" ]; then' >> "${DESTDIR}AppRun"
        echo "    $COMMAND \"\$@\"" >> "${DESTDIR}AppRun"
        echo 'else' >> "${DESTDIR}AppRun"
        echo "    $COMMAND" >> "${DESTDIR}AppRun"
        echo "fi" >> "${DESTDIR}AppRun"
    fi
    chmod +x "${DESTDIR}AppRun"
    echo "Created executable AppRun file, contents:" > $OUT
    cat "${DESTDIR}AppRun" > $OUT

    echo '<?xml version="1.0"?>' > ${DESTDIR}AppInfo.xml
    echo '<AppInfo>' >> ${DESTDIR}AppInfo.xml
    [ "$DESC" ] && echo "<Summary>$DESC</Summary>" >> ${DESTDIR}AppInfo.xml || echo "<!--<Summary>Insert tooltip here</Summary>-->" >> ${DESTDIR}AppInfo.xml
    echo '<About>' >> ${DESTDIR}AppInfo.xml
    [ "$PURPOSE" ] && echo "  <Purpose>$PURPOSE</Purpose>" >> ${DESTDIR}AppInfo.xml||echo '  <!--<Purpose></Purpose>-->' >> ${DESTDIR}AppInfo.xml
    echo '  <!--<Version></Version>-->' >> ${DESTDIR}AppInfo.xml
    echo '  <!--<Authors></Authors>-->' >> ${DESTDIR}AppInfo.xml
    echo '  <!--<License></License>-->' >> ${DESTDIR}AppInfo.xml
    echo '  <!--<Homepage></Homepage>-->' >> ${DESTDIR}AppInfo.xml
    echo '</About>' >> ${DESTDIR}AppInfo.xml
    echo '<AppMenu>' >> ${DESTDIR}AppInfo.xml
    echo "  <!-- You can define items in the left-click menu which call the program with different arguments. Here's an example: -->" >> ${DESTDIR}AppInfo.xml
    echo '  <!-- <Item option="-v"> -->' >> ${DESTDIR}AppInfo.xml
    echo '  <!--   <Label>Verbose output</Label> -->' >> ${DESTDIR}AppInfo.xml
    echo '  <!-- </Item> -->' >> ${DESTDIR}AppInfo.xml
    echo '</AppMenu>' >> ${DESTDIR}AppInfo.xml
    echo '</AppInfo>' >> ${DESTDIR}AppInfo.xml
    echo "Created AppInfo.xml file, contents:" > $OUT
    cat "${DESTDIR}AppInfo.xml" > $OUT

    [ "$ICON" ] && ICON=`echo $ICON | line` && cp "$ICON" "${DESTDIR}.DirIcon" && echo "Copied $ICON to ${DESTDIR}.DirIcon" > $OUT
    
    echo "Done with this application" > $OUT
    return 0
}


setvars () {
    DESTDIR=""
    [ "$LANGUAGE" ] && DESTDIR=`grep "^Name\[${LANGUAGE}\]=" $APP | cut -c$(($LANGUAGELEN + 6))-`
    [ ! "$DESTDIR" ] && DESTDIR=`grep "^Name=" $APP | cut -c6-`
    DESTDIR=$ROXDIR$DESTDIR/
    echo "Destination: $DESTDIR" > $OUT
    
    PRECOMMAND=`grep '^Exec=' $APP | cut -c6- | sed -e 's/ %U/ %u/g' | sed -e 's/ %F/ %u/g' | sed -e 's/ %f/ %u/'`
    if [ "true" = "`grep "^Terminal=" $APP | cut -c10-`" ]; then
        echo "Application runs in a terminal" > $OUT
        COMMAND="$TERMCOMMAND $PRECOMMAND"
    else
        COMMAND="$PRECOMMAND"
    fi
    echo "Command: $COMMAND" > $OUT
    
    DESC=""
    [ "$LANGUAGE" ] && DESC=`grep "^Comment\[${LANGUAGE}\]=" $APP | cut -c$(($LANGUAGELEN + 9))-`
    [ ! "$DESC" ] && DESC=`grep "^Comment=" $APP | cut -c9-`
    [ "$DESC" ] && echo "Description: $DESC" > $OUT || echo "No description found" > $OUT
    
    PURPOSE=""
    [ "$LANGUAGE" ] && PURPOSE=`grep "^GenericName\[${LANGUAGE}\]=" $APP | cut -c$(($LANGUAGELEN + 13))-`
    [ ! "$PURPOSE" ] && PURPOSE=`grep "^GenericName=" $APP | cut -c13-`
    [ "$PURPOSE" ] && echo "Purpose: $PURPOSE" > $OUT || echo "No purpose (GenericName) found" > $OUT

    ICONNAME=`grep "^Icon=" $APP | cut -c6-`
        
    if [ $ICONNAME ]; then
        [ "/" = "`echo $ICONNAME | cut -c1`" ] && FULLICONNAME=$ICONNAME || FULLICONNAME=""
        ICONNAME=`basename $ICONNAME`

        EXTENSION=`echo $ICONNAME | grep -o '\.\w\w*$'`
        [ "$EXTENSION" ] && ICONNAME=`basename $ICONNAME $EXTENSION`
        
        echo "Will look for the following icon: $ICONNAME" > $OUT
        
        if [ "$ICONTHEME" ]; then
            TFILE=/tmp/makeroxapp-`uuidgen`
            find $ICONTHEME -name "$ICONNAME.*" -fprint $TFILE
            for size in $ICONSIZES; do
                ICON=`grep "/${size}/" $TFILE`
                [ -n "$ICON" ] && echo "Icon found: $ICON" > $OUT && rm $TFILE && return 0
            done
            echo "Couldn't find icon in the ROX icon theme" > $OUT
            rm $TFILE
        fi
        
        if [ "$FULLICONNAME" ]; then
            ICON=$FULLICONNAME
            [ -e "$ICON" ] && echo "Icon found: $ICON" > $OUT && return 0
            echo "Couldn't find icon at $ICON" > $OUT
        fi
        
        ICON=/usr/share/pixmaps/$ICONNAME.svg
        [ -e "$ICON" ] && echo "Icon found: $ICON" > $OUT && return 0
        ICON=/usr/share/pixmaps/$ICONNAME.png
        [ -e "$ICON" ] && echo "Icon found: $ICON" > $OUT && return 0
        ICON=/usr/share/pixmaps/$ICONNAME.xpm
        [ -e "$ICON" ] && echo "Icon found: $ICON" > $OUT && return 0
        echo "Couldn't find icon in /usr/share/pixmaps" > $OUT

        ICON=""
        TFILE=/tmp/makeroxapp-`uuidgen`
        find /usr/share/icons/hicolor/ -name "$ICONNAME.*" -fprint $TFILE
        for size in $ICONSIZES; do
            ICON=`grep "/$size/" $TFILE`
            [ -n "$ICON" ] && echo "Icon found: $ICON" > $OUT && rm $TFILE && return 0
        done
        echo "Couldn't find icon in the default theme" > $OUT
        rm $TFILE
        
        echo "No icon found" > $OUT
        ICON=""
    else
        echo "No icon" > $OUT
        ICON=""
    fi
    return 0
}


findicontheme () {
    ICONTHEME=`grep '"icon_theme"' ${ROXCONFIG}ROX-Filer/Options`
    ICONTHEME=`echo $ICONTHEME | grep -o '>..*<'`
    ICONTHEME=`basename $ICONTHEME "<" | cut -c2-`
    if ([ "$ICONTHEME" ] && [ "`ls ~/.icons | grep \"^$ICONTHEME\$\"`" ]); then 
        ICONTHEME=~/.icons/${ICONTHEME}/
    elif ([ "$ICONTHEME" ] && [ "`ls /usr/share/icons | grep \"^$ICONTHEME\$\"`" ]); then 
        ICONTHEME=/usr/share/icons/${ICONTHEME}/
    else ICONTHEME=""
    fi
    [ "$ICONTHEME" ] && echo "ROX icon theme found: $ICONTHEME" > $OUT || echo "ROX icon theme not found" > $OUT
    return 0
}


dispatch () {
    [ "$MANUAL" ] && [ "$ALL" ] && echo "Incompatible options: -a -m" && usage && exit 1

    if [ "$ALL" ]; then
        echo "Processing all applications in $APPSDIR" > $OUT
        findicontheme
        for APP in `ls $APPSDIR | grep "..*\.desktop"`; do
            APP=$APPSDIR$APP
            if [ "Application" = `grep "^Type=" $APP | cut -c6-` ]; then
                echo "Application found: $APP" > $SOUT
                setvars
                makeapp
            fi
        done
        echo "Done" > $OUT
    elif [ "$MANUAL" ]; then
        echo "Manually creating app dir" > $OUT
        DESTDIR=~/ROXApps/$1/
        echo "    destination: $DESTDIR" > $OUT
        COMMAND=$1
        echo "    command: $COMMAND" > $OUT
        ICON=$2
        [ "$ICON" ] && echo "    icon: $ICON" > $OUT || echo "    no icon" > $OUT
        makeapp
        echo "Done" > $OUT
    else
        APP=$1
        if [ "`basename \"$APP\" .desktop`" = "$APP" ]; then
            APP=$APPSDIR$APP.desktop
        fi
        echo "Making application directory for application $APP" > $OUT
        [ ! -e $APP ] && echo "Cannot find application" > /dev/stderr && exit 1
        findicontheme
        setvars
        makeapp
        echo "Done" > $OUT
    fi
    return 0
}


usage () {
    echo 'Usage: makeroxapp [OPTIONS] APPLICATION'
    echo '       makeroxapp -a [OPTIONS]'
    echo '       makeroxapp -m [OPTIONS] COMMAND [ICON]'
    echo '    -a: process all .desktop files in the default applications directory'
    echo '    -h, --help: print this message'
    echo '    -v: verbose output'
    echo '    -q: silent'
    echo '    -l LANGUAGE: try to use names and information in this language'
    echo '    -m: manually provide a command and an (optional) icon'
    echo '    -i DIR: look for .desktop files in the directory DIR instead'
    echo '            of the default'
    echo '    -d DIR: create application directories in DIR instead of the'
    echo '            default'
    echo '    -f: overwrite the application directory if it already exists'
    echo '    -k: asks whether to overwrite the app dir if it already exists'
    return 0
}


ALL=""
MANUAL=""
SILENT=""
VERBOSE=""
FORCE=""
ASK=""
COMMAND=""
ICON=""
APP=""

while getopts ad:fhi:kl:mqv opt; do
    case $opt in
        a)  ALL=true;;
        d)  ROXDIR=$OPTARG;;
        f)  FORCE=true;;
        h)  usage; exit 0;;
        i)  APPSDIR=$OPTARG;;
        k)  ASK=true;;
        l)  LANGUAGE=$OPTARG;;
        m)  MANUAL=true;;
        q)  SILENT=true;;
        v)  VERBOSE=true;;
        \?) echo "Unknown option: $opt"
            usage()
            exit 1
            ;;
    esac
done

shift $(($OPTIND - 1))

[ "$VERBOSE" ] && OUT=/dev/stdout || OUT=/dev/null
[ "$SILENT" ] && SOUT=/dev/null || SOUT=/dev/stdout

LANGUAGELEN=$((`echo $LANGUAGE | wc -c` + 1)) # we're counting the brackets


[ ! -e "$ROXDIR" ] && mkdir "$ROXDIR" && echo "$ROXDIR didn't exist, created it"

dispatch "$@"

exit 0

Also, this is my first non-trivial shell script, so any comments will be appreciated.

Last edited by Arkane (2008-04-18 06:04:43)


What does not kill you will hurt a lot.

Offline

Board footer

Powered by FluxBB