#! /usr/bin/env python # -*- coding: iso-8859-15 -*- # # Backend CUPS pour laserjet # tout en réalisant le devis et debitant. # Codé par Benoit , Fred et Braice, inspirés par CUPSPykota # Licence : GNU General Public Licence, version 2 #TODO #Parser ce que réponds l'imprimante # import sys,os sys.path.append('/usr/scripts/impression') import couts import pjl_comm sys.path.append('/usr/scripts/gestion') from config import impression from ldap_crans import crans_ldap import tempfile import time base=crans_ldap() #on teste les argument AVANT le reste if len(sys.argv) == 1 : print '%s laserjet "Crans" "Imprime tout en debitant"' % sys.argv[0] sys.exit(0) if len(sys.argv) not in (6, 7) : sys.stderr.write("ERROR: %s job-id user title copies options [file]\n" % sys.argv[0]) sys.exit(0) # On passe sans stopper #préparation des mails sujet=u"Impression n°%(numero)s : %(fichier)s" % {'numero' : sys.argv[1], 'fichier' : sys.argv[3]} mail_err = u""" Bonjour, Il y a eu une erreur lors de votre impression Le message d'erreur est le suivant : %%(erreur)s Si l'erreur se reproduit envoyez un mail à %(adresse_imprimante)s -- L'imprimante """ % {"adresse_imprimante" : impression.From_imprimante} mail_ok = u""" Bonjour, L'impression que vous avez demandé coute la modique somme de %%(prix)s. Votre ancien solde sur votre compte impression etait crédité de %(solde)s euros. Rappel : votre compte est bloqué à %(blocage)s euros L'impression a été correctement effectuée et votre compte a été débité. Pour accéder à l'imprimante votre code unique pour cette impression est le suivant %(code)s# -- L'imprimante """ mail_err_solde = u""" Bonjour, Votre compte n'est pas assez approvisionné pour cette impression. Votre solde actuel est de %(solde)s or l'impressiom coûte %(prix)s. Par conséquent, votre compte ne sera pas débité. -- L'imprimante """ debut = """.%-12345X@PJL SET STRINGCODESET=UTF8 @PJL SET STRINGCODESET=UTF8 @PJL SET HOLD=ON @PJL SET HOLDTYPE=PRIVATE @PJL SET HOLDKEY="1234" @PJL SET USERNAME="PD" @PJL SET JOBNAME="Downloads for -" @PJL SET DUPLICATEJOB = REPLACE """ if sys.argv[-1].find('/') != -1 : # Fichier fourni entree = open(sys.argv[-1]) else : # Lecture sur stdin entree = sys.stdin #recuperation du nom de l'utilisateur user=sys.argv[2] #recuperation de l'adherent en écriture res=base.search("login=%s"%user,'w')['adherent'] #si on ne trouve rien if len(res) != 1 : sys.stderr.write("ERROR: Erreur : adherent %s non trouvé\n" % user) sys.exit(0) # on ne stoppe pas l'imprimante adherent=res[0] #\x1B est le caractere d'échappement échap. UEL="\x1B%-12345X" fic = tempfile.NamedTemporaryFile() nom_fic=fic.name ligne = entree.readline() # On rends le fichier propre et on enleve les options qui nous gènent while ligne: #On ne choisit pas le bac de sortie if ligne.find('%%BeginFeature: *OutputBin') != -1: while ligne.find('%%EndFeature') == -1: ligne = entree.readline() ligne = entree.readline() #On ne choisit pas le bac d'entree if ligne.find('%%BeginFeature: *InputSlot') != -1: while ligne.find('%%EndFeature') == -1: ligne = entree.readline() ligne = entree.readline() #On elimine les instructions PJL #Normalement on n'est pas obligé de retirer le UEL mais c'est plus propre while ligne.startswith('@PJL') or ligne.startswith(UEL): ligne = entree.readline() fic.write(ligne) ligne = entree.readline() fic.flush() # Récupérer l'adresse mail adrmail = adherent.mail() nom_adher = adherent.Nom() if adrmail.find('@') == -1 : adrmail += "@crans.org" adrmail = adrmail.encode("iso8859-15") # Récupérer le solde solde = adherent.solde() ## calcul du prix # Option par défaut (Couleur) mode_couleur = "Couleur" # On récupère les options passées if "media=transparency" in sys.argv: format = "transparent" # Calcul du coût de l'impression sys.stderr.write("DEBUG: Calcul du prix..\n" ) prix = couts.cout(nom_fic, mode_couleur) sys.stderr.write("DEBUG: Prix : %s format %s recto-verso : %s..\n" %(prix.c_total_euros,prix.format,prix.recto_v) ) raison="" if prix.erreur: raison=prix.erreur else: if prix.c_total_euros > (solde - impression.decouvert) : err_solde= 1 else : err_solde=0 #Si il y a une erreur (compte non approvisionné, postscript mal formatté) if raison: # On loggue l'erreur sys.stderr.write( ("ERROR: Erreur : utilisateur : \"%s\" raison %s" % (user,raison)).encode('latin-1')) #envoi du mail d'erreur prix.send_mail("%(nom)s <%(adrmail)s>" % {'nom' : nom_adher, 'adrmail' : adrmail}, sujet, mail_err % {'erreur' : raison} ) elif err_solde: prix.send_mail("%(nom)s <%(adrmail)s>" % {'nom' : nom_adher, 'adrmail' : adrmail}, sujet, mail_err_solde % { 'solde' : solde , 'prix' : prix.str_cout }) #Tout est OK on imprime else: #Adaptation de la facture try: #Envoi du fichier a l'imprimante nom_fic2=tempfile.mktemp() if(prix.recto_v=='Recto'): sys.stderr.write("DEBUG: Ceci est un recto simple, on inverse juste l'ordre..\n" ) os.system("cp %s %s " % (nom_fic, nom_fic2)) os.system("psselect -r %s > %s " % (nom_fic, nom_fic2)) else: sys.stderr.write("DEBUG: recto verso on permute deux a deux..\n" ) if(prix.faces%2 ==1): sys.stderr.write("DEBUG: nombre de faces impair..\n" ) prix.faces+=1 sys.exit(0) else: sys.stderr.write("DEBUG: nombre de faces pair..\n" ) liste_pages="" for i in range(1,int(prix.faces/2)+1): liste_pages+=str(2*i)+","+str(2*i-1)+"," #on enleve la virgule superflue liste_pages=liste_pages[:-1] sys.stderr.write("DEBUG: Liste pages : %s\n" % liste_pages ) os.system("cp %s %s " % (nom_fic, nom_fic2)) os.system("psselect -p%s %s > %s 2>/dev/null" % (liste_pages, nom_fic, nom_fic2)) sys.stderr.write("DEBUG: Envoi du fichier..\n" ) imprimante=pjl_comm.hp9500() imprimante.cx_open() # imprimante.pjl_command('RESET') imprimante.pjl_command('USTATUS PAGE = ON') imprimante.pjl_command('USTATUS JOB = ON') imprimante.pjl_command('USTATUS DEVICE = ON') # imprimante.pjl_command('SET MEDIATYPE=TRANSPARENCY') #a tester # imprimante.pjl_command('SET MEDIATYPE=PAPER') # imprimante.pjl_command('SET OUTBIN=LOWER') #a tester # imprimante.pjl_command('SET OUTBIN=UPPER') #a tester imprimante.write_postscript(nom_fic2, user, nom_adher) os.system("cp %s /tmp/last_printed.ps" % nom_fic2) os.system("chmod 666 /tmp/last_printed.ps") os.system("rm %s" % nom_fic2) message=imprimante.pjl_read() i=0 sys.stderr.write("DEBUG: Message de l'imprimante : \n%s\n" %message ) while(message.find("PAGES=")==-1 and i<200): message=imprimante.pjl_read() sys.stderr.write("DEBUG: Message : %s\n" %message ) sys.stderr.write("DEBUG: Impression non terminée..\n" ) i=i+1 time.sleep(2) sys.stderr.write("DEBUG: Impression terminée temporisation de 20s....\n" ) time.sleep(10) imprimante.cx_close() time.sleep(10) # On débite l'adhérent si l'impression a eu lieu adherent.solde(-prix.c_total_euros) adherent.save() #Génération du code et écriture du code i=0 code=0 import random #instance de base rand=random.Random() #graine automatique avec le temps rand.seed() while(i<1000) : #on génère le numéro de session code=rand.randint(100000,999999) #pour avoir six chiffres #on sauvegarde les données concernant la session dans un fichier qui périme dans duree_session try: open("/var/impression/codes/%d" %code, 'r') except : break i=i+1 if code: codefichier=open("/var/impression/codes/%d" %code, 'w') codefichier.write("Utilisateur %s\n"%(nom_adher)) codefichier.close() else : #Grosse erreur faudra faire qqch sys.stderr.write("ERROR: Erreur il n'y a pas de code disponible" ) sys.exit(0) #envoi du mail avec le code et le prix prix.send_mail("%(nom)s <%(adrmail)s>" % {'nom' : nom_adher, 'adrmail' : adrmail}, sujet, mail_ok % {'solde' : solde, 'blocage' : str(impression.decouvert), 'code' : code }) except: sys.stderr.write("ERROR: Erreur , impression annulée" ) prix.send_mail("%(nom)s <%(adrmail)s>" % {'nom' : nom_adher, 'adrmail' : adrmail}, sujet, mail_err % {'erreur' : u"Le fichier n'a pu être imprimé, \veuillez reessayer plus tard.\n"} ) # Report de bug import traceback from cStringIO import StringIO s = StringIO() sys.stderr = s traceback.print_exc() sys.stderr = sys.__stderr__ traceback = s.getvalue() try: prix.send_mail("Impression <%s>" % impression.From_imprimante , "ERREUR " + sujet, "Une erreur c'est produite lors de cette impression, voici le compte rendu :\n" + traceback) sys.stderr.write("INFO: Un rapport de bug à été automatiquement envoyé.\n") except : sys.stderr.write("ERROR: Impossible d'envoyer le rapport de bug.\n") # On loggue ce que ne loggue pas cups quelquepart ? sys.exit(0)