diff --git a/impression/class_impression.py b/impression/class_impression.py index e40e0375..aaea5f78 100644 --- a/impression/class_impression.py +++ b/impression/class_impression.py @@ -14,6 +14,8 @@ sys.path.append('/usr/scripts/gestion') from config import impression from ldap_crans import crans_ldap from syslog import openlog, syslog, LOG_DEBUG +from gen_code import NoCodeError, new_code + duree_vie_pdf=3600 @@ -39,7 +41,7 @@ class test: return (40.+modif) def save(self): pass - + ################################################################################ class fichier_impression: @@ -53,7 +55,8 @@ class fichier_impression: couleur = True cout = 0.0 portrait = True - agrafe=0 #-1 : agrafe diagonale, 0 : pas d'agrafe, 1 : 1 agrafe parallele, 2: 2 agrafes, 3: 3 agrafes, 6: 6 agrafes(stitching) + livret = False + agrafe= "None" # TopLeft, Top, TopRight, Left, Right, BottomLeft, BottomRight user = "" user_ldap = None # sera une instance de l'utilisateur dans la base ldap. imprime = -1 #-2 impression en suspend, -1 mise dans la file @@ -75,12 +78,12 @@ class fichier_impression: job_id = None # champs pour de futures améliorations - def actualise_cout(self): + def actualise_cout(self): """ Actualise le champ cout Leve l'erreur ErreurImpression si le calcul du cout ne c'est pas bien passe """ # 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 @@ -91,15 +94,13 @@ class fichier_impression: self.list_messages_admin.append('erreur_cout') raise ErreurImpression(retour) - def test_cout(self): """ Repond vrai si le solde est assez élevé. """ if self.user_ldap == None: self.user_ldap = utilisateur(self.user, False) # /!\ decouvert est négatif. - return not (self.cout > (self.user_ldap.solde() - impression.decouvert)) + return not (self.cout > (self.user_ldap.solde() - impression.decouvert)) - def fait_payer(self): """ Retire au solde de l'adherent la valeur de cout """ self.user_ldap = utilisateur(self.user, True) @@ -107,22 +108,13 @@ class fichier_impression: self.user_ldap.save() return not (self.cout > (self.user_ldap.solde() - impression.decouvert)) - def gen_code(self): """ Genere le code et l'enregistre dans /var/impression/codes pour radius """ - # Génération du code et écriture du code - rand=random.Random() - # Graine automatique avec le temps - rand.seed() - - for i in range(1000): - # On génère un code - code = rand.randint(100000, 999999) - # Si le code est libre, on sort de la boucle - if not os.path.exists("/var/impression/codes/%d" % code): - break - - else: + try: + self.code = new_code("Utilisateur %s\n" % self.user) + self.list_messages_importants.append('code') + + except NoCodeError: # Pas de code disponible print ("ERROR: Il n'y a pas de code disponible" ) sys.stderr.write ("ERROR: Il n'y a pas de code disponible" ) @@ -135,31 +127,20 @@ class fichier_impression: sys.stderr.write("ERROR: Penser a ouvrir a l'adherent debite...\n") return - # On enregistre le fichier avec le code pour numéro - codefichier = open("/var/impression/codes/%d" % code, 'w') - codefichier.write("Utilisateur %s\n" % self.user) - codefichier.close() - self.code = code - self.list_messages_importants.append('code') - - - def impression(self): + def impression_canon(self) """ Envoie l'impression a l'imprimante avec les parametres actuels """ # Envoi du fichier à CUPS options ='' # Création de la liste d'options # pour le nombre de copies et specifie non assemblee #options += '-# %d -o Collate=True' % self.nb_copies - - # Pour spécifier l'imprimante - options += ' -P laserjet' - # Pour spécifier le bac sortie - options += ' -o OutputBin=Left' - + # Pour spécifier l'imprimante + options += ' -P canon_irc3580' + # Pour spécifier la version du language postscript utilisé par pdftops - options += ' -o pdf-level3' - +# options += ' -o pdf-level3' + # Pour donner le titre de l'impression options += " -T \"%s\"" % self.nom_job.replace("\"","\\\"") @@ -170,10 +151,78 @@ class fichier_impression: #options += ' -o job-sheets=crans' #page de garde de type standard #options += " -o job-billing=%.2f" % self.cout #options += ' -o job-sheets=none' - + + #Indique la présence d'un bac de sortie avec agrafeuse + # options += " -o Option20=MBMStaplerStacker -o OutputBin=StackerDown" + + options += ' -o StapleLocation=%s' % self.agrafe + + if self.transparent: + options += ' -o InputSlot=SideDeck -o MediaType=OHP' + if self.taille == 'A4': + options += ' -o pdf-paper=571x817 -o PageSize=A4' + else: + options += ' -o pdf-expand -o pdf-paper=825x1166 -o PageSize=A3' + + if self.portrait: + if self.recto_verso: + options += ' -o sides=two-sided-long-edge' + else: + options += ' -o sides=one-sided' + else: + if self.recto_verso: + options += ' -o sides=two-sided-short-edge' + else: + options += ' -o sides=one-sided' + if self.couleur: + options += ' -o CNColorMode=color' + else: + options += ' -o CNColorMode=mono' + + if self.livret: + options += ' -o CNSaddleStitch=True' + options += ' -o OutputBin=TrayC' + else: + options += ' -o OutputBin=TrayA' + + (status,rep) = commands.getstatusoutput("lpr %s -# %d %s" % (options, self.nb_copies, self.nom_fichier_pdf)) + if status != 0: + print "

status:%d rep: %s

" % (status, rep) + openlog("impression") + syslog("lpr status:%d | rep: %s" % (status, rep)) + + + def impression_laserjet(self): + """ Envoie l'impression a l'imprimante avec les parametres actuels """ + # Envoi du fichier à CUPS + options ='' + # Création de la liste d'options + # pour le nombre de copies et specifie non assemblee + #options += '-# %d -o Collate=True' % self.nb_copies + + # Pour spécifier l'imprimante + options += ' -P laserjet' + + # Pour spécifier le bac sortie + options += ' -o OutputBin=Left' + + # Pour spécifier la version du language postscript utilisé par pdftops + options += ' -o pdf-level3' + + # Pour donner le titre de l'impression + options += " -T \"%s\"" % self.nom_job.replace("\"","\\\"") + + # Pour donner le login de l'adherent + options += ' -U \"%s\"' % self.user.replace("\"","\\\"") + + # Pour demander une page de garde + #options += ' -o job-sheets=crans' #page de garde de type standard + #options += " -o job-billing=%.2f" % self.cout + #options += ' -o job-sheets=none' + #Indique la présence d'un bac de sortie avec agrafeuse options += " -o Option20=MBMStaplerStacker -o OutputBin=StackerDown" - + if self.agrafe==-1: options += ' -o StapleLocation=1diagonal' elif self.agrafe==0: @@ -186,14 +235,14 @@ class fichier_impression: options += ' -o StapleLocation=3parallel' elif self.agrafe==6: options += ' -o StapleLocation=Stitching' - + if self.transparent: options += ' -o InputSlot=Tray1 -o Media=Transparency' if self.taille == 'A4': options += ' -o pdf-paper=571x817 -o PageSize=A4' - else: + else: options += ' -o pdf-expand -o pdf-paper=825x1166 -o InputSlot=Tray3 -o HPPaperPolicy=A3 -o PageSize=A3' - + if self.portrait: if self.recto_verso: options += ' -o sides=two-sided-long-edge' @@ -240,7 +289,7 @@ class fichier_impression: def affiche_messages_html(self): """ Creait le code html correspondant a un tableau contenant le code adequate [obsolete] """ body = "" - + """ if self.imprime: body=string.join(map ((dico_message_laserjet.get),self.list_messages_importants)) @@ -249,7 +298,7 @@ class fichier_impression: 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) @@ -277,10 +326,20 @@ class fichier_impression: raise ErreurImpression("class :erreur dans enregistrement du .pdf %s: %s" % (self.nom_fichier_pdf,str(inst))) os.chmod(self.nom_fichier_pdf, 0640) os.chmod(self.nom_fichier_desc, 0640) + if self.taille == 'A3': + pdfbook = "pdfbook --paper a3paper %s" + else: + pdfbook = "pdfbook %s" + (status,rep) = commands.getstatusoutput(pdfbook % self.nom_fichier_pdf) + self.nom_fichier_pdf = "%s-book.pdf" % self.nom_fichier_pdf[:-4] + if status != 0: + print "

status:%d rep: %s

" % (status, rep) + openlog("impression") + syslog("pdfbook status:%d | rep: %s" % (status, rep)) + 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): """ Sauve les parametre du travaille d'impression dans le fichier nom_fichier_desc """ try: @@ -288,7 +347,7 @@ class fichier_impression: for key in ("erreur_critique", "nom_job", "nbr_pages", "nb_copies","taille", "recto_verso", "transparent", "couleur", "cout", - "portrait", "user", "imprime", + "portrait", "user", "imprime", "livret", "nom_fichier_pdf", "nom_fichier_desc", "code", "modif_epoch", "job_id","agrafe"): file_obj_desc.write(key+"="+str(getattr(self,key))+"\n") @@ -306,13 +365,13 @@ class fichier_impression: parse = ligne.split("=") if parse[1] == 'None': setattr(self,parse[0],None) - elif parse[0] in ("nom_job", "taille", "user", "nom_fichier_pdf", "nom_fichier_desc", "job_id"): + elif parse[0] in ("nom_job", "taille", "user", "nom_fichier_pdf", "nom_fichier_desc", "job_id", "agrafe"): #pour les attributs strings setattr(self,parse[0],parse[1]) - elif parse[0] in ("nbr_pages", "nb_copies", "imprime", "code","agrafe"): + elif parse[0] in ("nbr_pages", "nb_copies", "imprime", "code"): #pour les attributs entiers setattr(self,parse[0],int(parse[1])) - elif parse[0] in ("recto_verso", "transparent", "couleur", "portrait", "erreur_critique"): + elif parse[0] in ("recto_verso", "transparent", "couleur", "portrait", "erreur_critique", "livret"): #pour les attributs boolean setattr(self,parse[0],(parse[1] == 'True')) elif parse[0] in ("cout", "modif_epoch"): @@ -321,14 +380,14 @@ class fichier_impression: else: self.erreur_critique = True print '

ligne non parsée: %s

' % ligne - + ligne=file_obj_desc.readline()[0:-1] file_obj_desc.close() except Exception, inst : raise ErreurImpression("class : erreur dans l'ouverture du .desc %s : %s" % (self.nom_fichier_desc,repr(inst))) - # Verifie que le fichier pdf existe bien si il doit exister. + # Verifie que le fichier pdf existe bien si il doit exister. if not os.path.exists(self.nom_fichier_pdf): - if self.imprime != -3: + if self.imprime != -3: self.imprime = -4 openlog("impression") syslog("class : %s a disparu" % self.nom_fichier_pdf) @@ -340,10 +399,10 @@ class fichier_impression: def __repr__(self): """ Cree le code html correspondant a un tableau contenant les informations pertinentes """ - - dict_contraire = { 'couleur' : 'Noir et Blanc', - 'transparent' : 'Normal', - 'portrait': 'Paysage', + + dict_contraire = { 'couleur' : 'Noir et Blanc', + 'transparent' : 'Normal', + 'portrait': 'Paysage', 'recto_verso' : 'Recto', 'erreur_critique' : "Pas d'erreur" } dict_normale = { 'couleur' : 'Couleur', @@ -351,14 +410,23 @@ class fichier_impression: 'portrait': 'Portrait', 'recto_verso' : 'Recto-Verso', 'erreur_critique' : "Problème survenu" } - + dict_agrafe = { -1 : "agrafe en diagonale", 0 : "aucune agrafe", 1 : "1 agrafe parallele", 2 : "reliure 2 agrafe", 3 : "reliure 3 agrafe", - 6 : "reliure 6 agrafe" } - + 6 : "reliure 6 agrafe", + "None" : "aucune agrafe", + "TopLeft" : u"agrafe en haut à gauche", + "TopRight" : u"agrafe en haut à droite", + "BottomLeft" : u"agrafe en bas à gauche", + "BottomRight" : u"agrafe en bas à droite", + "Left" : u"deux agrafes sur le bord gauche", + "Right" : u"deux agrafes sur le bord droit", + "Top" : u"deux agrafes sur le bord supérieur", + "Bottom" : u"deux agrafes sur le bord inférieur" } + corps = "\n\n" % (self.nom_job, time.ctime(0.0)) corps += "\n
%s%s
\n\n" @@ -369,7 +437,7 @@ class fichier_impression: self.code = self.code[:-1] corps += "
\n
\n\n" - corps += '\n' % dict_agrafe[self.agrafe] + corps += '\n' % dict_agrafe[self.agrafe] for key in ("couleur", "transparent", "portrait", "recto_verso"): if getattr(self, key): @@ -388,7 +456,7 @@ class fichier_impression: # Recuperation de lobjet ldap en lecture ou ecriture de l'adherent ayant le login user # reprise du backend -# Leve l'erreur ErreurImpression si l'adherent n'existe pas +# Leve l'erreur ErreurImpression si l'adherent n'existe pas def utilisateur(user, rw): """ Renvoie l'adherent qui imprime le job * user est l'utilisateur (argument n°2 des paramètres passés au backend) @@ -421,14 +489,64 @@ def utilisateur(user, rw): ################################################################################ # Fonction auxilliaire de calcul du cout, reprise directement de l'ancien backend -def cout(fic_impr): +def cout_canon(fic_impr): """ Calcule le pourcentage de couleur sur les pages fic_impr est une instance de fichier_impression retourn : un string avec le nom de l'erreur si erreur il y a un float dans les cas de fonctionnement """ - + + # taille peut valoir A3 ou A4 + # nb_copies est le nombre de copies désirées + + if (fic_impr.recto_verso == False): + feuilles = faces # nb de pages par copies + else: + feuilles = int(faces/2.+0.5) + + if (fic_impr.taille == "A3"): + c_papier = impression.c_a3 + pages = 2*faces + else: + pages = faces + if fic_impr.transparent: + c_papier = impression.c_trans + else: + c_papier = impression.c_a4 + + if fic_impr.couleur: + c_impression = c_papier * pages + impression.c_face_couleur * pages + else: + c_impression = c_papier * pages + impression.c_face_nb * pages + + # Cout des agrafes + if fic_impr.agrafe in ["Top", "Bottom", "Left", "Right"] or fic_impr.livret: + nb_agraphes = 2 + elif fic_impr.agrafe in ["None", None]: + nb_agraphes = 0 + else: + nb_agraphes = 1 + + if pages <= 50: + c_agrafes =fic nb_agraphes * impression.c_agrafe + else: + c_agrafes = 0 + + c_total = int(fic_impr.nb_copies * ( c_impression + impression.fact + + c_agrafes ) + 0.5) # arrondi et facture + + return float(c_total)/100 + + +def cout_laserjet(fic_impr): + """ Calcule le pourcentage de couleur sur les pages + fic_impr est une instance de fichier_impression + retourn : + un string avec le nom de l'erreur si erreur il y a + un float dans les cas de fonctionnement + """ + # taille peut valoir A3 ou A4 # nb_copies est le nombre de copies désirées @@ -475,20 +593,20 @@ def cout(fic_impr): pages = int(faces/2.+0.5) if total_couleur > 0: c_total = (c_taille * pages + (impression.c_tambour_coul + - impression.c_tambour_noir) * faces + + impression.c_tambour_noir) * faces + cout_noir * total_noir + cout_coul * total_couleur) else: # Pas de couleur, malgre l'indication - c_total = (c_taille * pages + + c_total = (c_taille * pages + impression.c_tambour_noir * faces+cout_noir * total_noir) else: # Convertit les pdf en png (status, rep) = commands.getstatusoutput("nice -n 5 gs -sDEVICE=pnggray -r30 -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000 -sOutputFile=%s%%d -q %s" % (nom_png, fic_impr.nom_fichier_pdf)) if status: return "ERREUR : Fichier invalide. Aucun png n'a été créé.\n" - - #récupère la liste des fichiers + + #récupère la liste des fichiers list_filepng=os.listdir(nom_rep) - + remplissage = [0, 0] # Noir, nombre de pages for fichier in list_filepng: resultats = commands.getoutput("nice -n 5 /usr/scripts/impression/percentblack '%s/%s'" % (nom_rep, fichier)) @@ -501,21 +619,21 @@ def cout(fic_impr): pages = faces # nb de pages par copies else: pages = int(faces/2.+0.5) - c_total = (c_taille * pages + + c_total = (c_taille * pages + impression.c_tambour_noir * faces+cout_noir * total_noir) - + # Cout des agrafes if pages <= 50: c_agrafes = fic_impr.nb_copies * (impression.c_agrafe * abs(fic_impr.agrafe)) else: c_agrafes = 0 - - c_total = int(fic_impr.nb_copies * c_total + impression.fact + + + c_total = int(fic_impr.nb_copies * c_total + impression.fact + c_agrafes + 0.5) # arrondi et facture if commands.getoutput("rm -r -f %s" % nom_rep): self.list_messages_admin.append('erreur_cout') sys.stderr.write("ERREUR : Impossible d'enlever le dossier.\n") - + return float(c_total)/100
%s
%s