def Tweet(self, date: str): """ Tweet the current `itemshop.png` local file to Twitter using the credentials provided in `configuration.json`. """ try: twitterAPI = twitter.Api( consumer_key=self.twitterAPIKey, consumer_secret=self.twitterAPISecret, access_token_key=self.twitterAccessToken, access_token_secret=self.twitterAccessSecret, ) twitterAPI.VerifyCredentials() except Exception as e: Log.Error(self, f"Failed to authenticate with Twitter, {e}") return body = f"#Fortnite Item Shop for {date}" if self.supportACreator is not None: body = f"{body}\n\nSupport-a-Creator Code: {self.supportACreator}" try: with open("itemshop.png", "rb") as shopImage: twitterAPI.PostUpdate(body, media=shopImage) Log.Success(self, "Tweeted Item Shop") except Exception as e: Log.Error(self, f"Failed to Tweet Item Shop, {e}")
def LoadConfiguration(self): """ Set the configuration values specified in configuration.json Return True if configuration sucessfully loaded. """ configuration = json.loads( Utility.ReadFile(self, "configuration", "json")) try: self.language = configuration["language"] self.delay = configuration["delayStart"] self.supportACreator = configuration["supportACreator"] self.twitterEnabled = configuration["twitter"]["enabled"] self.twitterAPIKey = configuration["twitter"]["apiKey"] self.twitterAPISecret = configuration["twitter"]["apiSecret"] self.twitterAccessToken = configuration["twitter"]["accessToken"] self.twitterAccessSecret = configuration["twitter"]["accessSecret"] Log.Success(self, "Loaded configuration") return True except Exception as e: Log.Error(self, f"Failed to load configuration, {e}")
def main(self): Log.Intro(self, "Athena - Fortnite Item Shop Generator") initialized = Athena.LoadConfiguration(self) if initialized is True: if self.delay > 0: Log.Info(self, f"Delaying process start for {self.delay}s...") sleep(self.delay) itemShop = Utility.GET(self, "https://fortnite-api.com/shop/br", parameters={'language': self.language}) if itemShop is not None: itemShop = json.loads(itemShop)['data'] # Strip time from the timestamp, we only need the date date = Utility.ISOtoHuman(self, itemShop["date"].split("T")[0]) Log.Success( self, f"Retrieved Item Shop for {date} in {self.language}") shopImage = Athena.GenerateImage(self, date, itemShop) if shopImage is True: if self.twitterEnabled is True: Athena.Tweet(self, date)
def GenerateImage(self, date: str, itemShop: dict): """ Generate the Item Shop image using the provided Item Shop. Return True if image sucessfully saved. """ try: featured = itemShop["featured"] daily = itemShop["daily"] # Ensure both Featured and Daily have at least 1 item if (len(featured) <= 0) or (len(daily) <= 0): raise Exception( f"Featured: {len(featured)}, Daily: {len(daily)}") except Exception as e: Log.Error( self, f"Failed to parse Item Shop Featured and Daily items, {e}") return False # Determine the max amount of rows required for the current # Item Shop when there are 3 columns for both Featured and Daily. # This allows us to determine the image height. rows = max(ceil(len(featured) / 3), ceil(len(daily) / 3)) shopImage = Image.new("RGB", (1920, ((545 * rows) + 340))) try: background = ImageUtil.Open(self, "background.png") background = ImageUtil.RatioResize(self, background, shopImage.width, shopImage.height) shopImage.paste( background, ImageUtil.CenterX(self, background.width, shopImage.width)) except FileNotFoundError: Log.Warn(self, "Failed to open background.png, defaulting to dark gray") shopImage.paste((18, 18, 18), [0, 0, shopImage.size[0], shopImage.size[1]]) logo = ImageUtil.Open(self, "logo.png") logo = ImageUtil.RatioResize(self, logo, 0, 210) shopImage.paste( logo, ImageUtil.CenterX(self, logo.width, shopImage.width, 20), logo) canvas = ImageDraw.Draw(shopImage) font = ImageUtil.Font(self, 48) textWidth, _ = font.getsize(date) canvas.text( ImageUtil.CenterX(self, textWidth, shopImage.width, 255), date, (255, 255, 255), font=font, ) canvas.text((20, 255), "Featured", (255, 255, 255), font=font) textWidth, _ = font.getsize("Daily") canvas.text( (shopImage.width - (textWidth + 20), 255), "Daily", (255, 255, 255), font=font, ) # Track grid position i = 0 for item in featured: card = Athena.GenerateCard(self, item) if card is not None: shopImage.paste( card, ( (20 + ((i % 3) * (card.width + 5))), (315 + ((i // 3) * (card.height + 5))), ), card, ) i += 1 # Reset grid position i = 0 for item in daily: card = Athena.GenerateCard(self, item) if card is not None: shopImage.paste( card, ( (990 + ((i % 3) * (card.width + 5))), (315 + ((i // 3) * (card.height + 5))), ), card, ) i += 1 try: shopImage.save("itemshop.png") Log.Success(self, "Generated Item Shop image") return True except Exception as e: Log.Error(self, f"Failed to save Item Shop image, {e}")