Parcourir la source

deleting orders, leaderboard and register crash fix

Eren Yilmaz il y a 6 ans
Parent
commit
784810b55c
11 fichiers modifiés avec 174 ajouts et 32 suppressions
  1. 1 13
      admin_console.py
  2. 32 5
      client_controller.py
  3. 1 1
      connection.py
  4. 17 8
      cool_query.py
  5. 7 0
      create_new_key.py
  6. 6 0
      create_new_stock.py
  7. 18 0
      db_setup.py
  8. 68 2
      model.py
  9. 3 1
      run_client.py
  10. 4 2
      run_server.py
  11. 17 0
      server_controller.py

+ 1 - 13
admin_console.py

@@ -1,14 +1,4 @@
 import model
-from util import random_chars
-
-
-def generate_keys(count=1):
-    # source https://stackoverflow.com/questions/17049308/python-3-3-serial-key-generator-list-problems
-
-    for i in range(count):
-        key = '-'.join(random_chars(5) for _ in range(5))
-        model.save_key(key)
-        print(key)
 
 
 def unused_keys():
@@ -22,9 +12,7 @@ def cleanup():
 
 
 if __name__ == '__main__':
-    generate_keys(count=2)
-    print(model.new_stocks(timeout=30, count=1))
-    # unused_keys()
+    unused_keys()
     # model.drop_old_sessions()
 
     cleanup()

+ 32 - 5
client_controller.py

@@ -46,7 +46,7 @@ def register(username=None, password=None, game_key=''):
 
     if password is None:
         if sys.stdin.isatty():
-            password = getpass.getpass('Password: ')
+            password = getpass('Password: ')
         else:
             password = input('Password: ')
 
@@ -61,6 +61,16 @@ def register(username=None, password=None, game_key=''):
         print('Registration failed with message:', response['error_message'])
 
 
+def cancel_order(order_no=None):
+    if order_no is None:
+        order_no = input('Order No.: ')
+
+    response = client_request('cancel_order', {"session_id": connection.session_id, "order_id": order_no})
+
+    if 'error_message' in response:
+        print('Order cancelling failed with message:', response['error_message'])
+
+
 # noinspection PyShadowingBuiltins
 def help():
     print('Allowed commands:')
@@ -75,8 +85,11 @@ def help():
                 print(' -', p)
         else:
             print('`' + cmd + '`', 'takes no arguments')
+        print()
 
-    print('NOTE: All arguments are optional!')
+    print('NOTE:')
+    print('  Commands can be combined in one line with ; between them.')
+    print('  All arguments for all commands are optional!')
 
 
 def depot():
@@ -91,6 +104,18 @@ def depot():
             print('Depot access failed.')
 
 
+def leaderboard():
+    response = client_request('leaderboard', {"session_id": connection.session_id})
+    success = 'data' in response
+    if success:
+        print(tabulate(response['data'], headers=['User', 'Score'], tablefmt="pipe"))
+    else:
+        if 'error_message' in response:
+            print('Leaderboard access failed with message:', response['error_message'])
+        else:
+            print('Leaderboard access failed.')
+
+
 def activate_key(key=''):
     if key == '':
         print('Entering a game key may get you some money or other useful stuff.')
@@ -144,19 +169,21 @@ def buy(amount=None, object_name=None, limit='', stop_loss='', time_until_expira
               'to see if the order has been executed already.')
 
 
-def sell(amount=None, object_name=None, limit='', stop_loss='', time_until_expiration=None):
+def sell(amount=None, object_name=None, limit=None, stop_loss=None, time_until_expiration=None):
     if object_name is None:  # TODO list some available objects
         object_name = input('Name of object to sell: ')
     if amount is None:
         amount = input('Amount: ')
-    if limit == '':
+    if limit is None:
         set_limit = yn_dialog('Do you want to place a limit?')
         if set_limit:
             limit = input('Limit: ')
-            stop_loss = yn_dialog('Is this a stop-loss limit?')
         else:
             limit = None
             stop_loss = None
+    if limit is not None:
+        stop_loss = yn_dialog('Is this a stop-loss limit?')
+
     if time_until_expiration is None:
         time_until_expiration = input('Time until order expires (minutes, default 60):')
         if time_until_expiration == '':

+ 1 - 1
connection.py

@@ -5,7 +5,7 @@ import requests
 from util import debug
 
 port = 8451
-host = 'http://koljastrohm-games.com:' + str(port)
+host = 'http://localhost:' + str(port)
 json_headers = {'Content-type': 'application/json'}
 
 

+ 17 - 8
cool_query.py

@@ -2,11 +2,20 @@ import model
 
 model.connect()
 model.cursor.execute('''
-        DELETE FROM orders
-        WHERE rowid = ?
-        ''', (2,))
-model.cursor.execute('''
-        SELECT * FROM orders
-        WHERE rowid = ?
-        ''', (2,))
-print(model.cursor.fetchall())
+            SELECT sell_order.stop_loss, buy_order.stop_loss
+            FROM orders buy_order, orders sell_order, ownership buyer, ownership seller
+            WHERE buy_order.buy AND NOT sell_order.buy
+            AND buyer.rowid = buy_order.ownership_id
+            AND seller.rowid = sell_order.ownership_id
+            AND buyer.ownable_id = ?
+            AND seller.ownable_id = ?
+            AND sell_order."limit" <= buy_order."limit"
+            ORDER BY CASE WHEN sell_order."limit" IS NULL THEN 0 ELSE 1 END ASC, 
+                     CASE WHEN buy_order."limit" IS NULL THEN 0 ELSE 1 END ASC, 
+                     buy_order."limit" DESC,
+                     sell_order."limit" ASC,
+                     buy_order.ordered_amount - buy_order.executed_amount DESC,
+                     sell_order.ordered_amount - sell_order.executed_amount DESC
+            LIMIT 1
+            ''', (3, 3,))
+print(model.cursor.fetchone())

+ 7 - 0
create_new_key.py

@@ -0,0 +1,7 @@
+from admin_console import cleanup
+from model import generate_keys, unused_keys
+
+if __name__ == '__main__':
+    generate_keys(count=1)
+    print(unused_keys())
+    cleanup()

+ 6 - 0
create_new_stock.py

@@ -0,0 +1,6 @@
+import model
+from admin_console import cleanup
+
+if __name__ == '__main__':
+    print(model.new_stock(30))
+    cleanup()

+ 18 - 0
db_setup.py

@@ -189,6 +189,24 @@ def integrity_checks(cursor):
                     SELECT RAISE(ROLLBACK, 'Can only set `stop_loss` `for limit orders.');
                 END
                 ''')
+    cursor.execute('''
+                CREATE TRIGGER IF NOT EXISTS limit_requires_stop_loss_after_insert
+                AFTER INSERT
+                ON orders
+                WHEN NEW."limit" IS NOT NULL AND NEW.stop_loss IS NULL
+                BEGIN
+                    SELECT RAISE(ROLLBACK, 'Need to set stop_loss to either True or False for limit orders.');
+                END
+                ''')
+    cursor.execute('''
+                CREATE TRIGGER IF NOT EXISTS limit_requires_stop_loss_after_update
+                AFTER UPDATE
+                ON orders
+                WHEN NEW."limit" IS NOT NULL AND NEW.stop_loss IS NULL
+                BEGIN
+                    SELECT RAISE(ROLLBACK, 'Need to set stop_loss to either True or False for limit orders.');
+                END
+                ''')
 
 
 def tables(cursor):

+ 68 - 2
model.py

@@ -12,10 +12,9 @@ from util import debug, random_chars
 
 # connection: db.Connection = None
 # cursor: db.Cursor = None
-connection = None  # no type annotations in python 2.7
+connection = None  # no type annotations in python 3.5
 cursor = None
 
-
 db_name = None
 
 
@@ -70,6 +69,18 @@ def setup():
     connection.commit()
 
 
+def used_key_count():
+    connect()
+
+    cursor.execute('''
+        SELECT COUNT(*)
+        FROM keys
+        WHERE used_by_user_id IS NOT NULL
+        ''')
+
+    return cursor.fetchone()[0]
+
+
 def login(username, password):
     connect()
 
@@ -755,3 +766,58 @@ def drop_expired_orders():
         ''')
 
     return cursor.fetchall()
+
+
+def generate_keys(count=1):
+    # source https://stackoverflow.com/questions/17049308/python-3-3-serial-key-generator-list-problems
+
+    for i in range(count):
+        key = '-'.join(random_chars(5) for _ in range(5))
+        save_key(key)
+        print(key)
+
+
+def user_has_order_with_id(session_id, order_id):
+    connect()
+
+    cursor.execute('''
+                SELECT orders.rowid
+                FROM orders, ownership, sessions
+                WHERE orders.rowid = ?
+                AND sessions.session_id = ?
+                AND sessions.user_id = ownership.user_id
+                AND ownership.rowid = orders.ownership_id
+                ''', (order_id, session_id,))
+
+    if cursor.fetchone():
+        return True
+    else:
+        return False
+
+
+def leaderboard():
+    connect()
+
+    cursor.execute('''
+        SELECT * 
+        FROM ( -- one score for each user
+            SELECT 
+                username, 
+                SUM(CASE -- sum score for each of the users ownables
+                    WHEN ownership.ownable_id = ? THEN ownership.amount
+                    ELSE ownership.amount * (SELECT price 
+                                             FROM transactions
+                                             WHERE ownable_id = ownership.ownable_id 
+                                             ORDER BY dt DESC 
+                                             LIMIT 1)
+                    END
+                ) score
+            FROM users, ownership
+            WHERE ownership.user_id = users.rowid
+            AND users.username != 'bank'
+        ) AS scores
+        ORDER BY score DESC
+        LIMIT 50
+        ''', (currency_id(),))
+
+    return cursor.fetchall()

+ 3 - 1
run_client.py

@@ -61,7 +61,9 @@ allowed_commands = ['help',
                     'buy',
                     'sell',
                     'transactions',
-                    'orders_on']
+                    'orders_on',
+                    'cancel_order',
+                    'leaderboard']
 
 
 def one_command():

+ 4 - 2
run_server.py

@@ -18,7 +18,9 @@ if __name__ == '__main__':
                     'order', 'orders',
                     'news',
                     'transactions',
-                    'orders_on']
+                    'orders_on',
+                    'cancel_order',
+                    'leaderboard']
 
 
     @route('/<path>', method='POST')
@@ -43,4 +45,4 @@ if __name__ == '__main__':
 
 
     run(host='0.0.0.0', port=connection.port, debug=debug)
-    model.connection.disconnect()
+    model.connection.close()

+ 17 - 0
server_controller.py

@@ -143,6 +143,16 @@ def orders_on():
     return {'data': data}
 
 
+def cancel_order():
+    missing = missing_attributes(['session_id', 'order_id'])
+    if missing:
+        return bad_request(missing)
+    if not model.user_has_order_with_id(request.json['session_id'], request.json['order_id']):
+        return bad_request('You do not have an order with that number.')
+    model.delete_order(request.json['order_id'])
+    return {'message': "Successfully deleted order"}
+
+
 def news():
     missing = missing_attributes(['session_id'])
     if missing:
@@ -159,6 +169,13 @@ def transactions():
     return {'data': model.transactions(model.ownable_id_by_name(request.json['ownable']))}
 
 
+def leaderboard():
+    missing = missing_attributes(['session_id'])
+    if missing:
+        return bad_request(missing)
+    return {'data': model.leaderboard()}
+
+
 def not_found(msg=''):
     response.status = 404
     if debug: