Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 03/01/2012, à 02:10

nordinatueur

[script] ToDoList en bash...

Suite à un de mes vieux billets sur un topic très sympa ( ./viewtopic.php?pid=3758609#p3758609 ) j'ai amélioré la script de todoList...

Voici la version avec YAD (bien plus puissant que zenity) et Zenity :

#!/bin/bash 
# Créé par Nordinatueur
# 
rouge='\e[31m'; vert='\e[32m'; jaune='\e[33m'; bleu='\e[34m'; rose='\e[35m'; cyan='\e[36m'; gris='\e[37m'; NC='\e[0m';

todoDir="${HOME}";
todoList="${todoDir}/.todo.list";
cd "${todoDir}";
#cp "${todoList}" "${todoList}.$(date '+%y.+%j')";

Erreur ()
{
    echo "${1}" >&2;
}

Init ()
{
    if [[ ! -e "${todoList}" ]]; then
        echo "Ligne 1" > "${todoList}";
    else
        Erreur "${todoList} existe...";
    fi;
}
Init;


Usage ()
{
    sed -nr 's/[[:space:]]+(-[^\)]*)\) #/\t\1\t/pg' ${0};
    #sed -rn 's/[[:space:]]+(-[^\)]*)\)#/\t\t/pg' ${0};
    exit;
}

SupprimerLigne ()
{
    i=${1:-$};
    sed -i "${1}d" "${todoList}";
}

AjouterLigne ()
{
    i=$((${1}-1));
    ligne="${2:-Ligne ${1}}";
    if [ ${i} -eq 0 ]; then
        sed -i "1i${2}" "${todoList}";
    else
        sed -i "${i}a${2}" "${todoList}";
    fi;
}

DeplacerLigne ()
{
    ligne=$(sed -n "${1}p" "${todoList}" );
    if [ ${1} -lt ${2} ]; then
        sed -i "${1}d;${2}a${ligne}" "${todoList}";
    elif [ ${1} -gt ${2} ]; then
        sed -i "${1}d;${2}i${ligne}" "${todoList}";
    fi;
}

ModifierLigne ()
{
    i=${1:-1};
    ligne=${2:-Ligne ${i}};
    sed -i "${i}c${ligne}" "${todoList}";
}

EchangerLigne ()
{
    i=${1:-1}; j=${2:-2};
    ligne1=$(sed -n "${i}p" "${todoList}" );
    ligne2=$(sed -n "${j}p" "${todoList}" );
    Erreur "lignes ${i} et ${j}";
    Erreur "lignes ${ligne1} et ${ligne2}";
    ModifierLigne "${i}" "${ligne1}";
    ModifierLigne "${j}" "${ligne2}";
}

if which yad; then
    GUI ()
    {
        while true; do
            choix="ajouter une tâche"\!"supprimer une tâche"\!"deplacer une tâche"\!"modifier une tâche"\!"echanger des tâches"\!"afficher/éditer les tâches";
            action=$( yad --on-top --center --title="Gui ToDoList" --text="" --form --field="":CB "${choix}" ) || break;
            continuer=true;

            maxLigne=$(grep -v '^ *$' "${todoList}" | wc -l );
            listeNombresYad=1;
            for i in $(seq 2 ${maxLigne} ); do
                listeNombresYad=${listeNombresYad}\!${i};
            done;
            listeLignesYad="$( cat -n "${todoList}" | sed -e 's/^[[:space:]]*//g;:boucle;N;$!b boucle;s/\n/\!/g;s/[[:space:]]\+/ /g;s/! /!/g' )";

            case ${action,,} in
            ajouter*)
                ((maxLigne++)); listeNombresYad=${listeNombresYad}\!${maxLigne};
                retourYad=$( yad --on-top --center --title="Ajout" --text="Ajout" --form --field=Ligne:CB "${listeNombresYad}" --field="Tâche :" "" ) || continue;
                ligne=${retourYad%%|*};
                contenu="${retourYad%|}"; contenu="${contenu#*|}";
                echo "${ligne} - ${contenu}" > error.log
                AjouterLigne ${ligne} "${contenu}";
                ;;
            supprimer*)
                retourYad=$( yad --on-top --center --title="Suppression" --text="Suppression" --form --field=Ligne:CB "${listeLignesYad}" ) || continue;
                ligne=${retourYad%%[^0-9]*};
                SupprimerLigne ${ligne};
                ;;
            deplacer*)
                retourYad=$( yad --on-top --center --title="Déplacement" --text="Déplacement" --form --field=de:CB "${listeLignesYad}" --field="à la ligne ":CB "${listeNombresYad}" ) || continue;
                Erreur "retour:${retourYad}";
                debut=${retourYad%%|*}; Ndebut=${debut%%[^0-9]*};
                fin=${retourYad%|}; fin=${fin#*|}; Nfin=${fin%%[^0-9]*};
                Erreur "${Ndebut} et ${Nfin}";
                DeplacerLigne ${Ndebut} ${Nfin};
                ;;
            modifier*)
                retourYad=$( yad --on-top --center --title="Modification" --text="Modification" --form --field=Ligne:CB "${listeLignesYad}" --field="Tâche :" "..." ) || continue;
                ligne=${retourYad%%[^0-9]*};
                contenu="${retourYad%|}"; contenu="${contenu#*|}";
                ModifierLigne ${ligne} "${contenu}";
                ;;
            echanger*)
                notify-send "${0##*/}" "L'action ${action} n'est pas valide.";
                continue;
                retourYad=$( yad --on-top --center --title="Échange" --text="Échange" --form --field=de:CB "${listeLignesYad}" --field=à:CB "${listeLignesYad}" ) || continue;
                debut=${retourYad%%|*}; Ndebut=${debut%%[^0-9]*};
                fin=${retourYad%|}; fin=${fin#*|}; Nfin=${fin%%[^0-9]*};
                Erreur "${Ndebut} et ${Nfin}";
                EchangerLigne ${Ndebut} ${Nfin};
                ;;
            afficher*)
                tmpFile="/tmp/.${0##*/}.tmp";
                >${tmpFile} yad --on-top --center --title="Afficher" --text-info --editable --show-uri --filename="${todoList}" --height="350" --width="300" && cp -f "${tmpFile}" "${todoList}" || continue;
                echo >> "${todoList}";
                ;;
            *)
                notify-send "${0##*/}" "L'action ${action} n'est pas valide.";
                ;;
            esac;
            ${continuer} || break;
        done;
    }
elif which zenity; then
    GUI ()
    {
        while true; do
            choix="ajouter une tâche
supprimer une tâche
deplacer une tâche
modifier une tâche
echanger des tâches
afficher/éditer les tâches
";
            action=$( zenity --list --title="Gui ToDoList" --column="Action" <<<"${choix}" ) || break;
            continuer=true;

            maxLigne=$(grep -v '^ *$' "${todoList}" | wc -l );

            case ${action,,} in
            ajouter*)
                ((maxLigne++));
                ligne=$( { cat -n "${todoList}"; printf "\t${maxLigne} Fin"; } | zenity --title="Ajout" --text="Quelle position ?" --list --column="Ligne ?" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue;
                contenu=$( zenity --title="Ajout" --text="Ajout" --entry --entry-text="Tâche n°${ligne}" ) || continue;
                echo "${ligne} - ${contenu}" > error.log
                AjouterLigne ${ligne} "${contenu}";
                ;;
            supprimer*)
                ligne=$( cat -n "${todoList}" | zenity --title="Supprimer" --text="Quelle ligne ?" --list --column="Lignes" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue ;

                SupprimerLigne ${ligne};
                ;;
            deplacer*)
                debut=$( cat -n "${todoList}" | zenity --title="Déplacer" --text="Quelle ligne ?" --list --column="Lignes" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue;
                fin=$( cat -n "${todoList}" | zenity --title="Déplacer" --text="Vers quelle position ?" --list --column="Lignes" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue;
                Ndebut=${debut%%[^0-9]*};
                Nfin=${fin%%[^0-9]*};
                DeplacerLigne ${Ndebut} ${Nfin};
                ;;
            modifier*)
                ligne=$( cat -n "${todoList}" | zenity --title="Déplacer" --text="Quelle ligne ?" --list --column="Lignes" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue;
                contenu=$(sed -n "${ligne}p" ${todoList} );
                contenu=$( zenity --title="Ajout" --text="Ajout" --entry --entry-text="${contenu}" ) || continue;
                ModifierLigne ${ligne} "${contenu}";
                ;;
            echanger*)
                notify-send "${0##*/}" "L'action ${action} n'est pas valide.";
                continue;
                debut=$( cat -n "${todoList}" | zenity --title="Déplacer" --text="Quelle ligne ?" --list --column="Lignes" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue;
                fin=$( cat -n "${todoList}" | zenity --title="Déplacer" --text="Vers quelle position ?" --list --column="Lignes" | sed -n 's/^\(\t*\| *\)\([0-9]\+\).*$/\2/gp' ) || continue;
                Erreur "${Ndebut} et ${Nfin}";
                EchangerLigne ${Ndebut} ${Nfin};
                ;;
            afficher*)
                tmpFile="/tmp/.${0##*/}.tmp";
                >${tmpFile} zenity --title="Afficher" --text-info --editable --filename="${todoList}" --height="350" --width="300" && cp -f "${tmpFile}" "${todoList}" || continue;
                echo >> "${todoList}";
                ;;
            *)
                notify-send "${0##*/}" "L'action ${action} n'est pas valide.";
                ;;
            esac;
            ${continuer} || break;
        done;
    }
else
    GUI()
    {
        notify-send "${0##*/}" "Erreut : ni Yad ni Zenity n'est installé.";
    }
fi;


if [ ! -e "${todoList}" ]; then
    exit ;
fi;

while (( $# )); do
    case ${1} in
    -h) # Affiche cette aide
        Usage ;;
    -e) # Éditer ce script
        vim ${0}; exit;;
    -v) # Édite e script avec vim
        vim "${todoList}"; exit;;
    -a) # <ligne> <contenu> : Ajouter une ligne avec du contenu 
        shift;
        AjouterLigne "${1}" "${2}"; shift;
        ;;
    -s) # <ligne> : Supprimer une ligne 
        shift;
        SupprimerLigne "${1}";
        ;;
    -m) # <ligne> <contenu> : Modifier une ligne 
        shift;
        ModifierLigne "${1}" "${2}"; shift;
        ;;
    -d) # <ligne 1> <ligne 2> : Déplacer les lignes 
        shift;
        DeplacerLigne "${1}" "${2}"; shift;
        ;;
    #-x) # <ligne1> <ligne2> : Échanger les lignes en argument
        #shift;
        #EchangerLigne "${1}" "${2}"; shift;
        #;;
    -g) # Interface graphique avec YAD ou Zenity
        shift;
        Erreur ${1};
        GUI ${1};
        ;;
    -*) Erreur "«${1}» option inconnue" >&2;;
    *)
        echo ;;
    esac;
    shift;
done;

sed -i '/^ *$/d' "${todoList}";
#grep -v '^ *$' "${todoList}" | cat -n
cat -b "${todoList}";

Si vous préférez la ligne de commande, le script gère ça aussi !

En plus, il y a ce script pipe pour OpenBox qui va bien avec :

#!/bin/bash
#Par Nordinatueur
#Liste les fichiers du dossier ~/.todo

dossierTodo="${HOME}/.todo";
todoList="${HOME}/.todo.list";
scriptTodo="${HOME}/Public/scripts/todolist.cli.sh ";

Init ()
{
cat <<EOF
    <item label=".    Gui ToDo List    .">
        <action name="Execute">
            <execute> ${HOME}/Public/scripts/todolist.cli.sh -g </execute>
        </action>
    </item>
EOF
}

#LigneExecute <nom> <commande>
LigneExecute ()
{
cat <<EOF
    <item label="${1}">
        <action name="Execute">
            <execute>
                ${2}
            </execute>
        </action>
    </item>
EOF
}

#Crée un pipemenu
#LigneMenu <nom> <commande>
LigneMenu ()
{
cat <<EOF
    <menu execute="${2}" id="todo-${1// /-}-${2##* }" label="${1}" />
EOF
}

# scripTodo -a <ligne> <contenu>

echo '<openbox_pipe_menu>';

case ${1} in
[0-9])
    LigneExecute "Ajouter à cet endroit (${1})" "${0} ajouter ${1}";
    LigneExecute "Supprimer cette tâche" "${scriptTodo} -s ${1}";
    LigneMenu "Déplacer cette tâche vers ..." "${0} deplacer ${1}";
    LigneExecute "Modifier cette tâche" "${0} modifier ${1} '${2}'";
    #LigneMenu "Échanger cette tâche avec ..." "${0} echanger ${1}";
;;
ajouter)
    shift;
    texte="$( yad --center --on-top --entry )" &&\
    ${scriptTodo} -a ${1} "${texte}";
;;
modifier)
    shift;
    texte="$( yad --center --on-top --entry --entry-text="${2}" )" &&\
    ${scriptTodo} -m ${1} "${texte}";
;;
deplacer)
    shift;
    i=1;
    while read ligne ; do
        LigneExecute "${i} - ${ligne}" "${scriptTodo} -d ${1} ${i}";
        ((i++));
    done < "${todoList}";
;;
echanger)
    shift;
    i=1;
    while read ligne ; do
        LigneExecute "${i} - ${ligne}" "${scriptTodo} -x ${1} ${i}";
        ((i++));
    done < "${todoList}";
;;
*)
    Init;
    i=1;
    while read ligne ; do
        #LigneMenu "${ligne}" "${0} ${i} '${ligne}'";
        LigneMenu "${ligne}" "${0} ${i}";
        ((i++));
    done < "${todoList}";
    LigneExecute "Ajouter à cet endroit (${i})" "${0} ajouter ${i}";
esac;

echo "</openbox_pipe_menu>";

N'hésitez pas à me faire part de vos avis.

Edit : Autre chose !
Le conky devient simplement :

${if_existing /home/nordine/.todo.list }${font size=14}ToDo List   (${execpi 5 wc -l < /home/nordine/.todo.list })${font}
${offset 1}${font size=10}${color0}${exec cat -b /home/nordine/.todo.list }${color}${font}${endif}

où vous devez remplacer « /home/nordine » par votre dossier utilisateur.

Dernière modification par nordinatueur (Le 03/01/2012, à 03:02)


Linux User #508094
Pour une meilleure coopération, utilisez des liens relatifs sur le forum !

Hors ligne

#2 Le 03/01/2012, à 02:43

Bousky

Re : [script] ToDoList en bash...

J'ai pas lu ton script (il est tard…), mais pour ma part, j'utilise ce script maison (en ligne de commande uniquement) :

#!/bin/bash

file=~/.todo
default_prio=D
display_color=1
colors=13264571 # A rouge, B jaune, C vert, D cyan, E bleu, F violet, G blanc, date rouge
numbers=1
date_alerte=3

while : ; do
    case "$1" in
    -h|-help|--help|-\?)
        cat <<-EOF
        todo.sh [options] commande ...

        OPTIONS

        -f fichier
                indique le fichier à utiliser au lieu de $(sed "s|^$HOME|~|" <<< "$file")

        -c      désactive la mise en forme
        -C      active la mise en forme
        -# couleurs
                indique les couleurs à utiliser, $colors par défaut

        -n      ne pas numéroter les tâches
        -N      numéroter les tâches

        -j jours
                délais pour la mise en évidence des dates

        -d      débugage

        COMMANDES

        add [@date] [%priorité] texte ...
                ajoute une tâche
        
        edit indice [@[date]] [%priorité] [texte ...]
                modifie une tâche. Sans arguments, l'édition est interactive.
                @ sans date permet de supprimer l'échéance.
        
        del indice ...
                supprime une(des) tâche(s)

        list    liste les tâches

        test    retourne 0 si il y a des tâches, 1 sinon

        Il est possible d'abréger une commande en ne mettant que son initiale.

        DATES, PRIORITÉS & TAGS

        Les dates doivent êtres comprises par « date --date ». Elles sont
        arondies au jour près.
        Les priorités sont des lettres de A à G ou des chiffres de 1 à 7
        (D (4) par défaut).
        Tout mot du texte commençant par un seul « + » est considéré comme
        un tag. C'est une fonctionnalité purement cosmétique (souligné gras).
        EOF
        exit
    ;;
    -v|-version|--version)
        cat <<-EOF
        todo.sh
                Version 2.1.1
                Créé par Nicolas « Bousky » Bouscarle
                Placé sous license WTFPL/LPRAB http://sam.zoy.org/lprab/
        EOF
        exit
    ;;
    -f)
        file="$2"
        shift
    ;;
    -#)
        if [[ ! "$2" =~ ^[-0-79][-0-79][-0-79][-0-79][-0-79][-0-79][-0-79][-0-79]$ ]] ; then
            echo "couleurs \"$2\" non valides" >&2
            exit 1
        fi
        for i in {0..7} ; do
            if [ "${2:$i:1}" = - ] ; then
                colors_new=${colors_new}${colors:$i:1}
            else
                colors_new=${colors_new}${2:$i:1}
            fi
        done
        colors=$colors_new
        shift
    ;;
    -j)
        if ! [ "$2" -ge 0 ] &> /dev/null ; then
            echo "nombre de jours invalide $2" >&2
            exit 1
        fi
        date_alerte="$2"
        shift
    ;;
    -c) display_color=0 ;;
    -C) display_color=1 ;;
    -n) numbers=0 ;;
    -N) numbers=1 ;;
    -d) debug=1 ;;
    -*)
        echo "Option \"$1\" invalide" >&2
        exit 1
    ;;
    *)  break
    esac
    shift
done

if [ "$debug" ] ; then
    echo "----DEBUG----"
    echo "file         : $file"
    echo "default_prio : $default_prio"
    echo "colors       : $colors"
fi

touch "$file" || exit 2

function read_input {
    while [ "$1" ] ; do
        case "$1" in
            @@*|%%*) task_text="$task_text ${1:1}" ;;
            @*     ) task_date="${1:1}" ;;
            %*     ) task_prio="${1:1}" ;;
            *      ) task_text="$task_text $1"
        esac
        shift
    done
    task_text=${task_text# }
}

case "$1" in
add|a)
    task_date=xxxx-xx-xx
    task_prio=$default_prio
    shift
    read_input "$@"
    [ "$task_date" = xxxx-xx-xx ] || task_date=$(date -d "$task_date" +%F) || exit 2
    task_prio_unif=$(tr 1234567 ABCDEFG <<< "${task_prio^^}")
    if [[ ! "$task_prio_unif" =~ ^[ABCDEFG]$ ]] ; then
        echo "priorité non valide \"$task_prio\"" >&2
        exit 2
    fi
    if ! [ "$task_text" ] ; then
        echo "toute tâche doit avoir un texte" >&2
        exit 2
    fi
    if [ "$debug" ] ; then
        echo "task_date      : $task_date"
        echo "task_prio      : $task_prio"
        echo "task_prio_unif : $task_prio_unif"
        echo "task_text      :$task_text"
    fi
    echo "$task_prio_unif $task_date $task_text" >> "$file"
;;
del|d)
    while [ "$2" ] ; do
        if ! [ "$2" -gt 0 ] &> /dev/null && ! [ "$2" -le $(cat "$file" | wc -l) ] &> /dev/null ; then
            echo "numéro de lige \"$2\" non valide" >&2
            exit 2
        fi
        sed -i "$2"d "$file"
        shift
    done
;;
list|l)
    sort -d "$file" -o "$file"
    grep -v "^. xxxx-xx-xx" "$file" &>/dev/null || no_date=1
    echap=$(echo -e "\E")
    if [ "$numbers" = 1 ] ; then
        nb_len=$(cat "$file" | wc -l)
        nb_len=${#nb_len}
        num=1
    fi
    while task_line=$(line) ; do
        task_date=$(cut -d" " -f2  <<< "$task_line")
        task_prio=$(cut -d" " -f1  <<< "$task_line")
        task_text=$(cut -d" " -f3- <<< "$task_line")
        if [ "$display_color" = 1 ] ; then
            task_prio="$echap[1;3"$(tr ABCDEFG "$colors" <<< $task_prio)"m($task_prio)$echap[0m"
        else
            task_prio="($task_prio)"
        fi
        if [ "$no_date" ] ; then
            task_date=""
        else
            if [ "$task_date" = xxxx-xx-xx ] ; then
                task_date="                "
            else
                [ "$display_color" = 1 ] && if (($(date -d "$task_date" +%s)<$(date -d "$date_alerte day" +%s))); then
                    red_date=1
                else
                    red_date=0
                fi
                task_date=$(date -d "$task_date" "+%a %e %b %Y")
                task_date="${task_date//.} "
                [ "$red_date" = 1 ] && task_date="$echap[1;3${colors:7:1}m$task_date$echap[0m"
            fi
        fi
        if [ "$numbers" = 1 ] ; then
            printf "%${nb_len}d) " $num
            ((num ++))
        fi
        if [ "$display_color" = 1 ] ; then
            task_text=$(sed -r 's/(^|[[:space:]])\+([^+[:space:]][^[:space:]]*)/\1+'"$echap"'[1;4m\2'"$echap"'[24;22m/g' <<< "$task_text")
            echo -n "$task_date$task_prio $task_text"
            echo -e  "\E[0m"
        else
            echo "$task_date$task_prio $task_text"
        fi
    done < "$file"
;;
test|t)
    [ -s "$file" ]
;;
edit|e)
    if ! [ "$2" -gt 0 ] &> /dev/null && ! [ "$2" -le $(cat "$file" | wc -l) ] &> /dev/null ; then
        echo "numéro de lige \"$2\" non valide" >&2
        exit 2
    fi
    index="$2"
    task_line=$(sed "$index"'!d' "$file")
    task_date=$(cut -d" " -f2  <<< "$task_line")
    task_prio=$(cut -d" " -f1  <<< "$task_line")
    task_text_old=$(cut -d" " -f3- <<< "$task_line")
    if [ "$3" ] ; then
        shift 2
        read_input "$@"
    else
        [ "$task_date" = xxxx-xx-xx ] && task_date=
        echo -n "$index) "
        [ "$task_date" ] && echo -n "@$task_date "
        echo "%$task_prio $task_text_old"
        read -re -i "$task_date" -p @ task_date
        read -re -i "$task_prio" -p % task_prio
        IFS_old="$IFS"
        IFS=
        read -re -i "$task_text_old" -p ">" task_text
        IFS=$IFS_old
    fi
    [ "$task_text" ] || task_text="$task_text_old"
    [ "$task_date" ] || task_date="xxxx-xx-xx"
    [ "$task_date" = xxxx-xx-xx ] || task_date=$(date -d "$task_date" +%F) || exit 2
    task_prio_unif=$(tr 1234567 ABCDEFG <<< "${task_prio^^}")
    if [[ ! "$task_prio_unif" =~ ^[ABCDEFG]$ ]] ; then
        echo "priorité non valide \"$task_prio\"" >&2
        exit 2
    fi
    sed -i "$index"d "$file"
    echo "$task_prio_unif $task_date ${task_text# }" >> "$file"
;;
*)
    echo "Commande \"$1\" invalide" >&2
    exit 1
esac

Linux qui plante complètement ? Plus rien ne répond ? On peut toujours le redémarrer proprement :
Alt + SysRq + REISUB (Retourne En Islande Sur Un Bateau !)

Hors ligne

#3 Le 03/01/2012, à 03:06

nordinatueur

Re : [script] ToDoList en bash...

Très intéressant !
J'étudierai ça dès demain !
D'abord dodo !


Linux User #508094
Pour une meilleure coopération, utilisez des liens relatifs sur le forum !

Hors ligne

#4 Le 06/02/2012, à 00:04

n3o51

Re : [script] ToDoList en bash...

Salut marche pas chez moi le -h

n3o:~ $ ./todo.sh -h
/home/n3o-chacha/.todo.list existe...
/usr/bin/yad
sed: impossible de lire ./todo.sh: Aucun fichier ou dossier de ce type
n3o:~ $

Welcome to the real world
________________________________

Hors ligne