#!/usr/bin/env python
# coding: UTF-8

#    Copyright (C) 2007-2008 by Nicolas ELIE
#    chrystalyst@free.fr
#
#    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 2 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, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import commands, string, os, sys

# Correspondance ID de périphérique / modèle
MODEL = {'0811':'RX620', '0801':'CX5200/CX5400/CX6600', '0802':'CX3200', '0805':'CX6400', '0808':'CX5200', '082f':'DX4050', '083f':'DX4450', '082b':'DX5050','082e':'DX6050', '0839':'DX8400'}

# Chemins vers les fichiers
EPSON_CONF = "/etc/sane.d/epson.conf"
UDEV_RULES = "/etc/udev/rules.d/45-libsane.rules"

# Quelques strings utiles
SCANNERS = ""
counter=0
for value in MODEL.values():
    if not counter==0:
        SCANNERS += "/"
    counter+=1
    SCANNERS += value
AUTHOR_EMAIL = "chrystalyst@free.fr"
INTRODUCTION = "Ce script gère les scanners Epson Stylus %s et éventuellement d'autres. Il va modifier les fichiers nécessaires à la reconnaissance du scanner, vous n'aurez plus qu'à utiliser xsane pour scanner vos documents\nPour toutes remarques, bugs, nouveaux scanners : %s\n" % (SCANNERS, AUTHOR_EMAIL)

# Quelques strings pour les éventuels messages d'erreurs
SEARCH_FILE = "Recherche du fichier %s..."
SCANNER_DETECTION = "Détection du scanner en cours..."
FILE_VERSION = "Vérification de la version des fichiers..."
FILE_VERSION_OK = "%s OK"
FILE_VERSION_ERROR = "%s est déjà modifié."
ERROR_IN_MODIFICATION = "Une erreur est survenue lors de la modification du fichier %s"
MODIFICATION_OK = "%s modifié"
UDEV_RESTART_ERROR = "Une erreur est survenue lors du redémarrage de udev."
UDEV_RESTART_OK ="udev redémarré avec succès."
SCANNER_DETECTION_ERROR = "Le scanner n'est pas connecté. Veuillez le connecter et le mettre sous tension."
SCANNER_DETECTION_OK = "Scanner reconnu : %s"

# Formate l'ID du périphérique en ajoutant un "x" après le premier caractère
def addX(text):
    return text[0] + "x" + text[1:]

# Teste si un fichier existe et affiche le résultat en couleur sur la console
def test_exists(filename):
    print SEARCH_FILE % filename
    if not os.path.exists(filename):
        print_in_color("red", "\t" + filename + " n'a pas été trouvé.")
        sys.exit(0)
    else:
        print_in_color("green", "\t" + filename + " trouvé.")

# Correspondance nom de couleur / code shell
colours = {
	"default"    :    "\033[0m",
	# style
	"bold"       :    "\033[1m",
	"underline"  :    "\033[4m",
	"blink"      :    "\033[5m",
	"reverse"    :    "\033[7m",
	"concealed"  :    "\033[8m",
	# couleur texte
	"black"      :    "\033[30m", 
	"red"        :    "\033[31m",
	"green"      :    "\033[32m",
	"yellow"     :    "\033[33m",
	"blue"       :    "\033[34m",
	"magenta"    :    "\033[35m",
	"cyan"       :    "\033[36m",
	"white"      :    "\033[37m",
	# couleur fond
	"on_black"   :    "\033[40m", 
	"on_red"     :    "\033[41m",
	"on_green"   :    "\033[42m",
	"on_yellow"  :    "\033[43m",
	"on_blue"    :    "\033[44m",
	"on_magenta" :    "\033[45m",
	"on_cyan"    :    "\033[46m",
	"on_white"   :    "\033[47m" }
 
# Ecrit en couleur sur la console
def print_in_color(color, text):
    print colours[color] + text + colours["default"]

print INTRODUCTION

#Tests préliminaires (existence des fichiers à modifier)
test_exists(EPSON_CONF)
test_exists(UDEV_RULES)

# Détection du scanner et obtention des IDs du fabricant et du périphérique
print SCANNER_DETECTION
scanner = commands.getoutput("lsusb | grep -i epson")

if scanner:
    # Extraction des IDs du fabricant et du périphérique
    ID = string.split(scanner)[5]
    (productID, deviceID) = string.split(ID, ":")

    if deviceID in MODEL.keys():
        model = "Epson Stylus " + MODEL[deviceID]
    else:
        model = "Scanner inconnu"

    print_in_color("green", "\t" + SCANNER_DETECTION_OK % model)

    #Les fichiers sont-ils déjà modifié?
    print FILE_VERSION
    if commands.getoutput("cat " + EPSON_CONF + " | grep " + addX(deviceID)):
        print_in_color("blue", "\t" + FILE_VERSION_ERROR % EPSON_CONF)
    else:
        print_in_color("green", "\t" + FILE_VERSION_OK % EPSON_CONF)
        # Back up du fichier epson.conf
        result = os.system("sudo cp " + EPSON_CONF + " " + EPSON_CONF + ".bak")
        if result > 0:
            print_in_color("red", ERROR_IN_MODIFICATION % EPSON_CONF)
            exit(0)
        else:
            print_in_color("green", EPSON_CONF + " modifié")

        # Décommenter les lignes commencant par usb
        os.system("sudo sed -i -e 's/^#usb /usb /g' " + EPSON_CONF)
        os.system("sudo sed -i -e \"/usb 0x/ c\\usb " + addX(productID) + " " + addX(deviceID) + "\" " + EPSON_CONF)

    if commands.getoutput("cat " + UDEV_RULES + " | grep " + deviceID):
        print_in_color("blue", "\t" + FILE_VERSION_ERROR % UDEV_RULES)
    else:
        print_in_color("green", "\t" + FILE_VERSION_OK % UDEV_RULES)
        # Back up du fichier 45-libsane.rules
        result = os.system("sudo cp " + UDEV_RULES + " " + UDEV_RULES + ".bak")
        if result > 0:
            print_in_color("red", ERROR_IN_MODIFICATION % UDEV_RULES)
            exit(0)
        else:
            print_in_color("green", MODIFICATION_OK % UDEV_RULES )

        numberoflines = commands.getoutput("cat " + UDEV_RULES + " | wc -l")
        numline = string.split(commands.getoutput("tac " + UDEV_RULES + " | grep -n -m 1 'SYSFS{idVendor}==\"" + productID + "\"'"), ":")[0]
        numline = int(numberoflines) - int(numline) + 1

        # Ajout d'une ligne concernant le scanner
        replace = "# " + model  + "\\nSYSFS{idVendor}==\\\"" + productID + "\\\", SYSFS{idProduct}==\\\"" + deviceID + "\\\", MODE=\\\"664\\\", GROUP=\\\"scanner\\\""

        os.system("sudo sed -i -e \"" + str(numline) + "a\\\n" + replace + "\" " + UDEV_RULES)

    print "Redémarrage de udev..."
    result = os.system("sudo /etc/init.d/udev restart")
    if result > 0:
        print_in_color("red", "\t" + UDEV_RESTART_ERROR)
        exit(0)
    else:
        print_in_color("green", "\t" + UDEV_RESTART_OK)
else:
    print_in_color("red", "\t" + SCANNER_DETECTION_ERROR)

