#! /usr/bin/env python # -*- coding: iso-8859-15 -*- # # Class pour l'impression depuis le web par cups # Codé par Francois # Inspiré par le backend écrit par Benoit, Fred et Brice, inspirés par CUPSPykota # Licence : GNU General Public Licence, version 2 import sys, time, tempfile, os, commands, string sys.path.append('/usr/scripts/impression') sys.path.append('/usr/scripts/gestion') from config import impression #sys.path.append('/localhome/bobot/scripts/gestion') from ldap_crans import crans_ldap #import vraicouts duree_vie_pdf=3600 #fonction principal: impression (fichier_impression) class test: def mail(self): return u"francois.bobot@crans.org" def Nom(self): return u"francois" def solde(self,modif=0.): return (40.+modif) def save(self): pass class fichier_impression : nom_job='' nbr_pages=1 nb_copie=1 taille="A4" recto_verso=False transparent=False couleur=True cout=0.0 portrait=True user="" user_ldap=None #seras une instance de l'utilisateur dans la base ldap. imprime=-1 #-2 impression en suspend, -1 mise dans la file d'attente, 0 devis, time pour l'heure, -3 déja imprimé ou devis fait depuis trops longtemps : le pdf n'est plus disponible nom_fichier_pdf="" #chemin et nom du pdf nom_fichier_desc="" #chemin et nom du fichier contenant les options de l'utilisateur list_messages=[] #liste d'erreur et de remarque list_messages_importants=[] list_messages_admin=[] #liste d'erreur réservé au administrateur erreur_critique=False #True si une erreur empêchant l'impression est apparue code=None #code pour le digicode modif_epoch=None #moment de création du job ou devis. exprimé en epoch (float) : nombre de seconde depuis la référence du temps unix (+-=1970) job_id=None #champs pour de futur amélioration def actualise_cout(self): # Calcul du cout de l'impression : retour = cout(self) # Met le prix dans cout s'il n'y a pas d'erreur if type(retour) is float : self.cout=retour self.list_messages_importants.append('cout') else: self.erreur_critique=True self.list_messages_importants.append('erreur_critique') self.list_messages_admin.append('erreur_cout') sys.stderr.write(retour) #repond vrai si le solde est assez élevé. def test_cout(self): if self.user_ldap==None: self.user_ldap = utilisateur(self.user,False) #self.user_ldap = test() return not (self.cout > (self.user_ldap.solde() - impression.decouvert)) #!impression.decouvert est négatif. def fait_payer(self): self.user_ldap = utilisateur(self.user,True) #self.user_ldap = test() self.user_ldap.solde(-self.cout) self.user_ldap.save() return not (self.cout > (self.user_ldap.solde() - impression.decouvert)) def gen_code(self): #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 verifie que le code n'est déja pas utilisé try: open("/var/impression/codes/%d" %code, 'r') #open("/home/bobot/tmp/codes/%d" %code, 'r') except : break i=i+1 if code: #on enregistre le fichier avec le code pour numéro codefichier=open("/var/impression/codes/%d" %code, 'w') #codefichier=open("/localhome/bobot/codes/%d" %code, 'w') codefichier.write("Utilisateur %s\n"%(self.user_ldap.Nom())) codefichier.close() self.code=code self.list_messages_importants.append('code') else : # Grosse erreur : on logue, on previent et on stoppe. print ("ERROR: Il n'y a pas de code disponible" ) sys.stderr.write ("ERROR: Il n'y a pas de code disponible" ) try: #crans_backend.send_email(prix.From, "Impression <%s>" % impression.From_imprimante , u"ERREUR " + sujet, mail_err % {'erreur' : "Il n'y a plus de code disponible.\n"}) self.list_messages_importants.append('erreur gen_code') sys.stderr.write("DEBUG: Un rapport de bug a ete automatiquement envoye.\n") except : sys.stderr.write("ERROR: Impossible d'envoyer le rapport de bug.\n") sys.stderr.write("ERROR: Plus de codes disponibles.\n") sys.stderr.write("ERROR: Penser a ouvrir a l'adherent debite...\n") #sys.exit(1) def impression(self): # Envoi du fichier à CUPS #Création de la liste d'options options ='-# '+str(self.nb_copie) #options ='-n '+str(self.nb_copie) options +=' -P laserjet' options +=' -T '+self.nom_job #options +=' -t '+self.nom_job options +=' -U '+self.user options +=' -o job-sheets=crans' #page de garde de type standard if self.transparent : options+=' -o PageSize=A4 -o Media=Transparency' else: options+=(' -o PageSize='+self.taille) if self.portrait: if self.recto_verso: options+=(' -o sides=two-sided-long-edge') else: options+=(' -o sides=one-sided') else: options+=(' -o landscape') if self.recto_verso: options+=' -o sides=two-sided-short-edge' else: options+=' -o sides=one-sided' options+=' -o HPColorasGray='+str(not self.couleur) (status,rep) = commands.getstatusoutput("lpr %s %s" %(options,self.nom_fichier_pdf)) #if status<>0: #print "
status:"+str(status)+" rep:"+rep+"
" #else: #self.job_id=rep.split(' ')[3] def corrige (self): # # fic_impr=fichier_impression() # fic_impr.user=utilisateur(arguments[2],rw) #trouve le nombre de pages self.nbr_pages = int(os.popen("pdfinfo %s | grep Pages " % (self.nom_fichier_pdf)).readline().split()[1]) ##Corrige les aberrations ##Correction des aberations (transparent et recto_verso :) ) ##Priorité des informations par ordre décroissant ##Transparent, paper, nbr_page, recto_verso if (self.taille<>'A4') & (self.taille<>'A3'): self.list_messages_importants.append("paper") self.erreur_critique=True if self.transparent: if self.paper<>'A4': self.list_messages.append("A3 transparent") self.paper='A4' if self.recto_verso: self.list_messages.append("Recto_verso transparent") self.recto_verso=False if self.nbr_pages==1 & self.recto_verso: self.list_messages.append("Recto_verso 1 page") self.recto_verso=False def affiche_messages_html(self): body="" """if self.imprime: body=string.join(map ((dico_message_laserjet.get),self.list_messages_importants)) if len(self.list_messages)<>0: body=body+'\nRemarques:\n'+string.join(map ((dico_message_laserjet.get),self.list_messages)) else: body=string.join(map ((dico_message_devis.get),self.list_messages_importants)) body=body+'\nRemarque:\n'+string.join(map ((dico_message_devis.get),self.list_messages)) body=body % {'taille' : self.taille, 'code' : self.code, 'solde' : self.user_ldap.solde(), 'cout' : self.cout , 'adresse_imprimante' : impression.From_imprimante} """ body=string.join(self.list_messages_importants) return ""+body+"
" def enregistre_pdf(self,f_value,f_nom,dossier): (fd_fichier_desc,self.nom_fichier_desc) = tempfile.mkstemp(suffix='.desc',prefix=f_nom,dir=dossier) os.close(fd_fichier_desc) os.chmod(self.nom_fichier_desc,33184) self.nom_fichier_pdf=self.nom_fichier_desc[0:-5]+".pdf" #(,self.nom_fichier_pdf) = tempfile.mkstemp(suffix='.pdf',prefix=identifiant+f_nom,dir=data_dir+identifiant) file_obj_pdf=open(self.nom_fichier_pdf,'w') file_obj_pdf.write(f_value) file_obj_pdf.close() self.nbr_pages = int(os.popen("pdfinfo %s | grep Pages " % (self.nom_fichier_pdf)).readline().split()[1]) self.modif_epoch=time.time() def sauve_desc(self): file_obj_desc=open(self.nom_fichier_desc,'w') for key in ("erreur_critique","nom_job","nbr_pages","nb_copie","taille","recto_verso","transparent","couleur","cout","portrait","user","imprime","nom_fichier_pdf","nom_fichier_desc","code","modif_epoch","job_id"): file_obj_desc.write(key+"="+str(getattr(self,key))+"\n") file_obj_desc.close() def read_desc(self): file_obj_desc=open(self.nom_fichier_desc,'r') ligne=file_obj_desc.readline()[0:-1] while ligne<>"": parse=ligne.split("=") if parse[1]=='None': setattr(self,parse[0],None) else: if parse[0] in ("nom_job","taille","user","nom_fichier_pdf","nom_fichier_desc","job_id"): setattr(self,parse[0],parse[1]) else: if parse[0] in ("nbr_pages","nb_copie","imprime","code"): setattr(self,parse[0],int(parse[1])) else: if parse[0] in ("recto_verso","transparent","couleur","portrait","erreur_critique"): setattr(self,parse[0],(parse[1]=='True')) else: if parse[0] in ("cout","modif_epoch"): setattr(self,parse[0],float(parse[1])) else: self.erreur_critique=True print 'ligne non parser:'+ligne+'
' ligne=file_obj_desc.readline()[0:-1] file_obj_desc.close() #Vérifie que le fichier existe bien si il doit exister. if not os.access(self.nom_fichier_pdf,os.F_OK): if self.imprime<>-3: self.imprime=-4 else: if (time.time()-self.modif_epoch)>duree_vie_pdf: os.remove(self.nom_fichier_pdf) self.imprime=-4 #fonction utilisé par print et str : renvoie le string canonique de l'objet def __repr__(self): dict_contraire={'couleur' : 'Noir et Blanc' , 'transparent' : 'Normal' , 'portrait': 'Paysage' , 'recto_verso' : 'Recto' , 'erreur_critique' : "Pas d'erreur"} dict_normale={'couleur' : 'Couleur' , 'transparent' : 'Transparent' , 'portrait': 'Portrait' , 'recto_verso' : 'Recto-Verso' , 'erreur_critique' : "Problême survenue"} #dict_imprime={-4: 'PDF indisponible', -3: 'Envoyé', -2 : 'En suspend', -1 : "En cours d'envoi", 0 : "Devis"} corps=""+self.nom_job+" | "+time.ctime(self.modif_epoch)+" | |||||||
---|---|---|---|---|---|---|---|---|
\n
| \n\n
| " if self.erreur_critique: corps+="erreur de comptage" else: corps+=str(self.cout)+"euros" corps+=" |