|
13 | 13 | UnsupportedMizFileException |
14 | 14 | from datetime import datetime, timezone |
15 | 15 | from discord import Interaction, app_commands, SelectOption |
16 | | -from discord.app_commands import Range |
| 16 | +from discord.app_commands import Range, describe |
17 | 17 | from discord.ext import commands, tasks |
18 | 18 | from discord.ui import Modal, TextInput |
19 | 19 | from io import BytesIO |
| 20 | +from mgrs import MGRS |
20 | 21 | from pathlib import Path |
21 | 22 | from psycopg.rows import dict_row |
22 | 23 | from services.bot import DCSServerBot |
@@ -128,6 +129,17 @@ def get_name(base_dir: str, path: str): |
128 | 129 | return [] |
129 | 130 |
|
130 | 131 |
|
| 132 | +class DDTransformer(app_commands.Transformer): |
| 133 | + def __init__(self): |
| 134 | + self.mgrs_converter = MGRS() |
| 135 | + |
| 136 | + async def transform(self, interaction: discord.Interaction, value: Union[str, float]) -> float: |
| 137 | + if isinstance(value, str): |
| 138 | + return self.mgrs_converter.dmstodd(value) |
| 139 | + else: |
| 140 | + return value |
| 141 | + |
| 142 | + |
131 | 143 | class Mission(Plugin[MissionEventListener]): |
132 | 144 |
|
133 | 145 | def __init__(self, bot: DCSServerBot, listener: Type[MissionEventListener] = None): |
@@ -1939,6 +1951,47 @@ async def validate(self, interaction: discord.Interaction): |
1939 | 1951 | # noinspection PyUnresolvedReferences |
1940 | 1952 | await interaction.response.send_message(_("No menus.yaml found."), ephemeral=True) |
1941 | 1953 |
|
| 1954 | + @command(description=_('Convert values')) |
| 1955 | + @app_commands.guild_only() |
| 1956 | + @utils.app_has_role('DCS') |
| 1957 | + @describe(lat="Latitude in DD or DMS (N491012.12)", |
| 1958 | + lon="Longitude in DD or DMS (E011012.34)", |
| 1959 | + mgrs="MGRS coordinates") |
| 1960 | + async def convert(self, interaction: discord.Interaction, mode: Literal['Lat/Lon => MGRS', 'MGRS => Lat/Lon'], |
| 1961 | + lat: Optional[app_commands.Transform[float, DDTransformer]] = None, |
| 1962 | + lon: Optional[app_commands.Transform[float, DDTransformer]] = None, |
| 1963 | + mgrs: Optional[str] = None): |
| 1964 | + mgrs_converter = MGRS() |
| 1965 | + if mode == 'Lat/Lon => MGRS': |
| 1966 | + if not lat or not lon: |
| 1967 | + # noinspection PyUnresolvedReferences |
| 1968 | + await interaction.response.send_message("Latitude and longitude must be provided", ephemeral=True) |
| 1969 | + return |
| 1970 | + if isinstance(lat, str): |
| 1971 | + lat = mgrs_converter.dmstodd(lat) |
| 1972 | + if isinstance(lon, str): |
| 1973 | + lon = mgrs_converter.dmstodd(lon) |
| 1974 | + mgrs = mgrs_converter.toMGRS(lat, lon, MGRSPrecision=5) |
| 1975 | + # noinspection PyUnresolvedReferences |
| 1976 | + await interaction.response.send_message(f"MGRS: {mgrs}") |
| 1977 | + elif mode == 'MGRS => Lat/Lon': |
| 1978 | + if not mgrs: |
| 1979 | + # noinspection PyUnresolvedReferences |
| 1980 | + await interaction.response.send_message("MGRS must be provided", ephemeral=True) |
| 1981 | + return |
| 1982 | + lat, lon = mgrs_converter.toLatLon(mgrs, inDegrees=True) |
| 1983 | + d, m, s, f = utils.dd_to_dms(lat) |
| 1984 | + lat_dms = ('N' if d > 0 else 'S') + '{:02d}°{:02d}\'{:02d}.{:02d}"'.format( |
| 1985 | + int(abs(d)), int(abs(m)), int(abs(s)), int(abs(f))) |
| 1986 | + d, m, s, f = utils.dd_to_dms(lon) |
| 1987 | + lon_dms = ('E' if d > 0 else 'W') + '{:03d}°{:02d}\'{:02d}.{:02d}"'.format( |
| 1988 | + int(abs(d)), int(abs(m)), int(abs(s)), int(abs(f))) |
| 1989 | + # noinspection PyUnresolvedReferences |
| 1990 | + await interaction.response.send_message(f"{lat_dms} ({lat}), {lon_dms} ({lon})") |
| 1991 | + else: |
| 1992 | + # noinspection PyUnresolvedReferences |
| 1993 | + await interaction.response.send_message("Invalid conversion mode", ephemeral=True) |
| 1994 | + |
1942 | 1995 | @tasks.loop(hours=1) |
1943 | 1996 | async def expire_token(self): |
1944 | 1997 | async with self.apool.connection() as conn: |
|
0 commit comments