コード例 #1
0
ファイル: ingest.py プロジェクト: AngellusMortis/boundlexx
    def _get_world(self, world_id):
        if world_id is not None:
            world = World.objects.filter(id=world_id).first()
            if world is None:
                c = BoundlessClient()
                world_data = c.get_world_data(world_id)
                world, _ = World.objects.get_or_create_from_game_dict(
                    world_data["worldData"])

        return world
コード例 #2
0
ファイル: worlds.py プロジェクト: AngellusMortis/boundlexx
def get_worlds(ids_to_scan, client=None):
    if client is None:
        client = BoundlessClient()

    worlds: list[dict] = []

    for world_id in ids_to_scan:
        world_data = client.get_world_data(SimpleWorld(world_id, None))

        if world_data is not None:
            worlds.append(world_data)

    return worlds
コード例 #3
0
ファイル: worlds.py プロジェクト: AngellusMortis/boundlexx
def _scan_worlds(ids_to_scan):
    client = BoundlessClient()
    worlds = get_worlds(ids_to_scan, client=client)

    worlds_found = 0
    world_objs = []
    for world_dict in worlds:
        poll_token = world_dict["pollData"]
        world_data = world_dict["worldData"]

        try:
            world, created = World.objects.get_or_create_from_game_dict(
                world_dict["worldData"])
        except Exception:
            logger.warning(world_dict)
            raise

        if created:
            worlds_found += 1
            world_objs.append(world)

            if not world.is_locked:
                try:
                    poll_dict = client.get_world_poll(
                        SimpleWorld(
                            world_data["id"],
                            world_data["apiURL"],
                        ),
                        poll_token=poll_token,
                    )
                except HTTPError as ex:
                    if world.is_sovereign and ex.response.status_code == 400:
                        logger.warning(
                            "Could not do inital world poll world: %s",
                            world.display_name,
                        )
                        world_data = None
                    else:
                        raise

                if world_data is not None:
                    WorldPoll.objects.create_from_game_dict(world_data,
                                                            poll_dict,
                                                            world=world,
                                                            new_world=True)

    logger.info("Found %s world(s)", worlds_found)

    return worlds_found, world_objs
コード例 #4
0
ファイル: ingest.py プロジェクト: AngellusMortis/boundlexx
    def _get_world(self, world_id, display_name):
        if world_id is not None:
            world = World.objects.filter(id=world_id).first()
            if world is None:
                c = BoundlessClient()
                world_data = c.get_world_data(world_id)
                world, _ = World.objects.get_or_create_from_game_dict(
                    world_data["worldData"])
        else:
            world = World.objects.filter(display_name=display_name).first()

            if world is None:
                world = World.objects.filter(
                    display_name={
                        "name": display_name
                    },
                    active=True,
                    owner__isnull=True,
                ).get()

        return world
コード例 #5
0
ファイル: worlds.py プロジェクト: AngellusMortis/boundlexx
def _poll_worlds(worlds):
    total = len(worlds)
    if total > settings.BOUNDLESS_MAX_WORLDS_PER_POLL:
        _split_polls(worlds)
        return

    client = BoundlessClient()
    logger.info("Boundless user: %s", client.user["boundless"]["username"])

    error_handler = GameErrorHandler(
        rd_callback=_handle_rd,
        http_callback=_handle_error,
        error_callback=_handle_error,
    )
    poll_world = error_handler(_poll_world)
    for index, world in enumerate(worlds):
        WorldPoll.objects.filter(world=world, active=True).update(active=False)

        logger.info("Polling world %s (%s/%s)", world.display_name, index + 1,
                    total)
        response = poll_world(client=client, world=world)

        if response.has_error:
            continue

        world_data, poll_data = response.response
        if world_data is None:
            _mark_world_inactive(world)
            continue

        try:
            world, _ = World.objects.get_or_create_from_game_dict(world_data)
        except Exception:
            logger.warning(world_data)
            raise

        if world.is_locked or (world.end is not None
                               and timezone.now() > world.end):
            logger.info("World %s expired, not polling...", world)
            continue

        if poll_data is not None:
            try:
                WorldPoll.objects.create_from_game_dict(world_data,
                                                        poll_data,
                                                        world=world)
            except Exception:
                logger.warning(poll_data)
                raise
コード例 #6
0
ファイル: worlds.py プロジェクト: AngellusMortis/boundlexx
def poll_settlements(world_ids=None):
    if world_ids is None:
        worlds = (World.objects.filter(
            api_url__isnull=False,
            is_public=True,
            is_creative=False,
            is_locked=False,
        ).filter(
            Q(active=True)
            | Q(end__isnull=False, end__gt=timezone.now())).order_by("id"))
    else:
        worlds = World.objects.filter(id__in=world_ids)

    client = BoundlessClient()
    colors = Color.objects.all()

    error_handler = GameErrorHandler(
        rd_callback=_handle_rd,
        http_callback=_handle_error,
        error_callback=_handle_error,
    )

    @error_handler
    def _poll_settlements(client, world):
        return client.get_world_settlements(
            SimpleWorld(world.id, world.api_url))

    for world in worlds:
        response = _poll_settlements(client=client, world=world)

        if response.has_error:  # pylint: disable=no-member
            continue

        settlements = response.response  # pylint: disable=no-member
        Settlement.objects.filter(world=world).delete()

        for settlement in settlements:
            Settlement.objects.create_from_game_obj(world,
                                                    settlement,
                                                    colors=colors)

        logger.info("Found %s settlements for %s", len(settlements), world)
コード例 #7
0
def _update_item_prices(
    item, rank_klass, client_method: str, price_klass, all_worlds: list[SimpleWorld]
):

    client = BoundlessClient()
    ranks, worlds = _get_ranks(item, rank_klass, all_worlds)

    if len(ranks) == 0:
        return -1

    total = 0

    for world in worlds:
        shops = _get_shops(client, client_method, item, world)

        if shops is None:
            continue

        # set all existing price records to inactive
        price_klass.objects.filter(item=item, active=True, world__id=world.id).update(
            active=False
        )

        item_total, state_hash = _create_item_prices(shops, price_klass, world, item)
        total += item_total

        digest = str(state_hash.hexdigest())
        rank = ranks[world.id]
        if rank.state_hash != "":
            if rank.state_hash == digest:
                rank.decrease_rank()
            else:
                rank.increase_rank()

        rank.state_hash = digest
        rank.last_update = timezone.now()
        rank.save()

    return total
コード例 #8
0
ファイル: worlds.py プロジェクト: AngellusMortis/boundlexx
def calculate_distances(world_ids=None):
    if world_ids is None:
        worlds = World.objects.filter(active=True)
        all_worlds = worlds
    else:
        worlds = World.objects.filter(id__in=world_ids)
        all_worlds = World.objects.filter(active=True)

    client = BoundlessClient()

    world_ids = {w.id for w in all_worlds}

    for world in worlds:
        world_distances = WorldDistance.objects.filter(
            Q(world_source=world) | Q(world_dest=world)).select_related(
                "world_source", "world_dest")

        world_distance_ids = set()
        for world_distance in world_distances:
            if world_distance.world_source.id == world_distance.world_dest.id:
                world_distance_ids.add(world.id)
            else:
                if world_distance.world_source.id != world.id:
                    world_distance_ids.add(world_distance.world_source.id)
                if world_distance.world_dest.id != world.id:
                    world_distance_ids.add(world_distance.world_dest.id)

        missing_distance_ids = world_ids.difference(world_distance_ids)

        logger.info(
            "Missing %s distance calulcation(s) for %s",
            len(missing_distance_ids),
            world,
        )
        for world_id in missing_distance_ids:
            world_dest = World.objects.get(id=world_id)

            world.get_distance_to_world(world_dest, client=client)