KabelBW Rechnung automatisch archivieren

[Update] Dieser Post stammt aus der guten alten Zeit als KBW noch Rechnungen per Mail verschickte. Leider fiel dieser tolle Service dem Merger mit UnityMedia zum Opfer, Rechnungen können jetzt nur noch vom Kunden heruntergeladen werden. Bekam der Kunde also vorher eine (verschlüsselte) elektronische Rechnung gestellt (Kunde was also passiv), so muss er sich heute aktiv anmelden und die Datei herunterladen.

Einleitung

Wie viele KabelBW Kunden bekomme ich meine Rechnungen per eMail. Die Rechnungsdokumente sind mit der Kundennummer verschlüsselte PDFs. Das hier vorgestellte Python Script holt das PDF aus dem Postfach, entschlüsselt es und legt die Datei dann ab.

Systemanforderungen

  • Linux
  • Python
  • pdftk (um das PDF zu entschlüsseln)

Das Script

 #!/usr/bin/env python

import getpass, imaplib, email, os

# Ort zum temporären Speichern der heruntergeladenen verschlüsselten Datei
detach_dir = '/tmp'

# Hier den Server, Benutzer und Passwort eintragen
M = imaplib.IMAP4('server_name')
M.login('user', 'pass')

# Selektiere INBOX
M.select()

# Such in der FROM Zeile nach dem Absender - in meinem Fall Rechnung@kabelbw.de
typ, data = M.search(None, 'FROM', '"Rechnung@kabelbw.de"')
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)')
email_body = data[0][1] # getting the mail content
mail = email.message_from_string(email_body) # parsing the mail content to get a mail object

# Check if any attachments at all
if mail.get_content_maintype() != 'multipart':
continue

print "["+mail["From"]+"] :" + mail["Subject"]

# we use walk to create a generator so we can iterate on the parts and forget about the recursive headache
for part in mail.walk():
# multipart are just containers, so we skip them
if part.get_content_maintype() == 'multipart':
continue

# is this part an attachment ?
if part.get('Content-Disposition') is None:
continue

filename = part.get_filename()
counter = 1

# if there is no filename, we create one with a counter to avoid duplicates
if not filename:
filename = 'part-%03d%s' % (counter, 'bin')
counter += 1

att_path = os.path.join(detach_dir, filename)

# Check if its already there
if not os.path.isfile(att_path) :
# finally write the stuff
fp = open(att_path, 'wb')
fp.write(part.get_payload(decode=True))
fp.close()

M.close()
M.logout()

# Name der verschlüsselten Datei ist wie folgt: 7 ziffern.MM.YYYY.pdf
# Die entschlüsselte Datei soll YYYY.MM.pdf heißen, daher an den Punkten splitten und neu zusammensetzen
outfile = filename.split('.')
output_filename = outfile [2] + '.' + outfile[1] + '.' + outfile[3]

# Nur wenns die Zieldatei noch nicht gibt
if not os.path.isfile('/pfad/zum/archivordner/KabelBW/' + output_filename):
    befehl = 'pdftk ' + att_path + ' input_pw KD-Nr output /pfad/zum/archivordner/KabelBW/' + output_filename
    os.system(befehl)
# Und die verschlüsselte Datei wieder aus detach_dir löschen
os.system('rm -f '+ att_path)

Vorsicht

Dieses quick-and-dirty Script ist nicht die Krone der Programmierung und auch nicht vollständig von mir. Keine Ahnung, wo der Teil zum parsen der Mail und speichern des Attachments herkam, irgendwo aus den Weiten des Internet…


Geschrieben von Jan Niggemann in Computer und Technik am 12.04.2010 , geändert am 21.07.2014