Posted By

vissu on 08/01/10


Tagged

python script free sms india way2sms


Versions (?)

Send free sms through way2sms (India)


 / Published in: Python
 

URL: http://viswanadh.com

This python script takes the SMS message and phone number as arguments.\\r\\n\\r\\n Before you run this script, please 1) search for \\\\'yourusername\\\\' in this file and replace it with your way2sms.com username. 2) search for \\\\'yourpassword\\\\' in this file and replace it with your way2sms.com password 3) save the file as way2sms and set executable permissions to this file\\r\\n\\r\\n Running the script ./way2sms \\\\"Hi, how are you?\\\\" \\\\"9876543210\\\\"\\r\\n\\r\\n The first argument is the message and the second argument is the phone number to which you want to send sms to.\\r\\n\\r\\n I tested this script in fedora as well as windows XP (of course, with all necessary python modules installed). I can\\\\'t guarantee that this script will run in future as way2sms website changes too often :p

  1. #! /usr/bin/python
  2. #----------------------------------------------------------------------
  3. #
  4. # Author: Laszlo Nagy
  5. #
  6. # Copyright: (c) 2005 by Szoftver Messias Bt.
  7. # Licence: BSD style
  8. #
  9. #
  10. #----------------------------------------------------------------------
  11. # WAY2SMS SMS Sender
  12. #----------------------------------------------------------------------
  13. #
  14. # Author: Kasi Viswanadh Yakkala
  15. #
  16. # Usage: way2sms <YourMessage> <PhoneNumber>
  17. #
  18. #----------------------------------------------------------------------
  19.  
  20. import os
  21. import md5
  22. import urllib
  23. import urllib2
  24. import mimetypes
  25. #from gzip import GzipFile
  26. import cStringIO
  27. from cPickle import loads,dumps
  28. import cookielib
  29. import random
  30. import sys
  31. import base64
  32.  
  33.  
  34. class MozillaCacher(object):
  35. """A dictionary like object, that can cache results on a storage device."""
  36. def __init__(self,cachedir='.cache'):
  37. self.cachedir = cachedir
  38. if not os.path.isdir(cachedir):
  39. os.mkdir(cachedir)
  40. def name2fname(self,name):
  41. return os.path.join(self.cachedir,name)
  42. def __getitem__(self,name):
  43. if not isinstance(name,str):
  44. raise TypeError()
  45. fname = self.name2fname(name)
  46. if os.path.isfile(fname):
  47. return file(fname,'rb').read()
  48. else:
  49. raise IndexError()
  50. def __setitem__(self,name,value):
  51. if not isinstance(name,str):
  52. raise TypeError()
  53. fname = self.name2fname(name)
  54. if os.path.isfile(fname):
  55. os.unlink(fname)
  56. f = file(fname,'wb+')
  57. try:
  58. f.write(value)
  59. finally:
  60. f.close()
  61. def __delitem__(self,name):
  62. if not isinstance(name,str):
  63. raise TypeError()
  64. fname = self.name2fname(name)
  65. if os.path.isfile(fname):
  66. os.unlink(fname)
  67. def __iter__(self):
  68. raise NotImplementedError()
  69. def has_key(self,name):
  70. return os.path.isfile(self.name2fname(name))
  71.  
  72. class MozillaEmulator(object):
  73. def __init__(self,cacher={},trycount=0):
  74. """Create a new MozillaEmulator object.
  75.  
  76. @param cacher: A dictionary like object, that can cache search results on a storage device.
  77. You can use a simple dictionary here, but it is not recommended.
  78. You can also put None here to disable caching completely.
  79. @param trycount: The download() method will retry the operation if it fails. You can specify -1 for infinite retrying.
  80. A value of 0 means no retrying. A value of 1 means one retry. etc."""
  81. self.cacher = cacher
  82. self.cookies = cookielib.CookieJar()
  83. self.debug = False
  84. self.trycount = trycount
  85. def _hash(self,data):
  86. h = md5.new()
  87. h.update(data)
  88. return h.hexdigest()
  89.  
  90. def build_opener(self,url,postdata=None,extraheaders={},forbid_redirect=False):
  91. txheaders = {
  92. 'Accept':'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
  93. 'Accept-Language':'en,hu;q=0.8,en-us;q=0.5,hu-hu;q=0.3',
  94. # 'Accept-Encoding': 'gzip, deflate',
  95. 'Accept-Charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
  96. # 'Keep-Alive': '300',
  97. # 'Connection': 'keep-alive',
  98. # 'Cache-Control': 'max-age=0',
  99. }
  100. for key,value in extraheaders.iteritems():
  101. txheaders[key] = value
  102. req = urllib2.Request(url, postdata, txheaders)
  103. self.cookies.add_cookie_header(req)
  104. if forbid_redirect:
  105. redirector = HTTPNoRedirector()
  106. else:
  107. redirector = urllib2.HTTPRedirectHandler()
  108.  
  109. http_handler = urllib2.HTTPHandler(debuglevel=self.debug)
  110. https_handler = urllib2.HTTPSHandler(debuglevel=self.debug)
  111.  
  112. u = urllib2.build_opener(http_handler,https_handler,urllib2.HTTPCookieProcessor(self.cookies),redirector)
  113. u.addheaders = [('User-Agent','Mozilla/5.0 (Windows; U; Windows NT 5.1; hu-HU; rv:1.7.8) Gecko/20050511 Firefox/1.0.4')]
  114. if not postdata is None:
  115. req.add_data(postdata)
  116. return (req,u)
  117.  
  118. def download(self,url,postdata=None,extraheaders={},forbid_redirect=False,
  119. trycount=None,fd=None,onprogress=None,only_head=False):
  120. """Download an URL with GET or POST methods.
  121.  
  122. @param postdata: It can be a string that will be POST-ed to the URL.
  123. When None is given, the method will be GET instead.
  124. @param extraheaders: You can add/modify HTTP headers with a dict here.
  125. @param forbid_redirect: Set this flag if you do not want to handle
  126. HTTP 301 and 302 redirects.
  127. @param trycount: Specify the maximum number of retries here.
  128. 0 means no retry on error. Using -1 means infinite retring.
  129. None means the default value (that is self.trycount).
  130. @param fd: You can pass a file descriptor here. In this case,
  131. the data will be written into the file. Please note that
  132. when you save the raw data into a file then it won't be cached.
  133. @param onprogress: A function that has two parameters:
  134. the size of the resource and the downloaded size. This will be
  135. called for each 1KB chunk. (If the HTTP header does not contain
  136. the content-length field, then the size parameter will be zero!)
  137. @param only_head: Create the openerdirector and return it. In other
  138. words, this will not retrieve any content except HTTP headers.
  139.  
  140. @return: The raw HTML page data, unless fd was specified. When fd
  141. was given, the return value is undefined.
  142. """
  143. if trycount is None:
  144. trycount = self.trycount
  145. cnt = 0
  146. while True:
  147. try:
  148. key = self._hash(url)
  149. if (self.cacher is None) or (not self.cacher.has_key(key)):
  150. req,u = self.build_opener(url,postdata,extraheaders,forbid_redirect)
  151. openerdirector = u.open(req)
  152. if self.debug:
  153. print req.get_method(),url
  154. print openerdirector.code,openerdirector.msg
  155. print openerdirector.headers
  156. self.cookies.extract_cookies(openerdirector,req)
  157. if only_head:
  158. return openerdirector
  159. if openerdirector.headers.has_key('content-length'):
  160. length = long(openerdirector.headers['content-length'])
  161. else:
  162. length = 0
  163. dlength = 0
  164. if fd:
  165. while True:
  166. data = openerdirector.read(1024)
  167. dlength += len(data)
  168. fd.write(data)
  169. if onprogress:
  170. onprogress(length,dlength)
  171. if not data:
  172. break
  173. else:
  174. data = ''
  175. while True:
  176. newdata = openerdirector.read(1024)
  177. dlength += len(newdata)
  178. data += newdata
  179. if onprogress:
  180. onprogress(length,dlength)
  181. if not newdata:
  182. break
  183. #data = openerdirector.read()
  184. if not (self.cacher is None):
  185. self.cacher[key] = data
  186. else:
  187. data = self.cacher[key]
  188. #try:
  189. # d2= GzipFile(fileobj=cStringIO.StringIO(data)).read()
  190. # data = d2
  191. #except IOError:
  192. # pass
  193. return data
  194. except urllib2.URLError:
  195. cnt += 1
  196. if (trycount > -1) and (trycount < cnt):
  197. raise
  198. # Retry :-)
  199. if self.debug:
  200. print "MozillaEmulator: urllib2.URLError, retryting ",cnt
  201.  
  202.  
  203. def post_multipart(self,url,fields, files, forbid_redirect=True):
  204. """Post fields and files to an http host as multipart/form-data.
  205. fields is a sequence of (name, value) elements for regular form fields.
  206. files is a sequence of (name, filename, value) elements for data to be uploaded as files
  207. Return the server's response page.
  208. """
  209. content_type, post_data = encode_multipart_formdata(fields, files)
  210. result = self.download(url,post_data,{
  211. 'Content-Type': content_type,
  212. 'Content-Length': str(len(post_data))
  213. },forbid_redirect=forbid_redirect
  214. )
  215. return result
  216.  
  217.  
  218. class HTTPNoRedirector(urllib2.HTTPRedirectHandler):
  219. """This is a custom http redirect handler that FORBIDS redirection."""
  220. def http_error_302(self, req, fp, code, msg, headers):
  221. e = urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)
  222. if e.code in (301,302):
  223. if 'location' in headers:
  224. newurl = headers.getheaders('location')[0]
  225. elif 'uri' in headers:
  226. newurl = headers.getheaders('uri')[0]
  227. e.newurl = newurl
  228. raise e
  229.  
  230.  
  231.  
  232. def encode_multipart_formdata(fields, files):
  233. """
  234. fields is a sequence of (name, value) elements for regular form fields.
  235. files is a sequence of (name, filename, value) elements for data to be uploaded as files
  236. Return (content_type, body) ready for httplib.HTTP instance
  237. """
  238. BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
  239. CRLF = ''
  240. L = []
  241. for (key, value) in fields:
  242. L.append('--' + BOUNDARY)
  243. L.append('Content-Disposition: form-data; name="%s"' % key)
  244. L.append('')
  245. L.append(value)
  246. for (key, filename, value) in files:
  247. L.append('--' + BOUNDARY)
  248. L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
  249. L.append('Content-Type: %s' % get_content_type(filename))
  250. L.append('')
  251. L.append(value)
  252. L.append('--' + BOUNDARY + '--')
  253. L.append('')
  254. body = CRLF.join(L)
  255. content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
  256. return content_type, body
  257.  
  258. def get_content_type(filename):
  259. return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
  260.  
  261. def smsg(sms_message="Default Message from way2sms script",phone_number=""):
  262. dl = MozillaEmulator()
  263. """ Make sure that we get cookies from the server before logging in """
  264. frontpage = dl.download("http://wwwm.way2sms.com/content/index.html",{},{},False)
  265. """ Log in to Way2sms server """
  266. post_data = "login=Login&username=yourusername&password=yourpassword"
  267. page = dl.download("http://wwwm.way2sms.com/auth.cl",post_data,{'Referer':'http://wwwm.way2sms.com/content/index.html'},False)
  268.  
  269. if "Problem while Authentication.. Please try again" in page:
  270. print "Cant login"
  271. elif "Hello" in page:
  272. print "Login Successful"
  273. post_data = "custid=undefine&Action=custfrom100000&HiddenAction=instantsms&login=&pass=&MobNo="+phone_number+"&textArea="+sms_message
  274. page = dl.download("http://wwwm.way2sms.com/FirstServletsms?custid=",post_data,{'Referer':'http://wwwm.way2sms.com/jsp/InstantSMS.jsp?val=0'},False)
  275. if "Message has been submitted successfully" in page:
  276. print "SMS sent successfully"
  277. logoutpage = dl.download("http://wwwm.way2sms.com/chat/logout.cl",{},{'Referer':'http://www2.way2sms.com//jsp/Main.jsp?id=41825F6E1C22654DE17497102AB859C5.d702'},False)
  278. logoutpage = dl.download("http://wwwm.way2sms.com/Signut","ysignout=yahoo",{'Referer':'http://www2.way2sms.com//jsp/Main.jsp?id=41825F6E1C22654DE17497102AB859C5.d702'},False)
  279. logoutpage = dl.download("http://wwwm.way2sms.com/LogOut","folder=inbox",{'Referer':'http://www2.way2sms.com//jsp/Main.jsp?id=41825F6E1C22654DE17497102AB859C5.d702'},False)
  280. logoutpage = dl.download("http://wwwm.way2sms.com/jsp/logout.jsp","",{'Referer':'http://www2.way2sms.com//jsp/Main.jsp?id=41825F6E1C22654DE17497102AB859C5.d702'},False)
  281. if 'successfully logged out' in logoutpage:
  282. print "Successfully logged out"
  283.  
  284.  
  285.  
  286. # HOW TO USE
  287. """ Main Function """
  288. if __name__ == "__main__":
  289. if len(sys.argv) < 2:
  290. sms_message="Default Message from way2sms script"
  291. phone_number="phone_number"
  292. elif len(sys.argv) == 2:
  293. sms_message=sys.argv[1]
  294. phone_number="phone_number"
  295. else:
  296. sms_message=sys.argv[1]
  297. phone_number=sys.argv[2]
  298. sms_message.lstrip('')
  299. sms_message.rstrip('')
  300. smsg(sms_message, phone_number)

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: vissu on August 1, 2010

Before you run this script, please 1) search for 'yourusername' in this file and replace it with your way2sms.com username. 2) search for 'yourpassword' in this file and replace it with your way2sms.com password 3) save the file as way2sms and set executable permissions to this file

Running the script ./way2sms "Hi, how are you?" "9876543210"

The first argument is the message and the second argument is the phone number to which you want to send sms to.

I tested this script in fedora as well as windows XP (of course, with all necessary python modules installed). I can't guarantee that this script will run in future as way2sms website changes too often :p

You need to login to post a comment.