1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 from xml.dom.minidom import parseString
36
38 """
39 Parses the XML respponse of a BlueVia Adsvertising requests and constructs a JSON object as result
40
41 Internal method
42 """
43
44 dom = parseString(xmlString)
45 arId = dom.getElementsByTagName ("NS1:adResponse")[0].attributes.getNamedItem("id").value
46 arVersion = dom.getElementsByTagName ("NS1:adResponse")[0].attributes.getNamedItem("version").value
47 adId = dom.getElementsByTagName ("NS1:ad")[0].attributes.getNamedItem("id").value
48 adPlace = dom.getElementsByTagName ("NS1:ad")[0].attributes.getNamedItem("ad_placement").value
49 adCampaign = dom.getElementsByTagName ("NS1:ad")[0].attributes.getNamedItem("campaign").value
50 adFlight = dom.getElementsByTagName ("NS1:ad")[0].attributes.getNamedItem("flight").value
51 adPresent = dom.getElementsByTagName ("NS1:resource")[0].attributes.getNamedItem("ad_presentation").value
52 ce = dom.getElementsByTagName ("NS1:creative_element")[0]
53 ceType = ce.attributes.items()[0]
54 ceAttrs = [(n.attributes.items(), n.childNodes[0].nodeValue) for n in ce.childNodes if n.nodeName == "NS1:attribute"]
55 ceInter = dom.getElementsByTagName ("NS1:interaction")[0]
56 ciType = ceInter.attributes.items()[0]
57 ciAttrs = [(n.attributes.items(), n.childNodes[0].nodeValue) for n in ceInter.childNodes if n.nodeName == "NS1:attribute"]
58
59
60 creativeElement = {
61 ceType[0]:ceType[1],
62 "attributes":[{x[0][0][0]:x[0][0][1],"value":x[1]} for x in ceAttrs],
63 "interaction":{ciType[0]:ciType[1],
64 "attributes":[{x[0][0][0]:x[0][0][1],"value":x[1]} for x in ciAttrs]}
65 }
66 fullAd = {"adResponse": { \
67 "id":arId, \
68 "version":arVersion, \
69 "ad": { \
70 "id":adId, \
71 "ad_place_ment":adPlace, \
72 "campaign":adCampaign, \
73 "flight":adFlight, \
74 "resource":{ \
75 "ad_representation":adPresent, \
76 "creative_element": creativeElement}}}}
77 return fullAd
78
79
80
81
82
83
84 import random, string, sys, mimetypes, base64, email, os
85
87 return ''.join (random.choice (string.letters) for ii in range (length + 1))
88
90 """
91 Encodes messages and files in Multipart MIME format fitting for BlueVia Send MMS API
92
93 Internal method
94 """
95
96
97
98 boundary1 = _random_string (32)
99 boundary2 = _random_string (32)
100
101 def get_content_type (filename):
102 return mimetypes.guess_type (filename)[0] or 'application/octet-stream'
103
104 def encode_message (num, message, boundary):
105 return ('--' + boundary,
106 'Content-Disposition: attachment; name="message%d.txt"' % num,
107 'Content-Type: text/plain',
108 'Content-Transfer-Encoding: 8bit;charset=UTF-8',
109 '', str(message))
110
111 def encode_file (field_name, boundary):
112 filename = files [field_name]
113 return ('\r\n--' + boundary,
114 'Content-Disposition: attachment; filename="%s"' % filename,
115 'Content-Type: %s' % get_content_type(filename),
116 'Content-Transfer-Encoding: base64',
117 '', base64.encodestring(open (filename, 'rb').read ()))
118
119 lines = ['\r\n--' + boundary1,
120 'Content-Disposition: form-data; name="root-fields"',
121 'Content-Type: application/json;charset=UTF-8',
122 'Content-Transfer-Encoding: 8bit',
123 '', str(root)]
124
125 if messages or files:
126 att = ('\r\n--' + boundary1,
127 'Content-Disposition: form-data; name="attachments"',
128 'Content-Type: multipart/mixed; boundary=%s' % boundary2,
129 '')
130 lines.extend(att)
131
132 if messages:
133 i=0
134 for msg in messages:
135 lines.extend (encode_message(i, msg, boundary2))
136 i += 1
137 if files:
138 for name in files:
139 lines.extend (encode_file (name, boundary2))
140
141 lines.extend (('--%s--' % boundary2, ''))
142 lines.extend (('--%s--' % boundary1, ''))
143 body = '\r\n'.join (lines)
144
145 headers = {'content-type': 'multipart/form-data; boundary=' + boundary1,
146 'content-length': str (len (body))}
147
148 return body, headers
149
151 """
152 Decodes the BlueVia Multipart MIME body from retrieving MMS attachemnts into a folder with message and file objects
153
154 Internal method
155 """
156
157 common_ext = { 'image/jpg': '.jpg',
158 'image/jpeg': '.jpg',
159 'image/png': '.png',
160 'application/json': '.json',
161 'application/xml': '.xml',
162 'text/plain': '.txt',
163 'text/html': '.html'
164 }
165
166 result = []
167 directory = msgId
168 os.mkdir(directory)
169
170
171 boundary = body[:200].split("\r\n")[1][2:]
172 fullbody = 'Content-Type: multipart/mixed; boundary="%s"\r\n%s\r\n"' % (boundary, body)
173
174 msg = email.message_from_string(fullbody)
175 counter = 1
176 for part in msg.walk():
177
178 if part.get_content_maintype() == 'multipart':
179 continue
180 filename = part.get_filename()
181 ext = common_ext.get(part.get_content_type())
182 if not ext:
183 ext = mimetypes.guess_extension(part.get_content_type())
184 if not ext:
185 ext = '.bin'
186 if filename:
187 if not os.path.splitext(filename)[1]:
188 filename += ext
189 else:
190 filename = 'part-%03d%s' % (counter, ext)
191 counter += 1
192
193 fp = open(os.path.join(directory, filename), 'wb')
194 fp.write(part.get_payload(decode=True))
195 fp.close()
196
197 print "%d files saved to %s" % (counter, msgId)
198 return (counter, msgId)
199