diff --git a/README.md b/README.md index c37f84f..d8399cc 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,9 @@ Cog Function | forcemention | **Alpha** |
Mentions unmentionable rolesVery simple cog, mention doesn't persist
| | hangman | **Beta** |
Play a game of hangmanSome visual glitches and needs more customization
| | howdoi | **Incomplete** |
Ask coding questions and get results from StackExchangeNot yet functional
| -| leaver | **Beta** |
Send a message in a channel when a user leaves the serverSeems to be functional, please report any bugs or suggestions
| | infochannel | **Beta** |
Create a channel to display server infoJust released, please report bugs
| +| launchlib | **Beta** |
Access rocket launch dataJust released, please report bugs
| +| leaver | **Beta** |
Send a message in a channel when a user leaves the serverSeems to be functional, please report any bugs or suggestions
| | lovecalculator | **Alpha** |
Calculate the love between two users[Snap-Ons] Just updated to V3
| | lseen | **Alpha** |
Track when a member was last onlineAlpha release, please report bugs
| | nudity | **Alpha** |
Checks for NSFW images posted in non-NSFW channelsSwitched libraries, now functional
| diff --git a/launchlib/__init__.py b/launchlib/__init__.py new file mode 100644 index 0000000..8e45f6e --- /dev/null +++ b/launchlib/__init__.py @@ -0,0 +1,5 @@ +from .launchlib import LaunchLib + + +def setup(bot): + bot.add_cog(LaunchLib(bot)) diff --git a/launchlib/countrymapper.py b/launchlib/countrymapper.py new file mode 100644 index 0000000..694fda5 --- /dev/null +++ b/launchlib/countrymapper.py @@ -0,0 +1,254 @@ +countryISOMapping = { + "AFG": "AF", + "ALA": "AX", + "ALB": "AL", + "DZA": "DZ", + "ASM": "AS", + "AND": "AD", + "AGO": "AO", + "AIA": "AI", + "ATA": "AQ", + "ATG": "AG", + "ARG": "AR", + "ARM": "AM", + "ABW": "AW", + "AUS": "AU", + "AUT": "AT", + "AZE": "AZ", + "BHS": "BS", + "BHR": "BH", + "BGD": "BD", + "BRB": "BB", + "BLR": "BY", + "BEL": "BE", + "BLZ": "BZ", + "BEN": "BJ", + "BMU": "BM", + "BTN": "BT", + "BOL": "BO", + "BIH": "BA", + "BWA": "BW", + "BVT": "BV", + "BRA": "BR", + "VGB": "VG", + "IOT": "IO", + "BRN": "BN", + "BGR": "BG", + "BFA": "BF", + "BDI": "BI", + "KHM": "KH", + "CMR": "CM", + "CAN": "CA", + "CPV": "CV", + "CYM": "KY", + "CAF": "CF", + "TCD": "TD", + "CHL": "CL", + "CHN": "CN", + "HKG": "HK", + "MAC": "MO", + "CXR": "CX", + "CCK": "CC", + "COL": "CO", + "COM": "KM", + "COG": "CG", + "COD": "CD", + "COK": "CK", + "CRI": "CR", + "CIV": "CI", + "HRV": "HR", + "CUB": "CU", + "CYP": "CY", + "CZE": "CZ", + "DNK": "DK", + "DJI": "DJ", + "DMA": "DM", + "DOM": "DO", + "ECU": "EC", + "EGY": "EG", + "SLV": "SV", + "GNQ": "GQ", + "ERI": "ER", + "EST": "EE", + "ETH": "ET", + "FLK": "FK", + "FRO": "FO", + "FJI": "FJ", + "FIN": "FI", + "FRA": "FR", + "GUF": "GF", + "PYF": "PF", + "ATF": "TF", + "GAB": "GA", + "GMB": "GM", + "GEO": "GE", + "DEU": "DE", + "GHA": "GH", + "GIB": "GI", + "GRC": "GR", + "GRL": "GL", + "GRD": "GD", + "GLP": "GP", + "GUM": "GU", + "GTM": "GT", + "GGY": "GG", + "GIN": "GN", + "GNB": "GW", + "GUY": "GY", + "HTI": "HT", + "HMD": "HM", + "VAT": "VA", + "HND": "HN", + "HUN": "HU", + "ISL": "IS", + "IND": "IN", + "IDN": "ID", + "IRN": "IR", + "IRQ": "IQ", + "IRL": "IE", + "IMN": "IM", + "ISR": "IL", + "ITA": "IT", + "JAM": "JM", + "JPN": "JP", + "JEY": "JE", + "JOR": "JO", + "KAZ": "KZ", + "KEN": "KE", + "KIR": "KI", + "PRK": "KP", + "KOR": "KR", + "KWT": "KW", + "KGZ": "KG", + "LAO": "LA", + "LVA": "LV", + "LBN": "LB", + "LSO": "LS", + "LBR": "LR", + "LBY": "LY", + "LIE": "LI", + "LTU": "LT", + "LUX": "LU", + "MKD": "MK", + "MDG": "MG", + "MWI": "MW", + "MYS": "MY", + "MDV": "MV", + "MLI": "ML", + "MLT": "MT", + "MHL": "MH", + "MTQ": "MQ", + "MRT": "MR", + "MUS": "MU", + "MYT": "YT", + "MEX": "MX", + "FSM": "FM", + "MDA": "MD", + "MCO": "MC", + "MNG": "MN", + "MNE": "ME", + "MSR": "MS", + "MAR": "MA", + "MOZ": "MZ", + "MMR": "MM", + "NAM": "NA", + "NRU": "NR", + "NPL": "NP", + "NLD": "NL", + "ANT": "AN", + "NCL": "NC", + "NZL": "NZ", + "NIC": "NI", + "NER": "NE", + "NGA": "NG", + "NIU": "NU", + "NFK": "NF", + "MNP": "MP", + "NOR": "NO", + "OMN": "OM", + "PAK": "PK", + "PLW": "PW", + "PSE": "PS", + "PAN": "PA", + "PNG": "PG", + "PRY": "PY", + "PER": "PE", + "PHL": "PH", + "PCN": "PN", + "POL": "PL", + "PRT": "PT", + "PRI": "PR", + "QAT": "QA", + "REU": "RE", + "ROU": "RO", + "RUS": "RU", + "RWA": "RW", + "BLM": "BL", + "SHN": "SH", + "KNA": "KN", + "LCA": "LC", + "MAF": "MF", + "SPM": "PM", + "VCT": "VC", + "WSM": "WS", + "SMR": "SM", + "STP": "ST", + "SAU": "SA", + "SEN": "SN", + "SRB": "RS", + "SYC": "SC", + "SLE": "SL", + "SGP": "SG", + "SVK": "SK", + "SVN": "SI", + "SLB": "SB", + "SOM": "SO", + "ZAF": "ZA", + "SGS": "GS", + "SSD": "SS", + "ESP": "ES", + "LKA": "LK", + "SDN": "SD", + "SUR": "SR", + "SJM": "SJ", + "SWZ": "SZ", + "SWE": "SE", + "CHE": "CH", + "SYR": "SY", + "TWN": "TW", + "TJK": "TJ", + "TZA": "TZ", + "THA": "TH", + "TLS": "TL", + "TGO": "TG", + "TKL": "TK", + "TON": "TO", + "TTO": "TT", + "TUN": "TN", + "TUR": "TR", + "TKM": "TM", + "TCA": "TC", + "TUV": "TV", + "UGA": "UG", + "UKR": "UA", + "ARE": "AE", + "GBR": "GB", + "USA": "US", + "UMI": "UM", + "URY": "UY", + "UZB": "UZ", + "VUT": "VU", + "VEN": "VE", + "VNM": "VN", + "VIR": "VI", + "WLF": "WF", + "ESH": "EH", + "YEM": "YE", + "ZMB": "ZM", + "ZWE": "ZW", + "XKX": "XK", +} + + +def country_mapping(countrycode): + return countryISOMapping[countrycode] diff --git a/launchlib/info.json b/launchlib/info.json new file mode 100644 index 0000000..8df1059 --- /dev/null +++ b/launchlib/info.json @@ -0,0 +1,20 @@ +{ + "author": [ + "Bobloy" + ], + "min_bot_version": "3.4.0", + "description": "Pull information from the Launch Library API for space flights", + "hidden": false, + "install_msg": "Thank you for installing LaunchLib. Get started with `[p]load launchlib`, then `[p]help LaunchLib`", + "short": "Access launch data for space flights", + "end_user_data_statement": "This cog does not store any End User Data", + "requirements": ["python-launch-library"], + "tags": [ + "bobloy", + "utils", + "launch", + "space", + "api", + "library" + ] +} \ No newline at end of file diff --git a/launchlib/launchlib.py b/launchlib/launchlib.py new file mode 100644 index 0000000..0c6eeef --- /dev/null +++ b/launchlib/launchlib.py @@ -0,0 +1,130 @@ +import asyncio +import functools +import logging + +import discord +import launchlibrary as ll +from redbot.core import Config, commands +from redbot.core.bot import Red + +from launchlib.countrymapper import country_mapping + +log = logging.getLogger("red.fox_v3.launchlib") + + +class LaunchLib(commands.Cog): + """ + Cog Description + + Less important information about the cog + """ + + def __init__(self, bot: Red): + super().__init__() + self.bot = bot + self.config = Config.get_conf(self, identifier=0, force_registration=True) + + default_guild = {} + + self.config.register_guild(**default_guild) + + self.api = ll.Api() + + async def red_delete_data_for_user(self, **kwargs): + """Nothing to delete""" + return + + async def _embed_launch_data(self, launch: ll.Launch): + status: ll.LaunchStatus = launch.get_status() + + rocket: ll.Rocket = launch.rocket + + title = launch.name + description = status.description + + urls = launch.vid_urls + launch.info_urls + if not urls and rocket: + urls = rocket.info_urls + [rocket.wiki_url] + if urls: + url = urls[0] + else: + url = None + + color = discord.Color.green() if status.id in [1, 3] else discord.Color.red() + + em = discord.Embed(title=title, description=description, url=url, color=color) + + if rocket and rocket.image_url and rocket.image_url != "Array": + em.set_image(url=rocket.image_url) + + agency = getattr(launch, "agency", None) + if agency is not None: + em.set_author( + name=agency.name, + url=agency.wiki_url, + icon_url=f"https://www.countryflags.io/{country_mapping(agency.country_code)}/flat/64.png", + ) + + field_options = [ + ("failreason", "Fail Reason"), + ("holdreason", "Hold Reason"), + ("id", "ID"), + ("hashtag", "Hashtag"), + ] + for f in field_options: + data = getattr(launch, f[0], None) + if data is not None and data: + em.add_field(name=f[1], value=data) + + if launch.missions: + field_options = [ + ("description", "Mission Description"), + ("typeName", "Mission Type"), + ("name", "Mission Name"), + ] + for mission in launch.missions: + for f in field_options: + data = mission.get(f[0], None) + if data is not None and data: + em.add_field(name=f[1], value=data) + + if rocket and rocket.family: + em.add_field(name="Rocket Family", value=rocket.family) + + em.timestamp = launch.windowstart + + em.set_footer() + + return em + + @commands.group() + async def launchlib(self, ctx: commands.Context): + if ctx.invoked_subcommand is None: + pass + + @launchlib.command() + async def next(self, ctx: commands.Context, num_launches: int = 1): + # launches = await api.async_next_launches(num_launches) + loop = asyncio.get_running_loop() + + launches = await loop.run_in_executor( + None, functools.partial(self.api.fetch_launch, num=num_launches) + ) + + # launches = self.api.fetch_launch(num=num_launches) + + print(len(launches)) + + async with ctx.typing(): + for x, launch in enumerate(launches): + if x >= num_launches: + return + + em = await self._embed_launch_data(launch) + if em is not None: + try: + await ctx.send(embed=em) + except discord.HTTPException: + await ctx.send(str(launch)) + log.exception("Failed to send embed") + await asyncio.sleep(2)