Exemple #1
0
def index_character(character, account):

  try:
    logging.info('Synching: Character {0} / {1}'.format(character.name, character.char_id))
    item_stats = ItemStats.query(ItemStats.character_key == character.key).fetch_async()
    orders = MarketOrder.query(MarketOrder.character_key == character.key).fetch_async()

    api = Api(account.api_id, account.api_vcode)
    api.authenticate()
    api_char = api.get_character(character.char_id)

    row_count = 250
    all_items, all_stations = {}, {}

    character.last_update = datetime.now()

    last_transaction_id = character.last_transaction_id
    last_transaction_date = character.last_transaction_date

    api_wallet_transactions = api_char.WalletTransactions(rowCount=(last_transaction_id is None and 1000 or row_count))
    item_stats = dict([(i.type_id, i) for i in item_stats.get_result()])

    newest_transaction, oldest_transaction, items, stations = sync_transactions(character,
                                                                       api_wallet_transactions,
                                                                       last_transaction_id,
                                                                       last_transaction_date,
                                                                       item_stats)

    all_items.update(items or {})
    all_stations.update(stations or {})

    while last_transaction_id and last_transaction_date and oldest_transaction and \
    (datetime.fromtimestamp(oldest_transaction.transactionDateTime) > last_transaction_date or oldest_transaction.transactionID > last_transaction_id):
      logging.info('Fetching another batch from id {0}'.format(oldest_transaction.transactionID))

      api_wallet_transactions = api_char.WalletTransactions(rowCount=row_count, fromID=oldest_transaction.transactionID)
      newest_transaction, oldest_transaction, items, stations = sync_transactions(character,
                                                                 api_wallet_transactions,
                                                                 last_transaction_id,
                                                                 last_transaction_date,
                                                                 item_stats)

      all_items.update(items or {})
      all_stations.update(stations or {})

    sync_orders(character,
                api_char.MarketOrders(),
                orders.get_result())

    character.put_async()
    logging.info('Syncing done: Character {0} / {1}'.format(character.name, character.char_id))
    return all_items, all_stations
  except:
    import traceback
    logging.error('Error while syncing character {0} / {1}'.format(character.name, character.char_id))
    logging.error(traceback.format_exc())
    return None
Exemple #2
0
def sync_transactions(character,
                      api_wallet_transactions,
                      last_transaction_id,
                      last_transaction_date,
                      item_stats):

  newest_transaction, oldest_transaction, items, stations = None, None, {}, {}
  to_put = []

  for row in api_wallet_transactions.transactions:
    if (not last_transaction_id and not last_transaction_date) or \
    datetime.fromtimestamp(row.transactionDateTime) > last_transaction_date or row.transactionID > last_transaction_id:

      wt = WalletTransaction(character_key=character.key,
                             char_id=character.char_id,
                             transaction_id=row.transactionID,
                             transaction_date=datetime.fromtimestamp(row.transactionDateTime),
                             quantity=int(row.quantity),
                             type_id=str(row.typeID),
                             unit_price=float(row.price),
                             station_id=str(row.stationID),
                             client_id=str(row.clientID),
                             client_name=str(row.clientName),
                             transaction_type=(row.transactionType == 'sell' and WalletTransaction.SELL or WalletTransaction.BUY),
                             journal_transaction_id=str(row.journalTransactionID))

      to_put.append(wt)
      items[wt.type_id] = row.typeName
      stations[wt.station_id] = row.stationName

      stats = item_stats.get(wt.type_id, None)
      abs_balance_change = wt.quantity * wt.unit_price

      if not stats:
        stats = ItemStats(user=character.user,
                          char_id=character.char_id,
                          character_key=character.key,
                          type_id=wt.type_id,
                          accumulated_cost=(wt.transaction_type == WalletTransaction.BUY and abs_balance_change or 0),
                          accumulated_earnings=(wt.transaction_type == WalletTransaction.SELL and abs_balance_change or 0),
                          items_bought=(wt.transaction_type == WalletTransaction.BUY and wt.quantity or 0),
                          items_sold=(wt.transaction_type == WalletTransaction.SELL and wt.quantity or 0),
                          )
        item_stats[wt.type_id] = stats
      else:
        if wt.transaction_type == WalletTransaction.BUY:
          stats.accumulated_cost += abs_balance_change
          stats.items_bought += wt.quantity
        else:
          stats.accumulated_earnings += abs_balance_change
          stats.items_sold += wt.quantity

    else:
      logging.debug('Skipped transaction {0}'.format(row.transactionID))

    if not oldest_transaction or row.transactionID < oldest_transaction.transactionID:
      oldest_transaction = row

    if not newest_transaction or row.transactionID > newest_transaction.transactionID:
      newest_transaction = row

    character.last_transaction_id = max(character.last_transaction_id, row.transactionID)
    row_date = datetime.fromtimestamp(row.transactionDateTime)
    character.last_transaction_date = character.last_transaction_date and max(character.last_transaction_date, row_date) or row_date

  ndb.put_multi_async(to_put)

  for stats in item_stats.values():
    stats.roi_yield = stats.accumulated_cost > 0 and (stats.accumulated_earnings - stats.accumulated_cost) / stats.accumulated_cost or 0
    avg_unit_cost = stats.items_bought > 0 and stats.accumulated_cost / stats.items_bought or 0
    avg_unit_earnings = stats.items_sold > 0 and stats.accumulated_earnings / stats.items_sold or 0
    stats.avg_roi_yield = avg_unit_cost > 0 and (avg_unit_earnings - avg_unit_cost) / avg_unit_cost or 0

  ndb.put_multi_async(item_stats.values())

  return newest_transaction, oldest_transaction, items, stations