[lib/impression] on déplace tout dans impression
Ignore-this: f8064e9bceb8818911dcdaf73cb9f0ec darcs-hash:20090518184018-bd074-ae9530b4d2aba374d34d5a9e26e422c649d9e8db.gz
This commit is contained in:
parent
9e2cd076f5
commit
788012f862
7 changed files with 32 additions and 67 deletions
|
@ -1,51 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- encoding: iso8859-15 -*-
|
||||
#
|
||||
# bourrages.py : récupération des fichiers de logs de bourrage l'imprimante.
|
||||
#
|
||||
# Stocke les logs de l'imprimante au fur et à mesure
|
||||
#
|
||||
# Copyright (c) 2008 Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
|
||||
#
|
||||
|
||||
import urllib
|
||||
import sys
|
||||
import re
|
||||
|
||||
nom_fichier_log = "/var/log/bourrages.log"
|
||||
URL = "https://laserjet.adm.crans.org/hp/device/this.LCDispatcher?dispatch=html&cat=0&pos=3"
|
||||
|
||||
span_rex = re.compile(r'<span[^>]+class="hpPageText"[^>]*>(?P<contenu>[^<]+)</span>', re.IGNORECASE)
|
||||
|
||||
try:
|
||||
f = open(nom_fichier_log)
|
||||
except:
|
||||
sys.stderr.write("Erreur d'ouverture du fichier de logs en lecture...\n")
|
||||
lastpage = 0
|
||||
else:
|
||||
lastpage = f.readlines()[-1].strip().split()[0]
|
||||
f.close()
|
||||
|
||||
try:
|
||||
lignesimpr = urllib.urlopen(URL).readlines()
|
||||
except:
|
||||
sys.stderr.write("Problème de lecture de la page d'impression...\n")
|
||||
else:
|
||||
lignes_recup = [span_rex.match(ligne).group("contenu") for ligne in lignesimpr if span_rex.match(ligne)]
|
||||
|
||||
premier_indice = lignes_recup.index('Num\xe9ro') + 4
|
||||
erreurs = []
|
||||
|
||||
for i in xrange(premier_indice, len(lignes_recup), 4):
|
||||
erreurs.append(tuple(lignes_recup[i+1:i+4]))
|
||||
|
||||
try:
|
||||
fichier_log = open(nom_fichier_log, 'a')
|
||||
except:
|
||||
sys.stderr.write("Erreur d'ouverture du fichier de logs en écriture...\n")
|
||||
else:
|
||||
for erreur in reversed(erreurs):
|
||||
if erreur[0] > lastpage:
|
||||
fichier_log.write("%s %s %s\n" % erreur)
|
||||
|
||||
fichier_log.close()
|
|
@ -1,180 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
# #############################################################
|
||||
# ..
|
||||
# .... ............ ........
|
||||
# . ....... . .... ..
|
||||
# . ... .. .. .. .. ..... . ..
|
||||
# .. .. ....@@@. .. . ........ .
|
||||
# .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. ....
|
||||
# .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... ....
|
||||
# @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. ..
|
||||
# .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. .....
|
||||
# ...@@@.... @@@ .@@.......... ........ ..... ..
|
||||
# . ..@@@@.. . .@@@@. .. ....... . .............
|
||||
# . .. .... .. .. . ... ....
|
||||
# . . .... ............. .. ...
|
||||
# .. .. ... ........ ... ...
|
||||
# ................................
|
||||
#
|
||||
# #############################################################
|
||||
"""
|
||||
cout.py
|
||||
|
||||
Fonctions pour calculer le prix d'une impression
|
||||
(ne calcul que le prix de l'encre.
|
||||
retourne le prix pour une copie en A4)
|
||||
|
||||
Copyright (c) 2006 by www.crans.org
|
||||
"""
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
import time
|
||||
# Fin
|
||||
import sys, tempfile, os, commands, shutil, syslog, stat
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
import config
|
||||
from crans.utils import QuoteForPOSIX as escapeForShell
|
||||
def __init__():
|
||||
pass
|
||||
|
||||
# ########################################################### #
|
||||
# CONSTANTES #
|
||||
# ########################################################### #
|
||||
#
|
||||
#
|
||||
import config
|
||||
COUT_UNITE_COULEUR = config.impression.c_coul
|
||||
COUT_UNITE_NOIRE = config.impression.c_noir
|
||||
COUT_PASSAGE_TAMBOUR_NOIR = config.impression.c_tambour_noir
|
||||
COUT_PASSAGE_TAMBOUR_COULEUR = config.impression.c_tambour_coul
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
FICHIER_LOG="/var/log/log_couts/estimations"
|
||||
# Fin
|
||||
|
||||
# ########################################################### #
|
||||
# ERREURS #
|
||||
# ########################################################### #
|
||||
#
|
||||
#
|
||||
class FichierInvalide(Exception):
|
||||
"""
|
||||
Si le fichier est invalide
|
||||
"""
|
||||
def __str__(self):
|
||||
return self.args[0]
|
||||
def file(self):
|
||||
try:
|
||||
return self.args[1]
|
||||
except:
|
||||
return "n/a"
|
||||
|
||||
def try_command(cmd, tmp_rep, error_msg):
|
||||
u""" Execute a command, log output and raise exception if it fails. """
|
||||
|
||||
(status, rep) = commands.getstatusoutput(cmd)
|
||||
if status:
|
||||
syslog.openlog('impression')
|
||||
syslog.syslog(syslog.LOG_ERR, 'command failed (%d): %s' % (status, cmd))
|
||||
for l in rep.split('\n'):
|
||||
syslog.syslog(syslog.LOG_ERR, 'output: %s' % l)
|
||||
syslog.closelog()
|
||||
shutil.rmtree(tmp_rep)
|
||||
raise ValueError, error_msg % status
|
||||
|
||||
# ########################################################### #
|
||||
# PRIX #
|
||||
# ########################################################### #
|
||||
def base_prix(path_pdf_file, color=False):
|
||||
u""" Calcul le prix d'une impression couleur ou noir et blanc sur papier A4 """
|
||||
|
||||
# nom_rep seras le dossier dans tmp ou tous les fichier créé par
|
||||
# convert seront entreposé
|
||||
nom_rep = tempfile.mkdtemp(prefix='tmpimpr')
|
||||
nom_png = "%s/convert.png" % nom_rep # Nom prefixe et chemin des png créé par convert
|
||||
escaped_path_pdf_file = escapeForShell(path_pdf_file)
|
||||
escaped_path_ps_file = escapeForShell(path_pdf_file + ".ps")
|
||||
error_msg = "ERREUR %%d : Fichier invalide. Aucun %s cree."
|
||||
if color:
|
||||
error_msg += " (couleurs)"
|
||||
gs_device = "png16m"
|
||||
nb_composante = 4 # Cyan, Magenta, Jaune, Noir
|
||||
percent_program = "percentcolour"
|
||||
else:
|
||||
gs_device = "pnggray"
|
||||
nb_composante = 1 # Noir
|
||||
percent_program = "percentblack"
|
||||
|
||||
if not os.access(path_pdf_file + ".ps",os.F_OK) or \
|
||||
os.stat(path_pdf_file)[stat.ST_MTIME] > os.stat(path_pdf_file + ".ps")[stat.ST_MTIME]:
|
||||
# Convertit les pdf en ps
|
||||
try_command("nice -n 5 pdftops %s %s" % (escaped_path_pdf_file,
|
||||
escaped_path_ps_file),
|
||||
nom_rep,
|
||||
error_msg % "ps")
|
||||
|
||||
# Convertit les ps en png (il est néscessaire de passer par un ps
|
||||
# car ghostscript refuse certain pdf)
|
||||
try_command("nice -n 5 gs -sDEVICE=%s -r30 -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000 -sOutputFile=%s%%d -q %s" %
|
||||
(gs_device, nom_png, escaped_path_ps_file),
|
||||
nom_rep,
|
||||
error_msg % "png")
|
||||
|
||||
# Récupère la liste des fichiers
|
||||
list_filepng=os.listdir(nom_rep)
|
||||
# Calcule le nombre de pixel
|
||||
remplissage = [0] * (nb_composante + 1) # couleurs (N ou CMJN), nombre de pages
|
||||
for fichier in list_filepng:
|
||||
resultats = commands.getoutput("nice -n 5 /usr/scripts/impression/%s %s/%s" % (percent_program, nom_rep, fichier))
|
||||
l_resultats = resultats.split(":")
|
||||
for i in range(nb_composante):
|
||||
remplissage[i] += float(l_resultats[i])*float(l_resultats[nb_composante])
|
||||
remplissage[nb_composante] += float(l_resultats[nb_composante])
|
||||
|
||||
# suppression des fichiers temporaires
|
||||
shutil.rmtree(nom_rep)
|
||||
|
||||
total_noir = remplissage[nb_composante-1]
|
||||
total_couleur = sum(remplissage[0:nb_composante-1])
|
||||
faces = int(remplissage[nb_composante])
|
||||
|
||||
if total_couleur > 0:
|
||||
c_total = ((COUT_PASSAGE_TAMBOUR_COULEUR + COUT_PASSAGE_TAMBOUR_NOIR) * faces # passage dans les toners
|
||||
+ COUT_UNITE_NOIRE * total_noir # cout encre noire
|
||||
+ COUT_UNITE_COULEUR * total_couleur) # cout encre couleur
|
||||
else: # Pas de couleur, malgre l'indication
|
||||
c_total = (COUT_PASSAGE_TAMBOUR_NOIR * faces # passage dans les toners
|
||||
+ COUT_UNITE_NOIRE * total_noir) # cout encre noire
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
fichier_log_est=open(FICHIER_LOG,"a")
|
||||
fichier_log_est.write("%d %d %3d %10.3f %10.3f %s\n" % (time.time(), color, faces, total_noir, total_couleur, path_pdf_file) )
|
||||
fichier_log_est.close()
|
||||
# Fin
|
||||
|
||||
return (float(c_total)/100, faces)
|
||||
|
||||
# ########################################################### #
|
||||
# PRIX COULEURS #
|
||||
# ########################################################### #
|
||||
#
|
||||
# Clacul le prix d'une impression couleur
|
||||
#
|
||||
def base_prix_couleurs(path_pdf_file):
|
||||
"""
|
||||
Clacul le prix d'une impression couleur sur papier A4 pour le fichier path_pdf_file
|
||||
"""
|
||||
return base_prix(path_pdf_file, color=True)
|
||||
|
||||
# ########################################################### #
|
||||
# PRIX N&B #
|
||||
# ########################################################### #
|
||||
#
|
||||
# calcul le prix d'une impression en noir et blanc
|
||||
#
|
||||
def base_prix_nb(path_pdf_file):
|
||||
"""
|
||||
Clacul le prix d'une impression noire et blanc sur papier A4 pour le fichier path_pdf_file
|
||||
"""
|
||||
return base_prix(path_pdf_file, color=False)
|
|
@ -1,157 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# #############################################################
|
||||
# ..
|
||||
# .... ............ ........
|
||||
# . ....... . .... ..
|
||||
# . ... .. .. .. .. ..... . ..
|
||||
# .. .. ....@@@. .. . ........ .
|
||||
# .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. ....
|
||||
# .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... ....
|
||||
# @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. ..
|
||||
# .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. .....
|
||||
# ...@@@.... @@@ .@@.......... ........ ..... ..
|
||||
# . ..@@@@.. . .@@@@. .. ....... . .............
|
||||
# . .. .... .. .. . ... ....
|
||||
# . . .... ............. .. ...
|
||||
# .. .. ... ........ ... ...
|
||||
# ................................
|
||||
#
|
||||
# #############################################################
|
||||
"""
|
||||
fake_digicode.py
|
||||
|
||||
Fonctions pour controler le digicode du 4@J (simulation)
|
||||
|
||||
Copyright (c) 2006 by www.crans.org
|
||||
"""
|
||||
import sys, time, tempfile, os, commands, string, random
|
||||
import crans.utils.files
|
||||
# #############################################################
|
||||
# CONSTANTES
|
||||
# #############################################################
|
||||
CODES_SERVER = "zamok"
|
||||
CODES_DIR = "/var/impression/codes/"
|
||||
|
||||
|
||||
# #############################################################
|
||||
# EXCEPTIONS
|
||||
# #############################################################
|
||||
def CodeAlreadyExists(Exception):
|
||||
pass
|
||||
|
||||
# #############################################################
|
||||
# FONCTIONS
|
||||
# #############################################################
|
||||
# test pour voir si on est bien sur la bonne machine
|
||||
import socket
|
||||
if socket.gethostname() != CODES_SERVER:
|
||||
CODES_DIR = tempfile.mkdtemp(prefix='fake_digicode')
|
||||
FAKE_DIR = True
|
||||
#raise EnvironmentError, "La manipulation des codes pour le digicode n'est possible que sur %s" % CODES_SERVER
|
||||
else:
|
||||
FAKE_DIR = False
|
||||
|
||||
def __del__():
|
||||
if FAKE_DIR:
|
||||
os.rmdir(CODES_DIR)
|
||||
|
||||
|
||||
def __init__():
|
||||
pass
|
||||
# ###############################
|
||||
# save_code
|
||||
# ###############################
|
||||
# enregistre le codes avec "monString" dans le fichier
|
||||
#
|
||||
def save_code(code, monString=""):
|
||||
"""enregistre le codes avec "monString" dans le fichier """
|
||||
code = str(code)
|
||||
if os.path.exists( os.path.join( CODES_DIR, code ) ):
|
||||
raise CodeAlreadyExists
|
||||
# On enregistre le fichier avec le code pour numero
|
||||
codefichier = open( os.path.join( CODES_DIR, code ) , 'w')
|
||||
codefichier.write(monString)
|
||||
codefichier.write("\n")
|
||||
codefichier.close()
|
||||
return code
|
||||
|
||||
|
||||
# ###############################
|
||||
# gen_code
|
||||
# ###############################
|
||||
# genere un code aleatoire
|
||||
# et l'enregistre
|
||||
#
|
||||
def gen_code(user_name):
|
||||
""" Genere un code au hasard l'enregistre avec user_name dans le fichier"""
|
||||
# Generation du code et ecriture du code
|
||||
rand=random.Random()
|
||||
# Graine automatique avec le temps
|
||||
rand.seed()
|
||||
|
||||
for i in range(1000):
|
||||
# On genere un code
|
||||
code = rand.randint(100000, 999999)
|
||||
# Si le code est libre, on sort de la boucle
|
||||
if not os.path.exists( os.path.join( CODES_DIR, str( code ) ) ):
|
||||
break
|
||||
|
||||
else:
|
||||
# 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" )
|
||||
try:
|
||||
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")
|
||||
return
|
||||
save_code(code, user_name)
|
||||
return code
|
||||
|
||||
|
||||
# ###############################
|
||||
# list_code
|
||||
# ###############################
|
||||
# liste les codes et leur age en secondes
|
||||
#
|
||||
def list_code():
|
||||
"""
|
||||
Renvoie la liste des codes existants.
|
||||
La liste est sous la forme [(code, age (en sec), contenu du fichier),...]
|
||||
"""
|
||||
files = os.listdir(CODES_DIR)
|
||||
code_list = []
|
||||
for aCode in files:
|
||||
age = crans.utils.files.ageOfFile(os.path.join(CODES_DIR, aCode ) )
|
||||
content = read_code_file(aCode)
|
||||
code_list.append((aCode, age, content ) )
|
||||
return code_list
|
||||
|
||||
def read_code_file(code):
|
||||
"""
|
||||
Lis le fichier correspondant à code.
|
||||
Renvoie le contenu du fichier.
|
||||
"""
|
||||
myfile = open(os.path.join(CODES_DIR, code ), 'r')
|
||||
lineStr = myfile.readline()
|
||||
myfile.close()
|
||||
return lineStr.replace('\n','')
|
||||
|
||||
|
||||
# ###############################
|
||||
# menage
|
||||
# ###############################
|
||||
# supprime les codes vieux de plus de 24h
|
||||
#
|
||||
def menage():
|
||||
"""
|
||||
Supprime les codes vieux de plus de 24h
|
||||
"""
|
||||
fileList = os.listdir(CODES_DIR)
|
||||
for aFile in fileList:
|
||||
aFilePath = os.path.join(CODES_DIR, aFile)
|
||||
if os.path.isfile(aFilePath):
|
||||
if crans.utils.files.fileIsOlderThan(aFilePath, days=1):
|
||||
os.remove(aFilePath)
|
|
@ -1,83 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: iso-8859-15 -*-
|
||||
"""
|
||||
etat_imprimante.py
|
||||
|
||||
Récupère, filtre et formate l'état actuel de l'imprimante
|
||||
|
||||
Copyright (c) 2006 by www.crans.org
|
||||
|
||||
"""
|
||||
|
||||
import sys
|
||||
sys.path.append("/usr/scripts/gestion")
|
||||
|
||||
from hptools import snmp
|
||||
from config import impression
|
||||
|
||||
class ErreurCommunication(Exception):
|
||||
"""Si une erreur est survenue lors de la communication avec l'imprimante"""
|
||||
pass
|
||||
|
||||
def etat():
|
||||
exec ("etat_%s()" % impression.imprimante)
|
||||
|
||||
def etat_canon():
|
||||
try:
|
||||
liste_msg = []
|
||||
comm = snmp(host="imprimante.adm.crans.org", version="1", community="public")
|
||||
for oid in [".hrPrinterStatus.1", ".hrPrinterDetectedErrorState.1"]:
|
||||
msg = comm.get_string(oid)
|
||||
if msg: liste_msg.append(msg)
|
||||
except Exception,err:
|
||||
liste_msg.append("[%s]" % unicode(err))
|
||||
return liste_msg
|
||||
|
||||
def etat_laserjet():
|
||||
""" Renvoie une liste des differents ecrans actuels du display de l'imprimante """
|
||||
_dico = {
|
||||
u"READY": u"Prête",
|
||||
u"PrÁt": u"Prêt",
|
||||
u"Pr menus, appuy \x1e": u"",
|
||||
u"Powersave activÅ": u"En veille",
|
||||
u"Verification": u"Vérification imprimante",
|
||||
u"imprimante": u"",
|
||||
u"PrÅchauffage": u"Préchauffage",
|
||||
u"Traitement de la": u"Impression en cours",
|
||||
u"tÀche du bac 4": u"",
|
||||
u"COMMANDER CARTOUCHE": u"",
|
||||
u"COMMANDER KIT NETTOY": u"",
|
||||
u"COMMANDER FOURNIT.": u"",
|
||||
u"CYAN": u"",
|
||||
u"MAGENTA": u"",
|
||||
u"JAUNE": u"",
|
||||
u"NOIR": u"",
|
||||
u'Pr aide appuyer \x1f': u"",
|
||||
u'13.12.12 BOURRAGE DS':u"Bourrage papier",
|
||||
u'ACCESSOIRE GAUCHE':u"",
|
||||
u'13.03.00 BOURRAGE':u"Bourrage papier",
|
||||
u'DS TRAPPE SUP DROITE':u"",
|
||||
u'COMM TAMB. NOIR':u"",
|
||||
u'PAGES REST.': u"",
|
||||
}
|
||||
|
||||
liste_oid = ["mib-2.43.16.5.1.2.1.1","mib-2.43.16.5.1.2.1.2","mib-2.43.16.5.1.2.1.3","mib-2.43.16.5.1.2.1.4","mib-2.43.16.5.1.2.1.5"]
|
||||
try:
|
||||
comm = snmp(host="laserjet.adm.crans.org",version="1",community="public")
|
||||
liste_msg = []
|
||||
for oid in liste_oid:
|
||||
msg = comm.get_string(oid).decode("ISO-8859-1")
|
||||
for k in _dico.keys():
|
||||
if k in msg: msg = _dico[k]
|
||||
if msg: liste_msg.append(msg)
|
||||
except Exception,err:
|
||||
raise ErreurCommunication, str(err)
|
||||
return liste_msg
|
||||
|
||||
def enregistre(filename="/usr/script/impression/imprimante.etat"):
|
||||
l = etat()
|
||||
fichier = open(filename,'w')
|
||||
for x in l:
|
||||
fichier.write(x+"\n")
|
||||
fichier.close()
|
||||
|
|
@ -1,453 +0,0 @@
|
|||
#!/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 as config_impression
|
||||
from commands import getstatusoutput
|
||||
from hptools import snmp
|
||||
from crans.utils import QuoteForPOSIX as escapeForShell
|
||||
import crans.utils.logs
|
||||
|
||||
# ######################################################## #
|
||||
# CONSTANTES #
|
||||
# ######################################################## #
|
||||
|
||||
LOG = crans.utils.logs.getFileLogger('impression')
|
||||
COMM = 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
|
||||
|
||||
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" }
|
||||
|
||||
# ######################################################## #
|
||||
# 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
|
||||
_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._settings['papier'] == 'A3':
|
||||
newfile = self._fichier[:-4] + '-a3book.pdf'
|
||||
pdfbook = "pdfbook --paper a3paper %%s --outfile %s" % newfile
|
||||
else:
|
||||
newfile = self._fichier[:-4] + '-book.pdf'
|
||||
pdfbook = "pdfbook %%s --outfile %s" % newfile
|
||||
(status, rep) = getstatusoutput(pdfbook % self._fichier)
|
||||
LOG.info("%s | rep: %s" % ((pdfbook % self._fichier), rep))
|
||||
self._fichier = newfile
|
||||
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
|
||||
elif couleur == "True":
|
||||
self._settings['couleur'] = True
|
||||
elif couleur == "False":
|
||||
self._settings['couleur'] = False
|
||||
|
||||
try:
|
||||
if int(kw['copies']) >= 1:
|
||||
self._settings['copies'] = int(kw['copies'])
|
||||
except:
|
||||
pass
|
||||
|
||||
recto_verso = kw.get('recto_verso', None)
|
||||
if recto_verso == "True": recto_verso = True
|
||||
if recto_verso == "False": recto_verso = False
|
||||
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 == "True": livret = True
|
||||
if livret == "False": livret = False
|
||||
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
|
||||
"""
|
||||
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._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)
|
||||
faces = 2 * feuilles
|
||||
elif self._settings['recto_verso']:
|
||||
feuilles = int(faces/2.+0.5)
|
||||
else:
|
||||
feuilles = faces
|
||||
|
||||
if (self._settings['papier'] == "A3"):
|
||||
c_papier = config_impression.c_a3
|
||||
pages = 2*faces
|
||||
else:
|
||||
pages = faces
|
||||
if self._settings['papier'] == "A4tr":
|
||||
c_papier = config_impression.c_trans
|
||||
else:
|
||||
c_papier = config_impression.c_a4
|
||||
|
||||
if self._settings['couleur']:
|
||||
c_impression = c_papier * feuilles + config_impression.c_face_couleur * pages
|
||||
else:
|
||||
c_impression = c_papier * feuilles + config_impression.c_face_nb * pages
|
||||
|
||||
# Cout des agrafes
|
||||
if self._settings['agrafage'] in ["Top", "Bottom", "Left", "Right"] or self._settings['livret']:
|
||||
nb_agrafes = 2
|
||||
elif self._settings['agrafage'] in ["None", None]:
|
||||
nb_agrafes = 0
|
||||
else:
|
||||
nb_agrafes = 1
|
||||
|
||||
if feuilles <= 50:
|
||||
c_agrafes = nb_agrafes * config_impression.c_agrafe
|
||||
else:
|
||||
c_agrafes = 0
|
||||
|
||||
c_total = int(self._settings['copies'] * ( c_impression +
|
||||
c_agrafes ) + 0.5) # arrondi et facture
|
||||
|
||||
self._prix= float(c_total)/100
|
||||
return self._prix
|
||||
|
||||
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._fichier.split('/')[-1].replace("\"","\\\"")
|
||||
|
||||
# Pour donner le login de l'adherent
|
||||
options += ' -U \"%s\"' % self._adh
|
||||
|
||||
# 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['papier'] == 'A4tr':
|
||||
options += ' -o InputSlot=SideDeck -o MediaType=OHP'
|
||||
options += ' -o pdf-paper=571x817 -o PageSize=A4'
|
||||
elif self._settings['papier'] == '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 Collate=StapleCollate -o StapleLocation=%s' % self._settings['agrafage']
|
||||
|
||||
cmd = "lpr %s -# %d %s" % (options, self._settings['copies'],
|
||||
self._fichier)
|
||||
(status, rep) = getstatusoutput(cmd)
|
||||
LOG.info("printing: %s" % 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)
|
||||
|
||||
|
|
@ -1,525 +0,0 @@
|
|||
#!/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
|
||||
sys.path.append('/usr/scripts/gestion')
|
||||
import config
|
||||
import cout
|
||||
from crans.utils import QuoteForPOSIX as escapeForShell
|
||||
import crans.utils.logs
|
||||
log = crans.utils.logs.getFileLogger('impression')
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
import time
|
||||
import hptools
|
||||
comm = hptools.snmp(host="imprimante.adm.crans.org",version="1",community="public")
|
||||
# Fin
|
||||
|
||||
# ######################################################## #
|
||||
# CONSTANTES #
|
||||
# ######################################################## #
|
||||
#
|
||||
#
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
FICHIER_LOG="/var/log/log_couts/impressions"
|
||||
|
||||
SNMP_CAR_B_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.18.1.0"
|
||||
SNMP_CAR_C_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.18.2.0"
|
||||
SNMP_CAR_M_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.18.3.0"
|
||||
SNMP_CAR_Y_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.18.4.0"
|
||||
SNMP_CAR_B_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.1.0"
|
||||
SNMP_CAR_C_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.2.0"
|
||||
SNMP_CAR_M_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.3.0"
|
||||
SNMP_CAR_Y_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.4.0"
|
||||
SNMP_TAM_B_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.37.5.0"
|
||||
SNMP_TAM_C_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.37.6.0"
|
||||
SNMP_TAM_M_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.37.7.0"
|
||||
SNMP_TAM_Y_PC="enterprises.11.2.3.9.4.2.1.4.1.10.1.1.37.8.0"
|
||||
SNMP_TAM_B_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.5.0"
|
||||
SNMP_TAM_C_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.6.0"
|
||||
SNMP_TAM_M_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.7.0"
|
||||
SNMP_TAM_Y_PR="enterprises.11.2.3.9.4.2.1.4.1.10.5.1.1.8.0"
|
||||
# Fin
|
||||
DECOUVERT_AUTHORISE = config.impression.decouvert
|
||||
|
||||
PAS_D_AGRAPHES = "pasdagraphes"
|
||||
AGRAPHE_DIAGONALE = "agraphediagonale"
|
||||
UNE_AGRAPHE = "uneagraphe"
|
||||
DEUX_AGRAPHE = "Deuxagraphes"
|
||||
TROIS_AGRAPHE = "troisAgraphes"
|
||||
STITCHING = "stitching"
|
||||
AGRAPHES_VALEURS_POSSIBLES = [PAS_D_AGRAPHES, AGRAPHE_DIAGONALE, UNE_AGRAPHE, DEUX_AGRAPHE, TROIS_AGRAPHE, STITCHING]
|
||||
NB_AGRAPHES = {
|
||||
PAS_D_AGRAPHES: 0,
|
||||
AGRAPHE_DIAGONALE: 1,
|
||||
UNE_AGRAPHE: 1,
|
||||
DEUX_AGRAPHE: 2,
|
||||
TROIS_AGRAPHE: 3,
|
||||
STITCHING: 6,
|
||||
}
|
||||
|
||||
PAPIER_A4 = "A4"
|
||||
PAPIER_A4_TRANSPARENT = "A4tr"
|
||||
PAPIER_A3 = "A3"
|
||||
PAPIER_VALEURS_POSSIBLES = [PAPIER_A4, PAPIER_A4_TRANSPARENT]
|
||||
|
||||
IMPRESSION_COULEUR = "couleurs"
|
||||
IMPRESSION_NB = "nb"
|
||||
COULEURS_VALEURS_POSSIBLES = [IMPRESSION_COULEUR, IMPRESSION_NB]
|
||||
|
||||
IMPRESSION_RECTO = "recto"
|
||||
IMPRESSION_RECTO_VERSO = "rectoverso"
|
||||
IMPRESSION_RECTO_VERSO_SHORT = "rectoversoshort"
|
||||
DISPOSITION_VALEURS_POSSIBLES = [IMPRESSION_RECTO, IMPRESSION_RECTO_VERSO, IMPRESSION_RECTO_VERSO_SHORT]
|
||||
|
||||
PU_AGRAPHE = config.impression.c_agrafe / 100.
|
||||
PU_FEUILLE = {
|
||||
PAPIER_A4: config.impression.c_a4/100,
|
||||
PAPIER_A4_TRANSPARENT: config.impression.c_trans/100,
|
||||
PAPIER_A3: config.impression.c_a3/1000,
|
||||
}
|
||||
|
||||
|
||||
LABELS = {
|
||||
PAS_D_AGRAPHES: "pas d'agrafe",
|
||||
AGRAPHE_DIAGONALE: 'une agrafe en diagonale',
|
||||
UNE_AGRAPHE: 'une agrafe en haut',
|
||||
DEUX_AGRAPHE: '2 agrafes',
|
||||
TROIS_AGRAPHE: '3 agrafes',
|
||||
STITCHING: 'stitching (6 agrafes)',
|
||||
|
||||
PAPIER_A4: "A4",
|
||||
PAPIER_A4_TRANSPARENT: "A4 transparent",
|
||||
PAPIER_A3: "A3",
|
||||
|
||||
IMPRESSION_COULEUR: "impression couleurs",
|
||||
IMPRESSION_NB: "impression noir et blanc",
|
||||
|
||||
IMPRESSION_RECTO: "impression recto",
|
||||
IMPRESSION_RECTO_VERSO: "impression recto-verso",
|
||||
IMPRESSION_RECTO_VERSO_SHORT: "impression recto-verso",
|
||||
}
|
||||
|
||||
LPR_OPTIONS = {
|
||||
PAS_D_AGRAPHES: ' -o StapleLocation=None',
|
||||
AGRAPHE_DIAGONALE: ' -o StapleLocation=1diagonal',
|
||||
UNE_AGRAPHE: ' -o StapleLocation=1parallel',
|
||||
DEUX_AGRAPHE: ' -o StapleLocation=2parallel',
|
||||
TROIS_AGRAPHE: ' -o StapleLocation=3parallel',
|
||||
STITCHING: ' -o StapleLocation=Stitching',
|
||||
|
||||
PAPIER_A4: ' -o InputSlot=Tray4 -o pdf-paper=571x817 -o PageSize=A4',
|
||||
PAPIER_A4_TRANSPARENT: ' -o PageSize=A4 -o InputSlot=Tray1 -o Media=Transparency',
|
||||
PAPIER_A3: ' -o pdf-expand -o pdf-paper=825x1166 -o InputSlot=Tray3 -o HPPaperPolicy=A3 -o PageSize=A3',
|
||||
|
||||
IMPRESSION_COULEUR: ' -o HPColorasGray=False',
|
||||
IMPRESSION_NB: ' -o HPColorasGray=True',
|
||||
|
||||
IMPRESSION_RECTO: ' -o sides=one-sided',
|
||||
IMPRESSION_RECTO_VERSO: ' -o sides=two-sided-long-edge',
|
||||
IMPRESSION_RECTO_VERSO_SHORT: ' -o sides=two-sided-short-edge',
|
||||
}
|
||||
|
||||
|
||||
# ######################################################## #
|
||||
# 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 = {
|
||||
'agraphes': PAS_D_AGRAPHES,
|
||||
'papier': PAPIER_A4,
|
||||
'couleurs': IMPRESSION_COULEUR,
|
||||
'recto_verso': IMPRESSION_RECTO_VERSO,
|
||||
'copies':1,
|
||||
}
|
||||
# le prix de l'impression
|
||||
_prix = 0.0
|
||||
_nb_pages = 0
|
||||
_details_devis = []
|
||||
# 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
|
||||
# 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)
|
||||
self._adh = adh
|
||||
# calcule le prix de l'encre tout de suite
|
||||
try:
|
||||
self._base_prix_couleurs, self._nb_pages = cout.base_prix_couleurs(path_to_pdf)
|
||||
self._base_prix_nb, self._nb_pages = cout.base_prix_nb(path_to_pdf)
|
||||
except ValueError, e:
|
||||
raise FichierInvalide, ("PDF bugge, Analyse impossible : %s." % e, path_to_pdf)
|
||||
except Exception, e:
|
||||
raise Exception, "Erreur dans le calcul du cout : %s " % str(e)
|
||||
self._calcule_prix()
|
||||
|
||||
|
||||
def changeSettings(self, agraphes = None, papier = None, couleurs = None, recto_verso=None, copies=None):
|
||||
"""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
|
||||
if (couleurs):
|
||||
if couleurs not in COULEURS_VALEURS_POSSIBLES:
|
||||
raise SettingsError, "Valeur de couleurs inconnue : %s" % str(couleurs)
|
||||
self._settings['couleurs'] = couleurs
|
||||
if (papier):
|
||||
if papier not in PAPIER_VALEURS_POSSIBLES:
|
||||
raise SettingsError, "Valeur de papier inconnue : %s" % str(papier)
|
||||
self._settings['papier'] = papier
|
||||
if (copies):
|
||||
try:
|
||||
int(copies)
|
||||
if int(copies) <1:
|
||||
raise Exception
|
||||
except:
|
||||
raise SettingsError, "Valeur incorecte pour le nombre de copies"
|
||||
self._settings['copies'] = copies
|
||||
if (recto_verso):
|
||||
if recto_verso not in DISPOSITION_VALEURS_POSSIBLES:
|
||||
raise SettingsError, "Valeur inconnue : %s" % str(recto_verso)
|
||||
if papier==PAPIER_A4_TRANSPARENT and (recto_verso==IMPRESSION_RECTO_VERSO or recto_verso==IMPRESSION_RECTO_VERSO_SHORT):
|
||||
raise SettingsError, "Pas de recto-verso sur du papier transparent !!"
|
||||
self._settings['recto_verso'] = recto_verso
|
||||
if (agraphes):
|
||||
if agraphes not in AGRAPHES_VALEURS_POSSIBLES:
|
||||
raise SettingsError, "Valeur inconnue pour agrafes : %s" % str(agrafes)
|
||||
if papier!=PAPIER_A4 and agraphes!=PAS_D_AGRAPHES:
|
||||
raise SettingsError, "Le type de papier choisi ne permet pas d'utiliser l'agrafeuse"
|
||||
if recto_verso==IMPRESSION_RECTO_VERSO or recto_verso==IMPRESSION_RECTO_VERSO_SHORT:
|
||||
if self._nb_pages > 100 and agraphes!=PAS_D_AGRAPHES:
|
||||
raise SettingsError, "Le document est trop volumineux pour utiliser l'agrafeuse"
|
||||
else:
|
||||
if self._nb_pages > 50 and agraphes!=PAS_D_AGRAPHES:
|
||||
raise SettingsError, "Le document est trop volumineux pour utiliser l'agrafeuse"
|
||||
self._settings['agraphes'] = agraphes
|
||||
return self._calcule_prix()
|
||||
|
||||
def printSettings(self):
|
||||
"""printSettings()
|
||||
|
||||
Affiche les paramètres courrants sur la sortie standard
|
||||
"""
|
||||
print "Type impression: " + LABELS[self._settings['couleurs']]
|
||||
print "Agraphes: " + LABELS[self._settings['agraphes']]
|
||||
print "Papier: " + LABELS[self._settings['papier']]
|
||||
print "Disposition: " + LABELS[self._settings['recto_verso']]
|
||||
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'accs au fichier pdf.
|
||||
"""
|
||||
return self._fichier
|
||||
|
||||
|
||||
def devisDetaille(self):
|
||||
"""devisDetaille()
|
||||
|
||||
renvoie un disctionnaire contenant le devis (intitulé, PU., quantité) pour tous les éléments de l'impression
|
||||
(papier, encre, agrafes...)
|
||||
"""
|
||||
return self._details_devis
|
||||
|
||||
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 printDevis(self):
|
||||
"""printDevis()
|
||||
|
||||
Affiche le devis sur la sortie standard.
|
||||
"""
|
||||
print "titre \t\t | p.u. \t quandtite \t total"
|
||||
for anItem in self._details_devis:
|
||||
print anItem[0][:5] + "\t\t | " + str(anItem[1]) + "\t\t | " + str(anItem[2]) + "\t\t | " + str(anItem[1]*anItem[2])
|
||||
|
||||
def _calcule_prix(self):
|
||||
prix = 0
|
||||
facture = []
|
||||
|
||||
# clacul du prix total pour l'encre
|
||||
if (self._settings['couleurs'] == IMPRESSION_COULEUR):
|
||||
base_prix_encre = self._base_prix_couleurs
|
||||
else:
|
||||
base_prix_encre = self._base_prix_nb
|
||||
|
||||
if (self._settings['papier'] == PAPIER_A3):
|
||||
pu_encre = base_prix_encre * 2
|
||||
else:
|
||||
pu_encre = base_prix_encre
|
||||
facture.append((
|
||||
LABELS[self._settings['couleurs']] + ' sur papier ' + LABELS[self._settings['papier']],
|
||||
pu_encre, self._settings['copies']))
|
||||
prix+= self._settings['copies'] * pu_encre
|
||||
|
||||
#calcul du prix des feuilles
|
||||
if (self._settings['recto_verso'] == IMPRESSION_RECTO_VERSO) or (self._settings['recto_verso'] == IMPRESSION_RECTO_VERSO_SHORT):
|
||||
nbfeuilles = int(self._nb_pages/2.+0.5) * self._settings['copies']
|
||||
else:
|
||||
nbfeuilles = self._nb_pages * self._settings['copies']
|
||||
facture.append((
|
||||
'feuilles ' + LABELS[self._settings['papier']],
|
||||
PU_FEUILLE[self._settings['papier']],
|
||||
nbfeuilles))
|
||||
prix+= PU_FEUILLE[self._settings['papier']] * nbfeuilles
|
||||
|
||||
|
||||
# calcul prix des Agraphes
|
||||
facture.append((
|
||||
'agrafes',
|
||||
PU_AGRAPHE,
|
||||
NB_AGRAPHES[self._settings['agraphes']] * self._settings['copies']))
|
||||
prix+= NB_AGRAPHES[self._settings['agraphes']] * self._settings['copies'] * PU_AGRAPHE
|
||||
|
||||
# arrondit
|
||||
prix = int((prix*100) + 0.5)/100.
|
||||
self._prix = prix
|
||||
self._details_devis = facture
|
||||
return prix
|
||||
|
||||
|
||||
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._adh != None):
|
||||
log.info('Impression [%s] : %s' % (self._adh, self._fichier))
|
||||
else:
|
||||
log.info("Impression : %s" % self._fichier)
|
||||
# Envoi du fichier a CUPS
|
||||
options =''
|
||||
# Creation de la liste d'options
|
||||
# pour le nombre de copies et specifie non assemblee
|
||||
#options += '-# %d -o Collate=True' % self.nb_copies
|
||||
|
||||
# Pour specifier l'imprimante
|
||||
options += ' -P laserjet'
|
||||
|
||||
#Indique la presence d'un bac de sortie avec agrafeuse
|
||||
options += " -o Option20=MBMStaplerStacker -o OutputBin=StackerStapled"
|
||||
|
||||
# Pour specifier la version du language postscript utilise par pdftops
|
||||
options += ' -o pdf-level3'
|
||||
|
||||
# Pour donner le titre de l'impression
|
||||
options += " -T '%s'" % self._fichier
|
||||
|
||||
# Pour donner le login de l'adherent
|
||||
if (self._adh != None):
|
||||
options += ' -U %s' % self._adh
|
||||
|
||||
# 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'
|
||||
|
||||
|
||||
# option agrafes
|
||||
options += LPR_OPTIONS[self._settings['agraphes']]
|
||||
|
||||
# option papier
|
||||
options += LPR_OPTIONS[self._settings['papier']]
|
||||
|
||||
# option disposition
|
||||
options += LPR_OPTIONS[self._settings['recto_verso']]
|
||||
|
||||
# options couleurs
|
||||
options += LPR_OPTIONS[self._settings['couleurs']]
|
||||
|
||||
# Début : Ajout log pour réestimer les coûts
|
||||
# Commandes snmp recuperation des etats
|
||||
val_car_b_pc=int(comm.get(SNMP_CAR_B_PC))
|
||||
val_car_c_pc=int(comm.get(SNMP_CAR_C_PC))
|
||||
val_car_m_pc=int(comm.get(SNMP_CAR_M_PC))
|
||||
val_car_y_pc=int(comm.get(SNMP_CAR_Y_PC))
|
||||
val_car_b_pr=int(comm.get(SNMP_CAR_B_PR))
|
||||
val_car_c_pr=int(comm.get(SNMP_CAR_C_PR))
|
||||
val_car_m_pr=int(comm.get(SNMP_CAR_M_PR))
|
||||
val_car_y_pr=int(comm.get(SNMP_CAR_Y_PR))
|
||||
val_tam_b_pc=int(comm.get(SNMP_TAM_B_PC))
|
||||
val_tam_c_pc=int(comm.get(SNMP_TAM_C_PC))
|
||||
val_tam_m_pc=int(comm.get(SNMP_TAM_M_PC))
|
||||
val_tam_y_pc=int(comm.get(SNMP_TAM_Y_PC))
|
||||
val_tam_b_pr=int(comm.get(SNMP_TAM_B_PR))
|
||||
val_tam_c_pr=int(comm.get(SNMP_TAM_C_PR))
|
||||
val_tam_m_pr=int(comm.get(SNMP_TAM_M_PR))
|
||||
val_tam_y_pr=int(comm.get(SNMP_TAM_Y_PR))
|
||||
|
||||
fichier_log_imp=open(FICHIER_LOG,"a")
|
||||
fichier_log_imp.write("%d %3d %2s : %3d %3d %3d %3d : %5d %5d %5d %5d : %3d %3d %3d %3d : %5d %5d %5d %5d : %s\n" %
|
||||
(time.time(),self._settings['copies'],self._settings['papier'],
|
||||
val_car_b_pc,
|
||||
val_car_c_pc,
|
||||
val_car_m_pc,
|
||||
val_car_y_pc,
|
||||
val_car_b_pr,
|
||||
val_car_c_pr,
|
||||
val_car_m_pr,
|
||||
val_car_y_pr,
|
||||
val_tam_b_pc,
|
||||
val_tam_c_pc,
|
||||
Val_tam_m_pc,
|
||||
val_tam_y_pc,
|
||||
val_tam_b_pr,
|
||||
val_tam_c_pr,
|
||||
val_tam_m_pr,
|
||||
val_tam_y_pr,
|
||||
self._fichier) )
|
||||
fichier_log_imp.close()
|
||||
# Fin
|
||||
|
||||
liste_nom_fichier_pdf=(' '+escapeForShell( self._fichier ) )*self._settings['copies']
|
||||
import commands
|
||||
#(status,rep) = commands.getstatusoutput("lpr %s %s" % (options, self.nom_fichier_pdf))
|
||||
(status,rep) = commands.getstatusoutput("lpr %s %s" % (options, liste_nom_fichier_pdf))
|
||||
if status != 0:
|
||||
log.error("erreur impression")
|
||||
log.error("lpr status:%d | rep: %s" % (status, rep))
|
||||
raise PrintError, "lpr %s %s \n status:%d rep: %s" % (options, liste_nom_fichier_pdf, status, rep)
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue