Améliorations post launch

This commit is contained in:
Simon Junod
2025-08-06 18:11:27 +02:00
parent e5e6eb0c53
commit e27b4af4ec

View File

@@ -3,15 +3,15 @@ import re
import requests import requests
from nextcord import File from nextcord import File
from unidecode import unidecode from unidecode import unidecode
from collections import defaultdict
from datetime import datetime from datetime import datetime
from math import ceil
from settings import * from settings import *
import geopandas as gpd import geopandas as gpd
from shapely.geometry import Point from shapely.geometry import Point
from geopy.distance import geodesic from geopy.distance import geodesic
from geopy.geocoders import Nominatim
from math import sinh, atan, pi, log, tan, cos, ceil from math import sinh, atan, pi, log, tan, cos, ceil
geolocator = Nominatim(user_agent="discord-bot-spoutnik")
def tile_to_wgs84(x, y, z): def tile_to_wgs84(x, y, z):
return atan(sinh(pi * (1 - 2 * y / 2 ** z))) * 180 / pi, (x / 2 ** z - 0.5) * 360 return atan(sinh(pi * (1 - 2 * y / 2 ** z))) * 180 / pi, (x / 2 ** z - 0.5) * 360
@@ -34,6 +34,10 @@ def random_point(filename):
if shape.contains(point): if shape.contains(point):
return point.coords[0][::-1] return point.coords[0][::-1]
def clean_address(address):
output = address
output = re.sub(r", Lausanne, District de Lausanne, Vaud, \d+, Suisse", "", output)
return output
class Game: class Game:
def __init__(self, channel): def __init__(self, channel):
@@ -44,11 +48,12 @@ class Game:
self.last_player = None self.last_player = None
self.last_datetime = None self.last_datetime = None
self.resetters = set() self.resetters = set()
self.jump_url = None
async def reset(self): async def reset(self):
output = "" output = ""
if self.target and not self.winner: if self.target and not self.winner:
output = f"Le lieu précédent était : `{self.target}`\n\n" output = f":expressionless: Le lieu précédent était [ici](<https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{SPOUTNIK_ZOOM}z>).\n\n"
random_lat, random_lon = random_point(SPOUTNIK_FILE) random_lat, random_lon = random_point(SPOUTNIK_FILE)
tile_x, tile_y = wgs84_to_tile(random_lat, random_lon, SPOUTNIK_ZOOM) tile_x, tile_y = wgs84_to_tile(random_lat, random_lon, SPOUTNIK_ZOOM)
req = requests.get(f"https://khms2.google.com/kh/v=1000?x={tile_x}&y={tile_y}&z={SPOUTNIK_ZOOM}") req = requests.get(f"https://khms2.google.com/kh/v=1000?x={tile_x}&y={tile_y}&z={SPOUTNIK_ZOOM}")
@@ -59,8 +64,11 @@ class Game:
self.last_player = None self.last_player = None
self.last_datetime = None self.last_datetime = None
self.resetters = set() self.resetters = set()
output += f"Il y a un nouveau lieu à trouver ! Donnez-moi les coordonnées GPS du centre de l'image, à {SPOUTNIK_MAX_DISTANCE} m près (sur Google Maps, clic droit puis clic sur les coordonnées)." output += f":satellite_orbital: Il y a un nouveau lieu à trouver !"
await self.channel.send(output, file=File(self.file)) output += f"\n\nDonnez-moi les coordonnées GPS du centre de l'image, à {SPOUTNIK_MAX_DISTANCE} m près."
output += f"\n\n*Sur le site Google Maps, clic droit puis clic sur les coordonnées.*"
output += f"\n*Sur l'app Google Maps, appui long puis appui sur les coordonnées.*"
self.jump_url = (await self.channel.send(output, file=File(self.file))).jump_url
async def parse(self, message): async def parse(self, message):
guess = unidecode(message.content.strip()).upper() guess = unidecode(message.content.strip()).upper()
@@ -105,12 +113,18 @@ class Game:
lon = float(regex.group(2).replace(",", ".")) lon = float(regex.group(2).replace(",", "."))
distance = geodesic((lat, lon), self.target).meters distance = geodesic((lat, lon), self.target).meters
blurred_distance = ceil(geodesic((lat, lon), self.target).meters / 1000) blurred_distance = f"{ceil(distance / 1000)} km" if distance > 1000 else f"{ceil(distance / 100) * 100} m"
if distance <= SPOUTNIK_MAX_DISTANCE: if distance <= SPOUTNIK_MAX_DISTANCE:
self.winner = message.author self.winner = message.author
self.resetters = set() self.resetters = set()
output = f":trophy: YOUPI ! {message.author.mention} a trouvé le lieu ! :trophy:" output = f":trophy: YOUPI ! {message.author.mention} a trouvé le lieu ! :trophy:"
output += f"\n\nLieu exact : https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{SPOUTNIK_ZOOM}z" output += f"\n\n[Lieu exact](<https://www.google.ch/maps/@{self.target[0]},{self.target[1]},{SPOUTNIK_ZOOM}z>)"
await self.channel.send(output) await self.channel.send(output)
else: else:
await self.channel.send(f"{message.author.mention} : c'est pas ça chef, mais tu es à moins de {blurred_distance} km de la cible") try:
address = clean_address(geolocator.reverse((lat, lon), language="fr").address)
except ValueError:
address = "un lieu apparemment invalide"
output = f"{message.author.mention} propose [un point](<https://www.google.ch/maps/@{lat},{lon},{SPOUTNIK_ZOOM}z>) proche de {address}."
output += f"\n\nC'est pas ça chef, mais tu es à moins de {blurred_distance} de [la cible](<{self.jump_url}>) !"
await self.channel.send(output)