#!/usr/bin/env python # -*- coding: iso-8859-15 -*- # ############################################################# # .. # .... ............ ........ # . ....... . .... .. # . ... .. .. .. .. ..... . .. # .. .. ....@@@. .. . ........ . # .. . .. ..@.@@..@@. .@@@@@@@ @@@@@@. .... # .@@@@. .@@@@. .@@@@..@@.@@..@@@..@@@..@@@@.... .... # @@@@... .@@@.. @@ @@ .@..@@..@@...@@@. .@@@@@. .. # .@@@.. . @@@. @@.@@..@@.@@..@@@ @@ .@@@@@@.. ..... # ...@@@.... @@@ .@@.......... ........ ..... .. # . ..@@@@.. . .@@@@. .. ....... . ............. # . .. .... .. .. . ... .... # . . .... ............. .. ... # .. .. ... ........ ... ... # ................................ # # ############################################################# # # interface d'impression # # Copyright (c) 2006 by www.crans.org # ############################################################# import cherrypy, tempfile, shutil, os, commands, re from re import compile BOOK_REGEXP = compile('book.pdf') from crans.impression.impression_canon import FichierInvalide,SoldeInsuffisant,impression import crans.impression.digicode import crans.impression.etat_imprimante import crans.cp from threading import Thread FILE_UPLOAD_BASE_FOLDER = cherrypy.config.get('fileUpload.folder', "/var/impression/fichiers/") class FileError(Exception): pass from ClassesIntranet.ModuleBase import ModuleBase # ############################################################# # Classe d'impression en multithread # ############################################################# 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): impression(self, self.tpath_to_pdf, self.tadh) if self.tcallback: self.tcallback(self) class main(ModuleBase): def category(self): return "Services" def title(self): return "Impression" def icon(self): return "icon.png" _club = True ########################## # affichage ########################## # # template principale # def index(self, submit = None, fileList = None, newFile = None ): data = {} # on efface un eventuel objet impression existant cherrypy.session['impression'] = None if submit == "Envoyer": try: newFile.filename = re.sub("\s+", "_", newFile.filename) newFile.filename = re.sub("[^\w\._]", "", newFile.filename) self.savePDF(newFile) data['fileName'] = newFile.filename.encode('ascii','replace').replace('?','_') except FileError, e: data['openError'] = e.args[0] elif submit == "Choisir": if (fileList): data['fileName'] = fileList else: data['openError'] = "Choisissez un fichier" data['fileList'] = self.getUploadedFileListFor(cherrypy.session['uid']) try: crans.impression.etat_imprimante.etat() except Exception, e: data['Erreur_imprimante'] = str(e).replace("\"", "\\\"") data['errorMsg'] = u"Imprimante injoignable" adh = cherrypy.session['LDAP'].getProprio(cherrypy.session['uid']) if not "Bureau" in adh.droits(): data['Erreur_imprimante'] = u"Imprimante non encore mise à disposition" data['errorMsg'] = u"La nouvelle imprimante est encore en cours d'installation" if not cherrypy.config.get('crans.activate', True): data['Erreur_imprimante'] = "Config impression" data['errorMsg'] = cherrypy.config.get('crans.activate.errorMsg', u"Imprimante HS") return {'template':'impression', 'values':data, 'stylesheets':['impression.css'], 'scripts':['impression.js', 'popup.js'], } index.exposed = True ########################## # devis ########################## # # methode qui affiche la template du devis # def devis(self): if cherrypy.session.has_key('impression') and cherrypy.session['impression'] != None : return { 'template':'impression-devis', 'values': { 'devis':cherrypy.session['impression'].devisDetaille(), 'total':cherrypy.session['impression'].prix(), 'nomFichier':cherrypy.session['impression'].fileName(), }, 'standalone':True, } else: return { 'template':'impression-devis', 'values': { }, 'standalone':True, } devis.exposed = True ########################## # AJAX ########################## # # methode qui renvoie la liste des codes de l'adherent # def codeList(self): try: listeBrute = crans.impression.digicode.list_code() # liste de la forme : # [(code, age, description),...] listeBrute = [item[0] for item in listeBrute if item[2] == cherrypy.session['uid']] return {'codes': listeBrute} except Exception, e: crans.cp.log('erreur lors de la creation de la liste de codes :' + str(e), 'IMPRESSION', 1) return {'erreur':str(e)} codeList.exposed = True # # methode qui indique quel fichier utiliser # def useFile(self, fileName): try: filepath = os.path.join(os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/"), fileName) 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 FichierInvalide, e: crans.cp.log("useFile : %s (%s)" % (str(e), e.file()), 'IMPRESSION', 1) return {'erreur':str(e) } except Exception, e: crans.cp.log("useFile : %s" % str(e), 'IMPRESSION', 1) return {'erreur':str(e) } useFile.exposed = True # # methode pour changer les parametres # def changeSettings(self, copies=None, couleur=None, recto_verso=None, agrafage=None, papier=None, livret=None): if not cherrypy.session.has_key('impression') or cherrypy.session['impression'] == None : return {'nouvPrix':0.0} try: nouvPrix = cherrypy.session['impression'].changeSettings(papier=papier, couleur=couleur, agrafage=agrafage, recto_verso=recto_verso, copies=int(copies), livret=livret) crans.cp.log("changeSettings returns : %s" % str(nouvPrix)) except Exception, e: crans.cp.log("changeSettings : %s" % str(e), 'IMPRESSION', 1) return {"erreur":str(e)} return {'nouvPrix':nouvPrix} changeSettings.exposed = True # # methode pour lancer l'impression # def lancerImpression(self): try: cherrypy.session['impression'].imprime() except SoldeInsuffisant: return {"SoldeInsuffisant":1} except Exception, e: crans.cp.log("lancerImpression : %s" % str(e), 'IMPRESSION', 1) return {"erreur":str(e)} crans.cp.log("impression", 'IMPRESSION') return { 'code':str(crans.impression.digicode.gen_code(cherrypy.session['uid'])) + "#", 'code_bat_j': cherrypy.config.get('crans.impression.codes.batJ', u"Non disponible") } lancerImpression.exposed = True # # methode pour recuperer l'etat de l'imprimante # def etatImprimante(self): if not cherrypy.config.get('crans.activate', True): return {"printer_state" : u"Système down"} try: return {"printer_state" : u"\\n".join(crans.impression.etat_imprimante.etat())} except Exception, e: return {"printer_state" : 'Imprimante hors ligne'} etatImprimante.exposed = True # # methode pour le solde # def AJAXGetSolde(self): try: adh = cherrypy.session['LDAP'].getProprio(cherrypy.session['uid']) return {"solde" : adh.solde() } except Exception, e: return {"erreure" : str(e)} AJAXGetSolde.exposed = True ########################## # privees ########################## # # methode pour obtenir la liste des fichiers uploadés # def getUploadedFileListFor(self, adh): file_folder = os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/") if not os.path.isdir(file_folder): return [] liste = os.listdir(file_folder) list_pdf = [] # exclusion des fichiers qui ne sont pas des PDF for f in liste: if commands.getoutput('file -ib %s' % commands.mk2arg(file_folder, f)) == "application/pdf": if not BOOK_REGEXP.search(f): list_pdf.append(f) return list_pdf # # methode pour enregistrer un fichier # def savePDF(self, aFile): _, tempFileName = tempfile.mkstemp() f = open(tempFileName, 'w+b') size = 0 while True: data = aFile.file.read(1024 * 8) # Read blocks of 8KB at a time if not data: break f.write(data) size += len(data) f.close() if size == 0: raise FileError("Fichier vide") file_folder = os.path.join(FILE_UPLOAD_BASE_FOLDER, cherrypy.session['uid']+"/") if not os.path.isdir(file_folder): os.makedirs(file_folder) newFilePath = os.path.join(file_folder, aFile.filename.encode('ascii','replace').replace('?','_')) shutil.move(tempFileName, newFilePath) crans.cp.log("New file uploaded at : %s" % newFilePath, "IMPRESSION") return newFilePath