11"""
2- This python script is reponsible for creating images for
2+ This python script is responsible for creating images for
33a user's Turnip Summary and then uploading to AWS S3.
44"""
55from PIL import Image , ImageDraw , ImageFont
88from boto3 .s3 .transfer import S3Transfer
99import datetime
1010import 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
1317session = boto3 .session .Session ()
1418client = 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 )
1620transfer = 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 )
2427colour = '#99AAB5'
2528headingColour = '#FFFFFF'
2629subHeadingColour = '#CCD5DA'
30+ # Constants for turnip Summary X locations
2731x = 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
3045class 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