~divmod-dev/divmod.org/imap-server-440

« back to all changes in this revision

Viewing changes to Reverend/reverend/guessers/email.py

  • Committer: washort
  • Date: 2005-10-25 18:49:27 UTC
  • Revision ID: svn-v4:866e43f7-fbfc-0310-8f2a-ec88d1da2979:trunk:2573
import Reverend

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# This module is part of the Divmod project and is Copyright 2003 Amir Bakhtiar:
 
2
# amir@divmod.org.  This is free software; you can redistribute it and/or
 
3
# modify it under the terms of version 2.1 of the GNU Lesser General Public
 
4
# License as published by the Free Software Foundation.
 
5
#
 
6
        
 
7
import os, sys
 
8
from rfc822 import AddressList
 
9
import email
 
10
 
 
11
from reverend.thomas import Bayes
 
12
from reverend.splitter import Splitter
 
13
 
 
14
 
 
15
class EmailClassifier(Bayes):
 
16
 
 
17
    def getTokens(self, msg):
 
18
        # Overide from parent
 
19
        # This should return a list of strings
 
20
        # which will be used as the key into
 
21
        # the table of token counts
 
22
        tokens = self.getHeaderTokens(msg)
 
23
        tokens += self.getBodyTokens(msg)
 
24
        
 
25
        # Get some tokens that are generated from the
 
26
        # header and the structure
 
27
        tokens += self.getMetaTokens(msg)
 
28
        return tokens
 
29
 
 
30
    def getBodyTokens(self, msg):
 
31
        text = self.getTextPlain(msg)
 
32
        if text is None:
 
33
            text =  ''
 
34
        tl = self.splitter.split(text)
 
35
        return tl
 
36
 
 
37
    def getHeaderTokens(self, msg):
 
38
        subj = msg.get('subject','nosubject')
 
39
        text =  subj + ' '
 
40
        text +=  msg.get('from','fromnoone') + ' '
 
41
        text +=  msg.get('to','tonoone') + ' '
 
42
        text +=  msg.get('cc','ccnoone') + ' '
 
43
        tl = self.splitter.split(text)
 
44
        return tl
 
45
          
 
46
    def getTextPlain(self, msg):
 
47
        for part in msg.walk():
 
48
            typ = part.get_type()
 
49
            if typ and typ.lower() == "text/plain":
 
50
                text = part.get_payload(decode=True)
 
51
                return text
 
52
        return None
 
53
 
 
54
    def getTextHtml(self, msg):
 
55
        for part in msg.walk():
 
56
            typ = part.get_type()
 
57
            if typ and typ.lower() == "text/html":
 
58
                text = part.get_payload(decode=False)
 
59
                return text
 
60
        return None
 
61
 
 
62
    def getMetaTokens(self, msg):
 
63
        r = []
 
64
        for f in ['Content-type', 'X-Priority', 'X-Mailer',
 
65
                  'content-transfer-encoding', 'X-MSMail-Priority']:
 
66
            r.append(f +':' + msg.get(f, 'None'))
 
67
 
 
68
        text = self.getTextPlain(msg)
 
69
        html = self.getTextHtml(msg)
 
70
            
 
71
        for stem, part in zip(['text','html'],[text,html]):
 
72
            if part is None:
 
73
                r.append(stem + '_None')
 
74
                continue
 
75
            else:
 
76
                r.append(stem + '_True')
 
77
        
 
78
            l = len(part.split())
 
79
            if l is 0:
 
80
                a = 'zero'
 
81
                r.append(stem + a)
 
82
            if l > 10000:
 
83
                a = 'more_than_10000'
 
84
                r.append(stem + a)
 
85
            if l > 1000:
 
86
                a = 'more_than_1000'
 
87
                r.append(stem + a)
 
88
            if l > 100:
 
89
                a = 'more_than_100'
 
90
                r.append(stem + a)
 
91
 
 
92
        t = msg.get('to','')
 
93
        at = AddressList(t).addresslist
 
94
        c = msg.get('cc','')
 
95
        ac = AddressList(c).addresslist
 
96
        
 
97
        if at > 5:
 
98
            r.append('to_more_than_5')
 
99
        if at > 10:
 
100
            r.append('to_more_than_10')
 
101
        if ac > 5:
 
102
            r.append('cc_more_than_5')
 
103
        if ac > 10:
 
104
            r.append('cc_more_than_10')
 
105
                
 
106
        return r
 
107