|
0
|
1 #!/usr/bin/python2
|
|
|
2 import sys
|
|
|
3 import re
|
|
|
4 import locale
|
|
|
5 from os import stat, unlink, system
|
|
|
6 from mailbox import mbox
|
|
|
7 from email.parser import Parser
|
|
|
8 import datetime
|
|
|
9 from tempfile import NamedTemporaryFile
|
|
|
10
|
|
|
11 locale.setlocale(locale.LC_ALL, '')
|
|
|
12
|
|
|
13 def cmp1(x,y):
|
|
|
14 c1=cmp(x[0],y[0])
|
|
|
15 if c1:
|
|
|
16 return c1
|
|
|
17 else:
|
|
|
18 return cmp(x[1],y[1])
|
|
|
19
|
|
|
20 def cmp2(x,y):
|
|
|
21 c1=cmp(x[0],y[0])
|
|
|
22 if c1:
|
|
|
23 return c1
|
|
|
24 else:
|
|
|
25 return locale.strcoll(x[1],y[1])
|
|
|
26
|
|
|
27 def dumpHdrsAndText(msg,outfile):
|
|
|
28 #print "MSG: %s"%repr(msg)
|
|
|
29 #print >>sys.stderr,'Content-Type: %s'%msg.get('Content-Type',None)
|
|
|
30 #print >>sys.stderr,'Content-Transfer-Encoding: %s'%msg.get('Content-Transfer-Encoding',None)
|
|
|
31 outfile.writelines("%s: %s\n"%(k,v) for (k,v) in msg.items())
|
|
|
32 outfile.write("\n")
|
|
|
33 if msg.is_multipart():
|
|
|
34 outfile.write('\nmultipart: %s\n\n'%len(msg.get_payload()))
|
|
|
35 for m in msg.get_payload():
|
|
|
36 #print "PART: %s"%repr(m)
|
|
|
37 #print "part %s"%m.get('Content-Type','xx')
|
|
|
38 dumpHdrsAndText(m,outfile)
|
|
|
39 elif msg.get('Content-Type',None).find('text/')==0:
|
|
|
40 outfile.write(msg.get_payload(decode=True))
|
|
|
41 else:
|
|
|
42 #print 'OCT: %s'%msg.get('Content-Type','xx')
|
|
|
43 pass
|
|
|
44
|
|
|
45 pl=re.compile("([^\t]*)\t\\[file://([^\\]]*)\\]\t\[(.*)\]\t")
|
|
|
46 pif=re.compile("/(pers|group)-([12][0-9][0-9][0-9].[01][0-9])/([0-9]*)")
|
|
|
47 pof=re.compile("/.evolution/mail/local/([12][0-9][0-9][0-9].[01][0-9])$")
|
|
|
48 ovf=re.compile("\.overview$")
|
|
|
49 incoming={}
|
|
|
50 outgoing={}
|
|
|
51 other=[]
|
|
|
52 mboxes={}
|
|
|
53 tfl=[]
|
|
|
54 ov=0
|
|
|
55 mparser=None
|
|
|
56
|
|
|
57 dosort=sys.argv[1]=="1"
|
|
|
58 doless=sys.argv[2]=="1"
|
|
|
59
|
|
|
60 locs=[]
|
|
|
61
|
|
|
62 for l in sys.stdin:
|
|
|
63 res=pl.match(l.rstrip())
|
|
|
64 if res:
|
|
|
65 (type,filename,subj)=res.groups()
|
|
|
66 #print type, filename, subj
|
|
|
67 res=pif.search(filename)
|
|
|
68 if res:
|
|
|
69 if ovf.search(filename):
|
|
|
70 ov=ov+1
|
|
|
71 else:
|
|
|
72 incoming[(res.group(2),res.group(3))]=filename
|
|
|
73 else:
|
|
|
74 res=pof.search(filename)
|
|
|
75 if res:
|
|
|
76 k=(res.group(1),subj)
|
|
|
77 n=outgoing.get(k,0)
|
|
|
78 outgoing[k]=n+1
|
|
|
79 else:
|
|
|
80 try:
|
|
|
81 k=stat(filename).st_mtime
|
|
|
82 #k=1216786059.1472759
|
|
|
83 other+=[(k,filename,subj)]
|
|
|
84 except:
|
|
|
85 pass
|
|
|
86 else:
|
|
|
87 print >> sys.stderr, "oops:",l
|
|
|
88 print "%s pers, %s out, %s other, %s .overview"%(len(incoming),len(outgoing),len(other),ov)
|
|
|
89 ik=incoming.keys()
|
|
|
90 ok=outgoing.keys()
|
|
|
91 xk=other
|
|
|
92 if dosort:
|
|
|
93 ik.sort(cmp=cmp1,reverse=True)
|
|
|
94 ok.sort(cmp=cmp2,reverse=True)
|
|
|
95 xk.sort(cmp=cmp2,reverse=True)
|
|
|
96 ikl=len(ik)
|
|
|
97 okl=len(ok)
|
|
|
98 xkl=len(xk)
|
|
|
99 i=o=x=0
|
|
|
100 iTop=None
|
|
|
101 oTop=None
|
|
|
102 xTop=None
|
|
|
103 # if not sorted will be pretty messed up. . .
|
|
|
104 while (i<ikl or o<okl or x<xkl):
|
|
|
105 if (iTop is None):
|
|
|
106 if (i<ikl):
|
|
|
107 iTop = ik[i][0]
|
|
|
108 else:
|
|
|
109 iTop = "0000-00"
|
|
|
110 if (oTop is None):
|
|
|
111 if (o<okl):
|
|
|
112 oTop = ok[o][0]
|
|
|
113 else:
|
|
|
114 oTop = "0000-00"
|
|
|
115 if (xTop is None):
|
|
|
116 if (x<xkl):
|
|
|
117 xTop = datetime.date.fromtimestamp(xk[x][0]).strftime("%Y-%m")
|
|
|
118 else:
|
|
|
119 xTop = "0000-00"
|
|
|
120 if iTop>=oTop:
|
|
|
121 if iTop>=xTop:
|
|
|
122 # it's i we want
|
|
|
123 #print >>sys.stderr,"i",i,iTop,ik[i],incoming[ik[i]]
|
|
|
124 iloc=incoming[ik[i]]
|
|
|
125 if doless:
|
|
|
126 # check for encoded text
|
|
|
127 ccmd="grep -Pzq 'Content-Transfer-Encoding: base64' \"%s\""%iloc
|
|
|
128 #print >>sys.stderr,ccmd
|
|
|
129 #sys.stderr.flush()
|
|
|
130 if not system(ccmd):
|
|
|
131 if mparser is None:
|
|
|
132 mparser=Parser()
|
|
|
133 tf=NamedTemporaryFile(delete=False)
|
|
|
134 print >>tf,iloc
|
|
|
135 dumpHdrsAndText(mparser.parse(open(iloc)),tf)
|
|
|
136 tfl.append(tf.name)
|
|
|
137 tf.close()
|
|
|
138 iloc=tf.name
|
|
|
139 locs.append(iloc)
|
|
|
140 i=i+1
|
|
|
141 iTop=None
|
|
|
142 continue
|
|
|
143 else:
|
|
|
144 # it's x we want
|
|
|
145 pass
|
|
|
146 elif oTop>=xTop:
|
|
|
147 # it's o we want
|
|
|
148 #print "o",o,oTop,ok[o],outgoing[ok[o]]
|
|
|
149 k=ok[o]
|
|
|
150 res=int(outgoing[k])
|
|
|
151 # Need to write a temporary file drawn from k[0] for successive
|
|
|
152 # subjects == k[1]
|
|
|
153 if doless:
|
|
|
154 try:
|
|
|
155 mb=mboxes[oTop]
|
|
|
156 except KeyError:
|
|
|
157 mboxes[oTop]=mb=mbox("/disk/scratch/mail/cpy/general/"+oTop).values()
|
|
|
158 for m in mb:
|
|
|
159 if m['subject']==k[1]:
|
|
|
160 tf=NamedTemporaryFile(delete=False)
|
|
|
161 locs.append(tf.name)
|
|
|
162 tfl.append(tf.name)
|
|
|
163 tf.write(m.as_string())
|
|
|
164 tf.close()
|
|
|
165 else:
|
|
|
166 locs.append("%s/%s"%(oTop,k[1]))
|
|
|
167 o=o+1
|
|
|
168 oTop=None
|
|
|
169 continue
|
|
|
170 else:
|
|
|
171 # it's x we want
|
|
|
172 pass
|
|
|
173 #print >>sys.stderr,"x",x,xTop,xk[x]
|
|
|
174 #sys.stderr.flush()
|
|
|
175 xloc=xk[x][1]
|
|
|
176 if doless:
|
|
|
177 # check for encoded text
|
|
|
178 ccmd="grep -Pzq 'Content-Transfer-Encoding: base64' \"%s\""%xloc
|
|
|
179 #print >>sys.stderr,ccmd
|
|
|
180 #sys.stderr.flush()
|
|
|
181 if not system(ccmd):
|
|
|
182 if mparser is None:
|
|
|
183 mparser=Parser()
|
|
|
184 tf=NamedTemporaryFile(delete=False)
|
|
|
185 print >>tf,xloc
|
|
|
186 dumpHdrsAndText(mparser.parse(open(xloc)),tf)
|
|
|
187 tfl.append(tf.name)
|
|
|
188 tf.close()
|
|
|
189 xloc=tf.name
|
|
|
190 locs.append(xloc)
|
|
|
191 x=x+1
|
|
|
192 xTop=None
|
|
|
193 if doless:
|
|
|
194 system('less '+' '.join(locs))
|
|
|
195 else:
|
|
|
196 print '\n'.join(locs)
|
|
|
197 for f in tfl:
|
|
|
198 unlink(f)
|