
Ignore-this: 423bf67a1a0f91b21069d43912ae8e82 darcs-hash:20121114154759-8ef3c-99555d07e68f54e6a2ddd5fa77a4698ceef0b554.gz
168 lines
6.2 KiB
Python
Executable file
168 lines
6.2 KiB
Python
Executable file
#! /usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
print_status.py
|
|
|
|
Récupère le statut des dernières impressions auprès de l'imprimante et envoie un
|
|
mail à l'intérressé quand son impression est sortie, ou envoie un message aux
|
|
imprimeurs si l'impression semble avoir échoué.
|
|
|
|
Auteur : Sylvain Boilard <boilard@crans.org>
|
|
License : BSD 2 clauses.
|
|
|
|
"""
|
|
|
|
import sys, os
|
|
sys.path.append("/usr/scripts/gestion")
|
|
|
|
import time
|
|
import httplib2
|
|
import re
|
|
import smtplib
|
|
from ldap_crans import crans_ldap
|
|
|
|
last_print_filename = "/var/run/print_status/last_print.txt"
|
|
printer_host ="imprimante.adm.crans.org"
|
|
smtp_server= "smtp.crans.org"
|
|
error_send_to= u"impression@crans.org"
|
|
ok_mail=u"""Content-Type: text/plain; charset=utf-8
|
|
Content-Disposition: inline
|
|
Content-Transfer-Encoding: quoted-printable
|
|
From: %s
|
|
To: %s
|
|
Subject: [Impression] Impression de "%s" terminée.
|
|
|
|
Bonjour %s,
|
|
|
|
Le fichier "%s" que tu as envoyé %s
|
|
a été imprimé. Tu peux venir le récupérer au local impression, au 4ème étage du
|
|
bâtiment J, muni du code secret qui t'a été donné lorsque tu as envoyé ton
|
|
document. Si tu as oublié ce code, ou pour tout autre problème lié au service
|
|
d'impression, tu peux contacter les imprimeurs à l'adresse %s .
|
|
|
|
Bonne journée,
|
|
|
|
--
|
|
Les imprimeurs du Cr@ns
|
|
"""
|
|
error_mail=u"""Content-Transfer-Encoding: quoted-printable
|
|
Content-Type: text/plain; charset=utf-8
|
|
Content-Disposition: inline
|
|
From: %s
|
|
To: %s
|
|
Subject: [Impression][print_status.py] Impression potentiellement échouée.
|
|
|
|
Bonjour,
|
|
|
|
Il semble y avoir eu un problème avec l'impression du fichier
|
|
"%s" (tâche n°%s) de %s (uid=%s),
|
|
lancée %s.
|
|
Le statut de la tâche est "%s".
|
|
|
|
Aucun autre mail ne sera envoyé à ce sujet. Si nécéssaire, veuillez tenir
|
|
l'intéressé au courant aux adresses suivantes :
|
|
|
|
%s
|
|
|
|
Bonne journée,
|
|
|
|
--
|
|
print_status.py
|
|
"""
|
|
|
|
litMonths = [u"Janvier", u"Février", u"Mars", u"Avril", u"Mai", u"Juin", u"Juillet", u"Août", u"Septembre", u"Octobre", u"Novembre", u"Décembre"]
|
|
|
|
def getMSE():
|
|
"""Retourne le nombre de millisecondes depuis le 1 Janvier 1970 sous forme d'une chaîne de caractères."""
|
|
return str(int(time.time()*1000.))
|
|
|
|
def buildDate(date):
|
|
"""Retourne la date et l'heure passée en argument après l'avoir mise en forme."""
|
|
dm, year, hms = date.split(' ')
|
|
day, month = dm.split('/')
|
|
hour, minute, _ = hms.split(':')
|
|
return u"le " + day + u" " + litMonths[int(month) - 1] + u" " + year + u" à " + hour + u":" + minute
|
|
|
|
def sendMail(from_addr, to_addrs, mail_content):
|
|
"""Wrapper pour smtplib.sendmail(). Permet d'attendre un peu en cas d'erreur temporaire (typiquement, si on essaie d'envoyer trop de mails à la minute)."""
|
|
conn = smtplib.SMTP(smtp_server)
|
|
try:
|
|
conn.sendmail(from_addr, to_addrs, mail_content)
|
|
except smtplib.SMTPSenderRefused as (code, _, _):
|
|
if code == 450:
|
|
time.sleep(65)
|
|
conn.sendmail(from_addr, to_addrs, mail_content)
|
|
else:
|
|
raise
|
|
conn.quit()
|
|
|
|
http = httplib2.Http()
|
|
|
|
# On récupère la liste des tâches. Pour faire la requête, on doit récupérer un cookie de session.
|
|
headers, _ = http.request("https://" + printer_host + "/twelcome.cgi?CorePGTAG=0&Dummy=" + getMSE())
|
|
_, content = http.request("https://" + printer_host + "/pprint.csv?Flag=Csv_Data&LogType=0&Dummy=" + getMSE(), 'GET', headers={'Cookie': headers['set-cookie']})
|
|
task_list = content.split('\n')
|
|
# On enlève les entêtes et les deux lignes vides à la fin de la liste.
|
|
task_list.pop(0)
|
|
task_list.pop()
|
|
task_list.pop()
|
|
|
|
# On récupère la dernière tâche à avoir été traitée la dernière fois quel le script a été lancé.
|
|
# Si le fichier n'existe pas, on le crée en y mettant la première tâche parmi celles que l'on vient de récupérer, et on s'arrête là.
|
|
try:
|
|
last_file = open(last_print_filename, "r")
|
|
last = last_file.read()
|
|
last_file.close()
|
|
except:
|
|
last_file = open(last_print_filename, "w")
|
|
last_file.write(task_list[0].split(',')[0])
|
|
last_file.close()
|
|
exit(0)
|
|
|
|
db = crans_ldap()
|
|
match_doc_name = re.compile(r"/[^/]*\.pdf")
|
|
|
|
# On parcoure les tâches récupérées et on ne garde que celles qui n'ont pas déja été traitées.
|
|
# Au passage, on inverse leur ordre pour traiter la plus ancienne en premier.
|
|
# Ainsi, si le script plante, on n'envoie pas un mail aux adhérents à chaque fois que le cron le relance.
|
|
tasks_to_treat = []
|
|
for item in task_list:
|
|
if item.split(',', 1)[0] == last:
|
|
break
|
|
tasks_to_treat.append(item)
|
|
tasks_to_treat.reverse()
|
|
|
|
for item in tasks_to_treat:
|
|
fields = item.split(',', 6)
|
|
if fields[3].strip('"') == "root":
|
|
result = fields[1].strip('"')
|
|
taskID, user, _ = fields[2].strip('"').split(':',2)
|
|
user = user.split('@').pop() # On récupère le nom du club si besoin.
|
|
date = buildDate(fields[5])
|
|
match_taskID = re.compile(r"impression\(%s\)" % taskID)
|
|
db_query = db.search("uid=" + user)
|
|
if db_query['adherent']:
|
|
target = db_query['adherent'][0]
|
|
full_name = target.prenom() + u" " + target.nom()
|
|
send_to = [ target.mail() + u"@crans.org" ]
|
|
else:
|
|
target = db_query['club'][0]
|
|
full_name = u"Club " + target.nom()
|
|
send_to = map(lambda aid : db.search("aid=" + aid)['adherent'][0].mail() + u"@crans.org", target.imprimeurs())
|
|
historique = target.historique()
|
|
historique.reverse() # Ce qu'on cherche a des chances d'être récent et donc d'être à la fin de l'historique.
|
|
for hist_line in historique:
|
|
if match_taskID.search(hist_line):
|
|
filename = match_doc_name.search(hist_line).group()[1:]
|
|
break
|
|
if result == "OK":
|
|
mail_content = ok_mail % (error_send_to, u", ".join(send_to), filename, full_name, filename, date, error_send_to)
|
|
sendMail(error_send_to, send_to, mail_content.encode("utf-8"))
|
|
else:
|
|
mail_content = error_mail % (error_send_to, error_send_to, filename, taskID, full_name, user, date, result, u"\n".join(send_to))
|
|
sendMail(error_send_to, error_send_to, mail_content.encode("utf-8"))
|
|
# On met à jour le numéro de la dernière tâche traitée.
|
|
last_file = open(last_print_filename, "w")
|
|
last_file.write(fields[0])
|
|
last_file.close()
|