KabelBW Rechnung automatisch archivieren

Hier zeige ich ein Python Script, mit dem man automatisch KabelBW-Rechnungen aus seinem IMAP-Postfach herunterlädt und entschlüsselt.

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

  1. #!/usr/bin/env python
  2.  
  3. import getpass, imaplib, email, os
  4.  
  5. # Ort zum temporären Speichern der heruntergeladenen verschlüsselten Datei
  6. detach_dir = '/tmp'
  7.  
  8. # Hier den Server, Benutzer und Passwort eintragen
  9. M = imaplib.IMAP4('server_name')
  10. M.login('user', 'pass')
  11.  
  12. # Selektiere INBOX
  13. M.select()
  14.  
  15. # Such in der FROM Zeile nach dem Absender - in meinem Fall Rechnung@kabelbw.de
  16. typ, data = M.search(None, 'FROM', '"Rechnung@kabelbw.de"')
  17. for num in data[0].split():
  18. typ, data = M.fetch(num, '(RFC822)')
  19. email_body = data[0][1] # getting the mail content
  20. mail = email.message_from_string(email_body) # parsing the mail content to get a mail object
  21.  
  22. # Check if any attachments at all
  23. if mail.get_content_maintype() != 'multipart':
  24. continue
  25.  
  26. print "["+mail["From"]+"] :" + mail["Subject"]
  27.  
  28. # we use walk to create a generator so we can iterate on the parts and forget about the recursive headache
  29. for part in mail.walk():
  30. # multipart are just containers, so we skip them
  31. if part.get_content_maintype() == 'multipart':
  32. continue
  33.  
  34. # is this part an attachment ?
  35. if part.get('Content-Disposition') is None:
  36. continue
  37.  
  38. filename = part.get_filename()
  39. counter = 1
  40.  
  41. # if there is no filename, we create one with a counter to avoid duplicates
  42. if not filename:
  43. filename = 'part-%03d%s' % (counter, 'bin')
  44. counter += 1
  45.  
  46. att_path = os.path.join(detach_dir, filename)
  47.  
  48. # Check if its already there
  49. if not os.path.isfile(att_path) :
  50. # finally write the stuff
  51. fp = open(att_path, 'wb')
  52. fp.write(part.get_payload(decode=True))
  53. fp.close()
  54.  
  55. M.close()
  56. M.logout()
  57.  
  58. # Name der verschlüsselten Datei ist wie folgt: 7 ziffern.MM.YYYY.pdf
  59. # Die entschlüsselte Datei soll YYYY.MM.pdf heißen, daher an den Punkten splitten und neu zusammensetzen
  60. outfile = filename.split('.')
  61. output_filename = outfile [2] + '.' + outfile[1] + '.' + outfile[3]
  62.  
  63. # Nur wenns die Zieldatei noch nicht gibt
  64. if not os.path.isfile('/pfad/zum/archivordner/KabelBW/' + output_filename):
  65. befehl = 'pdftk ' + att_path + ' input_pw KD-Nr output /pfad/zum/archivordner/KabelBW/' + output_filename
  66. os.system(befehl)
  67. # Und die verschlüsselte Datei wieder aus detach_dir löschen
  68. 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...