Skip to content

Commit

Permalink
[maps] 2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
owocado committed May 4, 2024
1 parent c109451 commit e27340a
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 66 deletions.
14 changes: 11 additions & 3 deletions maps/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
from discord.utils import maybe_coroutine
from __future__ import annotations
from typing import TYPE_CHECKING

from redbot.core.errors import CogLoadError

from .maps import Maps

if TYPE_CHECKING:
from redbot.core.bot import Red

__red_end_user_data_statement__ = "This cog does not persistently store data about users."


async def setup(bot):
await maybe_coroutine(bot.add_cog, Maps())
async def setup(bot: Red) -> None:
if not getattr(bot, "session", None):
raise CogLoadError("This cog requires bot.session attr to be set.")
await bot.add_cog(Maps())
20 changes: 20 additions & 0 deletions maps/converter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import discord
from redbot.core import commands


class MapFlags(commands.FlagConverter, prefix="-", delimiter=" "):
location: str | None = commands.flag(
default=None,
description="Input a location name that is available on Google Maps.",
positional=True,
)
zoom: int = commands.flag(
default=12,
description="Zoom level of the map, from 1 to 20. Defaults to 12.",
max_args=1,
)
map_type: str = commands.flag(
default="roadmap",
description="The type or format of the map, either 'roadmap' (default), 'satellite', 'terrain' or 'hybrid'",
max_args=1,
)
15 changes: 10 additions & 5 deletions maps/info.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
{
"name": "Google Maps",
"short": "Fetch a Google map of a specific location.",
"description": "Fetch a Google map of a specific location in various modes.",
"short": "Fetch map of a location from Google Maps.",
"description": "Fetch map of a location from Google Maps in various modes.",
"end_user_data_statement": "This cog does not persistently store data or metadata about users.",
"install_msg": "Hi, thanks for installing my Maps cog. Please note that this cog requires some setup to do on your part to get a free API key, mainly to enable Maps API. If you can figure that out on your own, that's genius, but if you find yourself struggling on how to enable it and still want to use this cog, you can ask me on Discord for help. I'll try my best to help you out.",
"author": ["siu3334"],
"author": ["owocado"],
"required_cogs": {},
"requirements": [],
"tags": ["maps", "map", "google map", "google maps"],
"min_bot_version": "3.4.0",
"hidden": false,
"min_bot_version": "3.6.0",
"min_python_version": [
3,
12,
0
],
"hidden": true,
"disabled": false,
"type": "COG"
}
117 changes: 59 additions & 58 deletions maps/maps.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import aiohttp
import asyncio

from io import BytesIO
import io
from typing import Optional

import discord
from redbot.core import commands
from redbot.core.utils.chat_formatting import humanize_list

from .converter import MapFlags

MAP_TYPES = ["roadmap", "satellite", "terrain", "hybrid"]
MAP_TYPES: tuple[str, ...] = ("roadmap", "satellite", "terrain", "hybrid")


class Maps(commands.Cog):
"""Fetch a Google map of a specific location."""
"""Fetch a Google map of a specific location with zoom and map types."""

__authors__ = ["ow0x"]
__version__ = "1.0.1"
__authors__ = "<@306810730055729152>"
__version__ = "2.0.0"

def format_help_for_context(self, ctx: commands.Context) -> str:
"""Thanks Sinbad."""
Expand All @@ -24,67 +26,66 @@ def format_help_for_context(self, ctx: commands.Context) -> str:
f"Cog version: v{self.__version__}"
)

@commands.command()
@commands.is_owner()
@commands.bot_has_permissions(attach_files=True)
async def map(
self,
ctx: commands.Context,
zoom: Optional[int],
map_type: str,
*,
location: str
):
"""Fetch a Google map of a specific location in various modes.
`zoom` parameter accepts values from 1 to 20. Defaults to 12 if any other value is provided.
@commands.command()
async def map(self, ctx: commands.Context, *, flags: MapFlags) -> None:
"""Fetch map of a location from Google Maps.
Zoom levels to show the approximate level of detail:
**Zoom:**
`zoom` value must be from level 1 to 20. Defaults to 12.
Below zoom levels that will show the approximate level of detail:
```
1 : World
5 : Landmass/continent
10 : City
15 : Streets
20 : Buildings
1 to 4 : World
5 to 9 : Landmass/continent
10 to 14 : City
15 to 19 : Streets
20 : Buildings
```
`map_type` parameter accepts only below 4 values:
```
roadmap, satellite, terrain, hybrid
```
You can read more on that in detail on Google Developers docs:
https://developers.google.com/maps/documentation/maps-static/start#MapTypes
**Map types:**
- `maptype` parameter accepts only below 4 values:
- `roadmap`, `satellite`, `terrain`, `hybrid`
Check out Google's detailed docs for more info:
https://developers.google.com/maps/documentation/maps-static/start
"""
api_key = (await ctx.bot.get_shared_api_tokens("googlemaps")).get("api_key")
if not api_key:
await ctx.send("\u26d4 API key not set. Ask bot owner to set it first!")
await ctx.send("⚠️ Bot owner need to set API key first!", ephemeral=True)
return
if map_type not in MAP_TYPES:
return await ctx.send_help()

zoom = zoom if (zoom and 1 <= zoom <= 20) else 12
# maptype = "roadmap" if maptype not in MAP_TYPES else maptype
location, zoom, map_type = flags.location, flags.zoom, flags.map_type
if not location:
await ctx.send("You need to provide a location name silly", ephemeral=True)
return
zoom = zoom if (1 <= zoom <= 20) else 12
map_type = "roadmap" if map_type not in MAP_TYPES else map_type

async with ctx.typing():
base_url = "https://maps.googleapis.com/maps/api/staticmap"
params = {
"zoom": zoom,
"size": "600x600",
"scale": "2",
"maptype": map_type,
"center": location,
"key": api_key
}
try:
async with aiohttp.ClientSession() as session:
async with session.get(base_url, params=params) as response:
if response.status != 200:
await ctx.send(f"https://http.cat/{response.status}")
return
image = BytesIO(await response.read())
image.seek(0)
except asyncio.TimeoutError:
return await ctx.send("Operation timed out.")
await ctx.typing()
base_url = "https://maps.googleapis.com/maps/api/staticmap"
params = {
"center": location,
"zoom": zoom,
"size": "640x640",
"scale": "2",
"format": "png32",
"maptype": map_type,
"key": api_key,
}
if map_type == "roadmap":
params["style"] = "feature:road.highway|element:labels.text.fill|visibility:on|color:0xffffff"
try:
async with ctx.bot.session.get(base_url, params=params) as response:
if response.status != 200:
await ctx.send(f"https://http.cat/{response.status}")
return
image = BytesIO(await response.read())
image.seek(0)
except Exception as error:
await ctx.send(f"Operation timed out: {error}")
return

url = f"<https://www.google.com/maps/search/{location.replace(' ', '+')}>"
return await ctx.send(content=url, file=discord.File(image, "map.png"))
url = f"<https://www.google.com/maps/search/{location.replace(' ', '+')}>"
await ctx.send(url, file=discord.File(image, "google_maps.png"))
image.close()
return

0 comments on commit e27340a

Please sign in to comment.