|
@@ -2,11 +2,12 @@ import asyncio
|
|
|
import collections
|
|
|
import logging
|
|
|
import random
|
|
|
+from itertools import groupby
|
|
|
from typing import List, Tuple, Dict, Union
|
|
|
|
|
|
from .random_street_view import call_random_street_view, VALID_COUNTRIES as RSV_COUNTRIES
|
|
|
from .urban_centers import urban_coord, VALID_COUNTRIES as URBAN_COUNTRIES
|
|
|
-from .shared import aiohttp_client
|
|
|
+from .shared import aiohttp_client, reverse_geocode
|
|
|
|
|
|
from ..schemas import GameConfig, GenMethodEnum, CountryCode, CacheInfo, GeneratorInfo
|
|
|
|
|
@@ -51,19 +52,26 @@ class PointStore:
|
|
|
|
|
|
async def _gen_rsv_point(self, country: CountryCode):
|
|
|
# RSV point function returns a collection of points, which should be cached
|
|
|
- points = await call_random_street_view(country)
|
|
|
- if len(points) > 0:
|
|
|
- point = points.pop()
|
|
|
- self.store[(GenMethodEnum.rsv, country)].extend(points)
|
|
|
- return point
|
|
|
+ for actual_country, points in groupby(await call_random_street_view(country), key=lambda p: p[0]):
|
|
|
+ # but these points need to be cached according to the actual reverse geocoded country they are in
|
|
|
+ self.store[(GenMethodEnum.rsv, actual_country)].extend(points)
|
|
|
+ stock = self.store[(GenMethodEnum.rsv, country)]
|
|
|
+ if len(stock) > 0:
|
|
|
+ return stock.popleft()
|
|
|
|
|
|
async def _gen_urban_point(self, countries: List[CountryCode], city_retries: int):
|
|
|
for country in countries:
|
|
|
logger.info(f"Selecting urban centers from {country}")
|
|
|
pt = await urban_coord(country, city_retries=city_retries)
|
|
|
if pt is not None:
|
|
|
- return pt
|
|
|
-
|
|
|
+ if pt[0] == country:
|
|
|
+ return pt
|
|
|
+ else:
|
|
|
+ # TODO technically this is slightly wasted effort in rare edge cases
|
|
|
+ self.store[(GenMethodEnum.urban, pt[0])].append(pt)
|
|
|
+
|
|
|
+ # TODO I think all of this logic still gets stuck in the trap of generating points even when there's a stock in some edge cases
|
|
|
+ # this needs a rewrite but I'm not doing that now
|
|
|
async def get_point(self, generator: GenMethodEnum, country: Union[CountryCode, None], force_generate: bool = False) -> Tuple[str, float, float]:
|
|
|
if country is None:
|
|
|
# generating points across the whole world
|
|
@@ -159,7 +167,7 @@ class PointStore:
|
|
|
await asyncio.wait_for(gathered, timeout)
|
|
|
except (asyncio.TimeoutError, ExhaustedSourceError):
|
|
|
# if this task times out, it's fine, as it's just intended to be a best effort
|
|
|
- logger.exception(f"Failed to fully restock point cache for {config}")
|
|
|
+ logger.exception("Failed to fully restock a point cache!")
|
|
|
|
|
|
|
|
|
points = PointStore({
|