Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update map command (see PR notes!) #160

Merged
merged 2 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions config.example.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,4 @@

# Astronomy util API keys
N2YO_API_KEY = None
MAPQUEST_API_KEY = None
BITLY_TOKEN = None
TOMTOM_API_KEY = None
31 changes: 26 additions & 5 deletions crimsobot/cogs/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from discord.ext import commands

from crimsobot.bot import CrimsoBOT
from crimsobot.exceptions import LocationNotFound
from crimsobot.exceptions import LocationNotFound, ZoomNotValid
from crimsobot.utils import astronomy, image as imagetools, tools as c

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -271,16 +271,37 @@ async def iss(self, ctx: commands.Context, *, location: str) -> None:
@commands.command(name='map')
@commands.cooldown(3, 10, commands.BucketType.channel)
async def get_map(self, ctx: commands.Context, *, location: str) -> None:
"""Get a map of a location."""
"""Get a map of a location using its name.
You can also specify a zoom level 1-22.
1 is zoomed out the most; 10 is the default.

Example usage: >map hell; 14
"""

# parse user input
try:
location, zoom = location.split(';', 1)
except ValueError: # no zoom provided
zoom = '10' # currently type str; will be converted later

# bounce API query for shitty or spammy zoom levels
try:
zoom_int = int(zoom)
except ValueError:
raise ZoomNotValid(zoom)

if not 1 <= zoom_int <= 22:
raise ZoomNotValid(zoom)

# send to geocoder and map URL maker
location = location.upper()
lat, lon, map_url = astronomy.whereis(location)
lat, lon, map_url = astronomy.whereis(location, zoom_int)

if map_url is not None:
embed = c.crimbed(
title='Map of {}\n{}'.format(location, map_url),
title=f'Map of {location}',
descr=None,
footer='{}°, {}°'.format(lat, lon)
footer=f'{lat}°, {lon}°'
)
embed.set_image(url=map_url)
else:
Expand Down
4 changes: 4 additions & 0 deletions crimsobot/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def __init__(self, location: str) -> None:
self.location = location


class ZoomNotValid(Exception):
pass


class NotDirectMessage(Exception):
pass

Expand Down
35 changes: 7 additions & 28 deletions crimsobot/utils/astronomy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
from geopy.geocoders import Nominatim
from geopy.location import Location
from lxml import html
from pyshorteners import Shortener
from timezonefinder import TimezoneFinder

from config import BITLY_TOKEN, MAPQUEST_API_KEY
from config import TOMTOM_API_KEY


ISSPass = namedtuple(
Expand Down Expand Up @@ -93,7 +92,7 @@ def format_passes(passes: List[ISSPass]) -> str:
return tabulate.tabulate(passes, headers=headers)


def whereis(query: str) -> Tuple[Optional[float], Optional[float], Optional[str]]:
def whereis(query: str, zoom: int) -> Tuple[Optional[float], Optional[float], Optional[str]]:
# Nomanatim geocoder
location = where_are_you(query)

Expand All @@ -104,32 +103,12 @@ def whereis(query: str) -> Tuple[Optional[float], Optional[float], Optional[str]
lat = round(location.latitude, 6)
lon = round(location.longitude, 6)

# get bounding box from raw dict
bounding = location.raw['boundingbox']

# get difference btw center and bounding box, and stretch (more if close, less if far)
dlat = (lat - float(bounding[0]))
stretch = 10 / dlat ** 0.3
dlat = (lat - float(bounding[0])) * stretch
dlon = (lon - float(bounding[2])) * stretch

# new bounding box
bound = [lat - dlat, lat + dlat, lon - dlon, lon + dlon]

# now the URL!
url_template = (
'https://www.mapquestapi.com/staticmap/v5/map?'
'locations={},{}&boundingbox={},{},{},{}&type=dark&size=800,600@2x&key={}'
'https://api.tomtom.com/map/1/staticimage?'
'layer=basic&style=night&format=png&'
'key={}&zoom={}&center={},{}&width=1036&height=1036&language=NGT'
)
url = url_template.format(
lat, lon,
bound[0], bound[2], bound[1], bound[3],
MAPQUEST_API_KEY
)

# return url
# bit.ly shortner
shortener = Shortener(api_key=BITLY_TOKEN)
short_url = shortener.bitly.short(url) # type: str
url = url_template.format(TOMTOM_API_KEY, zoom, lon, lat)

return lat, lon, short_url
return lat, lon, url
Loading