/brz/remove-bazaar

To get this branch, use:
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
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
39
from __future__ import absolute_import
40
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
41
import os
42
from ctypes import *
43
44
FLAGS = c_ulong
45
LHANDLE = c_ulong
46
LPLHANDLE = POINTER(LHANDLE)
47
48
# Return codes
7143.15.2 by Jelmer Vernooij
Run autopep8.
49
SUCCESS_SUCCESS = 0
50
MAPI_USER_ABORT = 1
51
MAPI_E_USER_ABORT = MAPI_USER_ABORT
52
MAPI_E_FAILURE = 2
53
MAPI_E_LOGON_FAILURE = 3
54
MAPI_E_LOGIN_FAILURE = MAPI_E_LOGON_FAILURE
55
MAPI_E_DISK_FULL = 4
56
MAPI_E_INSUFFICIENT_MEMORY = 5
57
MAPI_E_ACCESS_DENIED = 6
58
MAPI_E_TOO_MANY_SESSIONS = 8
59
MAPI_E_TOO_MANY_FILES = 9
60
MAPI_E_TOO_MANY_RECIPIENTS = 10
61
MAPI_E_ATTACHMENT_NOT_FOUND = 11
62
MAPI_E_ATTACHMENT_OPEN_FAILURE = 12
2681.3.6 by Lukáš Lalinsky
New version of simplemapi.py with MIT license.
63
MAPI_E_ATTACHMENT_WRITE_FAILURE = 13
7143.15.2 by Jelmer Vernooij
Run autopep8.
64
MAPI_E_UNKNOWN_RECIPIENT = 14
65
MAPI_E_BAD_RECIPTYPE = 15
66
MAPI_E_NO_MESSAGES = 16
67
MAPI_E_INVALID_MESSAGE = 17
68
MAPI_E_TEXT_TOO_LARGE = 18
69
MAPI_E_INVALID_SESSION = 19
70
MAPI_E_TYPE_NOT_SUPPORTED = 20
71
MAPI_E_AMBIGUOUS_RECIPIENT = 21
72
MAPI_E_AMBIG_RECIP = MAPI_E_AMBIGUOUS_RECIPIENT
73
MAPI_E_MESSAGE_IN_USE = 22
74
MAPI_E_NETWORK_FAILURE = 23
75
MAPI_E_INVALID_EDITFIELDS = 24
76
MAPI_E_INVALID_RECIPS = 25
77
MAPI_E_NOT_SUPPORTED = 26
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
78
# Recipient class
7143.15.2 by Jelmer Vernooij
Run autopep8.
79
MAPI_ORIG = 0
80
MAPI_TO = 1
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
81
# Send flags
7143.15.2 by Jelmer Vernooij
Run autopep8.
82
MAPI_LOGON_UI = 1
83
MAPI_DIALOG = 8
84
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
85
86
class MapiRecipDesc(Structure):
87
    _fields_ = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
88
        ('ulReserved', c_ulong),
89
        ('ulRecipClass', c_ulong),
90
        ('lpszName', c_char_p),
91
        ('lpszAddress', c_char_p),
92
        ('ulEIDSize', c_ulong),
93
        ('lpEntryID', c_void_p),
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
94
    ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
95
96
97
lpMapiRecipDesc = POINTER(MapiRecipDesc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
98
lppMapiRecipDesc = POINTER(lpMapiRecipDesc)
99
7143.15.2 by Jelmer Vernooij
Run autopep8.
100
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
101
class MapiFileDesc(Structure):
102
    _fields_ = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
103
        ('ulReserved', c_ulong),
104
        ('flFlags', c_ulong),
105
        ('nPosition', c_ulong),
106
        ('lpszPathName', c_char_p),
107
        ('lpszFileName', c_char_p),
108
        ('lpFileType', c_void_p),
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
109
    ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
110
111
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
112
lpMapiFileDesc = POINTER(MapiFileDesc)
113
7143.15.2 by Jelmer Vernooij
Run autopep8.
114
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
115
class MapiMessage(Structure):
116
    _fields_ = [
7143.15.2 by Jelmer Vernooij
Run autopep8.
117
        ('ulReserved', c_ulong),
118
        ('lpszSubject', c_char_p),
119
        ('lpszNoteText', c_char_p),
120
        ('lpszMessageType', c_char_p),
121
        ('lpszDateReceived', c_char_p),
122
        ('lpszConversationID', c_char_p),
123
        ('flFlags', FLAGS),
124
        ('lpOriginator', lpMapiRecipDesc),
125
        ('nRecipCount', c_ulong),
126
        ('lpRecips', lpMapiRecipDesc),
127
        ('nFileCount', c_ulong),
128
        ('lpFiles', lpMapiFileDesc),
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
129
    ]
7143.15.2 by Jelmer Vernooij
Run autopep8.
130
131
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
132
lpMapiMessage = POINTER(MapiMessage)
133
7143.15.2 by Jelmer Vernooij
Run autopep8.
134
MAPI = windll.mapi32
135
MAPISendMail = MAPI.MAPISendMail
136
MAPISendMail.restype = c_ulong
137
MAPISendMail.argtypes = (LHANDLE, c_ulong, lpMapiMessage, FLAGS, c_ulong)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
138
7143.15.2 by Jelmer Vernooij
Run autopep8.
139
MAPIResolveName = MAPI.MAPIResolveName
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
140
MAPIResolveName.restype = c_ulong
7143.15.2 by Jelmer Vernooij
Run autopep8.
141
MAPIResolveName.argtypes = (
142
    LHANDLE, c_ulong, c_char_p, FLAGS, c_ulong, lppMapiRecipDesc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
143
7143.15.2 by Jelmer Vernooij
Run autopep8.
144
MAPIFreeBuffer = MAPI.MAPIFreeBuffer
145
MAPIFreeBuffer.restype = c_ulong
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
146
MAPIFreeBuffer.argtypes = (c_void_p, )
147
7143.15.2 by Jelmer Vernooij
Run autopep8.
148
MAPILogon = MAPI.MAPILogon
149
MAPILogon.restype = c_ulong
150
MAPILogon.argtypes = (LHANDLE, c_char_p, c_char_p, FLAGS, c_ulong, LPLHANDLE)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
151
7143.15.2 by Jelmer Vernooij
Run autopep8.
152
MAPILogoff = MAPI.MAPILogoff
153
MAPILogoff.restype = c_ulong
154
MAPILogoff.argtypes = (LHANDLE, c_ulong, FLAGS, c_ulong)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
155
156
2681.3.6 by Lukáš Lalinsky
New version of simplemapi.py with MIT license.
157
class MAPIError(WindowsError):
158
159
    def __init__(self, code):
160
        WindowsError.__init__(self)
161
        self.code = code
162
163
    def __str__(self):
164
        return 'MAPI error %d' % (self.code,)
165
166
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
167
def _logon(profileName=None, password=None):
168
    pSession = LHANDLE()
169
    rc = MAPILogon(0, profileName, password, MAPI_LOGON_UI, 0, byref(pSession))
170
    if rc != SUCCESS_SUCCESS:
6619.3.11 by Jelmer Vernooij
Use modern exceptions.
171
        raise MAPIError(rc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
172
    return pSession
173
174
175
def _logoff(session):
176
    rc = MAPILogoff(session, 0, 0, 0)
177
    if rc != SUCCESS_SUCCESS:
6619.3.11 by Jelmer Vernooij
Use modern exceptions.
178
        raise MAPIError(rc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
179
180
181
def _resolveName(session, name):
182
    pRecipDesc = lpMapiRecipDesc()
183
    rc = MAPIResolveName(session, 0, name, 0, 0, byref(pRecipDesc))
184
    if rc != SUCCESS_SUCCESS:
6619.3.11 by Jelmer Vernooij
Use modern exceptions.
185
        raise MAPIError(rc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
186
    rd = pRecipDesc.contents
187
    name, address = rd.lpszName, rd.lpszAddress
188
    rc = MAPIFreeBuffer(pRecipDesc)
189
    if rc != SUCCESS_SUCCESS:
6619.3.11 by Jelmer Vernooij
Use modern exceptions.
190
        raise MAPIError(rc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
191
    return name, address
192
193
194
def _sendMail(session, recipient, subject, body, attach):
195
    nFileCount = len(attach)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
196
    if attach:
197
        MapiFileDesc_A = MapiFileDesc * len(attach)
198
        fda = MapiFileDesc_A()
199
        for fd, fa in zip(fda, attach):
200
            fd.ulReserved = 0
201
            fd.flFlags = 0
202
            fd.nPosition = -1
203
            fd.lpszPathName = fa
204
            fd.lpszFileName = None
205
            fd.lpFileType = None
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
206
        lpFiles = fda
207
    else:
208
        lpFiles = lpMapiFileDesc()
209
210
    RecipWork = recipient.split(';')
211
    RecipCnt = len(RecipWork)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
212
    MapiRecipDesc_A = MapiRecipDesc * len(RecipWork)
213
    rda = MapiRecipDesc_A()
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
214
    for rd, ra in zip(rda, RecipWork):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
215
        rd.ulReserved = 0
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
216
        rd.ulRecipClass = MAPI_TO
217
        try:
218
            rd.lpszName, rd.lpszAddress = _resolveName(session, ra)
219
        except WindowsError:
220
            # work-round for Mozilla Thunderbird
221
            rd.lpszName, rd.lpszAddress = None, ra
222
        rd.ulEIDSize = 0
223
        rd.lpEntryID = None
224
    recip = rda
225
226
    msg = MapiMessage(0, subject, body, None, None, None, 0, lpMapiRecipDesc(),
227
                      RecipCnt, recip,
228
                      nFileCount, lpFiles)
229
230
    rc = MAPISendMail(session, 0, byref(msg), MAPI_DIALOG, 0)
2681.3.6 by Lukáš Lalinsky
New version of simplemapi.py with MIT license.
231
    if rc != SUCCESS_SUCCESS:
6619.3.11 by Jelmer Vernooij
Use modern exceptions.
232
        raise MAPIError(rc)
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
233
234
235
def SendMail(recipient, subject="", body="", attachfiles=""):
236
    """Post an e-mail message using Simple MAPI
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
237
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
238
    recipient - string: address to send to (multiple addresses separated with a semicolon)
239
    subject   - string: subject header
240
    body      - string: message text
241
    attach    - string: files to attach (multiple attachments separated with a semicolon)
242
    """
243
244
    attach = []
245
    AttachWork = attachfiles.split(';')
6631.3.1 by Martin
Run 2to3 map fixer and refactor after
246
    for f in AttachWork:
247
        if os.path.exists(f):
248
            attach.append(os.path.abspath(f))
2681.3.3 by Lukáš Lalinsky
Convert to UNIX line endings.
249
250
    restore = os.getcwd()
251
    try:
252
        session = _logon()
253
        try:
254
            _sendMail(session, recipient, subject, body, attach)
255
        finally:
256
            _logoff(session)
257
    finally:
258
        os.chdir(restore)
259
260
261
if __name__ == '__main__':
262
    import sys
263
    recipient = "test@johnnypops.demon.co.uk"
264
    subject = "Test Message Subject"
265
    body = "Hi,\r\n\r\nthis is a quick test message,\r\n\r\ncheers,\r\nJohn."
266
    attachment = sys.argv[0]
267
    SendMail(recipient, subject, body, attachment)