#!/bin/sh set -u KATEG_FILES="`dirname $0`/kategorien-norm.lst `dirname $0`/kategorien-debian.lst `dirname $0`/kategorien-verwandte.lst" #READ_DESKTOP_DIR="/var/lib/menu-xdg/applications/menu-xdg" READ_DESKTOP_DIR="/usr/share/applications" WRITE_DESKTOP_DIR="`dirname $0`/desktop-files" #DATA_FILE="`dirname $0`/database.dat" DATA_FILE="/tmp/database.dat" EINTRAEGE_PRO_SEITE=10 exec -- 2>/tmp/output #set -x ############# Menue-Verwaltung ################ filter_empty() { sed -r '/^[[:space:]]*$/d ; s/^[[:space:]]*// ; s/[[:space:]]*$//' } hole_app_liste() { find "$READ_DESKTOP_DIR" -type f -name \*.desktop | while read a do basename "${a%.desktop}" done | filter_empty | sort | nl } # zuerst in der Datenbank nachsehen - ansonsten aus dem desktop-Verzeichnis holen # Parameter: app-name lade_app_kategs() { DDATEI=`find $READ_DESKTOP_DIR -type f -name $1.desktop` if [ -e "$DATA_FILE" ] && grep -q "^$1=" "$DATA_FILE" then grep "^$1=" "$DATA_FILE" | cut -d "=" -f 2 | tr " " "\n" else [ -e "$DDATEI" ] && grep "^Categories=" "$DDATEI" | cut -d "=" -f 2 | tr ";" "\n" fi | filter_empty | sort | uniq } hole_kateg_liste() { cat $KATEG_FILES | cut -f 1 | filter_empty | sort | uniq } # liefert eine Liste von Kategorien zurueck, die entweder auf die angegebene verweisen oder # solche, auf die sie selbst verweist # nicht-standard-konforme Kategorien (X-???-???) werden herausgefiltert # Parameter: die zu bearbeitende Kategorie hole_verwandte_kategs() { ( [ -z "$1" ] && return # erstmal die verweisenden: cat $KATEG_FILES | sed 's/$/\t/' | grep "[[:space:]]$1[[:space:]]" | cut -f 1 # dann die, auf die verwiesen wird: cat $KATEG_FILES | grep "^$1[[:space:]]" | cut -f 2-30 | tr "\t" "\n" | tr " " "\n" ) | grep -v "^X-" | filter_empty | sort | uniq } # liefert alle Kategorien zurueck, die mit den bisherigen Kategorien der Anwendung verwandt sind, # ihr jedoch noch nicht zugeordnet wurden hole_verwandte_kategs_der_app() { #local FILTER=`lade_app_kategs "$1" | sed 's#^#/# ; s#$#/d;#' | tr "\n" " "` local FILTER=`lade_app_kategs "$1" | sed 's#^.*$#/&/d; #' | tr "\n" " "` lade_app_kategs "$1" | while read a; do hole_verwandte_kategs "$a"; done | sed "$FILTER" | filter_empty | sort | uniq } hole_anzahl_apps() { echo "$ALLE_APPS" | wc -l } # entfernt alle Apps, die nicht in der angegebenen Kategorie sind # Parameter: - die Kategorie # - die Anwendungen filter_apps_nach_kateg() { local KATEG="$1" shift echo -e "$ALLE_APPS" | while read num name do lade_app_kategs "$name" | grep -q "$KATEG" && echo -e "$num\t$name" done } speichere_formdaten() { local POST_DATA=`cat - | tr "&" "\n"` local EINTRAEGE=`echo "$POST_DATA" | grep "^text_kategs_" | cut -d = -f 1 | sed 's/^text_kategs_//'` local NEUE_KATEGS local APP_NAME for a in $EINTRAEGE do NEUE_KATEGS=`echo "$POST_DATA" | grep "^text_kategs_$a=" | cut -d '=' -f 2 | tr '+' ' ' | tr ' ' '\n'` NEUE_KATEGS="$NEUE_KATEGS\n`echo -e \"$POST_DATA\" | grep "^liste_kateg[123]_$a=" | cut -d '=' -f 2`" NEUE_KATEGS=`echo -e "$NEUE_KATEGS" | sort | uniq | tr '\n' ' '` APP_NAME=`app_num2name $a` NEUE_ZEILE=`echo -e "$APP_NAME=$NEUE_KATEGS" | sed -r 's/[[:space:]]+/ /g; s/=[[:space:]]/=/'` [ ! -e "$DATA_FILE" ] && touch "$DATA_FILE" sed -i "s/^$APP_NAME=.*/$NEUE_ZEILE/" "$DATA_FILE" grep -q "^$APP_NAME=" "$DATA_FILE" || echo -e "$NEUE_ZEILE" >> "$DATA_FILE" done } app_num2name() { echo "$ALLE_APPS" | grep "^[[:space:]]*$1[[:space:]]" | cut -f 2 } app_name2num() { echo "$ALLE_APPS" | grep "[[:space:]]$1$" | cut -f 1 } ################# debug & test ################# debug_zeige_alle_apps() { for a in `hole_app_liste` do echo -en "$a\t-\t" lade_app_kategs "$a" | tr "\n" " " echo done } ############## html-encoding ################ html_header() { echo "Content-type: text/html" echo echo "<HTML>" echo "<HEAD>" echo " <TITLE>Debian-Menue-Designer</TITLE>" echo ' <META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">' echo "</HEAD>" echo "<BODY>" } html_footer() { echo "</BODY>" echo "</HTML>" } html_nav() { echo '<DIV ALIGN="CENTER"><TABLE BORDER="0" CELLPADDING="20"><TR>' echo "<FORM ACTION=\"`basename $0`\" METHOD=\"GET\">" echo ' <TD>Kategorie: <BR><SELECT NAME="kateg_filter">' echo ' <OPTION VALUE="">alle</OPTION>' for a in $ALLE_KATEGS do if [ "$a" = "$KATEG_FILTER" ] then echo " <OPTION SELECTED>$a</OPTION>" else echo " <OPTION>$a</OPTION>" fi done echo ' </SELECT></TD>' echo ' <TD>Einträge je Seite:<BR><SELECT NAME="eintraege_pro_seite">' for a in 10 25 50 100 500 1000 do if [ "$a" = "$EINTRAEGE_PRO_SEITE" ] then echo " <OPTION SELECTED>$a</OPTION>" else echo " <OPTION>$a</OPTION>" fi done echo ' </SELECT>' echo ' </TD>' echo ' <TD>Beginne bei Eintrag:<BR><SELECT NAME="app_start_nr">' for a in 1 10 25 100 500 do if [ "$a" = "$APP_START_NR" ] then echo " <OPTION SELECTED>$a</OPTION>" else echo " <OPTION>$a</OPTION>" fi done echo ' </SELECT>' echo ' </TD>' echo ' <TD><INPUT TYPE="SUBMIT" VALUE="Anzeigen"></TD>' echo '</FORM></TR></TABLE></DIV>' echo '<HR>' } # zwei Paramater: # (1) _all_ ODER Name der Anwendung, zu der nur die noch nicht verwendeten Verwandten eingetragen werden sollen # (2) der Name der HTML-Auswahlliste (entspricht dem spaeteren Variablennamen des Inhalts) html_kateg_liste() { echo "<SELECT NAME=\"$2\" SIZE=\"1\">" echo " <OPTION></OPTION>" if [ $1 = "_all_" ] then echo -e "$ALLE_KATEGS" else hole_verwandte_kategs_der_app "$1" fi | while read a; do echo " <OPTION>$a</OPTION>"; done echo "</SELECT>" echo } # Parameter: app-nummer html_apps_config() { local APP_NAME=`app_num2name $1` echo " <TR>" echo " <TD>$APP_NAME</TD>" echo " <TD><INPUT NAME=\"text_kategs_$1\" SIZE=\"50\" VALUE=\"`lade_app_kategs $APP_NAME | tr '\n' ' '`\"></TD>" echo " <TD>`html_kateg_liste $APP_NAME liste_kateg1_$1`</TD>" echo " <TD>`html_kateg_liste $APP_NAME liste_kateg2_$1`</TD>" echo " <TD>`html_kateg_liste _all_ liste_kateg3_$1`</TD>" echo " </TR>" } # als Parameter ist die Nummer der ersten Anwendung der Liste erforderlich html_edit_liste() { echo -n '<FORM NAME="Kategorien-Zuordnung" METHOD="POST"' echo " ACTION=\"`basename $0`?action=speichern&app_start_nr=$APP_START_NR&eintraege_pro_seite=$EINTRAEGE_PRO_SEITE&kateg_filter=$KATEG_FILTER\">" echo "<TABLE BORDER=\"0\">" echo " <TR>" echo " <TH>Programm</TH>" echo " <TH>bisherige Kategorien</TH>" echo " <TH>verwandte Kategorie I</TH>" echo " <TH>verwandte Kategorie II</TH>" echo " <TH>weitere Kategorie</TH>" echo " </TR>" local uebrig=$EINTRAEGE_PRO_SEITE echo -e "$ALLE_APPS\n" | sed -n "$((APP_START_NR)),$((APP_START_NR+EINTRAEGE_PRO_SEITE-1))p" | while read num name do [ -n "$num" ] && html_apps_config $num uebrig=$((uebrig-1)) done echo "</TABLE>" echo '<DIV ALIGN="CENTER"><INPUT TYPE="SUBMIT" VALUE=" Speichern "></DIV>' echo "</FORM>" if [ $APP_START_NR -gt 1 -o $((APP_START_NR+EINTRAEGE_PRO_SEITE-1)) -lt `hole_anzahl_apps` ] then echo '<P><BR><DIV ALIGN="CENTER">' if [ $APP_START_NR -gt 1 ] then local PREV_START_NR=$((APP_START_NR-EINTRAEGE_PRO_SEITE)) [ "$PREV_START_NR" -lt 1 ] && PREV_START_NR=1 echo "<A HREF=\"`basename $0`?app_start_nr=$PREV_START_NR&eintraege_pro_seite=$EINTRAEGE_PRO_SEITE&kateg_filter=$KATEG_FILTER\">vorherige Seite</A>" fi if [ $((APP_START_NR+EINTRAEGE_PRO_SEITE-1)) -lt `hole_anzahl_apps` ] then local NEXT_START_NR=$((APP_START_NR+EINTRAEGE_PRO_SEITE)) echo "<A HREF=\"`basename $0`?app_start_nr=$NEXT_START_NR&eintraege_pro_seite=$EINTRAEGE_PRO_SEITE&kateg_filter=$KATEG_FILTER\">nächste Seite</A>" fi echo "</DIV></P>" fi } ############# cgi-Zeug ############# # liest einen cgi-Parameter ein und liefert notfalls einen angegebenen Default-Wert zurueck # Parameter: der Name des Parameters und der default-Wert hole_parameter() { local ERG=$2 if set | grep -q "^QUERY_STRING" then ERG=`echo "$QUERY_STRING" | tr "&" "\n" | grep "^$1" | cut -d "=" -f 2` else ERG="$2" fi [ -z "$ERG" ] && ERG="$2" echo -e "$ERG" } ############# los geht es! ############ ALLE_KATEGS=`hole_kateg_liste` ALLE_APPS=`hole_app_liste` KATEG_FILTER=`hole_parameter kateg_filter ""` [ -n "$KATEG_FILTER" ] && ALLE_APPS=`filter_apps_nach_kateg "$KATEG_FILTER"` APP_START_NR=`hole_parameter app_start_nr 1` EINTRAEGE_PRO_SEITE=`hole_parameter eintraege_pro_seite $EINTRAEGE_PRO_SEITE` html_header html_nav ACTION=`hole_parameter action formular` case "$ACTION" in speichern|formular) [ "$ACTION" = "speichern" ] && speichere_formdaten html_edit_liste ;; *) echo '<H1><DIV ALIGN="CENTER">Fehlerhafte Aktion (' echo "$ACTION" echo ') angefordert!</DIV></H1>' ;; esac html_footer