dragon-bot/app/star_citizen.py
Luke Robles befad4d283
All checks were successful
Build and push / changes (push) Successful in 3s
Build and push / Lint-Python (push) Successful in 1s
Build and push / Build-and-Push-Docker (push) Successful in 13s
Build and push / sync-argocd-app (push) Successful in 2s
Build and push / post-failure-to-discord (push) Has been skipped
Build and push / post-success-to-discord (push) Successful in 1s
Converting star citizen file to use fstrings
2025-05-07 15:34:04 -07:00

533 lines
16 KiB
Python
Executable File

from bs4 import BeautifulSoup
import discord
import os
import re
import requests
wiki_url = "https://starcitizen.tools/"
async def rsi_find(player):
base_url = "https://robertsspaceindustries.com"
profile_url = f"{base_url}/citizens/{player}"
response = requests.get(profile_url).text
if "NAVIGATING UNCHARTED TERRITORY" in response:
embed = discord.Embed(
description="❌❌❌",
color=discord.Color.red(),
type="rich",
title=f"Player {player} does not exist",
)
return embed
soup = BeautifulSoup(response, "html.parser")
profile_photo = soup.find("div", class_="thumb").findNext("img")["src"]
if "avatar_default_big" not in profile_photo:
profile_photo = base_url + profile_photo
# handle = (
# soup.find("span", class_="label", string="Handle name")
# .findNext("strong", class_="value")
# .text
# )
citizen_number = (
soup.find("span", class_="label", string="UEE Citizen Record")
.findNext("strong", class_="value")
.text
)
enlisted = (
soup.find("span", class_="label", string="Enlisted")
.findNext("strong", class_="value")
.text
)
badge_url = (
soup.find("p", class_="entry")
.findNext("span", class_="icon")
.findNext("img")["src"]
)
if "/media/" in badge_url:
badge_url = base_url + badge_url
badge_text = (
soup.find("p", class_="entry")
.findNext("span", class_="icon")
.findNext("span", class_="value")
.text
)
embed = discord.Embed(
description="-------",
color=discord.Color.blue(),
type="rich",
title=f"{player}'s Star citizen information",
)
embed.add_field(
name="Link to profile",
value=profile_url,
inline=False,
)
embed.add_field(
name="Player ID",
value=citizen_number,
inline=True,
)
embed.add_field(
name="Enlisted",
value=enlisted,
inline=True,
)
embed.set_author(
name=badge_text,
icon_url=badge_url,
url=profile_url,
)
embed.set_thumbnail(url=profile_photo)
# Org info
if "NO MAIN ORG FOUND IN PUBLIC RECORDS" in response:
embed.add_field(
name="Org Info",
value="Player is not in an org",
inline=False,
)
return embed
if soup.find("div", class_="main-org right-col visibility-R"):
embed.add_field(
name="Org Info",
value="Player has hidden their org from their profile",
inline=False,
)
else:
org_div = soup.find(
"div", class_=re.compile("main-org right-col visibility-[VH]")
)
org_url = base_url + org_div.find("div", class_="thumb").findNext("a")["href"]
org_response = requests.get(org_url).text
org_soup = BeautifulSoup(org_response, "html.parser")
org_name = (
org_soup.find("div", class_="inner").findNext("h1").text.split("/")[0]
)
print(org_name)
org_abbreviation = (
org_soup.find("div", class_="inner").findNext("span", class_="symbol").text
)
org_rank = "N/A"
try:
org_rank = (
org_div.find("span", string="Organization rank").findNext("strong").text
)
except Exception:
pass
org_logo = org_soup.find("div", class_="inner").findNext("img")["src"]
if "robertsspaceindustries.com" not in org_logo:
org_logo = base_url + org_logo
org_member_count = org_soup.find("span", class_="count").text
embed.add_field(name="-------", value="", inline=False)
embed.add_field(
name="Org Name",
value=f"[{org_name} ({org_abbreviation})]({org_url})",
inline=True,
)
embed.add_field(
name="Rank",
value=org_rank,
inline=True,
)
embed.add_field(
name="Number of members",
value=org_member_count,
inline=False,
)
embed.set_image(url=org_logo)
return embed
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(f"{wiki_url}{wiki_ship_name}", headers=headers).text
soup = BeautifulSoup(response, "html.parser")
embed = discord.Embed(
description="-------", color=discord.Color.blue(), type="rich"
)
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=f"item UUID: {item_uuid}")
# 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=False)
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 Exception:
manufacturer = ""
embed.set_thumbnail(
url="https://media.robertsspaceindustries.com/t0q21kbb3zrpt/source.png"
)
embed.set_author(
name=f"{manufacturer} {ship_name_on_page}",
url=f"{wiki_url}{wiki_ship_name}",
)
try:
ship_role = (
soup.find("div", {"class": "infobox__label"}, string="Role")
.findNext("div")
.text
)
except Exception:
ship_role = ""
embed.add_field(name="**Role**", value=ship_role)
try:
ingame_price = requests.get(
f"https://finder.cstone.space/ShipShops1/{item_uuid}"
).text
price_soup = BeautifulSoup(ingame_price, "html.parser")
price_table = price_soup.find("div", class_="pricetab").find_next("table")
second_row = price_table.find_all("tr")[1]
if "Not sold directly or at all" in second_row.text:
price = "N/A"
else:
ingame_price = (
second_row.find_all("td")[1].get_text(strip=True).replace(" ", ",")
)
price = f"[{ingame_price}](https://finder.cstone.space/ShipShops1/{item_uuid})"
if "Not available" in ingame_price:
price = "N/A"
except Exception:
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("div", {"class": "infobox__data"})
.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=f"[{pledge_price}]({pledge_store_link}#buying-options)",
inline=True,
)
except Exception:
embed.add_field(
name="**Pledge Price**",
value=pledge_price,
inline=True,
)
try:
loaner = (
soup.find("div", {"class": "infobox__label"}, string="Loaner")
.findNext("div", {"class": "infobox__data"})
.text
)
embed.add_field(
name="**Loaner(s)**",
value=loaner,
inline=True,
)
except Exception:
pass
try:
price_table = price_soup.find("div", class_="pricetab").find_next("table")
buy_location = ", ".join(
[
x.find("td").get_text(strip=True).split("-")[-1].strip()
for x in price_table.find_all("tr")
if x.find("td")
]
)
embed.add_field(
name="**Buyable At**",
value=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("div", {"class": "infobox__data"})
.text
)
except Exception:
cargo_capacity = "N/A"
embed.add_field(name="**Cargo Capacity**", value=cargo_capacity, inline=True)
try:
health = (
soup.find("div", {"class": "infobox__label"}, string="Health")
.findNext("div", {"class": "infobox__data"})
.text
).split()[0]
except Exception:
health = "N/A"
embed.add_field(name="**Hull Health**", value=health, inline=True)
try:
quantum_fuel = (
soup.find("div", {"class": "infobox__label"}, string="Quantum capacity")
.findNext("div", {"class": "infobox__data"})
.text
)
except Exception:
quantum_fuel = "N/A"
embed.add_field(
name="**Quantum Fuel Capacity**", value=quantum_fuel, inline=True
)
try:
top_speed = (
soup.find("div", {"class": "infobox__label"}, string="Max speed")
.findNext("div", {"class": "infobox__data"})
.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)
dimensions = ["Length", "Width", "Height"]
for dimension in dimensions:
try:
value = (
soup.find(
"div", {"class": "template-dimensions-label"}, string=dimension
)
.findNext("div", {"class": "template-dimensions-data"})
.text
)
except Exception:
value = "N/A"
embed.add_field(name=f"**{dimension}**", value=value, inline=True)
embed.add_field(
name="**Link**", value=f"{wiki_url}{wiki_ship_name}", inline=False
)
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=f"You gave me {ship_name}. Did you spell it right?\n\n(Its also possible my shitty code isnt working)",
inline=True,
)
return embed
return embed
async def calculate_trade_profits(commodity, scu=None):
url = f"https://uexcorp.space/api/2.0/commodities_routes?id_commodity={await get_commodity_id(commodity)}"
headers = {"api_key": os.getenv("uexcorp_key")}
scu_string = f"{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"][0]
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"
)
# price_origin = response["price_origin"]
response["price_destination"]
margin = response["price_margin"]
investment = response["investment"]
profit = response["profit"]
best_buy_place = response["origin_terminal_name"]
best_sell_place = response["destination_terminal_name"]
embed.add_field(
name=f"Best place to buy {scu_string} of {commodity}",
value=best_buy_place,
inline=True,
)
embed.add_field(
name=f"Best place to sell {scu_string} of {commodity}",
value=best_sell_place,
inline=False,
)
embed.add_field(
name="Initial Investment",
value=f"¤{investment:20,.2f} aUEC",
inline=False,
)
embed.add_field(
name="Total Profit", value=f"¤{profit:20,.2f} aUEC", inline=True
)
embed.add_field(
name="Margin", value=f"¤{margin:20,.2f} aUEC/scu", inline=True
)
return embed
async def get_commodity_id(commodity):
headers = {"api_key": os.getenv("uexcorp_key")}
url = "https://uexcorp.space/api/2.0/commodities"
response = requests.get(url, headers=headers).json()["data"]
for item in response:
if commodity == item["name"]:
return item["id"]
async def get_price(commodity, scu):
url = " https://uexcorp.space/api/2.0/commodities_prices_all"
headers = {"api_key": os.getenv("uexcorp_key")}
scu_string = f"{scu} scu"
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"
)
# Same logic, but finding the place buying the commodity for the most
profits = {}
for items in response:
if commodity == items["commodity_name"]:
profits[items["terminal_name"]] = items["price_sell_avg"] * int(scu)
break
embed.add_field(
name=f"Best place to sell {scu_string} of {commodity}",
value=f"{max(profits, key=profits.get)}: ¤{profits[max(profits, key=profits.get)]:20,.2f}".strip(),
inline=True,
)
return embed