yetAnotherIdaBot/main.py

422 lines
11 KiB
Python

import discord
from discord.ext import commands
from discord.commands import option
import requests
import json
from datetime import datetime as dt
import aiohttp
import os
import asyncio
### reads token files
def readToken(filePath):
with open(filePath, 'r') as f:
return f.readline()
### sends a get request to the sheet
async def getFromSheet(gsheetToken):
async with aiohttp.ClientSession() as session:
async with session.get(gsheetToken) as response:
print("Status:", response.status)
text = await response.text()
return text
### takes a json, returns a http code
async def postToSheet(data, gsheetToken):
async with aiohttp.ClientSession() as session:
async with session.post(gsheetToken, json=data) as response:
text = await response.text()
print(text)
print("Status:", response.status)
return response.status
### carrier state parser, takes the values from the sheet and turn it into something we can use
async def parseCarrierState(state):
tupleList = []
splitState = state.split(",")
for i in range(0,len(splitState),2):
carrier = splitState[i]
state = splitState[i+1]
if carrier != "" and state != "":
tupleList.append((carrier, state))
return tupleList
### converts a list of tuple back to the sheet syntax (CSV)
async def toRawState(tupleList):
rawState = []
for value in tupleList:
for subval in value:
rawState.append([subval])
rawLen = len(rawState)
for i in range(rawLen, 41):
rawState.append([""])
return rawState
async def getListOfCarriers(state):
splitState = state.split(",")
carrierList = []
for i in range(0,len(splitState),2):
carrier = splitState[i]
if carrier != "":
carrierList.append(carrier)
return carrierList
### used to query the carrier state internally
async def getInternalCarrierState():
response = await getFromSheet(gsheetToken)
return response
#creates the file if it doesn't exist. stores last command used by... users on this delivery.
async def writeDeliveryToCommandFile(author, command):
#shitty hack to see if the file is empty
path = os.getcwd() + "/" + lastCommandFile
empty = os.stat(path).st_size < 1
with open(lastCommandFile, 'r') as f:
if empty:
jsonContent = json.loads("{}")
else:
jsonContent = json.load(f)
with open(lastCommandFile, 'w') as f:
jsonContent[author] = command
json.dump(jsonContent, f)
async def getDataFromDeliveryFile(author):
path = os.getcwd() + "/" + lastCommandFile
empty = os.stat(path).st_size < 1
with open(lastCommandFile, 'r') as f:
if empty:
return None
else:
jsonContent = json.load(f)
if author in jsonContent.keys():
return jsonContent[author]
else:
return None
async def delLastCommandFile():
open(lastCommandFile, 'w').close()
bot = commands.Bot()
# various tokens
discordToken = readToken("discord.token")
gsheetToken = readToken("sheet.token")
lastCommandFile = "command.last"
# default command to see if the bot has lived
@bot.listen()
async def on_connect():
print("I'm alive, bitch")
# delivery command
# guild IDs are both IDA servers
@bot.slash_command(
name="delivery",
# guild_ids=[401372086746087425],
description= "sends your delivery to the bot!"
)
async def delivery(ctx,
commodity:discord.Option(str, choices=[
"Aluminium",
"Ceramic Composites",
"CMM Composite",
"Computer Components",
"Copper",
"Food Cartridges",
"Fruit and Vegetables",
"Insulating Membrane",
"Liquid Oxygen",
"Medical Diagnostic Equipment",
"Non-Lethal Weapons",
"Polymers",
"Power Generators",
"Semiconductors",
"Steel",
"Superconductors",
"Titanium",
"Water",
"Water Purifiers"
]),
quantity: discord.Option(discord.SlashCommandOptionType.integer, description="Please be nice and input a value between 1 and 1326 (new rack update!!!!1!1)", min_value=1, max_value=1326),
target: discord.Option(str, choices=['Station', 'Carrier'])
):
author = str(ctx.author)
author = author[:author.find(" ")]
await ctx.defer()
data = {
"postType":"delivery",
"username":author,
"commodity": commodity,
"quantity": quantity,
"target": target
}
try:
response = await postToSheet(data, gsheetToken)
if response == 200:
await ctx.followup.send(f"your delivery of {quantity} of {commodity} to a {target} has been added to the sheet!")
print(f"[{dt.isoformat(dt.now())}]{author} delivery of {quantity} of {commodity} to a {target}")
await writeDeliveryToCommandFile(author, data)
else:
await ctx.followup.send(f"Failed to log delivery (HTTP {response}). Please contact the yellow people if that keeps happening")
except Exception as e:
await ctx.followup.send(f"help : Error: {e}")
# delivery command for misc commodity only
# guild IDs are both IDA servers
@bot.slash_command(
name="misc",
# guild_ids=[401372086746087425],
description= "Used for the commodities we're too lazy to create a sheet for"
)
async def misc(ctx,
quantity: discord.Option(discord.SlashCommandOptionType.integer, description="Please be nice and input a value between 1 and 1326 (new rack update!!!!1!1)", min_value=1, max_value=1326),
target: discord.Option(str, choices=['Station', 'Carrier'])
):
author = str(ctx.author)
author = author[:author.find(" ")]
await ctx.defer()
data = {
"postType":"delivery",
"username":author,
"commodity": commodity,
"quantity": quantity,
"target": target
}
try:
response = await postToSheet(data, gsheetToken)
if response == 200:
await ctx.followup.send(f"your delivery of {quantity} of Miscellaneous stuff to a {target} has been added to the sheet!")
print(f"[{dt.isoformat(dt.now())}]{author} delivery of {quantity} of Miscellaneous to a {target}")
await writeDeliveryToCommandFile(author, data)
else:
await ctx.followup.send(f"Failed to log delivery (HTTP {response}). Please contact the yellow people if that keeps happening")
except Exception as e:
await ctx.followup.send(f"help : Error: {e}")
@bot.slash_command(
name="last",
# guild_ids=[401372086746087425],
description= "send the last delivery you made again!"
)
async def last(ctx):
author = str(ctx.author)
author = author[:author.find(" ")]
data = await getDataFromDeliveryFile(author)
await ctx.defer()
if data is not None:
try:
response = await postToSheet(data, gsheetToken)
if response == 200:
await ctx.followup.send(f"your delivery of {data['quantity']} of {data['commodity']} to a {data['target']} has been added to the sheet!")
print(f"[{dt.isoformat(dt.now())}] delivery of {data['quantity']} of {data['commodity']} to a {data['target']}")
await writeDeliveryToCommandFile(author, data)
else:
await ctx.followup.send(f"Failed to log delivery (HTTP {response}). Please contact the yellow people if that keeps happening")
except Exception as e:
await ctx.followup.send(f"help : Error: {e}")
else:
await ctx.followup.send(f"You haven't delivered to this build yet, or I have amnesia.")
#change url command
@bot.slash_command(
name="change-sheet-url",
# guild_ids=[401372086746087425],
description= "changes the URL of the active sheet, use with caution"
)
async def changeSheetUrl(ctx,
url:discord.Option(discord.SlashCommandOptionType.string, description="the new URL")
):
global gsheetToken
await ctx.defer()
try:
with open("sheet.token",'w') as f:
f.write(url)
await ctx.followup.send(f"URL has been set to {url}")
gsheetToken = readToken("sheet.token")
await delLastCommandFile()
print("deleted command.last file content")
except Exception as e:
await ctx.followup.send(f"something shat the bed")
@bot.slash_command(
name="getcarrierstate",
# guild_ids=[401372086746087425],
description= "gets the carriers state from the sheet"
)
async def getCarrierState(ctx):
response = await getInternalCarrierState()
carrierState = await parseCarrierState(response)
await ctx.defer()
text = "Current Carrier State : \n"
for carrier, state in carrierState:
text += f"{carrier} is {state}\n"
await ctx.followup.send(text)
async def getCarriers(ctx: discord.AutocompleteContext):
state = await getInternalCarrierState()
carrierList = await getListOfCarriers(state)
# print(carrierList)
# return [carrier for carriers in carrierList]
return carrierList
@bot.slash_command(
name="setcarrierstate",
# guild_ids=[401372086746087425],
description= "Sets a carrier state on the sheet"
)
@option("carrier", description="The carrier you want to edit", autocomplete=getCarriers)
@option("state",required=True, description="The carrier you want to edit", choices=["Loading","Unloading","Full","Empty","Inactive"])
async def setCarrierState(ctx, carrier, state):
response = await getFromSheet(gsheetToken)
carrierState = await parseCarrierState(response)
newCarrierState = []
print(f"requested values: {carrier} to {state}")
print(f"current values : {carrierState}")
for carrierS, stateS in carrierState:
if carrier == carrierS:
newCarrierState.append((carrier,state))
else:
newCarrierState.append((carrierS,stateS))
print(f"new values : {newCarrierState}")
rawState = await toRawState(newCarrierState)
print(rawState)
await ctx.defer()
i = 1
text = "Current Carrier State : \n"
data = {
"postType":"carrier",
"carrierState": rawState
}
try:
response = await postToSheet(data, gsheetToken)
if response == 200:
await ctx.followup.send(f"hey")
else:
await ctx.followup.send(f"i fucked up ")
except Exception as e:
await ctx.followup.send(f"help : Error: {e}")
#run the damn thing
bot.run(discordToken)