コード例 #1
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_parsing_with_four_character_symbol(self):
     coin = Coin.create(name='foocoin', symbol='DASH')
     ping('DASH')
     dash = Coin.get(Coin.symbol == 'DASH')
     ticker = Ticker.get(Ticker.coin == dash)
     self.assertEqual(ticker.price, Decimal('56.12345678'))
     self.assertEqual(ticker.price_change_day_pct, Decimal('-1.23456789'))
コード例 #2
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_parsing_with_many_coins(self):
     ping('BTC', 'ETH')
     btc = Coin.get(Coin.symbol == 'BTC')
     eth = Coin.get(Coin.symbol == 'ETH')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     eth_ticker = Ticker.get(Ticker.coin == eth)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-1.23456789'))
     self.assertEqual(eth_ticker.price, Decimal('42.98765432'))
     self.assertEqual(eth_ticker.price_change_day_pct,
                      Decimal('-8.98765432'))
コード例 #3
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_parsing_with_many_ping_calls(self):
     ping('BTC')
     btc = Coin.get(Coin.symbol == 'BTC')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-2.33334567'))
     Ticker.delete().execute()
     ping('BTC')
     btc = Coin.get(Coin.symbol == 'BTC')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-2.33334567'))
コード例 #4
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_parsing_with_one_coin(self):
     ping('BTC')
     btc = Coin.get(Coin.symbol == 'BTC')
     btc_ticker = Ticker.get(Ticker.coin == btc)
     self.assertEqual(btc_ticker.price, Decimal('56.12345678'))
     self.assertEqual(btc_ticker.price_change_day_pct,
                      Decimal('-2.33334567'))
コード例 #5
0
ファイル: services.py プロジェクト: raziqraif/fortune
def get_coins_by_game_id(game_id):
    coins_query = Coin.select().join(GameCoin).where(GameCoin.game == game_id)
    if coins_query.count() == 0:
        raise BadRequest('Coins not found')
    coins = []
    for coin in coins_query:
        coins.append(coin)
    return coins
コード例 #6
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_parsing_with_one_coin(self, check_global_timed_game,
                                check_price_alerts_mock, mock_ticker,
                                mock_coin):
     mock_coin.get.return_value = Coin(symbol='FOO', name='Foocoin')
     ping('FOO')
     mock_ticker.create.assert_called_with(
         coin=mock_coin.get.return_value,
         price=Decimal('56.12345678'),
         price_change_day_pct=Decimal('-1.23456789'),
     )
コード例 #7
0
ファイル: services.py プロジェクト: raziqraif/fortune
def create_gamecoins_for_game(game, active_coins):
    if len(active_coins) == 0:
        raise BadRequest('At least one coin must be allowed in a game')
    res = []
    for coin in active_coins:
        coin = Coin.get_or_none(Coin.id == coin['id'])
        if coin is None:
            raise BadRequest('Invalid coin')
        res.append(GameCoin.create(
            game=game,
            coin=coin,
        ))
    return res
コード例 #8
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_parsing_with_many_coins(self, check_global_timed_game,
                                  check_price_alerts_mock, mock_ticker,
                                  mock_coin):
     side_effect = [
         Coin(symbol='FOO', name='Foocoin'),
         Coin(symbol='BAR', name='Barcoin'),
     ]
     mock_coin.get.side_effect = side_effect
     ping('FOO', 'BAR')
     calls = [
         call(
             coin=side_effect[0],
             price=Decimal('56.12345678'),
             price_change_day_pct=Decimal('-1.23456789'),
         ),
         call(
             coin=side_effect[1],
             price=Decimal('42.98765432'),
             price_change_day_pct=Decimal('-1.23456789'),
         ),
     ]
     mock_ticker.create.assert_has_calls(calls, any_order=False)
コード例 #9
0
def ping(*coins):
    res = requests.get(get_api_url(*coins))
    tickers = []
    for coin_res in res.json():
        symbol = coin_res['symbol']
        coin = Coin.get(Coin.symbol == symbol)
        price = Decimal(coin_res['price'])
        price_change_day_pct = Decimal(coin_res['1d']['price_change_pct'])
        ticker = Ticker.create(coin=coin, price=price, price_change_day_pct=price_change_day_pct)
        tickers.append(ticker)
        check_price_alerts(ticker)
        check_global_timed_game()
    return tickers
コード例 #10
0
 def test_get_coins_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     GameProfile.create(game=1, profile=profile, cash=10000)
     GameCoin.create(
         game=1,
         coin=1,
     )
     for coin in Coin.select():
         Ticker.create(
             coin=coin,
             price=30.0,
             captured_at=(datetime.utcnow()).isoformat(),
             price_change_day_pct=1.1,
         )
     res = self.client.get(
         '/game/1/coins?timeSpan=1&sortBy=0&numPerPage=10&pageNum=1',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
コード例 #11
0
def begin(cb=None):
    env = os.environ['FLASK_ENV']
    if env == 'testing':
        # TODO stubbed implementation
        return
    elif env == 'development':
        if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
            return
        while True:
            coins = Coin.select()
            tickers = list(stubbed(*coins))
            if cb is not None:
                cb(tickers)
            time.sleep(WAIT)
    elif env == 'production':
        while True:
            tickers = list(ping('BTC', 'ETH', 'LTC'))
            if cb is not None: cb(tickers)
            time.sleep(WAIT)
コード例 #12
0
ファイル: services.py プロジェクト: raziqraif/fortune
def get_coins_by_game_id_and_sorting(game_id, sorting_int, page_num,
                                     num_per_page):
    coins_query = Coin.select().join(GameCoin).where(GameCoin.game == game_id)
    if coins_query.count() == 0:
        raise BadRequest('Incorrect Sorting')
    if sorting_int == 1:
        coins_query = coins_query.order_by(+Coin.name)
    if sorting_int == 2:
        coins_query = coins_query.order_by(-Coin.name)
    if sorting_int == 3:
        coins_query = coins_query.order_by(
            -Coin.price)  # TODO: Double check if this should +/-
    if sorting_int == 4:
        coins_query = coins_query.order_by(
            +Coin.price)  # TODO: Double check if this should +/-

    coins_query = coins_query.paginate(page_num, num_per_page)
    coins = []
    for coin in coins_query:
        coins.append(coin)
    return coins
コード例 #13
0
ファイル: test_service.py プロジェクト: raziqraif/fortune
 def test_price_alerts(self):
     os.environ['NOMICS_BASE_URL'] = 'foo'
     profile = Profile.create(username='******',
                              hashed_password='******')
     coin = Coin.create(name='foocoin', symbol='FOO')
     alert = PriceAlert.create(
         profile=profile,
         above=True,
         coin=coin,
         strike_price=Decimal(0.1),
     )
     alert = PriceAlert.create(
         profile=profile,
         above=False,
         coin=coin,
         strike_price=Decimal(0.1),
     )
     ping('FOO')
     self.assertEqual(1, Notification.select().count())
     # ok, the line below throws an exception which causes all other tests to fail
     # as tearDown is not called and because db is in inconsistent state
     notif = Notification.get(Notification.profile == profile)
コード例 #14
0
ファイル: routes.py プロジェクト: raziqraif/fortune
def create_price_alert_route(profile):
    validated_data: dict = CreatePriceAlertRequestSerializer.deserialize(
        request.json)
    try:
        strike_price = Decimal(validated_data['strike_price'])
        if strike_price < 0:
            raise BadRequest('The strike price cannot be negative')
    except:
        raise BadRequest('Invalid decimal number for strike price')
    coin_id = validated_data['coin_id']
    type = validated_data['type']
    coin = Coin.get_or_none(Coin.id == coin_id)
    if coin is None:
        raise BadRequest('Invalid coin id')
    if type == 'above':
        alert = create_price_alert(profile, coin, strike_price, above=True)
    elif type == 'below':
        alert = create_price_alert(profile, coin, strike_price, above=False)
    else:
        raise BadRequest(
            'The type of a price alert must be "above" or "below"')
    return jsonify(PriceAlertSerializer.serialize(alert))
コード例 #15
0
def check_global_timed_game():
    game = Game.get(Game.shareable_link == 'TIMED')
    if game.ends_at < datetime.utcnow():
        # end global timed game, and start another
        profiles = []
        for game_profile in GameProfile.select().where(GameProfile.game == game):
            profiles.append(game_profile.profile)
            send_notification(game_profile.profile, 'The global timed game has expired')
            game_profile.delete_instance(recursive=True)
        game.delete_instance(recursive=True)
        global_timed = Game.create(name='Global Timed',
                        starting_cash=10000.00,
                        shareable_link='TIMED',
                        shareable_code='TIMED',
                        ends_at=datetime.utcnow() + timedelta(minutes=1))
        # CHANGEME for devel purposes, making it 1 min for now
        GameCoin.create(game=global_timed, coin=Coin.get())
        for profile in profiles:
            GameProfile.create(
                game=global_timed,
                profile=profile,
                cash=global_timed.starting_cash
            )
コード例 #16
0
ファイル: routes.py プロジェクト: raziqraif/fortune
def get_coins():
    return jsonify(CoinsResponse.serialize(Coin.select(), many=True))
コード例 #17
0
ファイル: v1.py プロジェクト: raziqraif/fortune
def up(db):
    with db.atomic():
        migrator = PostgresqlMigrator(db)
        db.bind(MODELS, bind_refs=False, bind_backrefs=False)
        db.create_tables(MODELS)
        if Coin.get_or_none(Coin.id == 1) is None:
            Coin.create(name='Bitcoin', symbol='BTC')
            Coin.create(name='Ethereum', symbol='ETH')
            Coin.create(name='Litecoin', symbol='LTC')
            Coin.create(name='Coin 3', symbol='CO3')
            Coin.create(name='Coin 4', symbol='CO4')
            Coin.create(name='Coin 5', symbol='CO5')

        global_indef = Game.create(name='Global Indefinite',
                                   starting_cash=10000.00,
                                   shareable_link='INDEF',
                                   shareable_code='INDEF',
                                   ends_at=None)

        # insert achievements into database
        Achievement.create(
            name="Win", description="Finish in first place in a private game")
        Achievement.create(
            name="Double net worth",
            description="Achieved by doubling your net worth in a game")
        Achievement.create(name="Identity Crisis",
                           description="Change your username")

        # insert goals into database
        Goal.create(name="Entrepreneur", description="Create a private game")

        all_coins = Coin.select()
        for coin in all_coins:
            GameCoin.create(game=global_indef, coin=coin)

        global_timed = Game.create(name='Global Timed',
                                   starting_cash=10000.00,
                                   shareable_link='TIMED',
                                   shareable_code='TIMED',
                                   ends_at=datetime.utcnow() +
                                   timedelta(minutes=1))
        # CHANGEME for devel purposes, making it 1 min for now
        GameCoin.create(game=global_timed, coin=Coin.get())

        # from auth.services import register
        hashed = bcrypt.hashpw("admin".encode(), bcrypt.gensalt()).decode()
        admin = Profile.create(username="******",
                               hashed_password=hashed,
                               is_admin=True)
        # Required so that admin can still view graphs in the landing page
        GameProfile.create(profile=admin, game=global_indef, cash=0.0)