model.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. import re
  2. import sqlite3 as db
  3. import sys
  4. import uuid
  5. import db_setup
  6. from game import CURRENCY_NAME
  7. from util import debug
  8. connection = None
  9. cursor = None
  10. db_name = None
  11. def query_save_name():
  12. global db_name
  13. if debug:
  14. db_name = 'test.db'
  15. return
  16. while True:
  17. save_name = input('Name of the savegame: ')
  18. if re.match(r"[A-Za-z0-9.-]{0,50}", save_name):
  19. db_name = save_name + '.db'
  20. return
  21. else:
  22. print('Must match "[A-Za-z0-9.-]{0,50}"')
  23. def connect(reconnect=False):
  24. global connection
  25. global cursor
  26. global db_name
  27. if reconnect:
  28. connection.commit()
  29. connection.close()
  30. cursor = None
  31. connection = None
  32. db_name = None
  33. if connection is None or cursor is None:
  34. query_save_name()
  35. try:
  36. connection = db.connect(db_name)
  37. cursor = connection.cursor()
  38. except db.Error as e:
  39. print("Database error %s:" % e.args[0])
  40. sys.exit(1)
  41. # finally:
  42. # if con is not None:
  43. # con.close()
  44. def setup():
  45. connect()
  46. db_setup.setup(cursor)
  47. connection.commit()
  48. def login(username, password):
  49. connect()
  50. # do not allow login as bank
  51. if password == '':
  52. return None
  53. cursor.execute('''
  54. SELECT rowid
  55. FROM users
  56. WHERE username = ?
  57. AND password = ?
  58. ''', (username, password))
  59. user_id = cursor.fetchone()
  60. if user_id:
  61. return new_session(user_id)
  62. else:
  63. return None
  64. def register(username, password, game_key):
  65. connect()
  66. if username == '':
  67. return False
  68. if password == '':
  69. return False
  70. cursor.execute('''
  71. INSERT INTO users
  72. (username, password)
  73. VALUES (? , ?)
  74. ''', (username, password))
  75. own(get_user_id_by_name(username), CURRENCY_NAME)
  76. if game_key != '':
  77. if valid_key(game_key):
  78. activate_key(game_key, get_user_id_by_name(username))
  79. return True
  80. def own(user_id, ownable_name):
  81. cursor.execute('''
  82. WITH ownableid AS (SELECT rowid FROM ownables WHERE name = ?),
  83. userid AS (SELECT ?)
  84. INSERT INTO ownership (user_id, ownable_id)
  85. SELECT *
  86. FROM userid, ownableid
  87. WHERE NOT EXISTS (
  88. SELECT * FROM ownership
  89. WHERE ownership.user_id IN userid
  90. AND ownership.ownable_id IN ownableid
  91. )
  92. ''', (ownable_name, user_id,))
  93. def send_ownable(from_user_id, to_user_id, ownable_name, amount):
  94. connect()
  95. if amount < 0:
  96. return False
  97. if from_user_id != bank_id():
  98. cursor.execute('''
  99. UPDATE ownership
  100. SET amount = amount - ?
  101. WHERE user_id = ?
  102. AND ownable_id = (SELECT rowid FROM ownables WHERE name = ?)
  103. ''', (amount, from_user_id, ownable_name,))
  104. if not cursor.fetchone():
  105. return False
  106. cursor.execute('''
  107. UPDATE ownership
  108. SET amount = amount + ?
  109. WHERE user_id = ?
  110. AND ownable_id = (SELECT rowid FROM ownables WHERE name = ?)
  111. ''', (amount, to_user_id, ownable_name))
  112. if cursor.rowcount == 0:
  113. return False
  114. return True
  115. def valid_key(key):
  116. connect()
  117. cursor.execute('''
  118. SELECT key
  119. FROM keys
  120. WHERE used_by_user_id IS NULL
  121. AND key = ?
  122. ''', (key,))
  123. if cursor.fetchone():
  124. return True
  125. else:
  126. return False
  127. def new_session(user_id):
  128. connect()
  129. session_id = str(uuid.uuid4())
  130. cursor.execute('''
  131. INSERT INTO SESSIONS
  132. (user_id, session_id)
  133. VALUES (? , ?)
  134. ''', (user_id[0], session_id))
  135. return session_id
  136. def save_key(key):
  137. connect()
  138. cursor.execute('''
  139. INSERT INTO keys
  140. (key)
  141. VALUES (?)
  142. ''', (key,))
  143. def drop_old_sessions():
  144. connect()
  145. # TODO: test
  146. cursor.execute('''
  147. DELETE FROM sessions s1
  148. WHERE
  149. (SELECT COUNT(*) as newer
  150. FROM sessions s2
  151. WHERE s1.user_id = s2.user_id
  152. AND s1.rowid < s2.rowid) >= 10
  153. ''')
  154. def user_exists(username):
  155. connect()
  156. cursor.execute('''
  157. SELECT rowid
  158. FROM users
  159. WHERE username = ?
  160. ''', (username,))
  161. if cursor.fetchone():
  162. return True
  163. else:
  164. return False
  165. def unused_keys():
  166. connect()
  167. cursor.execute('''
  168. SELECT key
  169. FROM keys
  170. WHERE used_by_user_id IS NULL
  171. ''')
  172. return [str(key[0]).strip().upper() for key in cursor.fetchall()]
  173. def get_user_id_by_session_id(session_id):
  174. connect()
  175. cursor.execute('''
  176. SELECT users.rowid
  177. FROM sessions, users
  178. WHERE sessions.session_id = ?
  179. AND users.rowid = sessions.user_id
  180. ''', (session_id,))
  181. ids = cursor.fetchone()
  182. if ids is None:
  183. return False
  184. return ids[0]
  185. def get_user_id_by_name(username):
  186. connect()
  187. cursor.execute('''
  188. SELECT users.rowid
  189. FROM users
  190. WHERE username = ?
  191. ''', (username,))
  192. return cursor.fetchone()[0]
  193. def get_user_ownership(user_id):
  194. connect()
  195. cursor.execute('''
  196. SELECT ownables.name, ownership.amount
  197. FROM ownership, ownables
  198. WHERE user_id = ?
  199. AND ownership.ownable_id = ownables.rowid
  200. ''', (user_id,))
  201. return cursor.fetchall()
  202. def activate_key(key, user_id):
  203. connect()
  204. cursor.execute('''
  205. UPDATE keys
  206. SET used_by_user_id = ?
  207. WHERE used_by_user_id IS NULL
  208. AND key = ?
  209. ''', (user_id, key,))
  210. if cursor.rowcount == 0:
  211. raise AssertionError
  212. send_ownable(bank_id(), user_id, CURRENCY_NAME, 1000)
  213. def bank_id():
  214. connect()
  215. cursor.execute('''
  216. SELECT users.rowid
  217. FROM users
  218. WHERE username = 'bank'
  219. ''')
  220. return cursor.fetchone()[0]
  221. def valid_session_id(session_id):
  222. connect()
  223. cursor.execute('''
  224. SELECT rowid
  225. FROM sessions
  226. WHERE session_id = ?
  227. ''', (session_id,))
  228. if cursor.fetchone():
  229. return True
  230. else:
  231. return False
  232. def get_user_orders(user_id):
  233. connect()
  234. cursor.execute('''
  235. SELECT
  236. orders.buy,
  237. ownables.name,
  238. orders.ordered_amount - orders.executed_amount,
  239. orders."limit",
  240. orders.stop_loss,
  241. orders.ordered_amount
  242. FROM orders, ownables, ownership
  243. WHERE ownership.user_id = ?
  244. AND ownership.ownable_id = ownables.rowid
  245. AND orders.ownership_id = ownership.rowid
  246. ORDER BY orders.buy, ownables.name
  247. ''', (user_id,))
  248. return cursor.fetchall()
  249. def sell_ordered_amount(user_id, ownable_id):
  250. connect()
  251. # if ownable_id == kollar_id():
  252. # return 0
  253. cursor.execute('''
  254. SELECT SUM(orders.ordered_amount - orders.executed_amount)
  255. FROM orders, ownership
  256. WHERE ownership.rowid = orders.ownership_id
  257. AND ownership.user_id = ?
  258. AND ownership.ownable_id = ?
  259. AND NOT orders.buy
  260. ''', (user_id, ownable_id))
  261. return cursor.fetchone()[0]
  262. def user_owns_at_least(amount, user_id, ownable_id):
  263. connect()
  264. cursor.execute('''
  265. SELECT users.rowid
  266. FROM ownership
  267. AND ownership.user_id = ?
  268. AND ownership.ownable_id = ?
  269. AND ownership.amount - ? >= ?
  270. ''', (user_id, ownable_id, sell_ordered_amount(user_id, ownable_id), amount))
  271. if cursor.fetchone():
  272. return True
  273. else:
  274. return False
  275. def news():
  276. connect()
  277. cursor.execute('''
  278. SELECT *
  279. FROM news
  280. ORDER BY dt
  281. LIMIT 20
  282. ''')
  283. return cursor.fetchall()