import json import sys import logging import discord from datetime import datetime from config import Config from logger import logger from tinydb import Query import matplotlib.pyplot as plt import pandas as pd from db import MarketDB, PlayerDB, _hist, getDF TOKEN = Config["Tokens"]["BoobyLegendsEcon"]["Token"] def getPlayerCard(name): today=datetime.utcnow().strftime('%Y-%m-%d') thisCard=PlayerDB.search(Query().fragment({'date':today,'name':name}))[0] return thisCard def histGrid(name,columns=None): logger.debug(f"histGrid(name={name},columns={columns})") MAX_RECORD_COUNT=45 df = getDF(name) footer="" dfSize=len(df) if dfSize > MAX_RECORD_COUNT: df.drop(df.head(dfSize-MAX_RECORD_COUNT).index,inplace=True) footer=f"\n{dfSize-MAX_RECORD_COUNT} more..." if columns is None: cols = ['date','cost','cost-min','cost-max'] else: cols = columns return "```"+df[cols].to_string(index=False,col_space=6,na_rep="-")+footer+"```" def todayGrid(level=None,tier=None,columns=None): logger.debug(f"todayGrid(level={level},tier={tier},columns={columns})") MAX_RECORD_COUNT=41 df = getDF(aDate=datetime.utcnow().strftime('%Y-%m-%d')) if level is not None: df=df[df['level']==level.lower()] if tier is not None: df=df[df['tier']==tier.upper()] footer="" dfSize=len(df) if dfSize > MAX_RECORD_COUNT: df.drop(df.tail(dfSize-MAX_RECORD_COUNT).index,inplace=True) footer=f"\n{dfSize-MAX_RECORD_COUNT} more..." if columns is None: cols = ['name','cost','cost-min','cost-max'] else: cols = columns return "```"+df[cols].to_string(index=False,col_space=6,na_rep="-")+footer+"```" def postPlot(card=None,columns=['cost','cost-min','cost-max']): df=getDF(card).plot(x='date',y=columns) plt.title(str(card)) plt.xticks(rotation=45) plt.xlabel("Date") plt.ylabel("Cost") plt.savefig(f"plots/{card}.png") with open(f"plots/{card}.png", 'rb') as f: picture = discord.File(f) return picture def getData(): d=MarketDB.all() df=pd.DataFrame(d) df.sort_values(by=['card-num','date'], ascending=[True,True], inplace=True) df.to_csv('plots/BoobyLegendsMarket.csv',index=False) with open(f"plots/BoobyLegendsMarket.csv", 'rb') as f: data = discord.File(f) return data def parse(input,author): # parse the input string from the message so that we can see what we need to do parts = input.strip().split() logger.debug(input) logger.debug(parts) #global decoder AuthorName = author #drop out if this is not a Roll command if len(parts) == 0: return None if parts[0].upper() not in ['!','/','\\']: #Try to make a command if first character is ! if parts[0][0]=="!": pt=["!",parts[0][1:]] pt.extend(parts[1:]) parts=pt logger.debug(parts) else: logger.debug("Not a command") return None try: logger.debug("Command: "+parts[1].upper()) if parts[1].upper() == "HISTORY": name = ' '.join(parts[2:]) logger.info("History for: "+name) history=histGrid(name.strip()) #give user message so he knows it's saved retstr = "{Author} requested history for **{name}**:\n{history}".format( Author=author, name=name, history=history ) logger.debug(retstr) elif parts[1].upper() == "TODAY": level=None tier=None if len(parts) > 2: level=parts[2] if len(parts) > 3: tier=parts[3] logger.info(f"Today {level} {tier}") history=todayGrid(level,tier) retstr = "{Author} requested today's Costs for Today:\n{history}".format( Author=author, history=history ) logger.debug(retstr) elif parts[1].upper() == "PLOT": name = ' '.join(parts[2:]) logger.info("Plot for: "+name) retstr = postPlot(card=name.strip()) elif parts[1].upper() == "GETDATA": logger.info("Getting Data Dump") retstr = getData() elif parts[1].upper() in ["LOGLEVEL"]: if parts[2].upper() == "DEBUG": logger.setLevel(logging.DEBUG) elif parts[2].upper() == "INFO": logger.setLevel(logging.INFO) retstr= "LogLevel set to "+parts[2].upper() elif parts[1].upper() in ["HELP"]: retstr = ''' My Key words are "!", "/", or "\\" Show a Card's Historical cost with:```!History Eva Elfie``` Show the current day's average prices with:```!Today``` You can also filter this by Level or Level and tier:```!Today rare```or```!Today common S``` You can get a graph plotted with the historical values for a star by:```!Plot Natasha Nice``` Get a Data Dump of the current data set with```!GetData``` ''' else: retstr = '{Author}, your command was not understood.'.format(Author=author) except Exception as e: print(e) retstr = None return retstr ######################################################################### # Main Program ######################################################################### intents = discord.Intents.default() intents.message_content = True client = discord.Client(intents=intents) # This block is the work horse part @client.event async def on_message(message): # we do not want the bot to reply to itself if message.author == client.user: return # get the output for the given message output = parse(message.content,message.author.display_name) if output is not None: if isinstance(output,str): if len(output) > 2000: output=output[:1997]+"..." await message.channel.send(output) else: await message.channel.send(file=output) @client.event async def on_ready(): print('Logged in as') print(client.user.name) print(client.user.id) print('------') client.run(TOKEN)