Advertisement
Guest User

Untitled

a guest
Sep 8th, 2017
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.05 KB | None | 0 0
  1. #!/usr/bin/env python
  2. import imaplib
  3. import re
  4. import email
  5. import os
  6.  
  7. ################################################################################
  8. # RULE DEFINITIONS
  9. ################################################################################
  10.  
  11. class ListHeaderRule:
  12. def __init__(self):
  13. self.name = 'List-Header check'
  14.  
  15. def hit_msg(self, msg):
  16. sender = msg['From']
  17. print 'Found unsub header in msg [ {0} ] from: [ {1} ]'.format(msgid, sender)
  18. print 'List-Unsubscribe: {0}'.format(msg['List-Unsubscribe'])
  19.  
  20. def is_hit(self, msg):
  21. return 'List-Unsubscribe' in msg
  22.  
  23. class RegexMatchRule:
  24. def __init__(self, regex):
  25. self.name = 'Regex Match: {0}'.format(regex)
  26. self.regex = regex
  27.  
  28. # Make sure we're not looking at things like attachments or images
  29. self.valid_payload_types= {
  30. 'text/plain': True,
  31. 'text/html': True,
  32. }
  33.  
  34. def hit_msg(self, msg):
  35. print '{0} got a hit in message with subject [ {1} ] from: [{2}]'.format(
  36. self.name, msg['Subject'], msg['From'])
  37.  
  38. def is_hit(self, msg):
  39. for part in msg.walk():
  40. if part.get_content_type() in self.valid_payload_types:
  41. payload = part.get_payload()
  42. match = re.match(self.regex, payload, re.I) # Case insensitive match
  43. return True if match else False
  44.  
  45. ################################################################################
  46. # HELPERS
  47. ################################################################################
  48.  
  49. def run_rules(rules, msg, msgid):
  50. subject = msg['Subject']
  51. print 'Running ruleset for msg: [ {0} ], id: [ {1} ]'.format(subject, msgid)
  52. is_hit = False
  53.  
  54. for rule in rules:
  55. print 'Executing rule [ {0} ] on msg_id [ {1} ]'.format(rule.name, msgid)
  56.  
  57. if rule.is_hit(msg):
  58. print "============================================================"
  59. print "MATCH! -> Rule: [ {0} ], Subject: [ {1} ]".format(rule.name, subject)
  60. print "============================================================"
  61. rule.hit_msg(msg)
  62. print "============================================================"
  63. is_hit = True
  64. break
  65.  
  66. if not is_hit:
  67. print 'No rules matched on message with subject: [ {0} ]'.format(subject)
  68.  
  69. return is_hit
  70.  
  71. ################################################################################
  72. # CONFIG
  73. ################################################################################
  74.  
  75. EMAIL_USER = 'xxx'
  76. EMAIL_PASS = 'xxx'
  77.  
  78. DUMP_MESSAGES = True
  79. DUMP_LOCATION = '/tmp/unsub_raw_mail'
  80.  
  81. ################################################################################
  82. # MAIN
  83. ################################################################################
  84.  
  85. print "============================================================"
  86. print "Starting unsub checker..."
  87. print "============================================================"
  88.  
  89. # Build rules
  90. rules = [
  91. ListHeaderRule(),
  92. RegexMatchRule(r'unsubscribe'),
  93. RegexMatchRule(r'no longer receive'),
  94. ]
  95.  
  96. mail = imaplib.IMAP4_SSL('imap.gmail.com')
  97. mail.login(EMAIL_USER, EMAIL_PASS)
  98. mail.select('[Gmail]/All Mail')
  99. _, data = mail.search(None, 'All')
  100. ids = data[0]
  101. id_list = ids.split()
  102.  
  103. hitcount = 0
  104. for msgid in id_list:
  105. _, data = mail.fetch(msgid, '(RFC822)')
  106. raw_msg = data[0][1]
  107. msg = email.message_from_string(raw_msg)
  108.  
  109. # dump all the messages to /tmp
  110. if DUMP_MESSAGES:
  111. if not os.path.exists(DUMP_LOCATION):
  112. os.makedirs(DUMP_LOCATION)
  113.  
  114. subject = msg['Subject'].replace(' ', '_')
  115. filename = DUMP_LOCATION + '/' + subject + '.txt'
  116. with open(filename, 'w') as f:
  117. f.write(raw_msg)
  118.  
  119. is_hit = run_rules(rules, msg, msgid)
  120.  
  121. if is_hit:
  122. hitcount += 1
  123.  
  124. print "============================================================"
  125. print "Status:"
  126. print "============================================================"
  127. print 'Found {0} of {1} messages with unsubscribe headers...'.format(hitcount, len(id_list))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement