Exemple #1
0
    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}")
Exemple #2
0
    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}")
Exemple #3
0
    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)
Exemple #4
0
    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}")