dragon-bot/app/star_citizen.py

369 lines
11 KiB
Python
Executable File

from bs4 import BeautifulSoup
import requests
import discord
import os
import json
# prints for debug
import pprint
pp = pprint.PrettyPrinter(indent=4)
wiki_url = "https://starcitizen.tools/"
async def send_alert(self, channel, embed):
await self.bot.get_channel(channel).send(embed=embed)
def build_alert_embed(
color, thumbnail=None, author=None, image=None, details=None, link=None
):
embed = discord.Embed(description="-------", color=color, type="rich")
if thumbnail:
embed.set_thumbnail(url=thumbnail)
embed.set_author(name=author)
if image:
embed.set_image(url=image)
embed.add_field(name="Details", value=details, inline=True)
embed.add_field(
name="LINK",
value=link,
inline=False,
)
return embed
def write_incident_file(file_path, url, details):
info_dict = {
"incident_link": url,
"details": details,
}
with open(file_path, "w") as out_file:
out_file.write(json.dumps(info_dict))
async def get_ship(ship_name):
try:
wiki_ship_name = "_".join(elem for elem in ship_name.split())
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/112.0"
}
response = requests.get(wiki_url + wiki_ship_name, headers=headers).text
soup = BeautifulSoup(response, "html.parser")
embed = discord.Embed(
description="-------", color=discord.Color.blue(), type="rich"
)
ship_image = (soup.find("a", {"class": "mw-file-description"})).img["src"]
embed.set_image(url=ship_image)
ship_name_on_page = soup.find("span", {"class": "mw-page-title-main"}).text
try:
manufacturer = (
soup.find("div", {"class": "infobox__subtitle infobox__data"})
.findNext("a")
.text
)
except:
manufacturer = ""
embed.set_thumbnail(
url="https://media.robertsspaceindustries.com/t0q21kbb3zrpt/source.png"
)
embed.set_author(
name="%s %s" % (manufacturer, ship_name_on_page),
url="%s%s" % (wiki_url, wiki_ship_name),
)
try:
ship_role = (
soup.find("div", {"class": "infobox__label"}, string="Role")
.findNext("div")
.text
)
except:
ship_role = ""
embed.add_field(name="**Role**", value=ship_role)
try:
ingame_price = soup.find("td", {"class": "Price smwtype_qty"}).text
price = "[%s](%s%s#Universe_availability)" % (
ingame_price,
wiki_url,
wiki_ship_name,
)
if "Not available" in ingame_price:
price = "N/A"
except:
price = "N/A"
embed.add_field(
name="**Ingame Price**",
value=price,
inline=True,
)
try:
pledge_price = (
soup.find("div", {"class": "infobox__label"}, string="Standalone")
.findNext("span", {"class": "smwtext"})
.text
)
except Exception:
pledge_price = "N/A"
try:
links = soup.find_all("a", {"class": "external text"})
pledge_store_link = list(filter(lambda x: "Pledge" in x.text, links))[0][
"href"
]
embed.add_field(
name="**Pledge Price**",
value="[%s](%s#buying-options)" % (pledge_price, pledge_store_link),
inline=True,
)
except Exception:
embed.add_field(
name="**Pledge Price**",
value=pledge_price,
inline=True,
)
try:
buy_location = (
soup.find("span", {"id": "Universe_availability"})
.findNext("tbody")
.find_all("td", {"class", "Location smwtype_wpg"})
)
if len(buy_location):
embed.add_field(
name="**Buyable At**",
value=", ".join(str(x.text) for x in buy_location),
inline=True,
)
except Exception:
pass
embed.add_field(name="-------", value="", inline=False)
try:
cargo_capacity = (
soup.find("div", {"class": "infobox__label"}, string="Cargo")
.findNext("span", {"class": "smwtext"})
.text
)
except Exception:
cargo_capacity = "N/A"
embed.add_field(name="**Cargo Capacity**", value=cargo_capacity, inline=True)
try:
top_speed = (
soup.find("div", {"class": "infobox__label"}, string="Max speed")
.findNext("span", {"class": "smwtext"})
.text
)
except Exception:
top_speed = "N/A"
embed.add_field(name="**Top Speed**", value=top_speed, inline=True)
try:
crew_size = (
soup.find("div", {"class": "infobox__label"}, string="Crew")
.findNext("div", {"class": "infobox__data"})
.text
)
except Exception:
crew_size = "N/A"
embed.add_field(name="**Crew Size**", value=crew_size, inline=True)
embed.add_field(name="-------", value="", inline=False)
try:
claim_time = (
soup.find("div", {"class": "infobox__label"}, string="Claim")
.findNext("div", {"class": "infobox__data"})
.text
)
except Exception:
claim_time = "N/A"
embed.add_field(name="**Insurance claim time**", value=claim_time, inline=True)
try:
expedited_claim_time = (
soup.find("div", {"class": "infobox__label"}, string="Expedite")
.findNext("div", {"class": "infobox__data"})
.text
)
except Exception:
expedited_claim_time = "N/A"
embed.add_field(
name="**Expedite claim time**", value=expedited_claim_time, inline=True
)
try:
expedite_fee = (
soup.find("div", {"class": "infobox__label"}, string="Expedite fee")
.findNext("div", {"class": "infobox__data"})
.text
)
except Exception:
expedite_fee = "N/A"
embed.add_field(name="**Expedite Fee**", value=expedite_fee, inline=True)
embed.add_field(name="-------", value="", inline=False)
try:
length = (
soup.find("div", {"class": "infobox__label"}, string="Length")
.findNext("span", {"class": "smwtext"})
.text
)
except Exception:
length = "N/A"
embed.add_field(name="**Length**", value=length, inline=True)
try:
width = (
soup.find("div", {"class": "infobox__label"}, string="Width")
.findNext("span", {"class": "smwtext"})
.text
)
except Exception:
width = "N/A"
embed.add_field(name="**Width**", value=width, inline=True)
try:
height = (
soup.find("div", {"class": "infobox__label"}, string="Height")
.findNext("span", {"class": "smwtext"})
.text
)
except Exception:
height = "N/A"
embed.add_field(name="**Height**", value=height, inline=True)
embed.add_field(
name="**Link**", value="%s%s" % (wiki_url, wiki_ship_name), inline=False
)
try:
description = (
soup.find("section", {"class": "citizen-section-collapsible"})
.findNext("p")
.text
)
except Exception:
description = "N/A"
embed.add_field(name="**Description**", value=description, inline=True)
try:
item_uuid = (
soup.find("div", {"class": "infobox__label"}, string="UUID")
.findNext("div", {"class": "infobox__data"})
.text
)
except Exception:
item_uuid = "N/A"
embed.set_footer(text="item UUID: %s" % item_uuid)
except Exception as e:
print(e)
embed = discord.Embed(description="", color=discord.Color.red(), type="rich")
embed.add_field(
name="**Could not find that ship**",
value="You gave me %s. Did you spell it right?\n\n(Its also possible my shitty code isnt working)"
% ship_name,
inline=True,
)
return embed
return embed
async def calculate_trade_profies(commodity, scu=None):
url = "https://portal.uexcorp.space/api/all_prices/pretty_mode/1/"
headers = {"api_key": os.getenv("uexcorp_key")}
scu_string = "%s scu" % scu
if not scu:
scu = 696
scu_string = "a C2 Hercules full"
embed = discord.Embed(
description="-------", color=discord.Color.blue(), type="rich"
)
response = requests.get(url, headers=headers).json()["data"]
embed.set_author(name=commodity)
embed.set_thumbnail(
url="https://media.starcitizen.tools/thumb/b/bb/Shubin_logo_circle.png/120px-Shubin_logo_circle.png"
)
# Loop through every system/outpost and find the cheapest place selling the commodity
costs = {}
for systems, stations in response.items():
for station, trades in stations.items():
if "buy" in trades and commodity in trades["buy"]:
costs[station] = trades["buy"][commodity] * int(scu)
break
if len(costs):
embed.add_field(
name="**Best place to buy %s of %s**" % (scu_string, commodity),
value="%s: $%s"
% (
min(costs, key=costs.get),
"{:20,.2f}".format(costs[min(costs, key=costs.get)]).strip(),
),
inline=True,
)
# Same logic, but finding the place buying the commodity for the most
profits = {}
for systems, stations in response.items():
for station, trades in stations.items():
if "sell" in trades and commodity in trades["sell"]:
profits[station] = trades["sell"][commodity] * int(scu)
break
embed.add_field(
name="Best palce to sell %s of %s" % (scu_string, commodity),
value="%s: $%s"
% (
max(profits, key=profits.get),
"{:20,.2f}".format(profits[max(profits, key=profits.get)]).strip(),
),
inline=True,
)
if len(costs) and len(profits):
net_profit = float(profits[max(profits, key=profits.get)]) - float(
costs[min(costs, key=costs.get)]
)
embed.add_field(
name="**Net Profit**",
value="$%s" % "{:20,.2f}".format(net_profit).strip(),
inline=True,
)
return embed