Exemplo n.º 1
0
def _populate_characters(account, characters_node_children):
    """
    Iterate through an account's character list and create/update the
    appropriate ApiPlayerCharacter objects.
    """
    ApiPlayerCorporation = get_api_model_class("apiplayercorporation")
    ApiPlayerCharacter = get_api_model_class("apiplayercharacter")

    for node in characters_node_children:
        try:
            # Get this first, as it's safe.
            corporation_id = node.get('corporationID')
            corp, created = ApiPlayerCorporation.objects.get_or_create(id=corporation_id)
            # Do this last, since the things we retrieved above are used
            # on the ApiPlayerCharacter object's fields.
            character_id = node.get('characterID')
            pchar, created = ApiPlayerCharacter.objects.get_or_create(id=character_id)
            name = node.get('name')
            # Save these for last to keep the save count low.
            pchar.name = name
            pchar.corporation = corp
            # This also saves the model.
            pchar.set_api_last_updated()
            account.characters.add(pchar)
        except AttributeError:
            # This must be a Text node, ignore it.
            continue
Exemplo n.º 2
0
def __transfer_divisions(tree, corp):
    """
    Transfer corporate divisions and wallet divisions.
    """
    ApiPlayerCorporationDivision = get_api_model_class("apiplayercorporationdivision")
    ApiPlayerCorporationWalletDivision = get_api_model_class("apiplayercorporationwalletdivision")
    rowsets = tree.findall('result/rowset')
    for rowset in rowsets:
        rowset_name = rowset.get('name')
        for row in rowset.getchildren():
            account_key = row.get('accountKey')
            if rowset_name == 'divisions':
                division, created = ApiPlayerCorporationDivision.objects.get_or_create(
                                                        account_key=account_key,
                                                        corporation=corp)
            elif rowset_name =='walletDivisions':
                division, created = ApiPlayerCorporationWalletDivision.objects.get_or_create(
                                                        account_key=account_key,
                                                        corporation=corp)
            else:
                # This shouldn't happen unless CCP adds a new rowset type
                # and we don't support it yet.
                continue                    
            division.name = row.get('description')
            division.save()
def update_alliance_corporations(**kwargs):
    """
    Imports all of the corps that are in all of the known alliances.
    
    WARNING: THIS WILL TAKE A _LONG_ TIME AND MUST BE RAN AFTER
    eve_db.api_puller.alliances.__start_full_import() OR YOU WON'T GET ALL
    OF THE CORPS (or any at all).
    """
    ApiPlayerAlliance = get_api_model_class('ApiPlayerAlliance')
    ApiPlayerCorporation = get_api_model_class('ApiPlayerCorporation')
    alliances = ApiPlayerAlliance.objects.all()
    
    # These two variables are used to track progress.
    alliance_count = alliances.count()
    # Use this as a progress indicator.
    current_alliance_num = 1
    
    for alliance in alliances:
        # Keep the user informed as to the progress.
        print "Alliance %d of %d..." % (current_alliance_num, alliance_count)
        # A list of the alliance's member corps.
        member_corps = alliance.apiplayercorporation_set.all()
        # We're getting the list of corps to update from alliance memberships.
        for corp in member_corps:
            print "Querying", corp.id
            corp = ApiPlayerCorporation.api.update_from_api(corp, **kwargs)
            print "DONE: %s" % corp
            
        # Increment progress counter.
        current_alliance_num += 1
Exemplo n.º 4
0
def query_character_journal(character_or_id, account_key=1000, 
                            before_ref_id=None, **kwargs):
    """
    This function queries a character's journal and creates/updates
    ApiJournalTransaction objects found therein.
    """
    try:
        # If the user has provided an int, this will fail.
        id = character_or_id.id
        # User has provided a corp object, use that instead of looking one up.
        character = character_or_id
    except AttributeError:
        # User provided an int, no corp object provided.
        id = character_or_id
        character = None
    
    # This raises a ApiAccount.DoesNotExist if there is no match.
    account = character.get_account()
    
    # Assemble GET keys.
    query_params = {'userID': account.api_user_id,
                    'apiKey': account.api_key,
                    'characterID': character.id,
                    'accountKey': account_key}
    
    if before_ref_id:
        # This allows for walking journal transactions backwards.
        # http://wiki.eve-id.net/APIv2_Char_JournalEntries_XML
        query_params['beforeRefID'] = before_ref_id

    # Retrieve the XML for the query from the API or the cache.
    corp_doc = CachedDocument.objects.api_query('/char/WalletJournal.xml.aspx',
                                                params=query_params, **kwargs)
    # Parse the XML response.
    tree = ElementTree.fromstring(corp_doc.body)
    
    # List of <row> elements, each being a transaction.
    transactions = tree.find('result/rowset').getchildren()
    
    # The following calls get around circular imports.
    ApiJournalTransaction = get_api_model_class('ApiJournalTransaction')
    ApiJournalRefType = get_api_model_class('ApiJournalRefType')
    ApiPlayerCorporation = get_api_model_class('ApiPlayerCorporation')

    for transaction in transactions:
        # Hand off importing logic.
        __import_transaction(transaction, ApiJournalTransaction,
                             ApiJournalRefType, ApiPlayerCorporation)
Exemplo n.º 5
0
def __import_transaction(elem, ApiJournalTransaction, ApiJournalRefType,
                         ApiPlayerCorporation):
    """
    Given an ElementTree Element, parse it for Journal transaction data and
    import it to the DB.
    """
    ref_id = elem.get('refID')
    ref_type_id = elem.get('refTypeID')
    
    transaction, created = ApiJournalTransaction.objects.get_or_create(id=ref_id)
    transaction.transaction_time = parse_api_datetime(elem.get('date'))
    ref_type, created = ApiJournalRefType.objects.get_or_create(id=ref_type_id)
    transaction.ref_type = ref_type
    transaction.owner_name1 = elem.get('ownerName1')
    transaction.owner_name2 = elem.get('ownerName2')
    transaction.arg_name = elem.get('argName1')
    transaction.arg_id = elem.get('argID1')
    transaction.amount = elem.get('amount')
    transaction.balance = elem.get('balance')
    transaction.reason = elem.get('reason')
    
    # For things like bounties, taxes get paid to the player's corp.
    tax_amount = elem.get('taxAmount')
    if tax_amount:
        transaction.tax_amount = tax_amount
    tax_receiver_id = elem.get('taxReceiverID')
    if tax_receiver_id:
        tax_receiver, created = ApiPlayerCorporation.objects.get_or_create(id=tax_receiver_id)
        transaction.tax_receiver = tax_receiver
    
    # Get around circular dependencies.
    ApiPlayerCharacter = get_api_model_class('ApiPlayerCharacter')
    ApiPlayerCorporation = get_api_model_class('ApiPlayerCorporation')

    # Resolve the generic relationships by the ownerID* values.
    transaction.owner1 = __resolve_generic_relation(elem.get('ownerID1'),
                                                    transaction.owner_name1,
                                                    ApiPlayerCharacter, 
                                                    ApiPlayerCorporation)
    transaction.owner2 = __resolve_generic_relation(elem.get('ownerID2'),
                                                    transaction.owner_name2,
                                                    ApiPlayerCharacter, 
                                                    ApiPlayerCorporation)

    # This also saves changes.
    transaction.set_api_last_updated()
Exemplo n.º 6
0
def __transfer_ceo(tree, corp):
    """
    Transfers the CEO data.
    """
    ApiPlayerCharacter = get_api_model_class("apiplayercharacter")
    ceo_id = int(tree.find('result/ceoID').text)
    ceo, created = ApiPlayerCharacter.objects.get_or_create(id=ceo_id)
    corp.ceo_character = ceo
    
    if not ceo.name:
        # Fill in the CEO's name if it's missing from their ApiPlayer object.
        ceo.name = ceo_id = tree.find('result/ceoName').text
        ceo.save()
Exemplo n.º 7
0
def __transfer_alliance(tree, corp):
    """
    Transfers alliance data (if applicable).
    """
    alliance_id = int(tree.find('result/allianceID').text)
    if alliance_id != 0:
        ApiPlayerAlliance = get_api_model_class("apiplayeralliance")
        alliance, created = ApiPlayerAlliance.objects.get_or_create(id=alliance_id)
        corp.alliance = alliance
        if not alliance.name:
            # Alliance name is missing from the ApiPlayerAlliance object.
            # Set it and save it.
            alliance.name = ceo_id = tree.find('result/allianceName').text
            alliance.save()
Exemplo n.º 8
0
def query_type_list(**kwargs):
    """
    This function is called to update the reference type list objects.
    """
    type_doc = CachedDocument.objects.api_query('/eve/RefTypes.xml.aspx ',
                                                    **kwargs)
    
    tree = ElementTree.fromstring(type_doc.body)
    type_rowset = tree.find('result/rowset').getchildren()
    
    for type_node in type_rowset:
        type_id = int(type_node.get('refTypeID'))
        
        ApiJournalRefType = get_api_model_class('ApiJournalRefType')
        reftype, created = ApiJournalRefType.objects.get_or_create(id=type_id)
        reftype.name = type_node.get('refTypeName')
        reftype.save()
Exemplo n.º 9
0
def __remove_invalid_corp_alliance_memberships():
    """
    Compares UPDATED_CORPS list to the full list of player corporations. If
    the corporation was not updated from being found in one of the alliance
    data sets, it has no alliance affiliation and needs to be set to no
    alliance if it is not already a None value.
    """
    ApiPlayerCorporation = get_api_model_class('apiplayercorporation')
    all_corps = ApiPlayerCorporation.objects.all()
    # This is not terribly efficient, but it will do for a background process.
    for corp in all_corps:
        """
        If the corp is not in the UPDATED_CORP list that was built from
        alliance memberCorporations rowsets, then it does not belong to an
        alliance and should be un-allianced if it currently is.
        """
        if corp.id not in UPDATED_CORPS and corp.alliance != None:
            corp.alliance = None
            corp.save()
Exemplo n.º 10
0
def query_server_status(**kwargs):
    """
    Populates and returns an ApiServer object.
    """
    server_doc = CachedDocument.objects.api_query('/server/ServerStatus.xml.aspx',
                                                  **kwargs)
    tree = ElementTree.fromstring(server_doc.body)
    
    server_open = tree.find('result/serverOpen').text
    online_players = tree.find('result/onlinePlayers').text
    
    ApiServer = get_api_model_class('apiserver')
                                        
    server, created = ApiServer.objects.get_or_create(id=1)
    server.server_open = server_open == 'True'
    server.online_players = online_players
    server.save()
    return server
    
Exemplo n.º 11
0
def query_character_list(api_key, user_id, account_obj=None, **kwargs):
    """
    Imports an account from the API into the ApiAccount model.
    
    Optional kwargs
    account_obj: (ApiAccount) Update the following account object instead
                 of querying for one. This is used to update ApiAccount
                 objects in place.
    """
    auth_params = {'userID': user_id, 'apiKey': api_key}
    account_doc = CachedDocument.objects.api_query('/account/Characters.xml.aspx',
                                                   params=auth_params,
                                                   **kwargs)

    tree = ElementTree.fromstring(account_doc.body)
    characters_node_children = tree.find('result/rowset').getchildren()

    if account_obj == None:
        # User did not specify an ApiAccount object to use. Query and get or
        # create one with a matching user_id.
        ApiAccount = get_api_model_class("apiaccount")
        # Create or retrieve the account last to make sure everything
        # before here is good to go.
        try:
            account = ApiAccount.objects.get(id=user_id)
        except ApiAccount.DoesNotExist:
            account = ApiAccount(id=user_id)
    else:
        # User specified an ApiAccount object to use.
        account = account_obj

    account.api_key = api_key
    account.api_user_id = user_id
    account.api_last_updated = datetime.now()
    account.api_status = API_STATUS_OK
    account.save()

    # Iterate through the characters on this account and create/update the
    # appropriate ApiPlayerCharacter models.
    _populate_characters(account, characters_node_children)
    
    # Finally, return the latest version of the ApiAccount.
    return account
Exemplo n.º 12
0
def query_alliance_list(**kwargs):
    """
    This method runs a full import of all known alliances. This may take a few
    minutes and should be ran regularly if you are maintaining a full corp
    list of all EVE corps as well.
    """
    alliance_doc = CachedDocument.objects.api_query('/eve/AllianceList.xml.aspx',
                                                    **kwargs)
    
    tree = ElementTree.fromstring(alliance_doc.body)
    alliance_rowset = tree.find('result/rowset').getchildren()
    
    # We now have a list of <row> tags representing each alliance.
    print "Updating alliance and member corporation data..."
    for alliance_node in alliance_rowset:
        try:
            # If this fails, this is a Text node and should be ignored.
            alliance_id = int(alliance_node.get('allianceID'))
        except AttributeError:
            # This is probably a Text node, ignore it.
            continue
        
        """
        Search for an existing ApiPlayerAlliance object with the given
        alliance ID. Create one if it doesn't exist, retrieve the existing
        object if it's already there.
        """
        ApiPlayerAlliance = get_api_model_class('apiplayeralliance')
        alliance, created = ApiPlayerAlliance.objects.get_or_create(id=alliance_id)
        alliance.id = alliance_id
        alliance.name = alliance_node.get('name')
        alliance.ticker = alliance_node.get('shortName')
        alliance.member_count = alliance_node.get('memberCount')
        alliance.date_founded = datetime.strptime(alliance_node.get('startDate'),
                                                  '%Y-%m-%d %H:%M:%S')
        alliance.save()
        # Update member corp alliance attributes.
        __update_corp_from_alliance_node(alliance_node, alliance)
    
    # Alliances and member corps updated.
    # Removing corps alliance memberships that are no longer valid...
    __remove_invalid_corp_alliance_memberships()
Exemplo n.º 13
0
def query_corporation_sheet(corp_or_id, query_character=None, **kwargs):
    """
    Returns a corp's data sheet from the EVE API in the form of an 
    ElementTree Element.
    
    corp_or_id: (ApiPlayerCorporation or int) A player corporation object to
                update, or an int matching a corporation's ID number.
    query_character: (ApiPlayerCharacter) To get detailed data about a corp,
                     provide a character that is a member of said corp.
    """
    try:
        # If the user has provided an int, this will fail.
        id = corp_or_id.id
        # User has provided a corp object, use that instead of looking one up.
        corp = corp_or_id
    except AttributeError:
        # User provided an int, no corp object provided.
        id = corp_or_id
        corp = None
    
    query_params = {}
    if query_character:
        # Character provided, provide their credentials.
        account = query_character.get_account()
        query_params['userID'] = account.api_user_id
        query_params['apiKey'] = account.api_key
        query_params['characterID'] = query_character.id
    else:
        # Outsider is looking for details on a corp.
        query_params['corporationID'] = id

    ApiPlayerCorporation = get_api_model_class("apiplayercorporation")
    try:
        corp_doc = CachedDocument.objects.api_query('/corp/CorporationSheet.xml.aspx',
                                                    params=query_params, **kwargs)
    except APIQueryErrorException, exc:
        if exc.code == 523:
            # The specified corp doesn't exist.
            raise ApiPlayerCorporation.DoesNotExist('No such corporation with ID: %s' % id)
        # Was some other error, re-raise it.
        raise
Exemplo n.º 14
0
def __update_corp_from_alliance_node(alliance_node, alliance):
    """
    Updates a corp's alliance membership from an alliance <row> element.
    """
    member_corp_nodelist = alliance_node.find('rowset').getchildren()

    for node in member_corp_nodelist:
        corp_row_node = None
        try:
            # If this fails, this is a Text node and should be ignored.
            corporation_id = int(node.get('corporationID'))
        except AttributeError:
            # This is probably a Text node, ignore it.
            continue
        
        ApiPlayerCorporation = get_api_model_class('apiplayercorporation')
        corp, created = ApiPlayerCorporation.objects.get_or_create(id=corporation_id)
        corp.id = corporation_id
        corp.alliance = alliance
        corp.alliance_join_date = datetime.strptime(alliance_node.get('startDate'),
                                                  '%Y-%m-%d %H:%M:%S')
        corp.save()
        # Store the corp in the updated corps list for later checks.
        UPDATED_CORPS.append(corp.id)