コード例 #1
0
    def post(self, request):
        try:
            character = request.user.characters.get(
                character_id=int(request.POST['character_id']))
        except EveUser.DoesNotExist:
            return HttpResponse(status=403)

        ESI.request('post_ui_openwindow_contract',
                    client=character.get_client(),
                    contract_id=int(request.POST['contract_id']))

        return HttpResponse(status=204)
コード例 #2
0
 def generate_route(self, character, route):
     if settings.GENERATE_ROUTE:
         for i in range(len(route['esi'])):
             if i == 0:
                 ESI.request('post_ui_autopilot_waypoint',
                             client=character.get_client(),
                             add_to_beginning=False,
                             clear_other_waypoints=True,
                             destination_id=route['esi'][i])
             else:
                 ESI.request('post_ui_autopilot_waypoint',
                             client=character.get_client(),
                             add_to_beginning=False,
                             clear_other_waypoints=False,
                             destination_id=route['esi'][i])
コード例 #3
0
def send_enqueued_mails():
    for m in MailSender.objects.all():
        client = m.character.get_client()

        while True:
            mails = (
                Mail.objects
                .filter(Q(sender__isnull=True) | Q(sender=m))
                .order_by('-priority', 'created')
            )

            if not mails.exists():
                break

            mail = mails[0]

            req = ESI.request(
                'post_characters_character_id_mail',
                client=client,
                character_id=m.character.character_id,
                mail={
                    "approved_cost": 0,
                    "body": mail.body,
                    "recipients": [
                        r.as_recipient_dict() for r in mail.recipients.all()
                    ],
                    "subject": mail.subject
                }
            )

            if req.status == 201:
                mail.delete()
            else:
                break
コード例 #4
0
ファイル: backend.py プロジェクト: unkwntech/blue-donut
    def structure_search(self, character, known_structures):
        logger.debug(f"Beginning deep search with character {character}.")

        structure_ids = []

        # Search /characters/{character_id}/search/ for the "»" character and some letters
        # and add everything to a list
        for item in search_list:
            structure_ids.extend(
                ESI.request('get_characters_character_id_search',
                            client=character.get_client(),
                            character_id=character.character_id,
                            categories=['structure'],
                            search=search_string + item).data.structure)

            # Log the length of the structure list after every iteration

        logger.debug(
            f"List complete with {structure_ids} structure IDs. Removing duplicates."
        )

        structure_ids = list(set(structure_ids))
        logger.debug(f"Duplicates removed. New total: {structure_ids}")

        # Remove any structures we've already found
        structure_list = [
            x for x in structure_ids if x not in known_structures
        ]

        logger.debug(f"Total structures to index: {structure_list}")

        # Get information about each structure
        structure_info = self.structure_parse(character, structure_list)

        return structure_list, structure_info
コード例 #5
0
def read_assets_for_character(character):
    valid_module_types = {
        x
        for x in ModuleType.objects.values_list('id', flat=True)
    }

    try:
        items = ESI.request('get_characters_character_id_assets',
                            client=character.get_client(),
                            multi_page=True,
                            character_id=character.character_id)
    except EsiException as e:
        logger.exception(
            "Retrieval of assets for character %d failed (status %d)",
            character.character_id, e.status)
        return

    abyssal_modules = [
        create_module.call_local(x['type_id'], x['item_id']) for x in items
        if x['type_id'] in valid_module_types
    ]

    with transaction.atomic():
        AssetRecord.objects.filter(owner=character).delete()

        for x in abyssal_modules:
            AssetRecord(owner=character, module=x).save()
コード例 #6
0
    def create_static_types(self):
        mod_to_source = defaultdict(set)

        for x in Mutator.objects.all():
            for y in x.applicable_modules.all():
                mod_to_source[x.result.id].add(y.id)

        for abyssal_id, sources in tqdm(mod_to_source.items()):
            for s in sources:
                data = ESI.request('get_universe_types_type_id',
                                   type_id=s).data

                module, _ = StaticModule.objects.update_or_create(
                    id=s, defaults={
                        'source_id': s,
                        'type_id': abyssal_id
                    })

                for attr in data['dogma_attributes']:
                    try:
                        ModuleAttribute.objects.update_or_create(
                            static_module=module,
                            attribute_id=attr['attribute_id'],
                            new_attribute=TypeAttribute.objects.get(
                                type_id=abyssal_id,
                                attribute_id=attr['attribute_id']),
                            defaults={'value': attr['value']})
                    except TypeAttribute.DoesNotExist:
                        pass
コード例 #7
0
def scan_public_contracts(scan_all=False):
    if (datetime.time(hour=10, minute=55) <= datetime.datetime.now(
            datetime.timezone.utc).time() <= datetime.time(hour=11,
                                                           minute=20)):
        return

    all_regions = ESI.request('get_universe_regions').data
    all_contract_ids = set()

    for region in all_regions:
        number_of_page = ESI.head('get_contracts_public_region_id',
                                  region_id=region).header['X-Pages'][0]

        for page in range(1, number_of_page + 1):
            req = ESI.request('get_contracts_public_region_id',
                              region_id=region,
                              page=page)

            contracts = list(req.data)

            for contract_dict in contracts:
                all_contract_ids.add(contract_dict['contract_id'])

                if contract_dict['type'] not in ['item_exchange', 'auction']:
                    continue

                COUNTER_CONTRACTS_FOUND.labels(
                    region=region, type=contract_dict['type']).inc()

                try:
                    contract = Contract.objects.get(
                        id=contract_dict['contract_id'])

                    if not contract.available:
                        contract.available = True
                        contract.save()

                    if scan_all:
                        scan_contract(dict(contract_dict), region)
                except Contract.DoesNotExist:
                    scan_contract(dict(contract_dict), region)

    Contract.objects.filter(Q(available=True)
                            & ~Q(id__in=all_contract_ids)).update(
                                available=False)
コード例 #8
0
    def get(self, request):
        security = ESI.get_security()

        tokens = security.auth(request.GET['code'])
        data = security.verify()

        login(request, authenticate(request, info=data, tokens=tokens))

        return redirect('/')
コード例 #9
0
    def post(self, request):
        try:
            character = request.user.characters.get(
                character_id=int(request.POST['character_id']))
        except EveUser.DoesNotExist:
            return HttpResponse(status=403)

        RoutePlannerBackend().check_alliance(character)

        # Get character's current location from ESI
        req = ESI.request(
            'get_characters_character_id_location',
            client=character.get_client(),
            character_id=int(
                request.POST['character_id'])).data.solar_system_id

        source_name = SolarSystems.objects.get(
            solarSystemID=req).solarSystemName

        # Error checking for characters in wormholes
        if re.match('J[0-9]{6}', source_name) or source_name == "Thera":
            return self.render_page(request, True, None, False, False,
                                    source_name, "wormhole")

        # Generate the route
        try:
            route = RoutePlannerBackend().generate(req,
                                                   request.POST['destination'])
        except NodeNotFound or AttributeError or ObjectDoesNotExist as error:
            logger.error(error)
            return self.render_page(request, True, None, False, False,
                                    source_name, "route")

        # Clicking the "Verify" button shows a map and a confirm route button
        if 'verify' in request.POST:
            return self.render_page(request, False, route, True, True)

        # Confirming the route after clicking "Verify"
        elif 'confirm' in request.POST:
            RoutePlannerBackend().updateRecents(request.user,
                                                request.POST['destination'])
            self.generate_route(character, route)
            return self.render_page(request, False, route, True, False)

        # Basically skipping having to click the "Confirm" button
        elif 'generate' in request.POST:
            RoutePlannerBackend().updateRecents(request.user,
                                                request.POST['destination'])
            self.generate_route(character, route)
            return self.render_page(request, False, route, True, False)

        # Clicking one of the "Favorites", "Recent", or "Popular" buttons
        else:
            RoutePlannerBackend().updateRecents(request.user,
                                                request.POST['destination'])
            self.generate_route(character, route)
            return self.render_page(request, False, route, True, False)
コード例 #10
0
    def create_invtypes(self):
        existing = set(InvType.objects.values_list('id', flat=True))
        available = set()

        res = ESI.head('get_universe_types')

        for p in range(1, 1 + res.header['X-Pages'][0]):
            available |= set(ESI.request('get_universe_types', page=p).data)

        to_fetch = available - existing

        for i in to_fetch:
            data = ESI.request('get_universe_types_type_id', type_id=i).data

            InvType.objects.update_or_create(id=i,
                                             defaults={
                                                 'group_id': data['group_id'],
                                                 'name': data['name'],
                                             })
コード例 #11
0
ファイル: backend.py プロジェクト: unkwntech/blue-donut
    def single_search(self, character, query):
        try:
            gate_id = ESI.request('get_characters_character_id_search',
                                  client=character.get_client(),
                                  character_id=character.character_id,
                                  categories=['structure'],
                                  search=query).data.structure
        except KeyError:
            return

        # Note that searching for 2 systems and the "»" character will return two gates
        return self.structure_parse(character, gate_id)
コード例 #12
0
    def check_alliance(self, character):
        if timezone.now() - character.esi_updated > timezone.timedelta(days=7):
            logger.debug(
                f"Updating {character.name}'s alliance and corporation.")

            req = ESI.request('get_characters_character_id',
                              character_id=character.character_id).data

            character.alliance_id = req.alliance_id
            character.corporation_id = req.corporation_id

            character.save()
コード例 #13
0
    def import_types(self):
        for i in tqdm(ITEMS):
            relevant = dict(i['relevant_attributes'])

            type_obj, _ = ModuleType.objects.update_or_create(
                id=i['abyssal_id'], defaults={'name': i['name']})

            items = ESI.request(
                'get_universe_types_type_id',
                client=self.client,
                type_id=i['normal_id']).data['dogma_attributes']

            for a in items:
                attr_data = ESI.request('get_dogma_attributes_attribute_id',
                                        client=self.client,
                                        attribute_id=a['attribute_id']).data

                if not attr_data.get('published', False):
                    continue

                attr_obj, _ = ModuleDogmaAttribute.objects.update_or_create(
                    id=attr_data['attribute_id'],
                    defaults={
                        'name': attr_data['display_name'],
                        'short_name': attr_data['name'],
                        'unit_str': UNIT_STR.get(attr_data.get('unit_id', -1),
                                                 ''),
                    })

                TypeAttribute.objects.update_or_create(
                    type=type_obj,
                    attribute=attr_obj,
                    defaults={
                        'high_is_good':
                        relevant.get(attr_data['attribute_id'],
                                     attr_data.get('high_is_good', None)),
                        'display':
                        attr_data['attribute_id'] in relevant
                    })
コード例 #14
0
    def post(self, request):
        scopes = [
            'esi-location.read_location.v1',
            'esi-ui.write_waypoint.v1',
        ]

        if "approve" in request.POST:
            scopes.extend([
                'esi-search.search_structures.v1',
                'esi-universe.read_structures.v1'
            ])

        return redirect(ESI.get_security().get_auth_uri(state=str(uuid4()),
                                                        scopes=scopes))
コード例 #15
0
    def post(self, request):
        form = ScopeForm(request.POST)

        if not form.is_valid():
            return redirect('/')

        scopes = []

        if form.cleaned_data['scope_open_window']:
            scopes.append('esi-ui.open_window.v1')

        if form.cleaned_data['scope_read_assets']:
            scopes.append('esi-assets.read_assets.v1')

        return redirect(ESI.get_security().get_auth_uri(scopes=scopes))
コード例 #16
0
    def get_or_create_by_id(self, character_id):
        try:
            return self.model.objects.get(id=character_id)
        except self.model.DoesNotExist:
            character_data = ESI.request(
                'get_characters_character_id',
                character_id=character_id
            ).data

            character, _ = EveCharacter.objects.update_or_create(
                id=character_id,
                defaults={
                    'name': character_data['name']
                }
            )

            return character
コード例 #17
0
def create_module(type_id, item_id, force=False):
    if not force:
        try:
            return Module.objects.get(id=item_id)
        except Module.DoesNotExist:
            pass

    try:
        module_data = ESI.request('get_dogma_dynamic_items_type_id_item_id',
                                  type_id=type_id,
                                  item_id=item_id).data
    except EsiException as e:
        logger.exception("Retrieval of stats for module %d failed (status %d)",
                         item_id, e.status)
        return

    with transaction.atomic():
        character = EveCharacter.objects.get_or_create_by_id(
            module_data['created_by'])

        res, created = Module.objects.get_or_create(
            id=item_id,
            defaults={
                'type_id': type_id,
                'mutator_id': module_data['mutator_type_id'],
                'source_id': module_data['source_type_id'],
                'creator': character
            })

        if created:
            COUNTER_MODULES_CREATED.labels(type=type_id).inc()

        for a in module_data['dogma_attributes']:
            try:
                ModuleAttribute(module=res,
                                attribute=ModuleDogmaAttribute.objects.get(
                                    id=a['attribute_id']),
                                new_attribute=TypeAttribute.objects.get(
                                    type_id=type_id,
                                    attribute_id=a['attribute_id']),
                                value=a['value']).save()
            except ModuleDogmaAttribute.DoesNotExist:
                pass

    return res
コード例 #18
0
    def get_security(self):
        res = ESI.get_security()
        res.update_token(self.tokens)

        if res.is_token_expired(offset=60):
            try:
                self.tokens = res.refresh()
            except APIException as e:
                if e.status_code == 400:
                    self.scope_open_window = False
                    self.scope_read_assets = False
                    self.save()

                    raise EveUser.KeyDeletedException(
                        "ESI refused to refresh our tokens."
                    )
                raise

        return res
コード例 #19
0
    def get_assets(self):
        results = []

        for page in itertools.count(start=1):
            req = ESI.request(
                'get_characters_character_id_assets',
                client=self.get_client(),
                character_id=self.character_id,
                page=page
            )

            date = datetime.datetime.strptime(
                req.header['Last-Modified'][0],
                "%a, %d %b %Y %H:%M:%S GMT"
            ).replace(tzinfo=pytz.UTC)
            results += req.data

            if page >= req.header['X-Pages'][0]:
                break

        return results, date
コード例 #20
0
ファイル: backend.py プロジェクト: unkwntech/blue-donut
    def structure_parse(self, character, structure_list):
        structure_info = []

        # Now query /universe/structures/{structure_id}/ to get information about each gate
        for item in structure_list:
            req = ESI.request('get_universe_structures_structure_id',
                              client=character.get_client(),
                              structure_id=item).data

            name = req.name.split(' ')

            structure = {
                'id': item,
                'from': name[0],
                'to': name[2],
                'owner': req.owner_id
            }

            structure_info.append(structure.copy())

        return structure_info
コード例 #21
0
ファイル: backend.py プロジェクト: unkwntech/blue-donut
    def update_characters(self):
        logger.debug("Updating character alliances and corporations.")

        for character in EveUser.objects.all():

            data = ESI.request('get_characters_character_id',
                               character_id=character.character_id).data

            if "alliance_id" in data:
                alliance = data.alliance_id
            else:
                alliance = 0

            corporation = data.corporation_id

            character.alliance_id = alliance
            character.corporation_id = corporation

            character.save()

        logger.debug("Character information updated!")
        return len(EveUser.objects.all())
コード例 #22
0
ファイル: backend.py プロジェクト: unkwntech/blue-donut
    def search_routine(self, alliances):
        logger.debug("Beginning jump gate search routine.")

        missing_alliances = []
        excluded_gates = []
        jump_gates = []

        for alliance in alliances:
            characters = EveUser.objects.filter(alliance_id=alliance,
                                                scope_search_structures=True,
                                                scope_read_structures=True)

            # Check if there is a character in the desired alliance. If not, skip this iteration.
            if not characters:
                logger.debug(f"No members found in alliance {alliance}.")
                missing_alliances.append(alliance)
                continue
            else:
                logger.debug(
                    f"Found {len(characters)} character(s) in {alliance}.")

            # Verify this person is in the correct alliance.
            exclude_list = []

            while True:
                character = random.choice(characters)
                logger.debug(
                    f"Checking if character {character.name} is in alliance {alliance}."
                )

                try:
                    alliance_esi = ESI.request(
                        'get_characters_character_id',
                        character_id=character.character_id).data.alliance_id
                except KeyError:
                    alliance_esi = 0

                if alliance == alliance_esi:
                    logger.debug(
                        f"Character {character.name} is verified as a member of alliance {alliance}."
                    )
                    break
                else:
                    logger.debug(
                        f"Character's alliance has changed. Updating to {alliance_esi}."
                    )
                    character.alliance_id = alliance_esi
                    character.save()

                    # Add the faulty character to the exclude list to avoid getting them again.
                    exclude_list.append(character.id)
                    characters = characters.exclude(id__in=exclude_list)

                if not characters:
                    break

            if not characters:
                logger.debug(
                    f"Character list has been exhausted. Skipping alliance {alliance}."
                )
                continue

            character = EveUser.objects.get(
                character_id=character.character_id)

            new_gate_ids, new_gate_info = self.structure_search(
                character, excluded_gates)

            # Add results from the structure search to ignored gates for future searches
            excluded_gates.extend(new_gate_ids)

            jump_gates.extend(new_gate_info)

            # For loop is over - iterate to next alliance after adding the gates to the two lists

        logger.debug("Removing single sided gates.")
        final_list = self.check_single_gates(jump_gates)

        logger.debug(f"{len(jump_gates)-len(final_list)} gates removed.")

        logger.debug(
            f"Updating database with {len(final_list)} total jump gates.")

        # Clear the database and all all the gates to it
        AnsiblexJumpGates.objects.all().delete()

        for gate in final_list:
            fromSolarSystemID = SolarSystems.objects.get(
                solarSystemName=gate['from']).solarSystemID
            toSolarSystemID = SolarSystems.objects.get(
                solarSystemName=gate['to']).solarSystemID

            AnsiblexJumpGates(structureID=gate['id'],
                              fromSolarSystemID=fromSolarSystemID,
                              toSolarSystemID=toSolarSystemID,
                              ownerID=gate['owner']).save()

        logger.debug("Completed jump gate update routine.")
        logger.debug(f"Jump gates found: {len(final_list)}")
        if missing_alliances:
            logger.debug(
                f"Could not find members in the following alliances: {missing_alliances}"
            )

        return len(jump_gates)
コード例 #23
0
def initialize_esi():
    logger.info("Initializing ESI application to start Huey consumer")
    ESI._initialize_app()
    logger.info("ESI application initialized for consumer!")
コード例 #24
0
def scan_contract(contract_dict, region_id):
    abyssal_ids = list(ModuleType.objects.values_list('id', flat=True))

    COUNTER_CONTRACTS_SCANNED.labels(region=region_id,
                                     type=contract_dict['type']).inc()

    with transaction.atomic():
        contract, _ = Contract.objects.get_or_create(
            id=contract_dict['contract_id'],
            defaults={
                'issuer_id': contract_dict['issuer_id'],
                'price': contract_dict['price'],
                'issued_at': contract_dict['date_issued'].v,
                'expires_at': contract_dict['date_expired'].v,
                'single_item': False,
                'location_id': contract_dict['start_location_id'],
                'region_id': region_id,
                'auction': (contract_dict['type'] == 'auction')
            })

        contract.available = True

        req = ESI.request('get_contracts_public_items_contract_id',
                          contract_id=contract.id)

        # This happens if a contract is deleted.
        if req.status == 404:
            return

        # Not totally sure when this happens...
        if req.status == 403:
            return

        # This prevents us from s******g the bed on contracts that are cached but have been accepted since
        if req.status == 204 and req.data is None:
            return

        data = req.data
        items = 0

        contract.single_item = True
        contract.plex = 0

        for item in data:
            if item['type_id'] in abyssal_ids and item.get(
                    'is_included', True):
                items += 1

                logger.info("Found abyssal module %d in contract %d.",
                            item['item_id'], contract_dict['contract_id'])

                module = create_module.call_local(type_id=item['type_id'],
                                                  item_id=item['item_id'])

                contract.modules.add(module)
            elif item['type_id'] == 44992 and not item['is_included']:
                contract.plex += item['quantity']
            else:
                items += 1

        contract.single_item = (items == 1)

        contract.save()
コード例 #25
0
 def get_contracts(self):
     return ESI.request(
         'get_characters_character_id_contracts',
         client=self.get_client(),
         character_id=self.character_id
     ).data
コード例 #26
0
ファイル: models.py プロジェクト: unkwntech/blue-donut
 def get_client(self):
     return ESI.get_client(self.get_security())
コード例 #27
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.client = ESI.get_client()