dragon-bot/app/cogs/star_citizen.py

361 lines
12 KiB
Python
Executable File

from bs4 import BeautifulSoup
from discord import option
from discord.ext import commands, tasks
import discord
import os
import requests
import json
import star_citizen
if os.getenv("DRAGON_ENV") == "prod":
channel_id = 1097567909640929340
else:
channel_id = 932476007439552522
class StarCitizen(commands.Cog):
def __init__(self, bot):
self.bot: commands.Bot = bot
self.poll_status_page.start()
starcitizen = discord.SlashCommandGroup(
"starcitizen", "StarCitizen related commands"
)
@starcitizen.command(
guild_ids=None,
name="medpens",
description="Posts an infographic about which medpens to use for which injuries in Star Citizen",
)
async def post_medpen_guide(self, ctx: commands.Context):
await ctx.respond("https://i.redd.it/lfswlf5c13t71.png")
@starcitizen.command(
guild_ids=None,
name="drugs",
description="Returns a list of all the drugs in game sorted by their price",
)
async def post_drugs(self, ctx: commands.Context):
headers = {"api_key": os.getenv("uexcorp_key")}
response = requests.get(
"https://portal.uexcorp.space/api/commodities/", headers=headers
)
all_commodities = [x for x in response.json()["data"]]
all_drugs = {
item["name"]: item["trade_price_sell"]
for item in all_commodities
if item["kind"] == "Drug" or "Gasping" in item["name"]
}
sorted_dict = dict(sorted(all_drugs.items(), key=lambda item: item[1]))
embed = discord.Embed(
description="-------", color=discord.Color.orange(), type="rich"
)
embed.set_thumbnail(
url="https://media.starcitizen.tools/3/31/ViceCommodity_E%27tam.jpg"
)
embed.set_author(name="Ranking of drugs by sell price")
for k, v in sorted_dict.items():
embed.add_field(
name=k,
value=f"${v:,}",
inline=False,
)
await ctx.defer()
await ctx.send_followup(embed=embed)
async def get_all_ships(ctx: discord.AutocompleteContext):
"""
returns a list of all ships in the game, which can then be passed to the /ship command for auto complete
"""
url = "https://starcitizen.tools/Category:Ships"
response = requests.get(url).text
soup = BeautifulSoup(response, "html.parser")
h2_heading = soup.find("h2", text='Pages in category "Ships"')
all_ships = [link.text for link in h2_heading.find_next("div").find_all("a")]
return all_ships
@starcitizen.command(
guild_ids=None,
name="ship",
description="Query the star citizen database about a ship",
)
async def get_ship(
self,
ctx: commands.Context,
ship: discord.Option(
str,
autocomplete=discord.utils.basic_autocomplete(get_all_ships),
description="The ship to look up",
),
):
await ctx.defer()
embed = await star_citizen.get_ship(ship_name=ship)
await ctx.send_followup(embed=embed)
async def get_all_commodities(ctx: discord.AutocompleteContext):
"""
Returns a list of commododites that can be used for autocomplete
for the /trade function.
Turning off its call to the API just to save key usage / i hear the devs
took data out of the game files so this may go away soon
"""
# headers = {"api_key": os.getenv("uexcorp_key")}
# response = requests.get(
# "https://portal.uexcorp.space/api/commodities/", headers=headers
# )
# all_commodities = [x["name"] for x in response.json()["data"]]
all_commodities = [
"Agricultural Supplies",
"Agricium",
"Agricium (Ore)",
"Altruciatoxin",
"Aluminum",
"Aluminum (Ore)",
"Amioshi Plague",
"Aphorite",
"Astatine",
"Audio Visual Equipment",
"Beryl (Raw)",
"Beryl",
"Bexalite",
"Bexalite (Raw)",
"Borase",
"Borase (Ore)",
"Chlorine",
"Construction Materials",
"Compboard",
"Copper",
"Copper (Ore)",
"Corundum",
"Corundum (Raw)",
"Degnous Root",
"Diamond",
"Diamond (Ore)",
"Distilled Spirits",
"Dolivine",
"E'tam",
"Fireworks",
"Fluorine",
"Gasping Weevil Eggs",
"Genalite",
"Golden Medmon",
"Gold",
"Gold (Ore)",
"Hadanite",
"Helium",
"Hephaestanite",
"Hephaestanite (Raw)",
"Heart of the Woods",
"Hydrogen",
"Inert Materials",
"Iodine",
"Iron",
"Janalite",
"Laranite",
"Laranite (Ore)",
"Luminalia Gift",
"Maze",
"Medical Supplies",
"Neon",
"Osoian Hides",
"Party Favors",
"Pitambu",
"Processed Food",
"Prota",
"Quartz (Raw)",
"Quantainium",
"Quartz",
"Quantainium (Raw)",
"Ranta Dung",
"Recycled Material Composite",
"Red Festival Envelope",
"Revenant Pod",
"Revenant Tree Pollen",
"Stone Bug Shell",
"Scrap",
"SLAM",
"Stims",
"Sunset Berries",
"Souvenirs",
"Taranite",
"Taranite (Raw)",
"Titanium",
"Titanium (Ore)",
"Tungsten",
"Tungsten (Ore)",
"Waste",
"WiDoW",
]
return all_commodities
@starcitizen.command(
guild_ids=None,
name="price",
description="Returns the price of Items in Star Citizen",
)
@option(
name="scu",
description="How much SCU you found",
required=True,
min_value=1,
max_value=98304,
)
async def get_price(
self,
ctx: commands.Context,
commodity: discord.Option(
str, autocomplete=discord.utils.basic_autocomplete(get_all_commodities)
),
scu: int,
):
await ctx.defer()
embed = await star_citizen.get_price(commodity=commodity, scu=scu)
await ctx.send_followup(embed=embed)
@starcitizen.command(
guild_ids=None,
name="trade",
description="Calculates the most profitable route for a given commodity",
)
@option(
name="scu",
description="Optinal how much SCU to fill",
required=False,
min_value=1,
max_value=98304,
)
async def calculate_trade_profits(
self,
ctx: commands.Context,
commodity: discord.Option(
str, autocomplete=discord.utils.basic_autocomplete(get_all_commodities)
),
scu: int,
):
await ctx.defer()
embed = await star_citizen.calculate_trade_profits(commodity=commodity, scu=scu)
await ctx.send_followup(embed=embed)
@tasks.loop(seconds=5)
async def poll_status_page(self):
# Wait until the bot is ready before we actually start executing code
await self.bot.wait_until_ready()
status_url = "https://status.robertsspaceindustries.com"
rsi_incident_file = "/tmp/rsi_incident"
status_json = requests.get(status_url + "/index.json").json()
if status_json["summaryStatus"] != "operational":
# Extract systems with unresolved issues
systems_with_issues = [
system
for system in status_json["systems"]
if system["unresolvedIssues"]
]
print(systems_with_issues)
unresolved_issue_permalink = systems_with_issues[0]["unresolvedIssues"][0][
"permalink"
]
# Remove any single quote characters from the URL
current_incident_url = unresolved_issue_permalink.replace("'", "")
response = requests.get(current_incident_url).text
incident_soup = BeautifulSoup(response, "html.parser")
details = incident_soup.find("div", class_="article__content").get_text()
if os.path.exists(rsi_incident_file):
file_contents = json.loads(open(rsi_incident_file).read())
deets = file_contents["details"]
incident_link = file_contents["incident_link"]
if current_incident_url != incident_link:
print(
"Current incident url did not match whats in the file, must be a new incident, send alert"
)
embed = star_citizen.build_alert_embed(
color=discord.Color.red(),
thumbnail="https://media.robertsspaceindustries.com/t0q21kbb3zrpt/source.png",
author="🚨 OH NO THERES AN INCIDENT 🚨",
image="https://media.giphy.com/media/WWIZJyXHXscn8JC1e0/giphy.gif",
details=details,
link=current_incident_url,
)
star_citizen.write_incident_file(
file_path=rsi_incident_file,
url=current_incident_url,
details=details,
)
await star_citizen.send_alert(self, channel=channel_id, embed=embed)
elif deets != details:
# The details we have in the json file do not match what was recently posted to the website
# Update the json file on disk and then send an update alert to the channel
star_citizen.write_incident_file(
file_path=rsi_incident_file,
url=current_incident_url,
details=details,
)
embed = star_citizen.build_alert_embed(
color=discord.Color.yellow(),
thumbnail="https://media.robertsspaceindustries.com/t0q21kbb3zrpt/source.png",
author="⚠️ THERE HAS BEEN AN UPDATE TO THE ONGOING INCIDENT ⚠️",
image="https://media.giphy.com/media/WWIZJyXHXscn8JC1e0/giphy.gif",
details=deets,
link=incident_link,
)
await star_citizen.send_alert(self, channel=channel_id, embed=embed)
else:
# Write the incident's body to a json file to read later
star_citizen.write_incident_file(
file_path=rsi_incident_file,
url=current_incident_url,
details=details,
)
embed = star_citizen.build_alert_embed(
color=discord.Color.red(),
thumbnail="https://media.robertsspaceindustries.com/t0q21kbb3zrpt/source.png",
author="🚨 OH NO THERES AN INCIDENT 🚨",
image="https://media.giphy.com/media/WWIZJyXHXscn8JC1e0/giphy.gif",
details=details,
link=current_incident_url,
)
await star_citizen.send_alert(self, channel=channel_id, embed=embed)
@starcitizen.command(
guild_ids=None,
name="rsifind",
description="Pull up info about a player from their RSI profile",
)
@option(
name="player",
description="The player name to search for",
required=True,
)
async def rsi_find(self, ctx: commands.Context, player: str):
await ctx.defer()
embed = await star_citizen.rsi_find(player=player)
await ctx.send_followup(embed=embed)
def setup(bot):
bot.add_cog(StarCitizen(bot))