Advertisement
Guest User

Untitled

a guest
May 8th, 2018
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.12 KB | None | 0 0
  1. from enum import Enum
  2. import hashlib
  3. import os
  4. import re
  5. import requests
  6. import sys
  7. import datetime
  8. import time
  9.  
  10. """
  11. Scalping bot but for seattle badminton ladder registration.
  12. Usage:
  13. 1. Change the configs below.
  14. 2. Run script early on registration day.
  15. 3. Chill.
  16. Note: Auto-registration doesn't work for some reason. Too lazy to debug. At least the script can be used as a detection tool.
  17. """
  18.  
  19. ############################################################
  20. # Configs
  21. username = ''
  22. password = '!'
  23. # The partner name as seen from the "Unregistered" column of registration table.
  24. # E.g. 'first_name lastname 1234' -- The whitespaces really do exist.
  25. partner = ''
  26. # 293 = May 15
  27. # Probably have to keep incrementing this by 2 every week.
  28. # If you exceed the latest play date, they will just register from max play_date.
  29. play_date = '293'
  30. # How often to try registering.
  31. delay_secs = 60
  32. play_date_str = "5/15/2018 8:00:00 PM"
  33. ######################################################################
  34.  
  35. class Status(Enum):
  36. SUCCESS = 0
  37. TEMPORARY_ERROR = 1
  38. PERMANENT_ERROR = 2
  39.  
  40. def main():
  41. while True:
  42. result = register(play_date, play_date_str, username, password, partner)
  43. print datetime.datetime.now().time()
  44. if result == Status.SUCCESS:
  45. os.system('spd-say "registration complete"')
  46. break
  47. time.sleep(delay_secs)
  48.  
  49. def register(play_date, play_date_str, username, password, partner):
  50. # 1. Get the initial session ids to be passed in future requests.
  51. initial_resp = requests.get("http://www.seattlebadmintonclub.com/Login.aspx")
  52. view_state = extract_hidden_form_value(initial_resp.text, '__VIEWSTATE')
  53. view_state_generator = extract_hidden_form_value(initial_resp.text, '__VIEWSTATEGENERATOR')
  54. event_validation = extract_hidden_form_value(initial_resp.text, '__EVENTVALIDATION')
  55. previous_page = extract_hidden_form_value(initial_resp.text, '__PREVIOUSPAGE')
  56. asp_net_session_id = initial_resp.cookies.get('ASP.NET_SessionId', '')
  57. forms_auth = initial_resp.cookies.get('.ASPXFORMSAUTH', '')
  58.  
  59. #2. Login request.
  60. login_body = {
  61. '__ASYNCPOST': 'true',
  62. '__EVENTARGUMENT': '',
  63. '__EVENTTARGET': '',
  64. '__EVENTVALIDATION': event_validation,
  65. '__PREVIOUSPAGE': previous_page,
  66. '__VIEWSTATE': view_state,
  67. '__VIEWSTATEGENERATOR': view_state_generator,
  68. 'ctl00$ScriptManager1': 'ctl00$bodyContentPlaceHolder$UpdatePanel1|ctl00$bodyContentPlaceHolder$Login1$LoginButton',
  69. 'ctl00$bodyContentPlaceHolder$Login1$LoginButton': 'Log In',
  70. 'ctl00$bodyContentPlaceHolder$Login1$Password': password,
  71. 'ctl00$bodyContentPlaceHolder$Login1$UserName': username
  72. }
  73.  
  74. login_headers = {
  75. 'Accept': '*/*',
  76. 'Accept-Encoding': 'gzip, deflate',
  77. 'Accept-Language': 'en-US,en;q=0.9,id;q=0.8',
  78. 'Cache-Control': 'no-cache',
  79. 'Connection': 'keep-alive',
  80. 'Content-Length': '1084',
  81. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  82. 'Host': 'www.seattlebadmintonclub.com',
  83. 'Origin': 'http://www.seattlebadmintonclub.com',
  84. 'Referer': 'http://www.seattlebadmintonclub.com/Login.aspx',
  85. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
  86. 'X-MicrosoftAjax': 'Delta=true'
  87. }
  88.  
  89. jar = requests.cookies.RequestsCookieJar()
  90. jar.set('ASP.NET_SessionId', asp_net_session_id)
  91.  
  92. login_resp = requests.post("http://www.seattlebadmintonclub.com/Login.aspx",
  93. data=login_body, headers=login_headers, cookies=jar)
  94. login_view_state = extract_hidden_form_value(login_resp.text, '__VIEWSTATE')
  95. login_view_state_generator = extract_hidden_form_value(login_resp.text, '__VIEWSTATEGENERATOR')
  96. login_event_validation = extract_hidden_form_value(login_resp.text, '__EVENTVALIDATION')
  97. login_session_id = login_resp.cookies.get('ASP.NET_SessionId', '')
  98. login_forms_auth = login_resp.cookies.get('.ASPXFORMSAUTH', '')
  99. jar.set('.ASPXFORMSAUTH', login_forms_auth)
  100.  
  101. if len(login_forms_auth) > 0:
  102. print ('Login successful!')
  103. else:
  104. print ('Login failed. Response: ' + login_resp.text[:20])
  105. return Status.PERMANENT_ERROR
  106.  
  107. #3. Load league radio buttons. Doesn't look like this can get bypassed. Need the new event validation ids.
  108. load_radio_headers = {
  109. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  110. 'Accept-Encoding': 'gzip, deflate',
  111. 'Accept-Language': 'en-US,en;q=0.9,id;q=0.8',
  112. 'Connection': 'keep-alive',
  113. 'Host': 'www.seattlebadmintonclub.com',
  114. 'Referer': 'http://www.seattlebadmintonclub.com/Login.aspx',
  115. 'Upgrade-Insecure-Requests': '1',
  116. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
  117. }
  118.  
  119. load_radio_resp = requests.get(
  120. "http://www.seattlebadmintonclub.com/Security.aspx",
  121. headers=load_radio_headers, cookies=jar)
  122. load_radio_view_state = extract_hidden_form_value(load_radio_resp.text, '__VIEWSTATE')
  123. load_radio_view_state_generator = extract_hidden_form_value(load_radio_resp.text, '__VIEWSTATEGENERATOR')
  124. load_radio_event_validation = extract_hidden_form_value(load_radio_resp.text, '__EVENTVALIDATION')
  125.  
  126. # Need to register POST twice. They chain the event validations.
  127. # It's only after this dance that the next GET Register2.aspx will show the ladder
  128. # Without this dance, it will GET Register2 will still show the radios.
  129. choose_radio_1_headers = {
  130. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  131. 'Accept-Encoding': 'gzip, deflate',
  132. 'Accept-Language': 'en-US,en;q=0.9,id;q=0.8',
  133. 'Connection': 'keep-alive',
  134. 'Host': 'www.seattlebadmintonclub.com',
  135. 'Referer': 'http://www.seattlebadmintonclub.com/Security.aspx',
  136. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
  137. 'X-MicrosoftAjax': 'Delta=true'
  138. }
  139.  
  140. choose_radio1_body = {
  141. 'ctl00$ScriptManager1': 'ctl00$bodyContentPlaceHolder$UpdatePanel1|ctl00$bodyContentPlaceHolder$leagueRadioButtonList$2',
  142. '__EVENTTARGET': 'ctl00$bodyContentPlaceHolder$leagueRadioButtonList$2',
  143. '__EVENTARGUMENT': '',
  144. '__LASTFOCUS': '',
  145. '__VIEWSTATE': load_radio_view_state,
  146. '__VIEWSTATEGENERATOR': load_radio_view_state_generator,
  147. '__EVENTVALIDATION': load_radio_event_validation,
  148. 'ctl00$bodyContentPlaceHolder$leagueRadioButtonList': '7',
  149. '__ASYNCPOST': 'true',
  150. }
  151.  
  152. choose_radio1_resp = requests.post(
  153. "http://www.seattlebadmintonclub.com/Security.aspx",
  154. data=choose_radio1_body, headers=choose_radio_1_headers, cookies=jar)
  155.  
  156. choose_radio1_view_state = extract_post_resp(choose_radio1_resp.text, '__VIEWSTATE')
  157. choose_radio1_view_state_generator = extract_post_resp(choose_radio1_resp.text, '__VIEWSTATEGENERATOR')
  158. choose_radio1_event_validation = extract_post_resp(choose_radio1_resp.text, '__EVENTVALIDATION')
  159.  
  160. #4. 2nd radio choosing.
  161. choose_radio2_body = {
  162. 'ctl00$ScriptManager1': 'ctl00$bodyContentPlaceHolder$UpdatePanel1|ctl00$bodyContentPlaceHolder$LoginButton',
  163. 'ctl00$bodyContentPlaceHolder$leagueRadioButtonList': '7',
  164. '__EVENTTARGET': '',
  165. '__EVENTARGUMENT': '',
  166. '__EVENTVALIDATION': choose_radio1_event_validation,
  167. '__LASTFOCUS': '',
  168. '__VIEWSTATE': choose_radio1_view_state,
  169. '__VIEWSTATEGENERATOR': choose_radio1_view_state_generator,
  170. '__ASYNCPOST': 'true',
  171. 'ctl00$bodyContentPlaceHolder$LoginButton': 'Enter',
  172. }
  173.  
  174. choose_radio2_resp = requests.post(
  175. "http://www.seattlebadmintonclub.com/Security.aspx",
  176. data=choose_radio2_body, headers=choose_radio_1_headers, cookies=jar)
  177.  
  178. # 5. Load registration page. Player list should show up.
  179. load_reg_headers = {
  180. 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
  181. 'Accept-Encoding': 'gzip, deflate',
  182. 'Accept-Language': 'en-US,en;q=0.9,id;q=0.8',
  183. 'Connection': 'keep-alive',
  184. 'Host': 'www.seattlebadmintonclub.com',
  185. 'Referer': 'http://www.seattlebadmintonclub.com/Security.aspx',
  186. 'Upgrade-Insecure-Requests': '1',
  187. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
  188. }
  189.  
  190. load_reg_resp = requests.get(
  191. "http://www.seattlebadmintonclub.com/Register2.aspx",
  192. headers=load_reg_headers, cookies=jar)
  193.  
  194. load_reg_view_state = extract_hidden_form_value(load_reg_resp.text, '__VIEWSTATE')
  195. load_reg_view_state_generator = extract_hidden_form_value(load_reg_resp.text, '__VIEWSTATEGENERATOR')
  196. load_reg_event_validation = extract_hidden_form_value(load_reg_resp.text, '__EVENTVALIDATION')
  197.  
  198. # 6 (Final). Make the actual registration request.
  199. register_body = {
  200. '__ASYNCPOST': 'true',
  201. '__EVENTARGUMENT': '',
  202. '__EVENTTARGET': '',
  203. '__EVENTVALIDATION': load_reg_event_validation,
  204. '__LASTFOCUS': '',
  205. '__VIEWSTATE': load_reg_view_state,
  206. '__VIEWSTATEGENERATOR': load_reg_view_state_generator,
  207. 'ctl00$ScriptManager1': 'ctl00$bodyContentPlaceHolder$UpdatePanel1|ctl00$bodyContentPlaceHolder$registerTB',
  208. 'ctl00$bodyContentPlaceHolder$ddlistPlayDate': play_date,
  209. 'ctl00$bodyContentPlaceHolder$listUnselected': partner,
  210. 'ctl00$bodyContentPlaceHolder$registerTB': 'Register'
  211. }
  212.  
  213. register_headers = {
  214. 'Accept': '*/*',
  215. 'Accept-Encoding': 'gzip, deflate',
  216. 'Accept-Language': 'en-US,en;q=0.9,id;q=0.8',
  217. 'Cache-Control': 'no-cache',
  218. 'Connection': 'keep-alive',
  219. 'Content-Length': '51043',
  220. 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
  221. 'Host': 'www.seattlebadmintonclub.com',
  222. 'Origin': 'http://www.seattlebadmintonclub.com',
  223. 'Referer': 'http://www.seattlebadmintonclub.com/Register2.aspx',
  224. 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
  225. 'X-MicrosoftAjax': 'Delta=true'
  226. }
  227.  
  228. register_resp = requests.get("http://www.seattlebadmintonclub.com/Register2.aspx",
  229. data=register_body, headers=register_headers, cookies=jar)
  230. if play_date_str not in register_resp.text:
  231. return Status.TEMPORARY_ERROR
  232. if 'Maximum number of teams' in register_resp.text:
  233. # Too lazy to regex to check if spot already taken.
  234. # If you run script early, then this should only mean next week's timeslot is not open yet.
  235. print ('All spots taken. Either registered too late, or spot not open yet')
  236. return Status.TEMPORARY_ERROR
  237. else:
  238. # Too lazy to check for other error cases.
  239. return Status.SUCCESS
  240.  
  241.  
  242. # Get the value corresponding to a hidden form field in html
  243. def extract_hidden_form_value(html_dump, hidden_field_name):
  244. search_result = re.search('id="' + hidden_field_name + '" value="(.*?)"', html_dump)
  245. return '' if search_result is None else search_result.group(1)
  246.  
  247. def extract_post_resp(resp_dump, field_name):
  248. search_result = re.search('\|' + field_name + '\|(.*?)\|', resp_dump)
  249. return '' if search_result is None else search_result.group(1)
  250.  
  251. # Summarize key-val strings. Values are summarized for ez comparison.
  252. def print_summary(dict):
  253. for k in dict:
  254. v = dict[k]
  255. hash = hashlib.md5(v.encode('utf-8')).hexdigest()
  256. print (" ", k, (v if (len(v) < 20) else '({})({}){}...{}'.format(len(v), hash, v[:5], v[-5:])))
  257.  
  258. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement