home *** CD-ROM | disk | FTP | other *** search
- #
- # mailRules.py
- # JunkMatcher
- #
- # Created by Benjamin Han on 3/9/05.
- # Copyright (c) 2005 Benjamin Han. All rights reserved.
- #
-
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
-
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
-
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- import sys, sets
-
- # uncomment the 2 lines below to test using CLI
- #sys.path.insert(0, '../Engine')
- #from consts import *
-
- from Foundation import *
- from AppKit import *
-
-
- def repairMailRules (mailRules, template, isTiger = False):
- """Repair the Mail rules so that JunkMatcher can take effect; returns True iff any repair
- has actually taken place (meaning the original rules were incorrect)."""
- repaired = False
-
- # check if we have "the one and only junk rule" (the hidden filter rule) as the last rule
- if isTiger:
- numMailRules = len(mailRules)
- for idx in range(numMailRules - 1, -1, -1):
- if mailRules[idx].get(u'IsOneAndOnlyJunkRule') is not None:
- maxRuleIdx = idx
- break
- else:
- maxRuleIdx = numMailRules
- else:
- r = mailRules[-1]
- if r.get(u'IsOneAndOnlyJunkRule') is not None:
- # we have the hidden rule
- maxRuleIdx = len(mailRules) - 1
- else:
- maxRuleIdx = len(mailRules)
-
- # find where the JunkMatcher rule is
- junkMatcherRuleIdx = -1
- for idx, r in enumerate(mailRules[:maxRuleIdx]):
- if r[u'RuleName'] == u'JunkMatcher':
- junkMatcherRuleIdx = idx
- break
-
- if junkMatcherRuleIdx != -1:
- junkMatcherRule = mailRules[junkMatcherRuleIdx]
-
- # we make sure that JunkMatcher rule is active, stops after junk is found, colors junk,
- # and move the junk to where they belong (no, not spammers' rear)
- v = junkMatcherRule.get(u'Active')
- if v is None or v != u'1':
- repaired = True
- junkMatcherRule[u'Active'] = u'1'
- v = junkMatcherRule.get(u'StopEvaluatingRules')
- if v is None or v != u'YES':
- repaired = True
- junkMatcherRule[u'StopEvaluatingRules'] = u'YES'
- v = junkMatcherRule.get(u'Color')
- if v is None: # respect users' aesthetics!
- repaired = True
- junkMatcherRule[u'Color'] = 16750738
- v = junkMatcherRule.get(u'ShouldTransferMessage')
- if v is None or v != u'YES':
- repaired = True
- junkMatcherRule[u'ShouldTransferMessage'] = u'YES'
- v = junkMatcherRule.get(u'Mailbox')
- if v is None or v != u'Junk':
- repaired = True
- junkMatcherRule[u'Mailbox'] = u'Junk'
-
- # starting from the rule following the JunkMatcher rule, look forward for the Full Stop rule
- fullStopRuleIdx = -1
- t = template[2]
- for idx in range(junkMatcherRuleIdx + 1, maxRuleIdx):
- r = mailRules[idx]
- keys = sets.Set(t.keys())
- keys.discard(u'RuleName') # don't care about the rule name here
- if isTiger:
- keys.discard(u'Criteria') # special care needed for Tiger
-
- for k in keys:
- v = r.get(k)
- if v is None or v != t[k]:
- break
- else:
- if isTiger:
- # check Criteria
- c = r.get(u'Criteria')
- if c is not None:
- cHeaderSet = sets.Set()
- for ci in c:
- h = ci.get(u'Header')
- if h is not None: cHeaderSet.add(h)
-
- tHeaderSet = sets.Set()
- for ti in t['Criteria']:
- h = ci.get(u'Header')
- if h is not None: tHeaderSet.add(h)
- if tHeaderSet <= cHeaderSet:
- fullStopRuleIdx = idx
- break
- else:
- fullStopRuleIdx = idx
- break
-
- if fullStopRuleIdx == -1:
- # remove the old Full Stop rule by name, if it exists
- for idx, r in enumerate(mailRules):
- if r[u'RuleName'] == u'Full Stop':
- del mailRules[idx]
- maxRuleIdx -= 1
- if idx < junkMatcherRuleIdx:
- junkMatcherRuleIdx -= 1
- break
-
- # insert the Full Stop rule as the last rule *before* the hidden rule, if that exists
- mailRules.insert(maxRuleIdx, t)
-
- repaired = True
-
- # starting from the rule preceeding the JunkMatcher rule, look backward for the Built-In Junk Filter rule
- builtinFilterRuleIdx = -1
- t = template[0]
- foundBuiltInJunkFilterRule = False
- for idx in range(junkMatcherRuleIdx - 1, -1, -1):
- r = mailRules[idx]
- c = r.get(u'Criteria')
- foundIsJunkMail = False
- if c is not None:
- for ci in c:
- h = ci.get(u'Header')
- if h is not None and h == 'IsJunkMail':
- foundIsJunkMail = True
- break
-
- if foundIsJunkMail:
- # check the other attributes
- v = r.get(u'StopEvaluatingRules')
- if v is not None and v == u'YES':
- foundBuiltInJunkFilterRule = True
- break
-
- if not foundBuiltInJunkFilterRule:
- # remove the old Built-In Junk Filter rule by name, if it exists
- for idx, r in enumerate(mailRules):
- if r[u'RuleName'] == u'Built-In Junk Filter':
- del mailRules[idx]
- if idx < junkMatcherRuleIdx:
- junkMatcherRuleIdx -= 1
- break
-
- # insert the Built-In Junk Filter immediately *before* the JunkMatcher rule
- mailRules.insert(junkMatcherRuleIdx, t)
-
- repaired = True
-
- else:
- # remove the old Full Stop rule by name, if it exists
- for idx, r in enumerate(mailRules):
- if r[u'RuleName'] == u'Full Stop':
- del mailRules[idx]
- maxRuleIdx -= 1
- break
-
- # remove the old Built-In Junk Filter rule by name, if it exists
- for idx, r in enumerate(mailRules):
- if r[u'RuleName'] == u'Built-In Junk Filter':
- del mailRules[idx]
- maxRuleIdx -= 1
- break
-
- # insert the factory version of the 3 rules as the last 3 rules *before* the hidden rule, if that exists
- mailRules[maxRuleIdx:maxRuleIdx] = template[:-1]
-
- repaired = True
-
- return repaired
-
-
- if __name__ == '__main__':
- if len(sys.argv) != 4:
- print 'Usage: ./mailRules.py <isTiger flag> <template FN> <rules FN>'
- print ' (isTiger flag = \'0\' or \'1\')'
- sys.exit(1)
-
- isTiger = (sys.argv[1] == '1')
-
- if isTiger:
- template = NSDictionary.dictionaryWithContentsOfFile_(sys.argv[2])['rules']
- tigerRules = NSMutableDictionary.dictionaryWithContentsOfFile_(sys.argv[3])
- mailRules = tigerRules['rules']
- else:
- template = NSArray.arrayWithContentsOfFile_(sys.argv[2])
- mailRules = NSMutableArray.arrayWithContentsOfFile_(sys.argv[3])
-
- if repairMailRules(mailRules, template, isTiger):
- print '* Rules repaired:'
- print '------------------------------'
- print mailRules
-
- if isTiger:
- tigerRules.writeToFile_atomically_(u'/Users/ben/Desktop/output.plist', True)
- else:
- mailRules.writeToFile_atomically_(u'/Users/ben/Desktop/output.plist', True)
-
- else:
- print 'Nothing needs to be repaired!'
-
-