]>
code.delx.au - offlineimap/blob - offlineimap/imaplibutil.py
2 # Copyright (C) 2002-2007 John Goerzen
3 # <jgoerzen@complete.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 import os
, re
, socket
, time
, subprocess
, sys
, threading
20 from offlineimap
.ui
import UIBase
21 from offlineimap
.imaplib2
import *
23 # Import the symbols we need that aren't exported by default
24 from offlineimap
.imaplib2
import IMAP4_PORT
, IMAP4_SSL_PORT
, InternalDate
, Mon2num
26 # ssl is new in python 2.6
27 if (sys
.version_info
[0] == 2 and sys
.version_info
[1] >= 6) or sys
.version_info
[0] >= 3:
30 class IMAP4_Tunnel(IMAP4
):
31 """IMAP4 client class over a tunnel
33 Instantiate with: IMAP4_Tunnel(tunnelcmd)
35 tunnelcmd -- shell command to generate the tunnel.
36 The result will be in PREAUTH stage."""
38 def __init__(self
, tunnelcmd
):
39 IMAP4
.__init__(self
, tunnelcmd
)
41 def open(self
, host
, port
):
42 """The tunnelcmd comes in on host!"""
43 self
.process
= subprocess
.Popen(host
, shell
=True, close_fds
=True,
44 stdin
=subprocess
.PIPE
, stdout
=subprocess
.PIPE
)
45 (self
.outfd
, self
.infd
) = (self
.process
.stdin
, self
.process
.stdout
)
46 self
.read_fd
= self
.infd
.fileno()
49 return os
.read(self
.read_fd
, size
)
52 return self
.infd
.readline()
55 self
.outfd
.write(data
)
63 def __init__(self
, sslsock
):
64 self
.sslsock
= sslsock
68 return self
.sslsock
.write(s
)
71 return self
.sslsock
.read(n
)
75 # Return the stuff in readbuf, even if less than n.
76 # It might contain the rest of the line, and if we try to
77 # read more, might block waiting for data that is not
79 bytesfrombuf
= min(n
, len(self
.readbuf
))
80 retval
= self
.readbuf
[:bytesfrombuf
]
81 self
.readbuf
= self
.readbuf
[bytesfrombuf
:]
83 retval
= self
._read
(n
)
85 self
.readbuf
= retval
[n
:]
92 linebuf
= self
.read(1024)
93 nlindex
= linebuf
.find("\n")
95 retval
+= linebuf
[:nlindex
+ 1]
96 self
.readbuf
= linebuf
[nlindex
+ 1:] + self
.readbuf
101 def new_mesg(self
, s
, tn
=None, secs
=None):
105 tn
= threading
.currentThread().getName()
106 tm
= time
.strftime('%M:%S', time
.localtime(secs
))
107 UIBase
.getglobalui().debug('imap', ' %s.%02d %s %s' % (tm
, (secs
*100)%100, tn
, s
))
109 class WrappedIMAP4_SSL(IMAP4_SSL
):
110 def open(self
, host
=None, port
=None):
111 IMAP4_SSL
.open(self
, host
, port
)
112 self
.sslobj
= sslwrapper(self
.sslobj
)
115 return self
.sslobj
.readline()
117 mustquote
= re
.compile(r
"[^\w!#$%&'+,.:;<=>?^`|~-]")
119 def Internaldate2epoch(resp
):
120 """Convert IMAP4 INTERNALDATE to UT.
122 Returns seconds since the epoch.
125 mo
= InternalDate
.match(resp
)
129 mon
= Mon2num
[mo
.group('mon')]
130 zonen
= mo
.group('zonen')
132 day
= int(mo
.group('day'))
133 year
= int(mo
.group('year'))
134 hour
= int(mo
.group('hour'))
135 min = int(mo
.group('min'))
136 sec
= int(mo
.group('sec'))
137 zoneh
= int(mo
.group('zoneh'))
138 zonem
= int(mo
.group('zonem'))
140 # INTERNALDATE timezone must be subtracted to get UT
142 zone
= (zoneh
*60 + zonem
)*60
146 tt
= (year
, mon
, day
, hour
, min, sec
, -1, -1, -1)
148 return time
.mktime(tt
)