home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 108 / MacAddict108.iso / Software / Internet & Communication / JunkMatcher 1.5.5.dmg / JunkMatcher.app / Contents / Resources / mailRules.py < prev    next >
Encoding:
Python Source  |  2005-06-01  |  8.3 KB  |  226 lines

  1. #
  2. #  mailRules.py
  3. #  JunkMatcher
  4. #
  5. #  Created by Benjamin Han on 3/9/05.
  6. #  Copyright (c) 2005 Benjamin Han. All rights reserved.
  7. #
  8.  
  9. # This program is free software; you can redistribute it and/or
  10. # modify it under the terms of the GNU General Public License
  11. # as published by the Free Software Foundation; either version 2
  12. # of the License, or (at your option) any later version.
  13.  
  14. # This program is distributed in the hope that it will be useful,
  15. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. # GNU General Public License for more details.
  18.  
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  22.  
  23. import sys, sets
  24.  
  25. # uncomment the 2 lines below to test using CLI
  26. #sys.path.insert(0, '../Engine')
  27. #from consts import *
  28.  
  29. from Foundation import *
  30. from AppKit import *
  31.  
  32.  
  33. def repairMailRules (mailRules, template, isTiger = False):
  34.     """Repair the Mail rules so that JunkMatcher can take effect; returns True iff any repair
  35.     has actually taken place (meaning the original rules were incorrect)."""
  36.     repaired = False
  37.  
  38.     # check if we have "the one and only junk rule" (the hidden filter rule) as the last rule
  39.     if isTiger:
  40.         numMailRules = len(mailRules)
  41.         for idx in range(numMailRules - 1, -1, -1):
  42.             if mailRules[idx].get(u'IsOneAndOnlyJunkRule') is not None:
  43.                 maxRuleIdx = idx
  44.                 break
  45.         else:
  46.             maxRuleIdx = numMailRules
  47.     else:
  48.         r = mailRules[-1]
  49.         if r.get(u'IsOneAndOnlyJunkRule') is not None:
  50.             # we have the hidden rule
  51.             maxRuleIdx = len(mailRules) - 1
  52.         else:
  53.             maxRuleIdx = len(mailRules)
  54.     
  55.     # find where the JunkMatcher rule is
  56.     junkMatcherRuleIdx = -1
  57.     for idx, r in enumerate(mailRules[:maxRuleIdx]):
  58.         if r[u'RuleName'] == u'JunkMatcher':
  59.             junkMatcherRuleIdx = idx
  60.             break
  61.  
  62.     if junkMatcherRuleIdx != -1:
  63.         junkMatcherRule = mailRules[junkMatcherRuleIdx]
  64.  
  65.         # we make sure that JunkMatcher rule is active, stops after junk is found, colors junk,
  66.         # and move the junk to where they belong (no, not spammers' rear)
  67.         v = junkMatcherRule.get(u'Active')
  68.         if v is None or v != u'1':
  69.             repaired = True
  70.             junkMatcherRule[u'Active'] = u'1'
  71.         v = junkMatcherRule.get(u'StopEvaluatingRules')
  72.         if v is None or v != u'YES':
  73.             repaired = True
  74.             junkMatcherRule[u'StopEvaluatingRules'] = u'YES'
  75.         v = junkMatcherRule.get(u'Color')
  76.         if v is None:                                  # respect users' aesthetics!
  77.             repaired = True
  78.             junkMatcherRule[u'Color'] = 16750738
  79.         v = junkMatcherRule.get(u'ShouldTransferMessage')
  80.         if v is None or v != u'YES':
  81.             repaired = True
  82.             junkMatcherRule[u'ShouldTransferMessage'] = u'YES'
  83.         v = junkMatcherRule.get(u'Mailbox')
  84.         if v is None or v != u'Junk':
  85.             repaired = True
  86.             junkMatcherRule[u'Mailbox'] = u'Junk'        
  87.  
  88.         # starting from the rule following the JunkMatcher rule, look forward for the Full Stop rule
  89.         fullStopRuleIdx = -1
  90.         t = template[2]
  91.         for idx in range(junkMatcherRuleIdx + 1, maxRuleIdx):
  92.             r = mailRules[idx]
  93.             keys = sets.Set(t.keys())
  94.             keys.discard(u'RuleName')   # don't care about the rule name here
  95.             if isTiger:
  96.                 keys.discard(u'Criteria')   # special care needed for Tiger
  97.  
  98.             for k in keys:
  99.                 v = r.get(k)
  100.                 if v is None or v != t[k]:
  101.                     break
  102.             else:
  103.                 if isTiger:
  104.                     # check Criteria
  105.                     c = r.get(u'Criteria')
  106.                     if c is not None:
  107.                         cHeaderSet = sets.Set()
  108.                         for ci in c:
  109.                             h = ci.get(u'Header')
  110.                             if h is not None: cHeaderSet.add(h)
  111.  
  112.                         tHeaderSet = sets.Set()
  113.                         for ti in t['Criteria']:
  114.                             h = ci.get(u'Header')
  115.                             if h is not None: tHeaderSet.add(h)
  116.                         if tHeaderSet <= cHeaderSet:
  117.                             fullStopRuleIdx = idx
  118.                             break
  119.                 else:
  120.                     fullStopRuleIdx = idx
  121.                     break
  122.  
  123.         if fullStopRuleIdx == -1:
  124.             # remove the old Full Stop rule by name, if it exists
  125.             for idx, r in enumerate(mailRules):
  126.                 if r[u'RuleName'] == u'Full Stop':
  127.                     del mailRules[idx]
  128.                     maxRuleIdx -= 1
  129.                     if idx < junkMatcherRuleIdx:
  130.                         junkMatcherRuleIdx -= 1
  131.                     break
  132.                 
  133.             # insert the Full Stop rule as the last rule *before* the hidden rule, if that exists
  134.             mailRules.insert(maxRuleIdx, t)
  135.  
  136.             repaired = True
  137.  
  138.         # starting from the rule preceeding the JunkMatcher rule, look backward for the Built-In Junk Filter rule
  139.         builtinFilterRuleIdx = -1
  140.         t = template[0]
  141.         foundBuiltInJunkFilterRule = False
  142.         for idx in range(junkMatcherRuleIdx - 1, -1, -1):
  143.             r = mailRules[idx]
  144.             c = r.get(u'Criteria')
  145.             foundIsJunkMail = False
  146.             if c is not None:
  147.                 for ci in c:
  148.                     h = ci.get(u'Header')
  149.                     if h is not None and h == 'IsJunkMail':
  150.                         foundIsJunkMail = True
  151.                         break
  152.  
  153.             if foundIsJunkMail:
  154.                 # check the other attributes
  155.                 v = r.get(u'StopEvaluatingRules')
  156.                 if v is not None and v == u'YES':
  157.                     foundBuiltInJunkFilterRule = True
  158.                     break
  159.  
  160.         if not foundBuiltInJunkFilterRule:
  161.             # remove the old Built-In Junk Filter rule by name, if it exists
  162.             for idx, r in enumerate(mailRules):
  163.                 if r[u'RuleName'] == u'Built-In Junk Filter':
  164.                     del mailRules[idx]
  165.                     if idx < junkMatcherRuleIdx:
  166.                         junkMatcherRuleIdx -= 1
  167.                     break                
  168.             
  169.             # insert the Built-In Junk Filter immediately *before* the JunkMatcher rule
  170.             mailRules.insert(junkMatcherRuleIdx, t)
  171.  
  172.             repaired = True
  173.  
  174.     else:
  175.         # remove the old Full Stop rule by name, if it exists
  176.         for idx, r in enumerate(mailRules):
  177.             if r[u'RuleName'] == u'Full Stop':
  178.                 del mailRules[idx]
  179.                 maxRuleIdx -= 1
  180.                 break
  181.  
  182.         # remove the old Built-In Junk Filter rule by name, if it exists
  183.         for idx, r in enumerate(mailRules):
  184.             if r[u'RuleName'] == u'Built-In Junk Filter':
  185.                 del mailRules[idx]
  186.                 maxRuleIdx -= 1
  187.                 break
  188.         
  189.         # insert the factory version of the 3 rules as the last 3 rules *before* the hidden rule, if that exists
  190.         mailRules[maxRuleIdx:maxRuleIdx] = template[:-1]
  191.  
  192.         repaired = True
  193.  
  194.     return repaired
  195.  
  196.  
  197. if __name__ == '__main__':
  198.     if len(sys.argv) != 4:
  199.         print 'Usage: ./mailRules.py <isTiger flag> <template FN> <rules FN>'
  200.         print '       (isTiger flag = \'0\' or \'1\')'
  201.         sys.exit(1)
  202.     
  203.     isTiger = (sys.argv[1] == '1')
  204.  
  205.     if isTiger:
  206.         template = NSDictionary.dictionaryWithContentsOfFile_(sys.argv[2])['rules']        
  207.         tigerRules = NSMutableDictionary.dictionaryWithContentsOfFile_(sys.argv[3])
  208.         mailRules = tigerRules['rules']
  209.     else:
  210.         template = NSArray.arrayWithContentsOfFile_(sys.argv[2])
  211.         mailRules = NSMutableArray.arrayWithContentsOfFile_(sys.argv[3])
  212.  
  213.     if repairMailRules(mailRules, template, isTiger):
  214.         print '* Rules repaired:'
  215.         print '------------------------------'
  216.         print mailRules
  217.         
  218.         if isTiger:
  219.             tigerRules.writeToFile_atomically_(u'/Users/ben/Desktop/output.plist', True)
  220.         else:
  221.             mailRules.writeToFile_atomically_(u'/Users/ben/Desktop/output.plist', True)
  222.         
  223.     else:
  224.         print 'Nothing needs to be repaired!'
  225.  
  226.