server_controller.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import json
  2. from bottle import request, response
  3. import model
  4. from debug import debug
  5. def missing_attributes(attributes):
  6. for attr in attributes:
  7. if attr not in request.json or request.json[attr] == '' or request.json[attr] is None:
  8. if str(attr) == 'session_id':
  9. return 'You are not signed in.'
  10. return 'Missing value for attribute ' + str(attr)
  11. if str(attr) == 'session_id':
  12. if not model.valid_session_id(request.json['session_id']):
  13. return 'You are not signed in.'
  14. return False
  15. def login():
  16. missing = missing_attributes(['username', 'password'])
  17. if missing:
  18. return bad_request(missing)
  19. username = request.json['username']
  20. password = request.json['password']
  21. session_id = model.login(username, password)
  22. if session_id:
  23. return {'session_id': session_id}
  24. else:
  25. return forbidden('Invalid login data')
  26. def depot():
  27. missing = missing_attributes(['session_id'])
  28. if missing:
  29. return bad_request(missing)
  30. user_id = model.get_user_id_by_session_id(request.json['session_id'])
  31. return {'data': model.get_user_ownership(user_id),
  32. 'own_wealth': model.user_wealth(user_id)}
  33. def register():
  34. missing = missing_attributes(['username', 'password'])
  35. if missing:
  36. return bad_request(missing)
  37. username = request.json['username']
  38. password = request.json['password']
  39. if model.user_exists(username):
  40. return forbidden('User already exists.')
  41. game_key = ''
  42. if 'game_key' in request.json:
  43. game_key = request.json['game_key'].strip().upper()
  44. if game_key != '' and game_key not in model.unused_keys():
  45. return bad_request('Game key is not valid.')
  46. if model.register(username, password, game_key):
  47. return {'message': "successfully registered user"}
  48. else:
  49. return bad_request('registration not successful')
  50. def activate_key():
  51. missing = missing_attributes(['key', 'session_id'])
  52. if missing:
  53. return bad_request(missing)
  54. if model.valid_key(request.json['key']):
  55. user_id = model.get_user_id_by_session_id(request.json['session_id'])
  56. model.activate_key(request.json['key'], user_id)
  57. return {'message': "successfully activated key"}
  58. else:
  59. return bad_request('Invalid key.')
  60. def order():
  61. missing = missing_attributes(['buy', 'session_id', 'amount', 'ownable', 'time_until_expiration'])
  62. if missing:
  63. return bad_request(missing)
  64. if not model.ownable_name_exists(request.json['ownable']):
  65. return bad_request('This kind of object can not be ordered.')
  66. buy = request.json['buy']
  67. sell = not buy
  68. session_id = request.json['session_id']
  69. amount = request.json['amount']
  70. amount = float(amount)
  71. if amount < 0:
  72. return bad_request('You can not order a negative amount.')
  73. if amount < 1:
  74. return bad_request('The minimum order size is 1.')
  75. ownable_name = request.json['ownable']
  76. time_until_expiration = float(request.json['time_until_expiration'])
  77. if time_until_expiration < 0:
  78. return bad_request('Invalid expiration time.')
  79. ownable_id = model.ownable_id_by_name(ownable_name)
  80. user_id = model.get_user_id_by_session_id(session_id)
  81. model.own(user_id, ownable_name)
  82. ownership_id = model.get_ownership_id(ownable_id, user_id)
  83. try:
  84. if request.json['limit'] == '':
  85. limit = None
  86. elif request.json['limit'] is None:
  87. limit = None
  88. else:
  89. limit = float(request.json['limit'])
  90. except ValueError: # for example when float fails
  91. limit = None
  92. except KeyError: # for example when limit was not specified
  93. limit = None
  94. try:
  95. if request.json['stop_loss'] == '':
  96. stop_loss = None
  97. elif request.json['stop_loss'] is None:
  98. stop_loss = None
  99. else:
  100. stop_loss = 'stop_loss' in request.json and request.json['stop_loss']
  101. if stop_loss is not None and limit is None:
  102. return bad_request('Can only set stop-loss for limit orders')
  103. except KeyError: # for example when stop_loss was not specified
  104. stop_loss = None
  105. if sell:
  106. if not model.user_owns_at_least(amount, user_id, ownable_id):
  107. return bad_request('You can not sell more than you own.')
  108. model.place_order(buy, ownership_id, limit, stop_loss, amount, time_until_expiration)
  109. return {'message': "Order placed."}
  110. def gift():
  111. missing = missing_attributes(['session_id', 'amount', 'object_name', 'username'])
  112. if missing:
  113. return bad_request(missing)
  114. if not model.ownable_name_exists(request.json['object_name']):
  115. return bad_request('This kind of object can not be given away.')
  116. if request.json['username'] == 'bank' or not model.user_exists(request.json['username']):
  117. return bad_request('There is no user with this name.')
  118. try:
  119. amount = float(request.json['amount'])
  120. except ValueError:
  121. return bad_request('Invalid amount.')
  122. ownable_id = model.ownable_id_by_name(request.json['object_name'])
  123. sender_id = model.get_user_id_by_session_id(request.json['session_id'])
  124. recipient_id = model.get_user_id_by_name(request.json['username'])
  125. if not model.user_owns_at_least(amount, sender_id, ownable_id):
  126. amount = model.available_amount(sender_id, ownable_id)
  127. model.send_ownable(sender_id, recipient_id, request.json['object_name'], amount)
  128. return {'message': "Gift sent."}
  129. def orders():
  130. missing = missing_attributes(['session_id'])
  131. if missing:
  132. return bad_request(missing)
  133. data = model.get_user_orders(model.get_user_id_by_session_id(request.json['session_id']))
  134. return {'data': data}
  135. def orders_on():
  136. missing = missing_attributes(['session_id', 'ownable'])
  137. if missing:
  138. return bad_request(missing)
  139. if not model.ownable_name_exists(request.json['ownable']):
  140. return bad_request('This kind of object can not be ordered.')
  141. data = model.get_ownable_orders(model.ownable_id_by_name(request.json['ownable']))
  142. return {'data': data}
  143. def cancel_order():
  144. missing = missing_attributes(['session_id', 'order_id'])
  145. if missing:
  146. return bad_request(missing)
  147. if not model.user_has_order_with_id(request.json['session_id'], request.json['order_id']):
  148. return bad_request('You do not have an order with that number.')
  149. model.delete_order(request.json['order_id'])
  150. return {'message': "Successfully deleted order"}
  151. def change_password():
  152. missing = missing_attributes(['session_id', 'password'])
  153. if missing:
  154. return bad_request(missing)
  155. model.change_password(request.json['session_id'], request.json['password'])
  156. model.sign_out_user(request.json['session_id'])
  157. return {'message': "Successfully deleted order"}
  158. def news():
  159. return {'data': model.news()}
  160. def transactions():
  161. missing = missing_attributes(['session_id', 'ownable'])
  162. if missing:
  163. return bad_request(missing)
  164. if not model.ownable_name_exists(request.json['ownable']):
  165. return bad_request('This kind of object can not have transactions.')
  166. return {'data': model.transactions(model.ownable_id_by_name(request.json['ownable']))}
  167. def leaderboard():
  168. missing = missing_attributes(['session_id'])
  169. if missing:
  170. return bad_request(missing)
  171. return {'data': model.leaderboard()}
  172. def not_found(msg=''):
  173. response.status = 404
  174. if debug:
  175. msg = str(response.status) + ': ' + msg
  176. response.content_type = 'application/json'
  177. return json.dumps({"error_message": msg})
  178. def forbidden(msg=''):
  179. response.status = 403
  180. if debug:
  181. msg = str(response.status) + ': ' + msg
  182. response.content_type = 'application/json'
  183. return json.dumps({"error_message": msg})
  184. def bad_request(msg=''):
  185. response.status = 400
  186. if debug:
  187. msg = str(response.status) + ': ' + msg
  188. response.content_type = 'application/json'
  189. return json.dumps({"error_message": msg})