Commit 5f5b8326 authored by Antoine Durand-Gasselin's avatar Antoine Durand-Gasselin
Browse files

[lib/impression] impression_canon

Ignore-this: 511660bb2b8806739014ed150276994f

darcs-hash:20090515135635-bd074-867c19053c701920543f6b8a1fc8d70c92d5ba01.gz
parent 5eba5336
......@@ -25,7 +25,7 @@
# #############################################################
import cherrypy, tempfile, shutil, os, commands, re
import crans.impression
from crans.impression.impression_canon import FichierInvalide,SoldeInsuffisant,impression
import crans.impression.digicode
import crans.impression.etat_imprimante
import crans.cp
......@@ -40,14 +40,14 @@ from ClassesIntranet.ModuleBase import ModuleBase
# #############################################################
# Classe d'impression en multithread
# #############################################################
class threadedImpression(Thread, crans.impression.impression):
class threadedImpression(Thread, impression):
def __init__(self, path_to_pdf, adh = None, callback = None):
self.tpath_to_pdf = path_to_pdf
self.tadh = adh
Thread.__init__(self)
def run(self):
crans.impression.impression.__init__(self, self.tpath_to_pdf, self.tadh)
impression(self, self.tpath_to_pdf, self.tadh)
if self.tcallback:
self.tcallback(self)
......@@ -158,10 +158,10 @@ class main(ModuleBase):
def useFile(self, fileName):
try:
filepath = os.path.join(os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/"), fileName)
cherrypy.session['impression'] = crans.impression.impression(filepath, cherrypy.session['uid'])
cherrypy.session['impression'] = impression(filepath, cherrypy.session['uid'])
crans.cp.log("useFile returns: %s" % str( cherrypy.session['impression'].pages() ))
return {'nbPages': cherrypy.session['impression'].pages()}
except crans.impression.FichierInvalide, e:
except FichierInvalide, e:
crans.cp.log("useFile : %s (%s)" % (str(e), e.file()), 'IMPRESSION', 1)
return {'erreur':str(e) }
except Exception, e:
......@@ -190,7 +190,7 @@ class main(ModuleBase):
def lancerImpression(self):
try:
cherrypy.session['impression'].imprime()
except crans.impression.SoldeInsuffisant:
except SoldeInsuffisant:
return {"SoldeInsuffisant":1}
except Exception, e:
crans.cp.log("lancerImpression : %s" % str(e), 'IMPRESSION', 1)
......
......@@ -26,7 +26,7 @@ def etat_canon():
try:
liste_msg = []
comm = hptools.snmp(host="imprimante.adm.crans.org", version="1", community="public")
for i in [".hrPrinterStatus.1"; ".hrPrinterDetectedErrorState.1"]:
for oid in [".hrPrinterStatus.1", ".hrPrinterDetectedErrorState.1"]:
msg = comm.get_string(oid)
msg = dico.get(msg, msg)
if msg: liste_msg.append(msg)
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# #############################################################
# ..
# .... ............ ........
# . ....... . .... ..
# . ... .. .. .. .. ..... . ..
# .. .. ....@@@. .. . ........ .
# .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. ....
# .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... ....
# @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. ..
# .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. .....
# ...@@@.... @@@ .@@.......... ........ ..... ..
# . ..@@@@.. . .@@@@. .. ....... . .............
# . .. .... .. .. . ... ....
# . . .... ............. .. ...
# .. .. ... ........ ... ...
# ................................
#
# #############################################################
# __init__.py
#
# Classe impression
#
# Copyright (c) 2006 by www.crans.org
# #############################################################
"""
Classe pour gérer l'envoie de pdf à l'imprimante.
Calcule le coût des options d'impression.
"""
__version__ = '1'
import sys, syslog, os.path, time
sys.path.append('/usr/scripts/gestion')
from config import impression
from hptools import snmp
from crans.utils import QuoteForPOSIX as escapeForShell
import crans.utils.logs
# ######################################################## #
# CONSTANTES #
# ######################################################## #
LOG = crans.utils.logs.getFileLogger('impression')
COMM = hptools.snmp(host="imprimante.adm.crans.org",version="1",community="public")
FICHIER_LOG="/var/log/log_couts/impressions"
SNMP_CAPA_B = "mib-2.43.11.1.1.8.1.1"
SNMP_CAPA_C = "mib-2.43.11.1.1.8.1.2"
SNMP_CAPA_M = "mib-2.43.11.1.1.8.1.3"
SNMP_CAPA_Y = "mib-2.43.11.1.1.8.1.4"
SNMP_TON_B = "mib-2.43.11.1.1.9.1.1"
SNMP_TON_C = "mib-2.43.11.1.1.9.1.2"
SNMP_TON_M = "mib-2.43.11.1.1.9.1.3"
SNMP_TON_Y = "mib-2.43.11.1.1.9.1.4"
SNMP_BAC1 = "mib-2.43.8.2.1.10.1.2"
SNMP_BAC2 = "mib-2.43.8.2.1.10.1.3"
SNMP_BAC3 = "mib-2.43.8.2.1.10.1.4"
SNMP_BAC4 = "mib-2.43.8.2.1.10.1.5"
SNMP_ETAT = "hrPrinterStatus.1"
SNMP_ERR = "hrPrinterDetectedErrorState.1"
DECOUVERT_AUTHORISE = config.impression.decouvert
# ######################################################## #
# ERREURS #
# ######################################################## #
#
class FichierInvalide(Exception):
"""
Exception renvoyée lorsqu'un fichier ne passe pas.
utilisée avec deux arguments : une chaîne décrivant l'erreur et une chaîne avec le nom du fichier
"""
def __str__(self):
"""
Description de l'erreur.
"""
return self.args[0]
def file(self):
"""
Nom du fichier qui pose problème
"""
try:
return self.args[1]
except:
return "n/a"
class SoldeInsuffisant(Exception):
"""
Solde insuffisant pour l'impression demandée
"""
pass
class PrintError(Exception):
"""
Erreur lors de l'impression
"""
pass
class SettingsError(Exception):
"""
Erreur de paramètres.
"""
pass
# ######################################################## #
# CLASSE IMPRESSION #
# ######################################################## #
#
#
class impression:
"""impression
Un objet impression correspond à un fichier pdf et un adhérent.
"""
# fichier (chemin)
_fichier = ""
# adherent (instance)
_adh = None
# paramettres
_settings = {
'agrafage': 'None',
'papier': 'A4'
'couleur': False,
'recto_verso': False,
'livret': False,
'copies': 1,
'portrait': True,
}
# le prix de l'impression
_prix = 0.0
_nb_pages = 0
# le cout de base encre pour une impression en couleurs/n&b
# (prix pour papier A4)
_base_prix_nb = 0.0
_base_prix_couleurs = 0.0
def __init__(self, path_to_pdf, adh = None):
"""impression(path_to_pdf [, adh])
Crée un nouvel objet impression à partir du fichier pdf pointé
par path_to_pdf. Si adh ext donné, il peut être soit une
instance d'un objet adhérent de crans_ldap soit le login de
l'adhérent. Lève l'exception FichierInvalide si le fichier
n'existe pas ou si ce n'est pas un pdf.
"""
self._fichier = path_to_pdf
self._adh = adh
# on verifie que le fichier existe
if not os.path.isfile(path_to_pdf):
raise FichierInvalide, ("Fichier introuvable", path_to_pdf)
if not open(path_to_pdf).read().startswith("%PDF"):
raise FichierInvalide, ("Le fichier ne semble pas etre un PDF", path_to_pdf)
# on compte les pages
self._pages = int(os.popen("pdfinfo %s | grep Pages " % (self._fichier)).readline().split()[1])
# calcule le prix de l'encre tout de suite
self._calcule_prix()
def _pdfbook(self):
if self.taille == 'A3':
pdfbook = "pdfbook --paper a3paper %s"
else:
pdfbook = "pdfbook %s"
(status, rep) = commands.getstatusoutput(pdfbook % self._fichier)
self._fichier = "%s-book.pdf" % self.n_fichier[:-4]
if status != 0:
log.error("pdfbook status:%d | rep: %s" % (status, rep))
raise FichierInvalide, ("pdfbook: Impossible de convertir le fichier",
self._fichier)
def changeSettings(self, **kw):
"""changeSettings([keyword=value])
Change les parametres de l'impression, recalcule et renvoie le nouveau prix.
Lève une exceotion SettingError si les paramètres son invalides.
"""
#recalcule et renvoie le prix
couleur = kw.get('couleur', None)
if couleur in [True, False]:
self._settings['couleur'] = couleur
try:
if int(kw['copies']) >= 1:
self._settings['copies'] = int(kw['copies'])
except:
pass
recto_verso = kw.get('recto_verso', None)
if recto_verso in [True, False]:
self._settings['recto_verso'] = recto_verso
papier = kw.get('papier', None)
if papier in ['A4', 'A3', 'A4tr']:
self._settings['papier'] = papier
if papier == 'A4tr':
self._settings['recto_verso'] = False
self._settings['agrafage'] = 'None'
agrafage = kw.get('agrafage', None)
if agrafage in ["None", "TopLeft", "Top", "TopRight",
"Left", "Right", "BottomLeft", "BottomRight"]:
self._settings['agrafage'] = agrafage
livret = kw.get('livret', None)
if livret in [True, False]:
self._settings['livret'] = livret
self._settings['portrait'] = not(livret)
if livret:
self._settings['recto_verso'] = True
self._settings['agrafage'] = 'None'
if self._settings['papier'] == 'A4tr':
self._settings['papier'] = 'A4'
return self._calcule_prix()
def printSettings(self):
"""printSettings()
Affiche les paramètres courrants sur la sortie standard
"""
dict_agrafage = { "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" }
dict_papier = { 'A4' : "Papier A4 ordinaire",
'A3' : "Papier A3 ordinaire",
'A4tr' : "Transparent A4" }
if self._settings['couleur']:
print "Type impression: Couleur"
else:
print "Type impression: Noir et blanc"
print "Papier: " + dict_papier[self._settings['papier']]
if self._settings['livret']:
print u"Agrafage: Livret (piqûre à cheval)"
else:
print "Agrafage: " + dict_agrafage[self._settings['agrafage']]
if self._setting['recto_verso']:
print "Disposition: recto/verso"
else:
print "Disposition: recto"
print "Copies: " + str(self._settings['copies'])
def prix(self):
"""prix()
Renvoie le prix courrant de l'impression
"""
return self._prix
def fileName(self):
"""fileName()
renvoie le nom du fichier pdf (exemple : monPdf.pdf)
"""
return os.path.basename(self._fichier)
def filePath(self):
"""filePath()
renvoie le chemin d'accès au fichier pdf.
"""
return self._fichier
def pages(self):
"""pages()
renvoie le nombre de pages du document (page au sens nombre de
faces à imprimer et non le nombre de feuilles)
"""
return self._nb_pages
def imprime(self):
"""imprime()
imprime le document pdf. débite l'adhérent si adhérent il y a.
(si il a été indiqué à l'initialisation de l'objet)
"""
# debite l'adhérent si adherent il y a
if (self._adh != None):
adh = self._get_adh(self._adh)
if (self._prix > (adh.solde() - DECOUVERT_AUTHORISE)):
raise SoldeInsuffisant
adh.solde(-self._prix, "impression: " + self._fichier)
adh.save()
del adh
# imprime le document
self._exec_imprime()
def _calcule_prix(self):
faces = self._pages
if self._settings['livret']:
feuilles = int(faces+3/4)
elif self._settings['recto_verso']:
feuilles = int(faces/2.+0.5)
else:
feuilles = faces
if (self._settings['papier'] == "A3"):
c_papier = impression.c_a3
pages = 2*faces
else:
pages = faces
if self._settings['papier'] == "A4tr":
c_papier = impression.c_trans
else:
c_papier = impression.c_a4
if self._settings['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 self._settings['agrafe'] in ["Top", "Bottom", "Left", "Right"] or self._settings['livret']:
nb_agrafes = 2
elif self._settings['agrafe'] in ["None", None]:
nb_agrafes = 0
else:
nb_agrafes = 1
if feuilles <= 50:
c_agrafes = nb_agrafes * impression.c_agrafe
else:
c_agrafes = 0
c_total = int(self._settings['copies'] * ( c_impression + impression.fact +
c_agrafes ) + 0.5) # arrondi et facture
return float(c_total)/100
def _get_adh(self, adh):
if type(adh) == str:
import sys
sys.path.append("/usr/scripts/gestion/")
#from ldap_crans_test import crans_ldap
from ldap_crans import CransLdap
adh = CransLdap().getProprio(adh, 'w')
return adh
## ################################# ##
## fonction qui imprime pour de vrai ##
## ################################# ##
##
def _exec_imprime(self):
""" Envoie l'impression a l'imprimante avec les parametres actuels """
if self._settings['livret']:
self._pdfbook()
if (self._adh != None):
log.info('Impression [%s] : %s' % (self._adh, self._fichier))
else:
log.info("Impression : %s" % self._fichier)
# 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 canon_irc3580'
# 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._settings['paper'] == 'A4tr':
options += ' -o InputSlot=SideDeck -o MediaType=OHP'
options += ' -o pdf-paper=571x817 -o PageSize=A4'
elif self._settings['paper'] == 'A4':
options += ' -o pdf-paper=571x817 -o PageSize=A4'
else:
options += ' -o pdf-expand -o pdf-paper=825x1166 -o PageSize=A3'
if self._settings['portrait']:
if self._settings['recto_verso']:
options += ' -o sides=two-sided-long-edge'
else:
options += ' -o sides=one-sided'
else:
if self._settings['recto_verso']:
options += ' -o sides=two-sided-short-edge'
else:
options += ' -o sides=one-sided'
if self._settings['couleur']:
options += ' -o CNColorMode=color'
else:
options += ' -o CNColorMode=mono'
if self._settings['livret']:
options += ' -o CNSaddleStitch=True'
options += ' -o OutputBin=TrayC'
else:
options += ' -o OutputBin=TrayA'
options += ' -o StapleLocation=%s' % self._settings['agrafage']
cmd = "lpr %s -# %d %s" % (options, self._settings['copies'],
self._fichier)
(status, rep) = commands.getstatusoutput(cmd)
if status != 0:
log.error("erreur impression")
log.error("lpr status:%d | rep: %s" % (status, rep))
raise PrintError, "%s \n status:%d rep: %s" % (cmp, status, rep)
......@@ -156,8 +156,8 @@ LPR_OPTIONS = {
class FichierInvalide(Exception):
"""
Exception renvoyée lorsqu'un fichier ne passe pas.
utilisée avec deux arguments : une chaîndéÃécrivant l'erreur et une chÃine avec le nom du fichier
Exception renvoyée lorsqu'un fichier ne passe pas.
utilisée avec deux arguments : une chaîne décrivant l'erreur et une chne avec le nom du fichier
"""
def __str__(self):
"""
......@@ -196,7 +196,7 @@ class SettingsError(Exception):
class impression:
"""impression
Un objet impression correspond ˆ un fichier pdf et un adhŽrent.
Un objet impression correspond à un fichier pdf et un adhérent.
"""
# fichier (chemin)
_fichier = ""
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment