Skip to content
This repository was archived by the owner on Dec 26, 2021. It is now read-only.

Commit f359c2f

Browse files
authored
Merge pull request #13 from vlee489/Alpha5.0
Alpha 5.0
2 parents dc380d6 + d0479c1 commit f359c2f

File tree

10 files changed

+224
-31
lines changed

10 files changed

+224
-31
lines changed

files/graphTemplate.clip

307 KB
Binary file not shown.

files/graphTemplate.png

12.6 KB
Loading

lookup.py

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import requests
77
import auth
88
import discord
9+
import datetime
910

1011

1112
class Lookup(commands.Cog):
@@ -17,7 +18,7 @@ def __init__(self, bot):
1718
"<villager>: The villager you want to search for",
1819
aliases=['Villager'])
1920
async def villagerOverview(self, ctx, villager):
20-
villager_URL = "https://nookipedia.com/api/villager/{}/".format(villager.title())
21+
villager_URL = "https://nookipedia.com/api/villager/{}/".format((villager.title()).replace("'", "%27"))
2122
try:
2223
api_response = requests.get(villager_URL, headers={"X-API-Key": auth.nookipedia_API_key})
2324
if api_response.status_code != 200:
@@ -43,11 +44,17 @@ async def villagerOverview(self, ctx, villager):
4344
embedded.set_footer(text="Info from nookipedia.com")
4445
await ctx.send(embed=embedded)
4546
return
46-
except ValueError:
47+
except ValueError as e:
4748
await ctx.send("Unable to read data from Nookipedia")
49+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
50+
datetime.datetime.now(),
51+
e))
4852
return
49-
except requests.exceptions.RequestException:
53+
except requests.exceptions.RequestException as e:
5054
await ctx.send("Unable to connect to Nookipedia")
55+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
56+
datetime.datetime.now(),
57+
e))
5158
return
5259

5360
@commands.command(name='critter',
@@ -81,11 +88,17 @@ async def critterOverview(self, ctx, critter):
8188
embedded.set_footer(text="Info from nookipedia.com")
8289
await ctx.send(embed=embedded)
8390
return
84-
except ValueError:
91+
except ValueError as e:
8592
await ctx.send("Unable to read data from Nookipedia")
93+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
94+
datetime.datetime.now(),
95+
e))
8696
return
87-
except requests.exceptions.RequestException:
97+
except requests.exceptions.RequestException as e:
8898
await ctx.send("Unable to connect to Nookipedia")
99+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
100+
datetime.datetime.now(),
101+
e))
89102
return
90103

91104
@commands.command(name='fossil',
@@ -116,11 +129,17 @@ async def fossilOverview(self, ctx, fossil):
116129
embedded.add_field(name="Scientific Name:", value=jsonData['scientific-name'], inline=True)
117130
embedded.set_footer(text="Info from nookipedia.com")
118131
await ctx.send(embed=embedded)
119-
except ValueError:
132+
except ValueError as e:
120133
await ctx.send("Unable to read data from Nookipedia")
134+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
135+
datetime.datetime.now(),
136+
e))
121137
return
122-
except requests.exceptions.RequestException:
138+
except requests.exceptions.RequestException as e:
123139
await ctx.send("Unable to connect to Nookipedia")
140+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
141+
datetime.datetime.now(),
142+
e))
124143
return
125144

126145
@commands.command(name='eventsToday',
@@ -145,11 +164,17 @@ async def todayOverview(self, ctx):
145164
embedded.add_field(name="Events {}:".format(x + 1), value=jsonData['events'][x], inline=False)
146165
embedded.set_footer(text="Info from nookipedia.com")
147166
await ctx.send(embed=embedded)
148-
except ValueError:
167+
except ValueError as e:
149168
await ctx.send("Unable to read data from Nookipedia")
169+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
170+
datetime.datetime.now(),
171+
e))
150172
return
151-
except requests.exceptions.RequestException:
173+
except requests.exceptions.RequestException as e:
152174
await ctx.send("Unable to connect to Nookipedia")
175+
print("ERROR:\nDiscordID: {}\nTime:{}\nError:{}\n-----".format(ctx.message.author.id,
176+
datetime.datetime.now(),
177+
e))
153178
return
154179

155180

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ async def on_ready():
2525
print(bot.user.name)
2626
print(bot.user.id)
2727
print('------')
28-
await bot.change_presence(activity=discord.Game(name="<help to get started on the Turnip Stock Market"))
28+
await bot.change_presence(activity=discord.Game(name="<help to get started on the Stalk Market"))
2929

3030

3131
# Handles incorrect input from user

others.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ async def credits(self, ctx):
3434
embedded.set_footer(text="Turnip Bot by vlee489")
3535
await ctx.send(embed=embedded)
3636

37+
@commands.command(name='add',
38+
help="Add the bot to your own server")
39+
async def add(self, ctx):
40+
embedded = discord.Embed(title='Turnip Bot', description='Add Turnip Bot Here',
41+
url='https://github.com/vlee489/Turnip-Bot/',
42+
color=0xCF70D3)
43+
embedded.set_author(name="Turnip Bot",
44+
url="https://github.com/vlee489/Turnip-Bot/",
45+
icon_url="https://vleedn.fra1.cdn.digitaloceanspaces.com/TurnipBot/icon.png")
46+
embedded.set_footer(text="Turnip Bot by vlee489")
47+
await ctx.send(embed=embedded)
48+
3749

3850
def setup(bot):
3951
bot.add_cog(Others(bot))

requirments.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ discord.py
22
boto3
33
setuptools_scm
44
pyjokes
5-
pillow
5+
pillow
6+
matplotlib
7+
numpy
8+
requests

turnipSummaryImage.py

Lines changed: 121 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
This python script is reponsible for creating images for
2+
This python script is responsible for creating images for
33
a user's Turnip Summary and then uploading to AWS S3.
44
"""
55
from PIL import Image, ImageDraw, ImageFont
@@ -8,23 +8,38 @@
88
from boto3.s3.transfer import S3Transfer
99
import datetime
1010
import os
11+
import matplotlib
12+
import matplotlib.pyplot as plt
13+
import matplotlib.patches as mpatches
14+
import matplotlib.font_manager as fm
1115

1216
# Initiate session
1317
session = boto3.session.Session()
1418
client = session.client('s3', region_name=auth.aws_region_name, endpoint_url=auth.endpoint_url,
1519
aws_access_key_id=auth.aws_access_key_id, aws_secret_access_key=auth.aws_secret_access_key)
1620
transfer = S3Transfer(client)
1721

18-
heading = "{:15} {:21} {:9}".format("Price(Bells)", "Likely Price(Bells)", "Chance(%)")
19-
image = Image.open('files/Template.png')
20-
draw = ImageDraw.Draw(image)
21-
font = ImageFont.truetype("files/Roboto-Regular.ttf", size=20)
22-
subHeadingFont = ImageFont.truetype("files/Roboto-Regular.ttf", size=20)
23-
headingFont = ImageFont.truetype("files/Roboto-Bold.ttf", size=24)
22+
# Colour and Font constants
23+
font = ImageFont.truetype("files/RobotoRegular.ttf", size=20)
24+
subHeadingFont = ImageFont.truetype("files/RobotoRegular.ttf", size=20)
25+
headingFont = ImageFont.truetype("files/RobotoBold.ttf", size=24)
26+
percentFont = ImageFont.truetype("files/RobotoRegular.ttf", size=18)
2427
colour = '#99AAB5'
2528
headingColour = '#FFFFFF'
2629
subHeadingColour = '#CCD5DA'
30+
# Constants for turnip Summary X locations
2731
x = 21
32+
x2 = 150
33+
x3 = 330
34+
# Configure constants for matplotlib
35+
matplotlib.use('Agg')
36+
matplotlib.rcParams['text.color'] = colour
37+
matplotlib.rcParams['axes.labelcolor'] = colour
38+
matplotlib.rcParams['xtick.color'] = subHeadingColour
39+
matplotlib.rcParams['ytick.color'] = subHeadingColour
40+
prop = fm.FontProperties(fname="files/RobotoRegular.ttf")
41+
matplotlib.rc('axes', edgecolor=headingColour)
42+
basewidth = 658
2843

2944

3045
class SummaryImage:
@@ -34,6 +49,7 @@ class SummaryImage:
3449
turnip_data = None
3550
discordID = None
3651
created = False
52+
graphCreated = False
3753

3854
def __init__(self, TurnipData, discordID) -> None:
3955
"""
@@ -53,34 +69,125 @@ def createImage(self) -> None:
5369
:return: None
5470
returns nothing
5571
"""
56-
y = 55
72+
y = 55 # Y Location
73+
image = Image.open('files/Template.png')
74+
draw = ImageDraw.Draw(image)
5775

5876
for periods in self.turnip_data:
5977
period = periods.replace("_", " ", 1)
6078
draw.text((x, y), period, fill=headingColour, font=headingFont)
6179
y = y + 25
62-
draw.text((x, y), heading, fill=subHeadingColour, font=subHeadingFont)
80+
draw.text((x, y), "Price(Bells)", fill=subHeadingColour, font=subHeadingFont)
81+
draw.text((x2, y), "Likely Price(Bells)", fill=subHeadingColour, font=subHeadingFont)
82+
draw.text((x3, y), "Chance(%)", fill=subHeadingColour, font=subHeadingFont)
6383
y = y + 25
64-
dataString = "{:23} {:29} {:6}".format(self.turnip_data[periods]['price'],
65-
self.turnip_data[periods]['likely'],
66-
self.turnip_data[periods]['chance'])
67-
draw.text((x, y), dataString, fill=colour, font=font)
84+
draw.text((x, y), self.turnip_data[periods]['price'], fill=colour, font=font)
85+
draw.text((x2, y), self.turnip_data[periods]['likely'], fill=colour, font=font)
86+
draw.text((x3, y), self.turnip_data[periods]['chance'], fill=colour, font=font)
87+
6888
y = y + 29
6989

7090
image.save("tempHolding/{}".format(self.fileName), optimize=True, quality=20)
7191
self.created = True
7292

93+
def createGraph(self) -> None:
94+
"""
95+
Creates Graph from dict
96+
:return: None
97+
Nothing is returned
98+
"""
99+
# This creates the lists with all the data to form the graph.
100+
priceLower = []
101+
priceUpper = []
102+
likelyLower = []
103+
likelyUpper = []
104+
xAxisLabels = []
105+
for periods in self.turnip_data:
106+
if " - " in self.turnip_data[periods]['price']:
107+
elements = (self.turnip_data[periods]['price']).split(" - ", 1)
108+
priceLower.append(int(elements[0]))
109+
priceUpper.append(int(elements[1]))
110+
else:
111+
priceLower.append(int(self.turnip_data[periods]['price']))
112+
priceUpper.append(int(self.turnip_data[periods]['price']))
113+
if " - " in self.turnip_data[periods]['likely']:
114+
elements = (self.turnip_data[periods]['likely']).split(" - ", 1)
115+
likelyLower.append(int(elements[0]))
116+
likelyUpper.append(int(elements[1]))
117+
else:
118+
likelyLower.append(int(self.turnip_data[periods]['likely']))
119+
likelyUpper.append(int(self.turnip_data[periods]['likely']))
120+
xAxisLabels.append(periods.replace("_", " ", 1))
121+
# Matplotlib graph functions
122+
pricePatch = mpatches.Patch(color="#CF70D3", label='Price Range')
123+
likelyPatch = mpatches.Patch(color="#32CD32", label='Likely Price Range')
124+
plt.subplots(facecolor='lightslategray')
125+
plt.xticks(range(len(xAxisLabels)), xAxisLabels, rotation='vertical', fontproperties=prop)
126+
plt.yticks(fontproperties=prop)
127+
plt.plot(xAxisLabels, priceLower, color="#CF70D3", label='Lower Price')
128+
plt.plot(xAxisLabels, priceUpper, color="#CF70D3", label='Upper Price')
129+
plt.fill_between(xAxisLabels, priceLower, priceUpper, color='#CF70D3')
130+
plt.plot(xAxisLabels, likelyLower, color="#32CD32", label='Lower Likely')
131+
plt.plot(xAxisLabels, likelyUpper, color="#32CD32", label='Upper Likely')
132+
plt.fill_between(xAxisLabels, likelyLower, likelyUpper, color="#32CD32")
133+
plt.ylabel("Amount: Bells", fontproperties=prop)
134+
plt.xlabel("Day", fontproperties=prop)
135+
plt.legend(handles=[pricePatch, likelyPatch], bbox_to_anchor=(0., 1.02, 1., .102), loc='lower left',
136+
ncol=2, mode="expand", borderaxespad=0., framealpha=0, prop=prop)
137+
# Save image to temp location
138+
plt.savefig("tempHolding/graph/{}".format(self.fileName), transparent=True, bbox_inches='tight')
139+
140+
# Uses Pillow to form final image with boarder
141+
templateImage = Image.open('files/graphTemplate.png')
142+
# We load in the graph image and resize it to make it fit into the middle of the template
143+
graphImage = Image.open("tempHolding/graph/{}".format(self.fileName))
144+
widthPercent = (basewidth / float(graphImage.size[0]))
145+
heightSize = int((float(graphImage.size[1]) * float(widthPercent)))
146+
graphImage = graphImage.resize((basewidth, heightSize), Image.ANTIALIAS)
147+
newImage = templateImage.copy()
148+
# paste graph onto template with transparency
149+
newImage.paste(graphImage, (x, 55), graphImage)
150+
# Add in %ages
151+
draw = ImageDraw.Draw(newImage)
152+
y = 31
153+
draw.text((714, y), "Chance(%)", fill=headingColour, font=headingFont)
154+
y = y + 34
155+
for periods in self.turnip_data:
156+
period = periods.replace("_", " ", 1)
157+
draw.text((714, y), period, fill=subHeadingColour, font=percentFont)
158+
y = y + 23
159+
draw.text((714, y), " {}".format(self.turnip_data[periods]['chance']), fill=colour, font=percentFont)
160+
y = y + 27
161+
newImage.save("tempHolding/Graph{}".format(self.fileName))
162+
self.graphCreated = True
163+
os.remove("tempHolding/graph/{}".format(self.fileName)) # Remove the temp image from matplotlib
164+
73165
def uploadImage(self) -> str:
74166
"""
75167
Uploads image to S3 bucket
76168
:return: str
77169
Link to the uploaded image
78170
"""
79171
if not self.created:
80-
raise AttributeError("FIle Not created")
172+
raise AttributeError("File Not created")
81173
client.upload_file("tempHolding/{}".format(self.fileName),
82174
auth.aws_bucket,
83175
"TurnipBot/predictions/{}".format(self.fileName),
84176
ExtraArgs={'ACL': 'public-read'})
85177
os.remove("tempHolding/{}".format(self.fileName))
86178
return "{}/TurnipBot/predictions/{}".format(auth.CDNLink, self.fileName)
179+
180+
def uploadGraphImage(self) -> str:
181+
"""
182+
Uploads Graph image to S3 bucket
183+
:return: str
184+
Link to the uploaded image
185+
"""
186+
if not self.graphCreated:
187+
raise AttributeError("File Not created")
188+
client.upload_file("tempHolding/Graph{}".format(self.fileName),
189+
auth.aws_bucket,
190+
"TurnipBot/predictions/Graph{}".format(self.fileName),
191+
ExtraArgs={'ACL': 'public-read'})
192+
os.remove("tempHolding/Graph{}".format(self.fileName))
193+
return "{}/TurnipBot/predictions/Graph{}".format(auth.CDNLink, self.fileName)

0 commit comments

Comments
 (0)