| #!/bin/bash
|
| # ============================================================
|
| # TERMUX SUIVI ARRÊT TABAC
|
| # Script pour Claire Ikenanka - 1er août 2026
|
| # Version: 6.0 - 100% SIMPLES QUOTES (pas de ")
|
| #
|
| # Copyright (C) 2026 Claire Ikenanka
|
| #
|
| # 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 3 of the License, 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, see <https://www.gnu.org/licenses/>.
|
| # ============================================================
|
|
|
| # Couleurs (séquences d'échappement avec $'...')
|
| if [ -t 1 ]; then
|
| RED=$'\033[0;31m'; GREEN=$'\033[0;32m'; YELLOW=$'\033[1;33m'
|
| BLUE=$'\033[0;34m'; CYAN=$'\033[0;36m'; WHITE=$'\033[1;37m'
|
| NC=$'\033[0m'
|
| else
|
| RED=''; GREEN=''; YELLOW=''; BLUE=''; CYAN=''; WHITE=''; NC=''
|
| fi
|
|
|
| # Fichiers (SANS quotes pour expansion)
|
| CSV_FILE=$HOME/suivi_arret_tabac.csv
|
| SC_FILE=$HOME/suivi_arret_tabac.sc
|
| BACKUP_DIR=$HOME/backups_suivi_tabac
|
| CONFIG_FILE=$HOME/.suivi_tabac_config
|
| DEFAULT_PRIX_PAQUET=10.52
|
| DEFAULT_DATE_DEBUT=2026-08-05
|
| PRIX_PAQUET=''; DATE_DEBUT=''
|
|
|
| # ========== FONCTIONS ==========
|
| msg() echo -e ${1}${2}${NC}
|
|
|
| print_title() {
|
| echo '============================================================'
|
| printf ${CYAN}|${NC} %*s ${CYAN}|${NC}\n $( (58 - ${#1}) / 2 )) $1
|
| echo ' ______ '
|
| echo ' / \ '
|
| echo ' / STOP \ '
|
| echo ' | / | '
|
| echo ' | ==/== ~ | '
|
| echo ' | / | '
|
| echo ' \ / '
|
| echo ' \_______/ '
|
| echo '============================================================'
|
| }
|
|
|
| check_package() { pkg list-installed 2>/dev/null | grep -q '$1'; return $?; }
|
|
|
| install_package() {
|
| msg '${YELLOW}' 'Installation de '$1'...'
|
| pkg install -y '$1' > /dev/null 2>&1
|
| [ $? -eq 0 ] && msg '${GREEN}' '[OK] '$1' installé' || msg '${RED}' '[ERREUR] Échec'
|
| }
|
|
|
| load_config() {
|
| [ -f $CONFIG_FILE ] && source $CONFIG_FILE || {
|
| PRIX_PAQUET=$DEFAULT_PRIX_PAQUET
|
| DATE_DEBUT=$DEFAULT_DATE_DEBUT
|
| save_config
|
| }
|
| PRIX_PAQUET=$(echo $PRIX_PAQUET | tr ',' '.')
|
| }
|
|
|
| save_config() {
|
| echo 'PRIX_PAQUET='"$PRIX_PAQUET > $CONFIG_FILE
|
| echo 'DATE_DEBUT='"$DATE_DEBUT >> $CONFIG_FILE
|
| }
|
|
|
| init_csv() {
|
| [ ! -f $CSV_FILE ] && {
|
| cat > $CSV_FILE << EOF
|
| Date,Heure,Type,Description,Prix_Paquet_Euro,Nombre_Cigarettes_Evitees,Economies_Jour_Euro,Economies_Cumulees_Euro,Jour_Sans_Fumer,Craving_Intensite_1_10,Craving_Declencheur,Craving_Duree_Min,Craving_Strategie,Angoisse_Niveau_1_10,Angoisse_Duree_Min,Angoisse_Action,Notes
|
| $(date +%Y-%m-%d),$(date +%H:%M),CONFIG,Prix moyen d'un paquet (20 cigarettes),$PRIX_PAQUET,0,,,0,,,,,,,,Prix moyen en France 2026
|
| $(date +%Y-%m-%d),$(date +%H:%M),CONFIG,Date de debut du sevrage,,,,,1,,,,,,,,$DATE_DEBUT
|
| EOF
|
| }
|
| }
|
|
|
| # ===== CORRECTION ARITHMÉTIQUE (sans quotes) =====
|
| get_next_jour() {
|
| local finance_count=$(grep -c 'FINANCE' $CSV_FILE 2>/dev/null || echo 0)
|
| echo $((finance_count + 1))
|
| }
|
|
|
| get_last_economies_cum() {
|
| local last_line=$(tail -n 1 $CSV_FILE)
|
| local eco_cum=$(echo $last_line | cut -d',' -f8)
|
| [ -z $eco_cum ] && echo 0 || echo $eco_cum
|
| }
|
|
|
| check_dependencies() {
|
| ! check_package 'sc-im' && install_package 'sc-im'
|
| ! check_package 'termux-api' && msg '${YELLOW}' 'termux-api non installé. Pour notifications: pkg install termux-api'
|
| ! command -v bc &> /dev/null && install_package 'bc'
|
| }
|
|
|
| convert_to_sc() {
|
| mkdir -p $BACKUP_DIR
|
| {
|
| echo '# Suivi Arrêt Tabac - Claire Ikenanka'
|
| echo '# Généré le '$(date +%Y-%m-%d\ %H:%M:%S)
|
| echo '# Prix: '$PRIX_PAQUET' EUR | Début: '$DATE_DEBUT
|
| echo ''
|
| echo ' /\ /\'
|
| echo ' ( o.o )'
|
| echo ' > ^ <'
|
| echo ''
|
| echo 'Date | Heure | Type | Description | Prix | Cigs | Eco/J | Eco/C | Jour'
|
| echo '============================================================'
|
| grep -v 'CONFIG' $CSV_FILE | tail -n +2 | while IFS=, read -r date heure type desc prix cigs eco_jour eco_cum jour rest; do
|
| printf '%-10s | %-6s | %-4s | %-16s | %-4s | %-4s | %-5s | %-5s | %-4s\n' \
|
| $date $heure $type '${desc:0:16}' $prix $cigs $eco_jour $eco_cum $jour
|
| done
|
| echo '============================================================'
|
| echo ''
|
| echo '# STATS: Moyenne cravings =@avg(J3:J1000), Max =@max(J3:J1000)'
|
| echo '# Total économies =H1000 EUR, Jours =I1000'
|
| } > $SC_FILE
|
| }
|
|
|
| backup_file() {
|
| mkdir -p $BACKUP_DIR
|
| local timestamp=$(date +%Y%m%d_%H%M%S)
|
| cp $CSV_FILE $BACKUP_DIR/suivi_arret_tabac_${timestamp}.csv
|
| cp $SC_FILE $BACKUP_DIR/suivi_arret_tabac_${timestamp}.sc 2>/dev/null
|
| }
|
|
|
| # ========== MENU ==========
|
| show_menu() {
|
| clear
|
| print_title 'SUIVI ARRÊT TABAC'
|
| echo ''
|
| echo $' .-\"\"\"-.'
|
| echo $' / \\\\'
|
| echo $'| |'
|
| echo $' \\\\ /'
|
| echo $' \'-...-\''
|
| echo ''
|
|
|
| if [ -f $CSV_FILE ]; then
|
| local total_lines=$(grep -v 'CONFIG' $CSV_FILE | tail -n +2 | wc -l)
|
| local cravings=$(grep -c 'CRAVING' $CSV_FILE 2>/dev/null || echo 0)
|
| local finance=$(grep -c 'FINANCE' $CSV_FILE 2>/dev/null || echo 0)
|
| local jours=$((finance + 1))
|
| local cigs_total=$(grep 'FINANCE' $CSV_FILE | awk -F',' '{sum+=$5} END {print sum}' 2>/dev/null || echo 0)
|
| local economies=$(printf '%.2f' $(echo $cigs_total * $PRIX_PAQUET / 20 | bc -l 2>/dev/null || echo 0))
|
|
|
| echo '+------------------------------------------------------------+'
|
| echo '| STATISTIQUES |'
|
| echo '+------------------------------------------------------------+'
|
| printf '| %-20s: %-20s |\n' 'Total entrées' $total_lines
|
| printf '| %-20s: %-20s |\n' 'Cravings' $cravings
|
| printf '| %-20s: %-20s |\n' 'Jours' $jours
|
| printf '| %-20s: %-20s |\n' 'Cigs évitées' $cigs_total
|
| printf '| %-20s: %-20s |\n' 'Économies' $economies' EUR'
|
| echo '+------------------------------------------------------------+'
|
| echo ''
|
| fi
|
|
|
| echo '+------------------------------------------------------------+'
|
| echo '| MENU PRINCIPAL |'
|
| echo '+------------------------------------------------------------+'
|
| printf '| %-2s -> %-40s |\n' '1' 'Ajouter un CRAVING'
|
| printf '| %-2s -> %-40s |\n' '2' 'Ajouter une ANGOISSE'
|
| printf '| %-2s -> %-40s |\n' '3' 'Ajouter un BILAN FINANCIER'
|
| printf '| %-2s -> %-40s |\n' '4' 'Afficher le tableau'
|
| printf '| %-2s -> %-40s |\n' '5' 'Ouvrir avec sc-im'
|
| printf '| %-2s -> %-40s |\n' '6' 'Statistiques détaillées'
|
| printf '| %-2s -> %-40s |\n' '7' 'Sauvegarder'
|
| printf '| %-2s -> %-40s |\n' '8' 'Restaurer'
|
| printf '| %-2s -> %-40s |\n' '9' 'Configurer'
|
| printf '| %-2s -> %-40s |\n' '0' 'Quitter'
|
| echo '+------------------------------------------------------------+'
|
| echo ''
|
| echo -n 'Choix [0-9]: '
|
| }
|
|
|
| # ========== AJOUTS ==========
|
| add_entry() {
|
| local type=$1; local title=$2
|
| clear; print_title $title; echo ''
|
| echo '+------------------------------------------------------------+'
|
| echo '| NOUVEL ENREGISTREMENT |'
|
| echo '+------------------------------------------------------------+'
|
|
|
| local date=$(date +%Y-%m-%d); local heure=$(date +%H:%M)
|
| local description=''; local cigs=1; local intensite=''; local declencheur=''
|
| local duree=15; local strategie=''; local notes=''; local niveau=''; local action=''
|
|
|
| echo -ne 'Date ['$date']: '; read -r date_input; [ -n $date_input ] && date=$date_input
|
| echo -ne 'Heure ['$heure']: '; read -r heure_input; [ -n $heure_input ] && heure=$heure_input
|
| echo -ne 'Description: '; read -r description
|
|
|
| if [ $type = 'CRAVING' ]; then
|
| echo -ne 'Cigarettes évitées ['$cigs']: '; read -r cigs_input; [ -n $cigs_input ] && cigs=$cigs_input
|
| echo -ne 'Intensité (1-10): '; read -r intensite
|
| echo -ne 'Déclencheur: '; read -r declencheur
|
| echo -ne 'Durée (min) ['$duree']: '; read -r duree_input; [ -n $duree_input ] && duree=$duree_input
|
| echo -ne 'Stratégie: '; read -r strategie
|
| echo -ne 'Notes: '; read -r notes
|
| local jour=$(get_next_jour)
|
| local eco_jour=$(printf '%.2f' $(echo $cigs * $PRIX_PAQUET / 20 | bc -l))
|
| local eco_cum=$(get_last_economies_cum)
|
| local new_eco_cum=$(printf '%.2f' $(echo $eco_cum + $eco_jour | bc -l))
|
| echo $date,$heure,CRAVING,$description,$PRIX_PAQUET,$cigs,$eco_jour,$new_eco_cum,$jour,$intensite,$declencheur,$duree,$strategie,,,$notes >> $CSV_FILE
|
| elif [ $type = 'ANGOISSE' ]; then
|
| echo -ne 'Niveau (1-10): '; read -r niveau
|
| echo -ne 'Durée (min) ['$duree']: '; read -r duree_input; [ -n $duree_input ] && duree=$duree_input
|
| echo -ne 'Action apaisante: '; read -r action
|
| echo -ne 'Notes: '; read -r notes
|
| local jour=$(get_next_jour)
|
| echo $date,$heure,ANGOISSE,$description,$PRIX_PAQUET,0,0,0,$jour,,,$niveau,$duree,$action,$notes >> $CSV_FILE
|
| else
|
| echo -ne 'Cigarettes évitées ['$cigs']: '; read -r cigs_input; [ -n $cigs_input ] && cigs=$cigs_input
|
| echo -ne 'Notes: '; read -r notes
|
| local jour=$(get_next_jour)
|
| local eco_jour=$(printf '%.2f' $(echo $cigs * $PRIX_PAQUET / 20 | bc -l))
|
| local eco_cum=$(get_last_economies_cum)
|
| local new_eco_cum=$(printf '%.2f' $(echo $eco_cum + $eco_jour | bc -l))
|
| echo $date,$heure,FINANCE,Bilan journée,$PRIX_PAQUET,$cigs,$eco_jour,$new_eco_cum,$jour,,,,,,$notes >> $CSV_FILE
|
| fi
|
|
|
| msg '${GREEN}' '[OK] '$type' ajouté !'
|
| convert_to_sc; backup_file
|
| check_package 'termux-api' && termux-toast '$type ajouté !' > /dev/null 2>&1
|
| read -n 1 -s -p 'Appuyer sur Entrée...'
|
| }
|
|
|
| # ========== AFFICHAGE ==========
|
| show_table() {
|
| clear; print_title 'TABLEAU DE SUIVI'; echo ''
|
| [ -f $CSV_FILE ] && {
|
| echo '+------------------------------------------------------------------+'
|
| echo '| Date | Heure | Type | Description | Prix | Cigs | Eco/J | Eco/C | Jour|'
|
| echo '+------------------------------------------------------------------+'
|
| grep -v 'CONFIG' $CSV_FILE | tail -n +2 | while IFS=, read -r date heure type desc prix cigs eco_jour eco_cum jour rest; do
|
| printf '| %-10s | %-5s | %-4s | %-16s | %-4s | %-4s | %-5s | %-5s | %-4s |\n' \
|
| $date $heure $type '${desc:0:16}' $prix $cigs $eco_jour $eco_cum $jour
|
| done
|
| echo '+------------------------------------------------------------------+'
|
| } || msg '${RED}' 'Aucun fichier trouvé.'
|
| echo ''; read -n 1 -s -p 'Appuyer sur Entrée...'
|
| }
|
|
|
| show_stats() {
|
| clear; print_title 'STATISTIQUES'; echo ''
|
| [ ! -f $CSV_FILE ] && { msg '${RED}' 'Aucun fichier.'; read -n 1 -s; return; }
|
|
|
| local finance=$(grep -c 'FINANCE' $CSV_FILE 2>/dev/null || echo 0)
|
| local jours=$((finance + 1))
|
| local cigs_total=$(grep 'FINANCE' $CSV_FILE | awk -F',' '{sum+=$5} END {print sum}' 2>/dev/null || echo 0)
|
| local economies=$(printf '%.2f' $(echo $cigs_total * $PRIX_PAQUET / 20 | bc -l 2>/dev/null || echo 0))
|
| local cravings=$(grep -c 'CRAVING' $CSV_FILE 2>/dev/null || echo 0)
|
| local angoisses=$(grep -c 'ANGOISSE' $CSV_FILE 2>/dev/null || echo 0)
|
| local crav_avg=$(grep 'CRAVING' $CSV_FILE | awk -F',' '{sum+=$10;c++} END {print (c>0)?sum/c:0}' 2>/dev/null || echo 0)
|
| local crav_max=$(grep 'CRAVING' $CSV_FILE | awk -F',' '{if($10>m)m=$10} END {print m+0}' 2>/dev/null || echo 0)
|
|
|
| echo '+------------------------------------------------------------+'
|
| echo '| RÉSUMÉ |'
|
| echo '+------------------------------------------------------------+'
|
| printf '| %-25s: %-15s |\n' 'Jours sans fumer' $jours
|
| printf '| %-25s: %-15s |\n' 'Cigs évitées' $cigs_total
|
| printf '| %-25s: %-15s |\n' 'Économies' $economies' EUR'
|
| printf '| %-25s: %-15s |\n' 'Cravings' $cravings' (moy: '$crav_avg', max: '$crav_max')'
|
| printf '| %-25s: %-15s |\n' 'Angoisses' $angoisses
|
| echo '+------------------------------------------------------------+'
|
| echo ''
|
| echo '+------------------------------------------------------------+'
|
| echo '| PROGRESSION |'
|
| echo '+------------------------------------------------------------+'
|
| printf '| %-20s: %s\n' '3 jours' '$([ $jours -ge 3 ] && echo '[ATTEINT]' || echo '[DANS '$((3-jours))' JOURS]')'
|
| printf '| %-20s: %s\n' '7 jours' '$([ $jours -ge 7 ] && echo '[ATTEINT]' || echo '[DANS '$((7-jours))' JOURS]')'
|
| printf '| %-20s: %s\n' '2 semaines' '$([ $jours -ge 14 ] && echo '[ATTEINT]' || echo '[DANS '$((14-jours))' JOURS]')'
|
| printf '| %-20s: %s\n' '1 mois' '$([ $jours -ge 30 ] && echo '[ATTEINT]' || echo '[DANS '$((30-jours))' JOURS]')'
|
| echo '+------------------------------------------------------------+'
|
| echo ''
|
| echo '+------------------------------------------------------------+'
|
| echo '| CONSEILS |'
|
| echo '+------------------------------------------------------------+'
|
| echo '| 4-7-8: Inspire 4s -> Bloque 7s -> Expire 8s (x4) |'
|
| echo '| Eau: Grand verre deau citronnee |'
|
| echo '| Marche: 5-10 min rapide |'
|
| echo '| Douche: 30-60s froide |'
|
| echo '| Metal: Ecoute du metal |'
|
| echo '+------------------------------------------------------------+'
|
| read -n 1 -s -p 'Appuyer sur Entrée...'
|
| }
|
|
|
| # ========== SAUVEGARDE ==========
|
| backup_data() {
|
| mkdir -p $BACKUP_DIR
|
| local timestamp=$(date +%Y%m%d_%H%M%S)
|
| cp $CSV_FILE $BACKUP_DIR/suivi_arret_tabac_${timestamp}.csv
|
| cp $SC_FILE $BACKUP_DIR/suivi_arret_tabac_${timestamp}.sc 2>/dev/null
|
| msg '${GREEN}' '[OK] Sauvegarde: '$BACKUP_DIR/suivi_arret_tabac_${timestamp}.csv
|
| read -n 1 -s -p 'Appuyer sur Entrée...'
|
| }
|
|
|
| restore_backup() {
|
| clear; print_title 'RESTAURER'; echo ''
|
| [ ! -d $BACKUP_DIR ] && { msg '${RED}' 'Aucune sauvegarde.'; read -n 1 -s; return; }
|
|
|
| local backups=(); local i=1
|
| for file in $BACKUP_DIR/suivi_arret_tabac_*.csv; do
|
| [ -f $file ] && backups+=('$(basename $file)') && printf ' %2d. %s\n' $i '$(basename $file)' && i=$((i+1))
|
| done
|
|
|
| [ ${#backups[@]} -eq 0 ] && { msg '${RED}' 'Aucune sauvegarde.'; read -n 1 -s; return; }
|
|
|
| echo -ne '
|
| Choix (0=annuler): '; read -r choix
|
| [ $choix = '0' ] && return
|
| [ $choix -ge 1 ] && [ $choix -le ${#backups[@]} ] && {
|
| cp $BACKUP_DIR/${backups[$((choix-1))]} $CSV_FILE
|
| msg '${GREEN}' '[OK] Restauration: '${backups[$((choix-1))]}''
|
| convert_to_sc; backup_file
|
| } || msg '${RED}' 'Choix invalide.'
|
| read -n 1 -s -p 'Appuyer sur Entrée...'
|
| }
|
|
|
| # ========== CONFIG ==========
|
| edit_config() {
|
| clear; print_title 'CONFIGURATION'; echo ''
|
| printf ' %-20s: %s\n' 'Prix paquet' $PRIX_PAQUET' EUR'
|
| printf ' %-20s: %s\n' 'Date début' $DATE_DEBUT
|
| echo ''
|
| echo -ne 'Nouveau prix (EUR): '; read -r new_prix; [ -n $new_prix ] && PRIX_PAQUET=$new_prix
|
| echo -ne 'Nouvelle date: '; read -r new_date; [ -n $new_date ] && DATE_DEBUT=$new_date
|
|
|
| if [ -f $CSV_FILE ]; then
|
| grep -v 'CONFIG' $CSV_FILE > ${CSV_FILE}.tmp
|
| {
|
| echo 'Date,Heure,Type,Description,Prix_Paquet_Euro,Nombre_Cigarettes_Evitees,Economies_Jour_Euro,Economies_Cumulees_Euro,Jour_Sans_Fumer,Craving_Intensite_1_10,Craving_Declencheur,Craving_Duree_Min,Craving_Strategie,Angoisse_Niveau_1_10,Angoisse_Duree_Min,Angoisse_Action,Notes'
|
| echo $(date +%Y-%m-%d),$(date +%H:%M),CONFIG,'Prix moyen dun paquet (20 cigarettes),$PRIX_PAQUET, Prix moyen en France 2026'
|
| echo $(date +%Y-%m-%d),$(date +%H:%M),CONFIG,'Date de debut du sevrage,,,,,1,,,,,,,,'$DATE_DEBUT
|
| cat ${CSV_FILE}.tmp
|
| } > $CSV_FILE; rm ${CSV_FILE}.tmp
|
| fi
|
| save_config; msg '${GREEN}' '[OK] Configuration mise à jour !'
|
| convert_to_sc; backup_file
|
| read -n 1 -s -p 'Appuyer sur Entrée...'
|
| }
|
|
|
| # ========== MAIN ==========
|
| main() {
|
| load_config; init_csv; check_dependencies; convert_to_sc
|
| while true; do
|
| show_menu; read -r choice
|
| case $choice in
|
| 1) add_entry 'CRAVING' 'AJOUTER UN CRAVING' ;;
|
| 2) add_entry 'ANGOISSE' 'AJOUTER UNE ANGOISSE' ;;
|
| 3) add_entry 'FINANCE' 'AJOUTER UN BILAN FINANCIER' ;;
|
| 4) show_table ;;
|
| 5) convert_to_sc; check_package 'sc-im' && sc-im $SC_FILE || msg '${RED}' 'sc-im non installé' ;;
|
| 6) show_stats ;;
|
| 7) backup_data ;;
|
| 8) restore_backup ;;
|
| 9) edit_config ;;
|
| 0) echo ''; echo '============================================================'; msg '${GREEN}' 'Au revoir, Claire ! Continuez à résister !'; echo '============================================================'; exit 0 ;;
|
| *) msg '${RED}' 'Option invalide'; read -n 1 -s -p 'Appuyer sur Entrée...' ;;
|
| esac
|
| done
|
| }
|
|
|
| main
|