1 # -*- coding: UTF-8 -*-
2 # vim: expandtab sw=4 ts=4 sts=4:
5 Module for writing SMS to Email.
7 __author__
= 'Michal Čihař'
8 __email__
= 'michal@cihar.com'
10 Copyright © 2003 - 2010 Michal Čihař
12 This program is free software; you can redistribute it and/or modify it
13 under the terms of the GNU General Public License version 2 as published by
14 the Free Software Foundation.
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 from Wammu
.Utils
import SearchNumber
27 from Wammu
.MessageDisplay
import SmsTextFormat
28 from email
.MIMEAudio
import MIMEAudio
29 from email
.MIMEImage
import MIMEImage
30 from email
.MIMEText
import MIMEText
31 from email
.MIMEMultipart
import MIMEMultipart
33 from hashlib
import md5
35 from hashlib
import md5
37 from md5
import new
as md5
43 if Wammu
.gammu_error
== None:
46 HEADER_FORMAT
= 'X-Wammu-%s'
47 CID_FORMAT
= '%d*sms@wammu.sms'
62 Convert XPM data to PNG image.
64 @todo: I'd like to avoid creating temporary file, but even PIL doesn't
65 seem to provide such functionality.
67 handle
, name
= tempfile
.mkstemp()
69 bitmap
= wx
.BitmapFromXPMData(image
)
70 bitmap
.SaveFile(name
, wx
.BITMAP_TYPE_PNG
)
77 def RingtoneToMIDI(data
):
79 Converts ringtone to MIDI data.
81 @todo: I'd like to avoid creating temporary file, but Gammmu doesn't
82 provide such functionality.
84 handle
, name
= tempfile
.mkstemp()
85 f
= os
.fdopen(handle
, 'w+')
86 gammu
.SaveRingtone(f
, data
, 'mid')
93 def DateToString(date
):
95 Convert date to RFC 2822 format.
97 return email
.Utils
.formatdate(time
.mktime(date
.timetuple()), True)
99 def SMSToMail(cfg
, sms
, lookuplist
= None, mailbox
= False):
101 Converts SMS to formated mail. It will contain all images and sounds from
102 message and predefined animations. Also text formatting is preserved in
105 msg
= MIMEMultipart('related', None, None, type='text/html')
108 if lookuplist
!= None:
109 i
= SearchNumber(lookuplist
, sms
['Number'])
111 msg
.add_header(HEADER_FORMAT
% 'ContactID', str(i
))
112 name
= '%s ' % lookuplist
[i
]['Name']
114 for header
in PARTS_TO_HEADER
:
115 msg
.add_header(HEADER_FORMAT
% header
, unicode(sms
['SMS'][0][header
]))
116 msg
.add_header(HEADER_FORMAT
% 'SMSC', sms
['SMS'][0]['SMSC']['Number'])
117 if sms
['SMS'][0]['SMSCDateTime'] is not None:
118 msg
.add_header(HEADER_FORMAT
% 'SMSCDate',
119 DateToString(sms
['SMS'][0]['SMSCDateTime']))
121 remote
= '%s<%s@wammu.sms>' % (name
, sms
['Number'].replace(' ', '_'))
122 local
= cfg
.Read('/MessageExport/From')
124 if sms
['SMS'][0]['Type'] == 'Submit':
130 prepend
= ('Received: from %s via GSM\n' %
131 unicode(sms
['SMS'][0]['SMSC']['Number'])) + prepend
133 if len(sms
['Name']) > 0 :
134 msg
['Subject'] = SmsTextFormat(cfg
, sms
['Name'], False)
136 msg
['Subject'] = SmsTextFormat(cfg
, sms
['Text'], False)[:50] + '...'
138 if sms
['DateTime'] is not None:
139 msg
['Date'] = DateToString(sms
['DateTime'])
141 if sms
.has_key('SMSInfo'):
144 for i
in sms
['SMSInfo']['Entries']:
145 if i
['ID'] in Wammu
.Data
.SMSIDs
['PredefinedAnimation']:
146 if i
['Number'] > len(Wammu
.Data
.PredefinedAnimations
):
147 sub
= MIMEImage(XPMToPNG(Wammu
.Data
.UnknownPredefined
))
149 img
= Wammu
.Data
.PredefinedAnimations
[i
['Number']][1]
152 sub
.add_header('Content-ID', '<%s>' % CID_FORMAT
% cid
)
153 sub
.add_header('Content-Disposition', 'inline')
155 text
= text
+ '<img src="cid:%s">' % (CID_FORMAT
% cid
)
159 if 0 and i
['ID'] in Wammu
.Data
.SMSIDs
['PredefinedSound']:
160 if i
['Number'] >= len(Wammu
.Data
.PredefinedSounds
):
164 sub
.add_header('Content-Disposition', 'attachment')
167 if i
['ID'] in Wammu
.Data
.SMSIDs
['Sound']:
168 sub
= MIMEAudio(RingtoneToMIDI(i
['Ringtone']), 'midi')
169 sub
.add_header('Content-Disposition', 'attachment')
172 if i
['ID'] in Wammu
.Data
.SMSIDs
['Text']:
174 for format_data
in Wammu
.Data
.TextFormats
:
175 for name
, dummy
, style
in format_data
[1:]:
176 if i
.has_key(name
) and i
[name
]:
178 text
= text
+ (fmt
% SmsTextFormat(cfg
, i
['Buffer']))
180 if i
['ID'] in Wammu
.Data
.SMSIDs
['Bitmap']:
181 for bitmap
in i
['Bitmap']:
182 sub
= MIMEImage(XPMToPNG(bitmap
['XPM']))
183 sub
.add_header('Content-ID', '<%s>' % CID_FORMAT
% cid
)
184 sub
.add_header('Content-Disposition', 'inline')
186 text
= text
+ '<img src="cid:%s">' % (CID_FORMAT
% cid
)
189 if i
['ID'] in Wammu
.Data
.SMSIDs
['Animation']:
190 for bitmap
in i
['Bitmap']:
191 sub
= MIMEImage(XPMToPNG(bitmap
['XPM']))
192 sub
.add_header('Content-ID', '<%s>' % CID_FORMAT
% cid
)
193 sub
.add_header('Content-Disposition', 'inline')
195 text
= text
+ '<img src="cid:%s">' % (CID_FORMAT
% cid
)
199 text
= SmsTextFormat(cfg
, sms
['Text'])
201 html
= '<html><head></head><body>%s</body></html>'
202 sub
= MIMEText(html
% text
.encode('utf-8'), 'html', 'utf-8')
205 if sms
['DateTime'] is not None:
206 filename
= '%s-%s-%s.eml' % (
207 sms
['SMS'][0]['Type'],
208 sms
['DateTime'].strftime("%Y%m%d%H%M%S"),
209 md5(sms
['Text'].encode('utf-8')).hexdigest())
211 filename
= '%s-%s.eml' % (
212 sms
['SMS'][0]['Type'],
213 md5(sms
['Text'].encode('utf-8')).hexdigest())
216 msgid
= '<%s@%s>' % (filename
[:-4], sms
['Number'].replace(' ', '_'))
217 msgid
= msgid
.encode('ascii', 'xmlcharrefreplace')
218 msg
.add_header('Message-ID', msgid
)
221 if sms
['DateTime'] is None:
222 timestamp
= time
.asctime(time
.localtime(None))
224 timestamp
= time
.asctime(sms
['DateTime'].timetuple())
225 prepend
= ('From wammu@wammu.sms %s\n' % timestamp
) + prepend
227 return filename
, prepend
+ msg
.as_string(), msgid