Skip to content
This repository was archived by the owner on Feb 28, 2025. It is now read-only.

Commit 5259c09

Browse files
committed
독립 repo로 이전
1 parent 1411aa6 commit 5259c09

16 files changed

Lines changed: 802 additions & 0 deletions

coolsms.py

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
# -*- coding: utf8 -*-
2+
"""
3+
Copyright (C) 2008-2015 NURIGO
4+
http://www.coolsms.co.kr
5+
"""
6+
7+
__version__ = "1.1"
8+
9+
from hashlib import md5
10+
import sys,httplib,urllib,hmac,mimetypes,uuid,json,time
11+
import platform
12+
# reload(sys) needs to use sys.setdefaultencoding()
13+
reload(sys)
14+
sys.setdefaultencoding('utf-8')
15+
16+
# send multipart form to the server
17+
def post_multipart(host, selector, fields, files):
18+
content_type, body = encode_multipart_formdata(fields, files)
19+
h = httplib.HTTPS(host)
20+
h.putrequest('POST', selector)
21+
h.putheader('content-type', content_type)
22+
h.putheader('content-length', str(len(body)))
23+
h.putheader('User-Agent', 'sms-python')
24+
h.endheaders()
25+
h.send(body)
26+
errcode, errmsg, headers = h.getreply()
27+
return errcode, errmsg, h.file.read()
28+
29+
# format multipart form
30+
def encode_multipart_formdata(fields, files):
31+
BOUNDARY = str(uuid.uuid1())
32+
CRLF = '\r\n'
33+
L = []
34+
for key, value in fields.items():
35+
L.append('--' + BOUNDARY)
36+
L.append('Content-Disposition: form-data; name="%s"' % key)
37+
L.append('')
38+
L.append(value)
39+
L.append('')
40+
body = CRLF.join(L)
41+
for key, value in files.items():
42+
body = body + '--' + BOUNDARY + CRLF
43+
body = body + 'Content-Type: %s' % get_content_type(value['filename']) + CRLF
44+
body = body + 'Content-Disposition: form-data; name="%s"; filename="%s"' % (key, value['filename']) + CRLF
45+
body = body + CRLF
46+
body = body.encode('utf-8') + value['content'] + CRLF
47+
body = body + '--' + BOUNDARY + '--' + CRLF
48+
body = body + CRLF
49+
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
50+
return content_type, body
51+
52+
def get_content_type(filename):
53+
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
54+
55+
# class rest
56+
# SMS Gateway access url : https://api.coolsms.co.kr/{verson}/{resource name}
57+
class rest:
58+
# SMS Gateway address
59+
host = 'api.coolsms.co.kr'
60+
61+
# use secure channel as default
62+
port = 443
63+
64+
# api version
65+
api_version = '1.5'
66+
67+
# API Key
68+
api_key = None
69+
70+
# API Secret
71+
api_secret = None
72+
73+
# solution registration key
74+
srk = None
75+
76+
# message type (sms, lms, mms)
77+
mtype = 'sms'
78+
79+
# image file
80+
imgfile = None
81+
82+
# error handle
83+
error_string = None
84+
85+
# TRUE : test mode
86+
test = False
87+
88+
# application version
89+
app_version = 'APP 1.0'
90+
91+
# constructor
92+
def __init__(self, api_key, api_secret, app_version = None, srk = None, test = False, api_version = None):
93+
self.api_key = api_key
94+
self.api_secret = api_secret
95+
self.srk = srk
96+
if app_version:
97+
self.app_version = app_version
98+
self.test = test
99+
if api_version:
100+
self.api_version = api_version
101+
102+
# return salt, timestamp, signature
103+
def __get_signature__(self):
104+
salt = str(uuid.uuid1())
105+
timestamp = str(int(time.time()))
106+
data = timestamp + salt
107+
return timestamp, salt, hmac.new(self.api_secret, data, md5)
108+
109+
# error handle
110+
def __set_error__(self, error_str):
111+
self.error_string = error_str
112+
113+
# return message type set
114+
def get_type(self):
115+
return self.mtype
116+
117+
# return error string set
118+
def get_error(self):
119+
return self.error_string
120+
121+
# set one of sms , lms , mms
122+
def set_type(self, mtype):
123+
if mtype.lower() not in ['sms','lms','mms']:
124+
return False
125+
self.mtype = mtype.lower()
126+
return True
127+
128+
# set image file path
129+
def set_image(self, image):
130+
self.imgfile = image
131+
132+
# access to send resource
133+
def send(self, to=None, text=None, sender=None, mtype=None, subject=None, image=None, datetime=None, extension=None, app_version=None):
134+
"""Request to REST API server to send SMS messages
135+
136+
Arguments:
137+
to : A comma seperated string which contains phone numbers.
138+
text : Message content
139+
sender : sender id
140+
mtype : one of sms, lms, mms
141+
subject : If you send LMS or MMS, you should input the subject of the message(s).
142+
image : Include image, when you send MMS.
143+
datetime : Use this field when you send scheduled messages.
144+
extension : JSON formatted string. Please refer to API document.
145+
app_version : You'd better set this field as your own application's name. It's useful when you need any helf from COOLSMS service center.
146+
147+
Returns:
148+
A JSON type string will be returned. On failure, False will be returned.
149+
"""
150+
# convert list to a comma seperated string
151+
if type(to) == list:
152+
to = ','.join(to)
153+
154+
if mtype:
155+
if mtype.lower() not in ['sms','lms','mms']:
156+
self.__set_error__('invalid message type')
157+
return False
158+
else:
159+
mtype = self.get_type()
160+
161+
os_platform = platform.system()
162+
dev_lang = "Python %s" % platform.python_version()
163+
sdk_version = "sms-python %s" % __version__
164+
if app_version:
165+
self.app_version = app_version
166+
167+
# get authentication info.
168+
timestamp, salt, signature = self.__get_signature__()
169+
170+
fields = {'api_key':self.api_key
171+
, 'timestamp':timestamp
172+
, 'salt':salt
173+
, 'signature':signature.hexdigest()
174+
, 'type':mtype
175+
, 'os_platform':os_platform
176+
, 'dev_lang':dev_lang
177+
, 'sdk_version':sdk_version
178+
, 'app_version':self.app_version}
179+
if self.test:
180+
fields['mode'] = 'test'
181+
if self.srk != None:
182+
fields['srk'] = self.srk
183+
if to:
184+
fields['to'] = to
185+
if text:
186+
fields['text'] = text
187+
if sender:
188+
fields['from'] = sender
189+
if subject:
190+
fields['subject'] = subject
191+
if datetime:
192+
fields['datetime'] = datetime
193+
if extension:
194+
fields['extension'] = extension
195+
196+
if image == None:
197+
image = self.imgfile
198+
199+
if mtype.lower() == 'mms':
200+
if image == None:
201+
self.__set_error__('image file path input required')
202+
return False
203+
try:
204+
with open(image, 'rb') as content_file:
205+
content = content_file.read()
206+
except IOError as e:
207+
self.__set_error__("I/O error({0}): {1}".format(e.errno, e.strerror))
208+
return False
209+
except:
210+
self.__set_error__("Unknown error")
211+
return False
212+
files = {'image':{'filename':image,'content':content}}
213+
else:
214+
files = {}
215+
216+
# request post multipart-form
217+
host = self.host + ':' + str(self.port)
218+
selector = "/sms/%s/send" % self.api_version
219+
220+
try:
221+
status, reason, response = post_multipart(host, selector, fields, files)
222+
except:
223+
self.__set_error__("could not connect to server")
224+
return False
225+
if status != 200:
226+
try:
227+
err = json.loads(response)
228+
except:
229+
self.__set_error__("%u:%s" % (status, reason))
230+
return False
231+
self.__set_error__("%s:%s" % (err['code'], reason))
232+
return False
233+
return json.loads(response)
234+
235+
# access to sent resource
236+
def status(self, page = 1, count = 20, s_rcpt = None, s_start = None, s_end = None, mid = None):
237+
params = dict()
238+
if page:
239+
params['page'] = page
240+
if count:
241+
params['count'] = count
242+
if s_rcpt:
243+
params['s_rcpt'] = s_rcpt
244+
if s_start:
245+
params['s_start'] = s_start
246+
if s_end:
247+
params['s_end'] = s_end
248+
if mid:
249+
params['mid'] = mid
250+
response, obj = self.request_get('sent', params)
251+
return obj
252+
253+
# access to status resource
254+
def line_status(self, count = 1):
255+
params = dict()
256+
if count:
257+
params['count'] = count
258+
response, obj = self.request_get('status', params)
259+
return obj
260+
261+
# access to balance resource
262+
def balance(self):
263+
timestamp, salt, signature = self.__get_signature__()
264+
response, obj = self.request_get('balance')
265+
return int(obj['cash']), int(obj['point'])
266+
267+
# access to cancel resource
268+
def cancel(self, mid = None, gid = None):
269+
if mid == None and gid == None:
270+
return False
271+
272+
params = dict()
273+
if mid:
274+
params['mid'] = mid
275+
if gid:
276+
params['gid'] = gid
277+
278+
response, obj = self.request_post('cancel', params)
279+
if response.status == 200:
280+
return True
281+
return False
282+
283+
def request_get(self, resource, params = None):
284+
timestamp, salt, signature = self.__get_signature__()
285+
base_params = {'api_key':self.api_key, 'timestamp':timestamp, 'salt':salt, 'signature':signature.hexdigest()}
286+
if params:
287+
base_params = dict(base_params.items() + params.items())
288+
params_str = urllib.urlencode(base_params)
289+
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain", "User-Agent": "sms-python"}
290+
conn = httplib.HTTPSConnection(self.host, self.port)
291+
conn.request("GET", "/sms/%s/%s?" % (self.api_version, resource) + params_str, None, headers)
292+
response = conn.getresponse()
293+
data = response.read()
294+
conn.close()
295+
obj = response, json.loads(data)
296+
return obj
297+
298+
def request_post(self, resource, params = None):
299+
timestamp, salt, signature = self.__get_signature__()
300+
base_params = {'api_key':self.api_key, 'timestamp':timestamp, 'salt':salt, 'signature':signature.hexdigest()}
301+
if params:
302+
base_params = dict(base_params.items() + params.items())
303+
params_str = urllib.urlencode(base_params)
304+
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain", "User-Agent": "sms-python"}
305+
conn = httplib.HTTPSConnection(self.host, self.port)
306+
conn.request("POST", "/sms/%s/%s" % (self.api_version, resource), params_str, headers)
307+
response = conn.getresponse()
308+
data = response.read()
309+
conn.close()
310+
json_obj = None
311+
if data:
312+
json_obj = json.loads(data)
313+
return response, json_obj

coolsms.pyc

9.61 KB
Binary file not shown.

examples/balance.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf8 -*-
2+
"""
3+
Copyright (C) 2008-2014 NURIGO
4+
http://www.coolsms.co.kr
5+
"""
6+
import sys
7+
sys.path.append("..")
8+
import coolsms
9+
10+
def main():
11+
api_key = 'NCS52A57F48C3D32'
12+
api_secret = '5AC44E03CE8E7212D9D1AD9091FA9966'
13+
cool = coolsms.rest(api_key, api_secret)
14+
cash, point = cool.balance()
15+
print "cash : %u, point : %u" % (cash, point)
16+
17+
if __name__ == "__main__":
18+
main()
19+
sys.exit(0)

examples/cancel_reservation.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf8 -*-
2+
"""
3+
Copyright (C) 2008-2014 NURIGO
4+
http://www.coolsms.co.kr
5+
"""
6+
import sys
7+
sys.path.append("..")
8+
import coolsms
9+
10+
def main():
11+
api_key = 'NCS52A57F48C3D32'
12+
api_secret = '5AC44E03CE8E7212D9D1AD9091FA9966'
13+
cool = coolsms.rest(api_key, api_secret)
14+
status = cool.cancel(mid='R1M52D35EAF44960')
15+
print status
16+
17+
if __name__ == "__main__":
18+
main()
19+
sys.exit(0)

examples/get_status_by_mid.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf8 -*-
2+
"""
3+
Copyright (C) 2008-2014 NURIGO
4+
http://www.coolsms.co.kr
5+
"""
6+
import sys
7+
sys.path.append("..")
8+
import coolsms
9+
10+
def main():
11+
api_key = 'NCS52A57F48C3D32'
12+
api_secret = '5AC44E03CE8E7212D9D1AD9091FA9966'
13+
cool = coolsms.rest(api_key, api_secret)
14+
status = cool.status(mid='R2M5301BF9F6113C')
15+
print status
16+
17+
if __name__ == "__main__":
18+
main()
19+
sys.exit(0)

examples/line_status.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf8 -*-
2+
"""
3+
Copyright (C) 2008-2014 NURIGO
4+
http://www.coolsms.co.kr
5+
"""
6+
import sys
7+
sys.path.append("..")
8+
import coolsms
9+
10+
def main():
11+
api_key = 'NCS52A57F48C3D32'
12+
api_secret = '5AC44E03CE8E7212D9D1AD9091FA9966'
13+
cool = coolsms.rest(api_key, api_secret)
14+
status = cool.line_status()
15+
print status
16+
17+
if __name__ == "__main__":
18+
main()
19+
sys.exit(0)

0 commit comments

Comments
 (0)