scripts/impression/backend/laserjet
rozel 9b12d8f960 Rcupration de l'utilisateur rel de cups en parsant son spool.
On ne peut pas utiliser le 2me argument pass au backend car en mode
authentifi Samba fournit root plutot que de faire suivre l'utilisateur
connect  Samba.

darcs-hash:20050616091142-061a7-4047755bb27376e46c05548d3ac06e2aac9c697b.gz
2005-06-16 11:11:42 +02:00

307 lines
9.9 KiB
Python
Executable file

#! /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] #On ne fait pas comme ca, car samba passe l'utilisateur root
if len(sys.argv[1]) < 5 :
fichier_ipp = "c%05i" % int(sys.argv[1])
else:
fichier_ipp = "c%s" % sys.argv[1]
try:
message = IPPMessage(open('/var/spool/cups/%s' % fichier_ipp).read())
except:
sys.stderr.write("ERROR: Erreur : Ne peut pas ouvrir/parser le fichier /var/spool/cups/%s" % fichier_ipp)
user=message["job-originating-user-name"]
# 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)