bra1n/judgebot

View on GitHub
modules/standard.ts

Summary

Maintainability
A
1 hr
Test Coverage
import * as utils from "../utils.js";
import { Discord, Slash, SlashChoice, SlashOption } from "discordx";
import { CommandInteraction, EmbedBuilder, Message } from "discord.js";
import _ from "lodash";
import fetch from "node-fetch";

const log = utils.getLogger("standard");

interface WhatsInStandard {
  deprecated: boolean;
  sets: StandardSet[];
}

interface StandardSet {
  name: string;
  enterDate: StandardDate;
  exitDate: StandardDate;
}

interface StandardDate {
  exact: string;
  rough: string;
}

@Discord()
export default class Standard {
  static api = "https://whatsinstandard.com/api/v6/standard.json";
  static cacheExpireTime = 24 * 60 * 60 * 1000; //day in milliseconds

  cachedEmbed: EmbedBuilder | null;
  cachedTime: number | null;

  constructor() {
    this.cachedEmbed = null;
    this.cachedTime = null;
    this.loadList().then(() => {
      log.info("Standard is cached");
    });
  }

  generateEmbed(setList: WhatsInStandard): EmbedBuilder {
    const currentDate = new Date();
    const removedFutureAndPastSetList = setList.sets.filter((set) => {
      // A set is in standard if:
      // It has been released, and
      return (
        set.enterDate.exact !== null &&
        // It was released before today, and
        currentDate.getTime() >= new Date(set.enterDate.exact).getTime() &&
        // The exit date is unknown, or in the future
        (set.exitDate.exact === null ||
          currentDate.getTime() < new Date(set.exitDate.exact).getTime())
      );
    });
    const groupedSetList = _.groupBy(
      removedFutureAndPastSetList,
      (set) => set.exitDate.rough
    );
    const descriptions: string[] = [];
    _.forEach(groupedSetList, (value, key) => {
      descriptions.push(
        "*Rotates ",
        key,
        ":*```",
        value.map((set) => set.name).join(" | "),
        "```\n"
      );
    });
    const embed = new EmbedBuilder({
      title: "Currently in Standard",
      url: "http://whatsinstandard.com/",
      description: descriptions.join(""),
    });
    this.cachedEmbed = embed;
    this.cachedTime = currentDate.getTime();
    return embed;
  }

  async loadList(): Promise<EmbedBuilder> {
    try {
      const res = await fetch(Standard.api);
      const body = await res.json();
      return await this.generateEmbed(body as WhatsInStandard);
    } catch (err) {
      log.error("Error getting Standard list", err);
      return new EmbedBuilder({
        title: "Standard - Error",
        description: "Couldn't create Standard list.",
        color: 0xff0000,
      });
    }
  }

  @Slash({
    name: "standard",
    description:
      "Lists the currently standard legal sets and when they will rotate",
  })
  async standard(interaction: CommandInteraction) {
    if (
      this.cachedEmbed !== null &&
      this.cachedTime !== null &&
      new Date().getTime() - this.cachedTime < Standard.cacheExpireTime
    ) {
      await interaction.reply({ embeds: [this.cachedEmbed] });
    } else {
      const embed = await this.loadList();
      await interaction.reply({ embeds: [embed] });
    }
  }
}