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

  1. #
  2. #  MetaPatterns.py
  3. #  JunkMatcher
  4. #
  5. #  Created by Benjamin Han on 2/1/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. #!/usr/bin/env python
  24.  
  25. import string
  26.  
  27. from consts import *
  28. from utilities import *
  29. from emailAddress import *
  30.  
  31.  
  32. # pattern to glean email addresses from com.apple.mail.plist
  33. _epPat = re.compile(r'EmailAddresses\s*=\s*\(([^;]*)\);')
  34.  
  35. # this is a much simplified version of RFC 2822
  36. _emailPat = re.compile(r'((?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]))[\040\t]*(?:\.[\040\t]*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]))[\040\t]*)*)@[\040\t]*((?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]))[\040\t]*(?:\.[\040\t]*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]))[\040\t]*)*)')
  37.  
  38.  
  39. def getReservedMPs ():
  40.     """(MAC OS X ONLY) Getting names, domains and emails from Mail's account settings."""
  41.     pLines = ' '.join(map(lambda l:l.strip(),
  42.                           os.popen('defaults read com.apple.mail MailAccounts')))
  43.     srcEList = []
  44.     for m in _epPat.finditer(pLines):
  45.         srcEList.extend(map(lambda e:e.strip()[1:-1], m.group(1).split(',')))
  46.  
  47.     reservedMPs = []
  48.     nList = []
  49.     dList = []
  50.     eList = []
  51.     for i,e in enumerate(srcEList):
  52.         m = _emailPat.search(e)
  53.         if m:
  54.             n = re.escape(m.group(1).strip())
  55.             d = re.escape(m.group(2).strip())
  56.             e = re.escape(e)
  57.  
  58.             id = i + 1
  59.             reservedMPs.append(('myName%d' % id, r'\b%s\b' % n))
  60.             reservedMPs.append(('myDomain%d' % id, r'\b%s\b' % d))
  61.             reservedMPs.append(('myEmail%d' % id, r'\b%s\b' % e))
  62.         
  63.             nList.append(n)
  64.             dList.append(d)
  65.             eList.append(e)
  66.  
  67.     if len(nList):
  68.         reservedMPs.append(('myNames', r'\b(?:%s)\b' % '|'.join(map(lambda n: '(?:%s)' % n, nList))))
  69.         reservedMPs.append(('myDomains', r'\b(?:%s)\b' % '|'.join(map(lambda n: '(?:%s)' % n, dList))))
  70.         reservedMPs.append(('myEmails', r'\b(?:%s)\b' % '|'.join(map(lambda n: '(?:%s)' % n, eList))))
  71.  
  72.     return reservedMPs
  73.  
  74.  
  75. class _ReplaceMP (object):
  76.     __slots__ = 'metaPatterns'
  77.  
  78.     def __init__ (self, metaPatterns):
  79.         self.metaPatterns = metaPatterns
  80.  
  81.     def __call__ (self, mo):
  82.         mp = self.metaPatterns.get(mo.group(0)[3:-1])
  83.         if mp is not None: return '(?:%s)' % mp[0]
  84.         else: raise JMExceptionMetaPattern(mo.group(0)[3:-1])
  85.  
  86.         
  87. class MetaPatterns (dict):
  88.     """A dictionary of meta patterns
  89.        -----------------------------
  90.        fn: file name
  91.  
  92.        NOTE: the key is the name of the pattern, and the value is a tuple (str, bool, bool)
  93.        where the first bool == True means it's a reserved MP, the second bool == True
  94.        iff it's a managed meta pattern.
  95.     """
  96.     def __init__ (self, fn):
  97.         self.fn = fn
  98.         self._replaceMP = _ReplaceMP(self)
  99.         
  100.         self.load()
  101.  
  102.     def load (self):
  103.         self.clear()
  104.         
  105.         # pattern file format: odd lines are patterns, even lines are names
  106.         isName = False
  107.         for l in filter(lambda l:len(l) and l[0] != '#',  map(string.strip, openFile(self.fn))):
  108.             if isName:
  109.                 self[l[1:-3]] = (pat, False, l[-1] == 'M')
  110.                 isName = False
  111.             else:
  112.                 pat = l.strip()[1:-1]
  113.                 isName = True
  114.  
  115.         # add the reserved meta patterns        
  116.         for k, v in getReservedMPs(): self[k] = (v, True, True)        
  117.  
  118.     def writeToFile (self):
  119.         strList = []
  120.         for k, v in self.items():
  121.             if v[1]: continue      # don't save the reserved meta patterns
  122.             if v[2]: mStr = 'M'
  123.             else: mStr = 'U'
  124.             strList.append('"%s"\n"%s" %s' % (v[0], k, mStr))
  125.  
  126.         openFile(self.fn, 'w').write('\n'.join(strList))
  127.         
  128.     def instantiate (self, pat):
  129.         return mpPat.sub(self._replaceMP, pat)
  130.  
  131.     def findAll (self, pat):
  132.         """Returns a set containing the names of the meta patterns used in pat."""
  133.         return sets.Set(filter(lambda name: self.get(name) is not None,
  134.                                map(lambda mo: mo.group(0)[3:-1], mpPat.finditer(pat))))
  135.  
  136.  
  137. if __name__ == '__main__':
  138.     mps = MetaPatterns('%smetaPatterns' % CONF_PATH)
  139.     items = mps.items()
  140.     items.sort()
  141.     for k, v in items:
  142.         s = '%s: %s'%(k,v[0])
  143.         print s.encode('utf8')
  144.         
  145.  
  146.     origPattern = u'(?i)(?#v-)(?#i-)agra'
  147.     print
  148.     print '* original pattern:', origPattern
  149.     print '* real pattern:', encodeText(mps.instantiate(origPattern))
  150.     print '* meta patterns used:', encodeText(', '.join(mps.findAll(origPattern)))
  151.