Commit 452be816 authored by Daniel STAN's avatar Daniel STAN

[impression] menage

parent 7af07b09
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Fonctions utilises par les backend devis et laserjet
# crit par Benoit avec la contribution de Brice et Fred
# Licence : GNU General Public Licence, version 2
import sys, tempfile
import couts
sys.path.append('/usr/scripts/gestion')
from ldap_crans import crans_ldap
def preliminaires(arguments, description):
""" Verifie le nombre d'arguments passes.
Si pas d'arguments : print description,
si le bon nombre d'argument : retourne le fichier nettoye,
sinon sort sans stopper.
"""
# \x1B est le caractere d'chappement chap.
UEL="\x1B%-12345X"
if len(arguments) == 1 :
print description
sys.exit(0)
if len(arguments) not in (6, 7) :
sys.stderr.write("ERROR: %s job-id user title copies options [file]\n" % arguments[0])
sys.exit(0) # On n'arrte pas l'imprimante
if arguments[-1].find('/') != -1 :
try:
# Fichier fourni
entree = open(arguments[-1])
except:
# Des fois les options contiennent un / ...
entree = sys.stdin
else :
# Lecture sur entre standard
entree = sys.stdin
## On nettoie le fichier :
fic = tempfile.NamedTemporaryFile()
ligne = entree.readline()
# On enlve les options qui nous gnent et on rend le fichier propre
while ligne:
# On ne choisit pas le bac de sortie
if ligne.find('%%BeginFeature: *OutputBin') != -1:
while ligne.find('%%EndFeature') == -1:
ligne = entree.readline()
ligne = entree.readline()
# On ne choisit pas le bac d'entree sauf si transparent
if ligne.find('%%BeginFeature: *InputSlot') != -1:
if ligne.find('Transparency') == -1:
while ligne.find('%%EndFeature') == -1:
ligne = entree.readline()
ligne = entree.readline()
# On limine les instructions PJL
# Normalement on n'est pas oblig de retirer le UEL
# mais c'est plus propre
while ligne.startswith('@PJL') or ligne.startswith(UEL):
ligne = entree.readline()
fic.write(ligne)
ligne = entree.readline()
fic.flush()
return fic
def utilisateur(user, rw):
""" Renvoie l'adherent qui imprime le job
* user est l'utilisateur (argument n2 des paramtres passs au backend)
* rw vaut 1 si on veut modifier le compte LDAP de l'adhrent,
0 dans le cas contraire
"""
# Impression en local avec les certificats (possible pour le groupe adm)
if user=="root":
sys.stderr.write("ERROR: Utilisateur root pass en paramtre.\n")
sys.exit(0) # On conclue l'impression
# Rcupration de l'adhrent
try:
base = crans_ldap()
if rw == 0 :
res=base.search("login=%s"%user)['adherent']
else:
res=base.search("login=%s"%user,'w')['adherent']
except:
sys.stderr.write("ERROR: Erreur : Base LDAP non joignable\n")
sys.exit(0) # On arrete l'impression
# Si on ne trouve rien :
if len(res) != 1 :
sys.stderr.write("ERROR: Erreur : adhrent %s non trouv\n" % user)
sys.exit(0) # On conclue l'impression sans stopper l'imprimante
adherent = res[0]
sys.stderr.write("DEBUG: Adherent %s recupere.\n" % adherent.Nom())
return adherent
def calcul_prix(nom_fic):
"""Calcul le prix du fichier nom_fic"""
## #Temporaire pour debugage
## fs=open(nom_fic,'r')
## fd=open('/tmp/benoit_Routard','w')
## while 1:
## txt=fs.readline()
## if txt == '':
## break
## fd.write(txt)
## fs.close()
## fd.close()
# Calcul du cout de l'impression :
try:
prix = couts.cout(nom_fic)
except:
sys.stderr.write("ERROR: Erreur : Impossible de calculer le couts de %s." % nom_fic)
sys.exit(1) # On arrete l'imprimante
if prix.erreur == "Taille invalide":
sys.stderr.write("ERROR: Erreur de taille de papier (%s).\n" % prix.taille)
elif prix.erreur:
sys.stderr.write("ERROR: Erreur du calcul du prix : %s.\n" % prix.erreur)
else:
sys.stderr.write("DEBUG: Prix calcule : %s euros (%s, %s).\n" % (prix.c_total_euros, prix.taille, prix.recto_v) )
return prix
def send_email(sender, recipient, subject, body):
"""Send an email.
All arguments should be Unicode strings (plain ASCII works as well).
Only the real name part of sender and recipient addresses may contain
non-ASCII characters.
The email will be properly MIME encoded and delivered though SMTP to
localhost port 25. This is easy to change if you want something different.
The charset of the email will be the first one out of US-ASCII, ISO-8859-1
and UTF-8 that can represent all the characters occurring in the email.
"""
from smtplib import SMTP
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import parseaddr, formataddr
# Header class is smart enough to try US-ASCII, then the charset we
# provide, then fall back to UTF-8.
header_charset = 'ISO-8859-1'
# We must choose the body charset manually
for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8':
try:
body.encode(body_charset)
except UnicodeError:
pass
else:
break
# Split real name (which is optional) and email address parts
sender_name, sender_addr = parseaddr(sender)
recipient_name, recipient_addr = parseaddr(recipient)
# We must always pass Unicode strings to Header, otherwise it will
# use RFC 2047 encoding even on plain ASCII strings.
sender_name = str(Header(unicode(sender_name), header_charset))
recipient_name = str(Header(unicode(recipient_name), header_charset))
# Make sure email addresses do not contain non-ASCII characters
sender_addr = sender_addr.encode('ascii')
recipient_addr = recipient_addr.encode('ascii')
# Create the message ('plain' stands for Content-Type: text/plain)
msg = MIMEText(body.encode(body_charset), 'plain', body_charset)
msg['From'] = formataddr((sender_name, sender_addr))
msg['To'] = formataddr((recipient_name, recipient_addr))
msg['Subject'] = Header(unicode(subject), header_charset)
# Send the message via SMTP to localhost:25
smtp = SMTP("localhost")
smtp.sendmail(sender, recipient, msg.as_string())
smtp.quit()
import crans.impression
import crans.impression.digicode
import crans.ldap_crans_test
import os, sys
# ######################################################## #
# COMMAND LINE OPTION #
# ######################################################## #
#
#
OPTIONS_AGRAFES = {
0: crans.impression.PAS_D_AGRAPHES,
-1: crans.impression.AGRAPHE_DIAGONALE,
1: crans.impression.UNE_AGRAPHE,
2: crans.impression.DEUX_AGRAPHE,
3: crans.impression.TROIS_AGRAPHE,
6: crans.impression.STITCHING,
}
OPTIONS_NOIRETBLANC = {
False: crans.impression.IMPRESSION_COULEUR,
True: crans.impression.IMPRESSION_NB
}
OPTIONS_RECTOVERSO = {
False: crans.impression.IMPRESSION_RECTO,
True: crans.impression.IMPRESSION_RECTO_VERSO
}
from optparse import OptionParser
parser = OptionParser("usage: %prog [options] pdf")
parser.add_option("-a", "--agrafes",
action="store", type='int', dest="agrafes", default=0,
help="Choix du mode d'agrafes (%s)" % ", ".join(["%s: %s" % (val, crans.impression.LABELS[OPTIONS_AGRAFES[val]]) for val in OPTIONS_AGRAFES.keys()]))
parser.add_option("-p", "--papier",
action="store", type="string", dest="typepapier",
help="Choix papier (%s)" % ", ".join(["%s: %s" % (val, crans.impression.LABELS[val]) for val in crans.impression.PAPIER_VALEURS_POSSIBLES]))
parser.add_option("-r", "--recto-verso",
action="store_true", dest="rectoverso", default=False,
help="Impression recto-verso")
parser.add_option("-c", "--copies",
action="store", type="int", dest="copies",
help="Nombre de copies")
parser.add_option("-n", "--noir-et-blanc",
action="store_true", dest="noiretblanc", default=False,
help="impression en noir et blanc")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error("Nombre d'arguments incorect")
PDF_PATH = os.path.join(os.getcwd(), args[0])
USER_LOGIN = os.getlogin()
print("Analyse du fichier...")
lpr = crans.impression.impression(PDF_PATH, USER_LOGIN)
try:
lpr.changeSettings(agraphes=OPTIONS_AGRAFES[options.agrafes],
papier=options.typepapier,
couleurs=OPTIONS_NOIRETBLANC[options.noiretblanc],
recto_verso = OPTIONS_RECTOVERSO[options.rectoverso],
copies=options.copies )
except crans.impression.SettingsError, e:
print "erreur: %s" % e
sys.exit(1)
lpr.printSettings()
print "Prix total : %s Euros" % str(lpr.prix())
#! /usr/bin/env python
# -*- coding: ISO-8859-15 -*-
#
# PyKota - Print Quotas for CUPS and LPRng
#
# (c) 2003-2004 Jerome Alet <alet@librelogiciel.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
# $Id: ipp.py,v 1.2 2004/12/03 20:29:33 jalet Exp $
#
# $Log: ipp.py,v $
# Revision 1.2 2004/12/03 20:29:33 jalet
# ipp.py can now be run in standalone mode for testing purposes
#
# Revision 1.1 2004/11/06 22:35:58 jalet
# Added a miniparser for IPP messages (RFC 2910). The job-originating-host-name
# retrieval is now fiable, unless the CUPS developpers change something...
#
#
import sys
from struct import unpack
OPERATION_ATTRIBUTES_TAG = 0x01
JOB_ATTRIBUTES_TAG = 0x02
END_OF_ATTRIBUTES_TAG = 0x03
PRINTER_ATTRIBUTES_TAG = 0x04
UNSUPPORTED_ATTRIBUTES_TAG = 0x05
class PyKotaIPPError(Exception):
"""An exception for PyKota IPP related stuff."""
def __init__(self, message = ""):
self.message = message
Exception.__init__(self, message)
def __repr__(self):
return self.message
__str__ = __repr__
class IPPMessage :
"""A class for IPP message files."""
def __init__(self, data) :
"""Initializes an IPP Message object."""
self.data = data
self._attributes = {}
self.curname = None
self.tags = [ None ] * 256 # by default all tags reserved
# Delimiter tags
self.tags[0x01] = "operation-attributes-tag"
self.tags[0x02] = "job-attributes-tag"
self.tags[0x03] = "end-of-attributes-tag"
self.tags[0x04] = "printer-attributes-tag"
self.tags[0x05] = "unsupported-attributes-tag"
# out of band values
self.tags[0x10] = "unsupported"
self.tags[0x11] = "reserved-for-future-default"
self.tags[0x12] = "unknown"
self.tags[0x13] = "no-value"
# integer values
self.tags[0x20] = "generic-integer"
self.tags[0x21] = "integer"
self.tags[0x22] = "boolean"
self.tags[0x23] = "enum"
# octetString
self.tags[0x30] = "octetString-with-an-unspecified-format"
self.tags[0x31] = "dateTime"
self.tags[0x32] = "resolution"
self.tags[0x33] = "rangeOfInteger"
self.tags[0x34] = "reserved-for-collection"
self.tags[0x35] = "textWithLanguage"
self.tags[0x36] = "nameWithLanguage"
# character strings
self.tags[0x20] = "generic-character-string"
self.tags[0x41] = "textWithoutLanguage"
self.tags[0x42] = "nameWithoutLanguage"
# self.tags[0x43] = "reserved"
self.tags[0x44] = "keyword"
self.tags[0x45] = "uri"
self.tags[0x46] = "uriScheme"
self.tags[0x47] = "charset"
self.tags[0x48] = "naturalLanguage"
self.tags[0x49] = "mimeMediaType"
# now parses the IPP message
self.parse()
def __getattr__(self, attrname) :
"""Allows self.attributes to return the attributes names."""
if attrname == "attributes" :
keys = self._attributes.keys()
keys.sort()
return keys
raise AttributeError, attrname
def __getitem__(self, ippattrname) :
"""Fakes a dictionnary d['key'] notation."""
value = self._attributes.get(ippattrname)
if value is not None :
if len(value) == 1 :
value = value[0]
return value
get = __getitem__
def parseTag(self) :
"""Extracts information from an IPP tag."""
pos = self.position
valuetag = self.tags[ord(self.data[pos])]
# print valuetag.get("name")
pos += 1
posend = pos2 = pos + 2
namelength = unpack(">H", self.data[pos:pos2])[0]
if not namelength :
name = self.curname
else :
posend += namelength
self.curname = name = self.data[pos2:posend]
pos2 = posend + 2
valuelength = unpack(">H", self.data[posend:pos2])[0]
posend = pos2 + valuelength
value = self.data[pos2:posend]
oldval = self._attributes.setdefault(name, [])
oldval.append(value)
return posend - self.position
def operation_attributes_tag(self) :
"""Indicates that the parser enters into an operation-attributes-tag group."""
return self.parseTag()
def job_attributes_tag(self) :
"""Indicates that the parser enters into an operation-attributes-tag group."""
return self.parseTag()
def printer_attributes_tag(self) :
"""Indicates that the parser enters into an operation-attributes-tag group."""
return self.parseTag()
def parse(self) :
"""Parses an IPP Message.
NB : Only a subset of RFC2910 is implemented.
We are only interested in textual informations for now anyway.
"""
self.version = "%s.%s" % (ord(self.data[0]), ord(self.data[1]))
self.operation_id = "0x%04x" % unpack(">H", self.data[2:4])[0]
self.request_id = "0x%08x" % unpack(">I", self.data[4:8])[0]
self.position = 8
try :
tag = ord(self.data[self.position])
while tag != END_OF_ATTRIBUTES_TAG :
self.position += 1
name = self.tags[tag]
if name is not None :
func = getattr(self, name.replace("-", "_"), None)
if func is not None :
self.position += func()
if ord(self.data[self.position]) > UNSUPPORTED_ATTRIBUTES_TAG :
self.position -= 1
continue
tag = ord(self.data[self.position])
except IndexError :
raise PyKotaIPPError, "Unexpected end of IPP message."
if __name__ == "__main__" :
if len(sys.argv) < 2 :
print "usage : python ipp.py /var/spool/cups/c00005 (for example)\n"
else :
infile = open(sys.argv[1])
message = IPPMessage(infile.read())
infile.close()
print "Client user name : %s" % message["job-originating-user-name"]
#!/usr/bin/python
# -*- encoding: utf-8 -*-
# canon_wrapper.py
# Authors: Daniel STAN <dstan@crans.org>
# Antoine Durand-Gasselin <adg@crans.org>
# License: GPLv3
import requests #pip install requests
# See:
......
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