Advertisement
Guest User

Untitled

a guest
Apr 11th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.93 KB | None | 0 0
  1. """Move the mouse based on Beam Interactive controls."""
  2.  
  3. import asyncio
  4. from urllib.parse import urljoin
  5. from getpass import getpass
  6. from math import isnan
  7.  
  8. from beam_interactive import start, proto
  9. from requests import Session
  10.  
  11. URL = "https://beam.pro/api/v1/"
  12. URL_LOGIN = "https://beam.pro/api/v1/users/login"
  13. URL_INTERACIVE = "https://beam.pro/api/v1/interactive/{channel}/robot"
  14.  
  15. USE_2FA = False
  16. AUTHENTICATION = {
  17. "username": "",
  18. "password": "",
  19. "code": "" # Unnecessary if two-factor authentication is disabled.
  20. }
  21.  
  22. if AUTHENTICATION['username'] == '':
  23. AUTHENTICATION['username'] = input("Username : ")
  24.  
  25. if AUTHENTICATION['password'] == '':
  26. AUTHENTICATION['password'] = getpass("Password : ")
  27.  
  28. if USE_2FA:
  29. while not ((len(AUTHENTICATION['code']) == 6) or
  30. any(c.isalpha() for c in AUTHENTICATION['code'])):
  31.  
  32. AUTHENTICATION['code'] = input("2FA code : ")
  33.  
  34. if (len(AUTHENTICATION['code']) < 6) or (len(AUTHENTICATION['code']) > 6):
  35. print("ERROR: 2FA Code must be 6 characters long")
  36.  
  37. if any(c.isalpha() for c in AUTHENTICATION['code']):
  38. print("ERROR: 2FA Code MUST NOT contain letters or special characters")
  39.  
  40.  
  41. SESSION = Session()
  42.  
  43. def _build(endpoint, *, url=URL):
  44. """Build an address for an API endpoint."""
  45. return urljoin(url, endpoint.lstrip('/'))
  46.  
  47.  
  48. def login(username, password, code='', *, session=SESSION, url=URL_LOGIN):
  49. """Log into Beam via the API."""
  50. auth = dict(username=username, password=password, code=code)
  51. return session.post(url, data=auth).json()
  52.  
  53.  
  54. def join_interactive(channel, *, session=SESSION, url=URL_INTERACIVE):
  55. """Retrieve interactive connection information."""
  56. return session.get(url.format(channel=channel)).json()
  57.  
  58.  
  59. def on_error(error):
  60. """Handle error packets."""
  61. print("Oh no, there was an error!", error.message)
  62.  
  63.  
  64. def on_report(report):
  65. """Handle report packets."""
  66.  
  67. # Tactile Mouse Click Control
  68. for tactile in report.tactile:
  69. if tactile.pressFrequency:
  70. print("Tactile report received!", tactile, sep='\n')
  71.  
  72. # Joystick Mouse Movement Control
  73. for joystick in report.joystick:
  74. if not isnan(joystick.coordMean.x) and not isnan(joystick.coordMean.y):
  75. print("Joystick report received!", joystick, sep='\n')
  76.  
  77.  
  78.  
  79. @asyncio.coroutine
  80. def run():
  81. """Run the interactive app."""
  82.  
  83. # Authenticate with Beam and retrieve the channel id from the response.
  84. channel_id = login( # **AUTHENTICATION is a cleaner way of doing this.
  85. AUTHENTICATION["username"],
  86. AUTHENTICATION["password"],
  87. AUTHENTICATION["code"]
  88. )["channel"]["id"]
  89.  
  90. # Get Interactive connection information.
  91. data = join_interactive(channel_id)
  92.  
  93. # Initialize a connection with Interactive.
  94. connection = yield from start(data["address"], channel_id, data["key"])
  95.  
  96. # Handlers, to be called when Interactive packets are received.
  97. handlers = {
  98. proto.id.error: on_error,
  99. proto.id.report: on_report
  100. }
  101.  
  102. # wait_message is a coroutine that will return True when it receives
  103. # a complete packet from Interactive, or False if we got disconnected.
  104. while (yield from connection.wait_message()):
  105.  
  106. # Decode the Interactive packet.
  107. decoded, _ = connection.get_packet()
  108. packet_id = proto.id.get_packet_id(decoded)
  109.  
  110. # Handle the packet with the proper handler, if its type is known.
  111. if packet_id in handlers:
  112. handlers[packet_id](decoded)
  113. elif decoded is None:
  114. print("Unknown bytes were received. Uh oh!", packet_id)
  115. else:
  116. print("We got packet {} but didn't handle it!".format(packet_id))
  117.  
  118. connection.close()
  119.  
  120.  
  121. if __name__ == "__main__":
  122. loop = asyncio.get_event_loop()
  123.  
  124. try:
  125. loop.run_until_complete(run())
  126. finally:
  127. loop.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement