bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
1  | 
"""
 | 
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
2  | 
Copyright (c) 2007 Ian Cook and John Popplewell
 | 
3  | 
||
4  | 
Permission is hereby granted, free of charge, to any person obtaining
 | 
|
5  | 
a copy of this software and associated documentation files (the
 | 
|
6  | 
"Software"), to deal in the Software without restriction, including
 | 
|
7  | 
without limitation the rights to use, copy, modify, merge, publish,
 | 
|
8  | 
distribute, sublicense, and/or sell copies of the Software, and to
 | 
|
9  | 
permit persons to whom the Software is furnished to do so, subject to
 | 
|
10  | 
the following conditions:
 | 
|
11  | 
||
12  | 
The above copyright notice and this permission notice shall be included
 | 
|
13  | 
in all copies or substantial portions of the Software.
 | 
|
14  | 
||
15  | 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
|
16  | 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
|
17  | 
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 | 
|
18  | 
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
|
19  | 
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 | 
|
20  | 
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
|
21  | 
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
|
22  | 
||
23  | 
Date    : 11 August 2007
 | 
|
24  | 
Version : 1.0.1
 | 
|
25  | 
Contact : John Popplewell
 | 
|
26  | 
Email   : john@johnnypops.demon.co.uk
 | 
|
27  | 
Web     : http://www.johnnypops.demon.co.uk/python/
 | 
|
28  | 
Origin  : Based on the original script by Ian Cook
 | 
|
29  | 
          http://www.kirbyfooty.com/simplemapi.py
 | 
|
30  | 
Comments: Works (and tested) with:
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
31  | 
          Outlook Express, Outlook 97 and 2000,
 | 
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
32  | 
          Eudora, Incredimail and Mozilla Thunderbird (1.5.0.2)
 | 
33  | 
Thanks  : Werner F. Bruhin and Michele Petrazzo on the ctypes list.
 | 
|
34  | 
||
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
35  | 
If you have any bug-fixes, enhancements or suggestions regarding this
 | 
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
36  | 
software, please contact me at the above email address.
 | 
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
37  | 
"""
 | 
38  | 
||
39  | 
import os  | 
|
40  | 
from ctypes import *  | 
|
41  | 
||
42  | 
FLAGS = c_ulong  | 
|
43  | 
LHANDLE = c_ulong  | 
|
44  | 
LPLHANDLE = POINTER(LHANDLE)  | 
|
45  | 
||
46  | 
# Return codes
 | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
47  | 
SUCCESS_SUCCESS = 0  | 
48  | 
MAPI_USER_ABORT = 1  | 
|
49  | 
MAPI_E_USER_ABORT = MAPI_USER_ABORT  | 
|
50  | 
MAPI_E_FAILURE = 2  | 
|
51  | 
MAPI_E_LOGON_FAILURE = 3  | 
|
52  | 
MAPI_E_LOGIN_FAILURE = MAPI_E_LOGON_FAILURE  | 
|
53  | 
MAPI_E_DISK_FULL = 4  | 
|
54  | 
MAPI_E_INSUFFICIENT_MEMORY = 5  | 
|
55  | 
MAPI_E_ACCESS_DENIED = 6  | 
|
56  | 
MAPI_E_TOO_MANY_SESSIONS = 8  | 
|
57  | 
MAPI_E_TOO_MANY_FILES = 9  | 
|
58  | 
MAPI_E_TOO_MANY_RECIPIENTS = 10  | 
|
59  | 
MAPI_E_ATTACHMENT_NOT_FOUND = 11  | 
|
60  | 
MAPI_E_ATTACHMENT_OPEN_FAILURE = 12  | 
|
61  | 
MAPI_E_ATTACHMENT_WRITE_FAILURE = 13  | 
|
62  | 
MAPI_E_UNKNOWN_RECIPIENT = 14  | 
|
63  | 
MAPI_E_BAD_RECIPTYPE = 15  | 
|
64  | 
MAPI_E_NO_MESSAGES = 16  | 
|
65  | 
MAPI_E_INVALID_MESSAGE = 17  | 
|
66  | 
MAPI_E_TEXT_TOO_LARGE = 18  | 
|
67  | 
MAPI_E_INVALID_SESSION = 19  | 
|
68  | 
MAPI_E_TYPE_NOT_SUPPORTED = 20  | 
|
69  | 
MAPI_E_AMBIGUOUS_RECIPIENT = 21  | 
|
70  | 
MAPI_E_AMBIG_RECIP = MAPI_E_AMBIGUOUS_RECIPIENT  | 
|
71  | 
MAPI_E_MESSAGE_IN_USE = 22  | 
|
72  | 
MAPI_E_NETWORK_FAILURE = 23  | 
|
73  | 
MAPI_E_INVALID_EDITFIELDS = 24  | 
|
74  | 
MAPI_E_INVALID_RECIPS = 25  | 
|
75  | 
MAPI_E_NOT_SUPPORTED = 26  | 
|
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
76  | 
# Recipient class
 | 
77  | 
MAPI_ORIG = 0  | 
|
78  | 
MAPI_TO = 1  | 
|
79  | 
# Send flags
 | 
|
80  | 
MAPI_LOGON_UI = 1  | 
|
81  | 
MAPI_DIALOG = 8  | 
|
82  | 
||
83  | 
class MapiRecipDesc(Structure):  | 
|
84  | 
_fields_ = [  | 
|
85  | 
('ulReserved', c_ulong),  | 
|
86  | 
('ulRecipClass', c_ulong),  | 
|
87  | 
('lpszName', c_char_p),  | 
|
88  | 
('lpszAddress', c_char_p),  | 
|
89  | 
('ulEIDSize', c_ulong),  | 
|
90  | 
('lpEntryID', c_void_p),  | 
|
91  | 
    ]
 | 
|
92  | 
lpMapiRecipDesc = POINTER(MapiRecipDesc)  | 
|
93  | 
lppMapiRecipDesc = POINTER(lpMapiRecipDesc)  | 
|
94  | 
||
95  | 
class MapiFileDesc(Structure):  | 
|
96  | 
_fields_ = [  | 
|
97  | 
('ulReserved', c_ulong),  | 
|
98  | 
('flFlags', c_ulong),  | 
|
99  | 
('nPosition', c_ulong),  | 
|
100  | 
('lpszPathName', c_char_p),  | 
|
101  | 
('lpszFileName', c_char_p),  | 
|
102  | 
('lpFileType', c_void_p),  | 
|
103  | 
    ]
 | 
|
104  | 
lpMapiFileDesc = POINTER(MapiFileDesc)  | 
|
105  | 
||
106  | 
class MapiMessage(Structure):  | 
|
107  | 
_fields_ = [  | 
|
108  | 
('ulReserved', c_ulong),  | 
|
109  | 
('lpszSubject', c_char_p),  | 
|
110  | 
('lpszNoteText', c_char_p),  | 
|
111  | 
('lpszMessageType', c_char_p),  | 
|
112  | 
('lpszDateReceived', c_char_p),  | 
|
113  | 
('lpszConversationID', c_char_p),  | 
|
114  | 
('flFlags', FLAGS),  | 
|
115  | 
('lpOriginator', lpMapiRecipDesc),  | 
|
116  | 
('nRecipCount', c_ulong),  | 
|
117  | 
('lpRecips', lpMapiRecipDesc),  | 
|
118  | 
('nFileCount', c_ulong),  | 
|
119  | 
('lpFiles', lpMapiFileDesc),  | 
|
120  | 
    ]
 | 
|
121  | 
lpMapiMessage = POINTER(MapiMessage)  | 
|
122  | 
||
123  | 
MAPI = windll.mapi32  | 
|
124  | 
MAPISendMail = MAPI.MAPISendMail  | 
|
125  | 
MAPISendMail.restype = c_ulong  | 
|
126  | 
MAPISendMail.argtypes = (LHANDLE, c_ulong, lpMapiMessage, FLAGS, c_ulong)  | 
|
127  | 
||
128  | 
MAPIResolveName = MAPI.MAPIResolveName  | 
|
129  | 
MAPIResolveName.restype = c_ulong  | 
|
130  | 
MAPIResolveName.argtypes= (LHANDLE, c_ulong, c_char_p, FLAGS, c_ulong, lppMapiRecipDesc)  | 
|
131  | 
||
132  | 
MAPIFreeBuffer = MAPI.MAPIFreeBuffer  | 
|
133  | 
MAPIFreeBuffer.restype = c_ulong  | 
|
134  | 
MAPIFreeBuffer.argtypes = (c_void_p, )  | 
|
135  | 
||
136  | 
MAPILogon = MAPI.MAPILogon  | 
|
137  | 
MAPILogon.restype = c_ulong  | 
|
138  | 
MAPILogon.argtypes = (LHANDLE, c_char_p, c_char_p, FLAGS, c_ulong, LPLHANDLE)  | 
|
139  | 
||
140  | 
MAPILogoff = MAPI.MAPILogoff  | 
|
141  | 
MAPILogoff.restype = c_ulong  | 
|
142  | 
MAPILogoff.argtypes = (LHANDLE, c_ulong, FLAGS, c_ulong)  | 
|
143  | 
||
144  | 
||
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
145  | 
class MAPIError(WindowsError):  | 
146  | 
||
147  | 
def __init__(self, code):  | 
|
148  | 
WindowsError.__init__(self)  | 
|
149  | 
self.code = code  | 
|
150  | 
||
151  | 
def __str__(self):  | 
|
152  | 
return 'MAPI error %d' % (self.code,)  | 
|
153  | 
||
154  | 
||
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
155  | 
def _logon(profileName=None, password=None):  | 
156  | 
pSession = LHANDLE()  | 
|
157  | 
rc = MAPILogon(0, profileName, password, MAPI_LOGON_UI, 0, byref(pSession))  | 
|
158  | 
if rc != SUCCESS_SUCCESS:  | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
159  | 
raise MAPIError, rc  | 
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
160  | 
return pSession  | 
161  | 
||
162  | 
||
163  | 
def _logoff(session):  | 
|
164  | 
rc = MAPILogoff(session, 0, 0, 0)  | 
|
165  | 
if rc != SUCCESS_SUCCESS:  | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
166  | 
raise MAPIError, rc  | 
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
167  | 
|
168  | 
||
169  | 
def _resolveName(session, name):  | 
|
170  | 
pRecipDesc = lpMapiRecipDesc()  | 
|
171  | 
rc = MAPIResolveName(session, 0, name, 0, 0, byref(pRecipDesc))  | 
|
172  | 
if rc != SUCCESS_SUCCESS:  | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
173  | 
raise MAPIError, rc  | 
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
174  | 
rd = pRecipDesc.contents  | 
175  | 
name, address = rd.lpszName, rd.lpszAddress  | 
|
176  | 
rc = MAPIFreeBuffer(pRecipDesc)  | 
|
177  | 
if rc != SUCCESS_SUCCESS:  | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
178  | 
raise MAPIError, rc  | 
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
179  | 
return name, address  | 
180  | 
||
181  | 
||
182  | 
def _sendMail(session, recipient, subject, body, attach):  | 
|
183  | 
nFileCount = len(attach)  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
184  | 
if attach:  | 
185  | 
MapiFileDesc_A = MapiFileDesc * len(attach)  | 
|
186  | 
fda = MapiFileDesc_A()  | 
|
187  | 
for fd, fa in zip(fda, attach):  | 
|
188  | 
fd.ulReserved = 0  | 
|
189  | 
fd.flFlags = 0  | 
|
190  | 
fd.nPosition = -1  | 
|
191  | 
fd.lpszPathName = fa  | 
|
192  | 
fd.lpszFileName = None  | 
|
193  | 
fd.lpFileType = None  | 
|
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
194  | 
lpFiles = fda  | 
195  | 
else:  | 
|
196  | 
lpFiles = lpMapiFileDesc()  | 
|
197  | 
||
198  | 
RecipWork = recipient.split(';')  | 
|
199  | 
RecipCnt = len(RecipWork)  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
200  | 
MapiRecipDesc_A = MapiRecipDesc * len(RecipWork)  | 
201  | 
rda = MapiRecipDesc_A()  | 
|
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
202  | 
for rd, ra in zip(rda, RecipWork):  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
203  | 
rd.ulReserved = 0  | 
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
204  | 
rd.ulRecipClass = MAPI_TO  | 
205  | 
try:  | 
|
206  | 
rd.lpszName, rd.lpszAddress = _resolveName(session, ra)  | 
|
207  | 
except WindowsError:  | 
|
208  | 
            # work-round for Mozilla Thunderbird
 | 
|
209  | 
rd.lpszName, rd.lpszAddress = None, ra  | 
|
210  | 
rd.ulEIDSize = 0  | 
|
211  | 
rd.lpEntryID = None  | 
|
212  | 
recip = rda  | 
|
213  | 
||
214  | 
msg = MapiMessage(0, subject, body, None, None, None, 0, lpMapiRecipDesc(),  | 
|
215  | 
RecipCnt, recip,  | 
|
216  | 
nFileCount, lpFiles)  | 
|
217  | 
||
218  | 
rc = MAPISendMail(session, 0, byref(msg), MAPI_DIALOG, 0)  | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
219  | 
if rc != SUCCESS_SUCCESS:  | 
220  | 
raise MAPIError, rc  | 
|
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
221  | 
|
222  | 
||
223  | 
def SendMail(recipient, subject="", body="", attachfiles=""):  | 
|
224  | 
"""Post an e-mail message using Simple MAPI  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
225  | 
|
| 
2681.3.3
by Lukáš Lalinsky
 Convert to UNIX line endings.  | 
226  | 
    recipient - string: address to send to (multiple addresses separated with a semicolon)
 | 
227  | 
    subject   - string: subject header
 | 
|
228  | 
    body      - string: message text
 | 
|
229  | 
    attach    - string: files to attach (multiple attachments separated with a semicolon)
 | 
|
230  | 
    """
 | 
|
231  | 
||
232  | 
attach = []  | 
|
233  | 
AttachWork = attachfiles.split(';')  | 
|
234  | 
for file in AttachWork:  | 
|
235  | 
if os.path.exists(file):  | 
|
236  | 
attach.append(file)  | 
|
237  | 
attach = map(os.path.abspath, attach)  | 
|
238  | 
||
239  | 
restore = os.getcwd()  | 
|
240  | 
try:  | 
|
241  | 
session = _logon()  | 
|
242  | 
try:  | 
|
243  | 
_sendMail(session, recipient, subject, body, attach)  | 
|
244  | 
finally:  | 
|
245  | 
_logoff(session)  | 
|
246  | 
finally:  | 
|
247  | 
os.chdir(restore)  | 
|
248  | 
||
249  | 
||
250  | 
if __name__ == '__main__':  | 
|
251  | 
import sys  | 
|
252  | 
recipient = "test@johnnypops.demon.co.uk"  | 
|
253  | 
subject = "Test Message Subject"  | 
|
254  | 
body = "Hi,\r\n\r\nthis is a quick test message,\r\n\r\ncheers,\r\nJohn."  | 
|
255  | 
attachment = sys.argv[0]  | 
|
256  | 
SendMail(recipient, subject, body, attachment)  | 
|
| 
2681.3.6
by Lukáš Lalinsky
 New version of simplemapi.py with MIT license.  | 
257  |