#!/bin/bash # Wrapper GUI pour MD_to_Print avec support sélection multiple # Usage: md_to_print_gui.sh --print|--convert|--preview fichier1.md [fichier2.md ...] set -euo pipefail # Couleurs RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # Variables ACTION="" USE_DOCKER=false FILES=() SCRIPT_DIR="" # Fonction de notification notify() { local level="$1" shift local message="$*" local icon="" local urgency="normal" case "$level" in info) icon="dialog-information" urgency="low" ;; success) icon="dialog-information" urgency="normal" ;; warning) icon="dialog-warning" urgency="normal" ;; error) icon="dialog-error" urgency="critical" ;; esac if command -v notify-send &> /dev/null; then notify-send -u "$urgency" -i "$icon" "MD_to_Print" "$message" 2>/dev/null || true fi } # Fonction pour afficher le dialogue d'options d'impression show_print_options() { if ! command -v zenity &> /dev/null; then # Fallback si zenity n'est pas disponible return 1 fi # Récupérer la liste des imprimantes local printers="Par défaut" if command -v lpstat &> /dev/null; then local printer_list=$(lpstat -p 2>/dev/null | grep -E "^printer" | awk '{print $2}' | tr '\n' '|') if [ -n "$printer_list" ]; then printers="${printer_list%|}|Par défaut" fi fi # Dialogue zenity avec formulaire (forcer DISPLAY et mode synchrone) echo "DEBUG show_print_options: Tentative d'affichage avec DISPLAY=${DISPLAY}" >> /tmp/md_to_print_debug.log local result # Utiliser dbus-launch si nécessaire pour les applications GUI depuis un contexte non-GUI if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ] && command -v dbus-launch &> /dev/null; then eval $(dbus-launch --sh-syntax) fi result=$(DISPLAY="${DISPLAY}" zenity --forms \ --title "Options d'impression MD_to_Print" \ --text "Configurez les options d'impression" \ --add-combo "Imprimante" \ --combo-values "$printers" \ --add-combo "Recto-verso" \ --combo-values "none|simplex|duplex" \ --add-entry "Nombre de copies (1-10)" \ --add-combo "Couleur" \ --combo-values "Non|Oui" \ --add-combo "Qualité" \ --combo-values "draft|normal|high" \ --add-combo "Orientation" \ --combo-values "portrait|landscape" \ 2>&1) local zenity_exit=$? echo "DEBUG show_print_options: zenity_exit=$zenity_exit, result=$result" >> /tmp/md_to_print_debug.log # Code 1 = utilisateur a annulé (normal) # Code 0 = OK # Autre = erreur if [ $zenity_exit -eq 1 ]; then # Utilisateur a annulé echo "DEBUG: Utilisateur a annulé le dialogue" >> /tmp/md_to_print_debug.log return 1 elif [ $zenity_exit -ne 0 ]; then # Erreur d'exécution echo "Erreur zenity (code $zenity_exit): $result" >> /tmp/md_to_print_zenity_error.log echo "DEBUG: Erreur zenity (code $zenity_exit): $result" >> /tmp/md_to_print_debug.log return 1 fi if [ -z "$result" ]; then echo "DEBUG: Résultat vide" >> /tmp/md_to_print_debug.log return 1 # Pas de résultat fi echo "DEBUG: Dialogue réussi, résultat: $result" >> /tmp/md_to_print_debug.log # Parser les résultats (zenity forms retourne les valeurs séparées par |) IFS='|' read -r selected_printer duplex_mode copies color quality orientation <<< "$result" # Valider et formater les options (déclarer comme globale) declare -ga PRINT_OPTS=() if [ -n "$selected_printer" ] && [ "$selected_printer" != "Par défaut" ] && [ "$selected_printer" != "" ]; then PRINT_OPTS+=(--printer "$selected_printer") fi if [ -n "$duplex_mode" ] && [ "$duplex_mode" != "none" ]; then PRINT_OPTS+=(--duplex "$duplex_mode") fi if [ -n "$copies" ] && [[ "$copies" =~ ^[0-9]+$ ]] && [ "$copies" -ge 1 ] && [ "$copies" -le 10 ]; then PRINT_OPTS+=(--copies "$copies") fi if [ "$color" = "Oui" ]; then PRINT_OPTS+=(--color) fi if [ -n "$quality" ] && [ "$quality" != "normal" ]; then PRINT_OPTS+=(--quality "$quality") fi if [ -n "$orientation" ] && [ "$orientation" != "portrait" ]; then PRINT_OPTS+=(--orientation "$orientation") fi return 0 } # Fonction d'aide show_help() { cat << EOF MD_to_Print - Wrapper GUI Usage: $0 --print|--convert|--preview [--docker] fichier1.md [fichier2.md ...] OPTIONS: --print Conversion + Impression (avec dialogue d'options) --convert Conversion uniquement (sans impression) --preview Prévisualisation avant impression --docker Forcer l'utilisation de Docker --help Afficher cette aide EXEMPLES: $0 --print document.md $0 --convert fichier1.md fichier2.md $0 --preview document.md --docker EOF } # Détection du script principal detect_script() { # Chercher md_to_print.sh dans le PATH if command -v md_to_print.sh &> /dev/null; then SCRIPT_DIR="$(dirname "$(command -v md_to_print.sh)")" return 0 fi # Chercher dans le répertoire parent local current_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" local parent_dir="$(dirname "$current_dir")" if [ -f "$parent_dir/md_to_print.sh" ]; then SCRIPT_DIR="$parent_dir" return 0 fi return 1 } # Détection automatique Docker vs Local detect_mode() { # Si flag --docker explicite if [ "$USE_DOCKER" = true ]; then return 0 fi # Vérifier si script local existe if detect_script; then USE_DOCKER=false return 0 fi # Vérifier si Docker est disponible if command -v docker &> /dev/null; then if docker images md-to-print:latest --format "{{.Repository}}:{{.Tag}}" 2>/dev/null | grep -q "md-to-print:latest"; then USE_DOCKER=true notify info "Utilisation Docker (dépendances locales non disponibles)" return 0 fi fi # Aucune option disponible return 1 } # Parsing des arguments while [[ $# -gt 0 ]]; do case $1 in --print|--convert|--preview) ACTION="${1#--}" shift ;; --docker) USE_DOCKER=true shift ;; --help|-h) show_help exit 0 ;; -*) echo "Option inconnue: $1" >&2 show_help exit 1 ;; *) if [ -f "$1" ]; then FILES+=("$1") else echo "Fichier introuvable: $1" >&2 exit 1 fi shift ;; esac done # Vérification des arguments if [ -z "$ACTION" ]; then echo "Erreur: Action non spécifiée (--print, --convert, ou --preview)" >&2 show_help exit 1 fi if [ ${#FILES[@]} -eq 0 ]; then echo "Erreur: Aucun fichier spécifié" >&2 show_help exit 1 fi # Filtrer seulement les fichiers markdown MD_FILES=() for file in "${FILES[@]}"; do if [[ "$file" =~ \.(md|markdown)$ ]]; then MD_FILES+=("$file") fi done if [ ${#MD_FILES[@]} -eq 0 ]; then notify error "Aucun fichier Markdown trouvé dans la sélection" exit 1 fi # Détection du mode d'exécution if ! detect_mode; then if command -v zenity &> /dev/null; then if zenity --question --text "Aucune installation locale trouvée.\n\nInstaller les dépendances localement ou utiliser Docker?" --title "MD_to_Print" --ok-label "Installer" --cancel-label "Docker"; then if detect_script && [ -f "$SCRIPT_DIR/md_to_print.sh" ]; then notify info "Installation des dépendances..." "$SCRIPT_DIR/md_to_print.sh" --install-deps || { notify error "Échec de l'installation des dépendances" exit 1 } USE_DOCKER=false else notify error "Script md_to_print.sh introuvable" exit 1 fi else USE_DOCKER=true fi else echo "Erreur: Aucune installation trouvée. Installez md_to_print.sh ou Docker." >&2 exit 1 fi fi # Confirmation pour plusieurs fichiers if [ ${#MD_FILES[@]} -gt 1 ]; then count=${#MD_FILES[@]} if command -v zenity &> /dev/null; then if ! zenity --question --text "Traiter $count fichiers?\n\n${MD_FILES[*]}" --title "MD_to_Print" --ok-label "Continuer" --cancel-label "Annuler"; then exit 0 fi else echo "Traitement de $count fichiers..." read -p "Continuer? (o/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Oo]$ ]]; then exit 0 fi fi fi # Afficher le dialogue d'options d'impression AVANT le traitement si action print et un seul fichier # (doit être fait depuis l'hôte, pas dans Docker) PRINT_OPTS=() # S'assurer que DISPLAY est défini (nécessaire quand appelé depuis Caja Actions) if [ -z "${DISPLAY:-}" ]; then # Essayer de trouver DISPLAY depuis l'environnement utilisateur if [ -f "$HOME/.Xauthority" ] && [ -S "/tmp/.X11-unix/X0" ]; then export DISPLAY=":0" elif [ -S "/tmp/.X11-unix/X0" ]; then export DISPLAY=":0" fi # Dernière tentative : utiliser la valeur par défaut if [ -z "${DISPLAY:-}" ]; then export DISPLAY=":0" fi fi # Logs de débogage echo "DEBUG: ACTION=$ACTION" >> /tmp/md_to_print_debug.log echo "DEBUG: DISPLAY=${DISPLAY:-}" >> /tmp/md_to_print_debug.log echo "DEBUG: zenity disponible: $(command -v zenity 2>&1)" >> /tmp/md_to_print_debug.log echo "DEBUG: Nombre de fichiers: ${#MD_FILES[@]}" >> /tmp/md_to_print_debug.log # Afficher le dialogue d'options pour print ET preview (si un seul fichier) if [ \( "$ACTION" = "print" -o "$ACTION" = "preview" \) ] && command -v zenity &> /dev/null && [ ${#MD_FILES[@]} -eq 1 ]; then echo "DEBUG: Conditions remplies, tentative d'affichage du dialogue" >> /tmp/md_to_print_debug.log # Toujours essayer d'afficher le dialogue pour print et preview if show_print_options; then echo "DEBUG: Dialogue OK, options: ${PRINT_OPTS[*]}" >> /tmp/md_to_print_debug.log notify info "Options sélectionnées: ${PRINT_OPTS[*]}" else echo "DEBUG: Dialogue échoué ou annulé" >> /tmp/md_to_print_debug.log notify info "Utilisation des options par défaut" fi else echo "DEBUG: Conditions non remplies - ACTION=$ACTION, zenity=$(command -v zenity), fichiers=${#MD_FILES[@]}" >> /tmp/md_to_print_debug.log fi # Notification de début notify info "Traitement de ${#MD_FILES[@]} fichier(s)..." # Traitement des fichiers SUCCESS_COUNT=0 ERROR_COUNT=0 ERROR_FILES=() for file in "${MD_FILES[@]}"; do file_name="$(basename "$file")" notify info "Traitement: $file_name" if [ "$USE_DOCKER" = true ]; then # Utilisation Docker file_dir="$(dirname "$(realpath "$file")")" file_base="$(basename "$file")" output_dir="$HOME/MD_to_print_output" mkdir -p "$output_dir" # Construire les arguments Docker docker_args=() if [ "$ACTION" = "convert" ]; then docker_args+=(--convert-only) elif [ "$ACTION" = "preview" ]; then # Pour "preview", utiliser les options déjà récupérées avant la boucle if [ ${#PRINT_OPTS[@]} -gt 0 ]; then docker_args+=("${PRINT_OPTS[@]}") fi docker_args+=(--preview --keep-pdf) else # Pour "print", utiliser les options déjà récupérées avant la boucle if [ ${#PRINT_OPTS[@]} -gt 0 ]; then docker_args+=("${PRINT_OPTS[@]}") fi # On garde le PDF après impression docker_args+=(--keep-pdf) fi if docker run --rm \ -v "$file_dir:/workspace/documents:ro" \ -v "$output_dir:/workspace/output" \ -v "$HOME/MD_to_print/logs:/workspace/logs" \ --network host \ ${DISPLAY:+-e DISPLAY="$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix:ro} \ ${CUPS_SOCKET:+-v /var/run/cups:/var/run/cups:ro} \ md-to-print:latest \ "/workspace/documents/$file_base" \ "${docker_args[@]}" \ > /tmp/md_to_print_docker.log 2>&1; then SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) # Pour preview, ouvrir le PDF depuis l'hôte après conversion if [ "$ACTION" = "preview" ]; then pdf_file="$output_dir/${file_base%.*}.pdf" if [ -f "$pdf_file" ]; then if command -v evince &> /dev/null; then evince "$pdf_file" 2>/dev/null & elif command -v xdg-open &> /dev/null; then xdg-open "$pdf_file" 2>/dev/null & else notify warn "Aucun visualiseur PDF trouvé pour prévisualisation" fi fi fi notify success "✓ $file_name traité" else ERROR_COUNT=$((ERROR_COUNT + 1)) ERROR_FILES+=("$file_name") notify error "✗ Erreur: $file_name" fi else # Utilisation locale script_path="" if [ -n "$SCRIPT_DIR" ]; then script_path="$SCRIPT_DIR/md_to_print.sh" else script_path="md_to_print.sh" fi cmd_args=("$file") case "$ACTION" in print) # Pour print, utiliser les options déjà récupérées avant la boucle if [ ${#PRINT_OPTS[@]} -gt 0 ]; then cmd_args+=("${PRINT_OPTS[@]}") fi # On garde le PDF après impression cmd_args+=(--keep-pdf) ;; convert) # Pour convert, conversion uniquement sans impression cmd_args+=(--convert-only) ;; preview) # Pour preview, utiliser les options déjà récupérées avant la boucle if [ ${#PRINT_OPTS[@]} -gt 0 ]; then cmd_args+=("${PRINT_OPTS[@]}") fi cmd_args+=(--preview --keep-pdf) ;; esac if "$script_path" "${cmd_args[@]}" > /tmp/md_to_print.log 2>&1; then SUCCESS_COUNT=$((SUCCESS_COUNT + 1)) # Pour preview, ouvrir le PDF depuis l'hôte après conversion if [ "$ACTION" = "preview" ]; then # Chercher le PDF dans le répertoire de sortie pdf_file="" if [ -f "${file%.*}.pdf" ]; then pdf_file="${file%.*}.pdf" elif [ -f "$HOME/MD_to_print_output/$(basename "${file%.*}.pdf")" ]; then pdf_file="$HOME/MD_to_print_output/$(basename "${file%.*}.pdf")" elif [ -f "./output/$(basename "${file%.*}.pdf")" ]; then pdf_file="./output/$(basename "${file%.*}.pdf")" fi if [ -n "$pdf_file" ] && [ -f "$pdf_file" ]; then if command -v evince &> /dev/null; then evince "$pdf_file" 2>/dev/null & elif command -v xdg-open &> /dev/null; then xdg-open "$pdf_file" 2>/dev/null & else notify warn "Aucun visualiseur PDF trouvé pour prévisualisation" fi fi fi notify success "✓ $file_name traité" else ERROR_COUNT=$((ERROR_COUNT + 1)) ERROR_FILES+=("$file_name") notify error "✗ Erreur: $file_name" fi fi done # Résumé final if [ $ERROR_COUNT -eq 0 ]; then notify success "Tous les fichiers ont été traités avec succès ($SUCCESS_COUNT fichier(s))" exit 0 else summary="Terminé: $SUCCESS_COUNT succès, $ERROR_COUNT erreur(s)" if [ ${#ERROR_FILES[@]} -gt 0 ]; then summary="$summary\n\nErreurs:\n${ERROR_FILES[*]}" fi notify error "$summary" exit 1 fi