aboutsummaryrefslogtreecommitdiffstats
path: root/src/eu/equalparts/cardbase/standalone
diff options
context:
space:
mode:
Diffstat (limited to 'src/eu/equalparts/cardbase/standalone')
-rw-r--r--src/eu/equalparts/cardbase/standalone/CardbaseCLI.java493
1 files changed, 0 insertions, 493 deletions
diff --git a/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java b/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
deleted file mode 100644
index be3616a..0000000
--- a/src/eu/equalparts/cardbase/standalone/CardbaseCLI.java
+++ /dev/null
@@ -1,493 +0,0 @@
-package eu.equalparts.cardbase.standalone;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.Scanner;
-
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-
-import eu.equalparts.cardbase.Cardbase;
-import eu.equalparts.cardbase.data.Card;
-import eu.equalparts.cardbase.data.FullCardSet;
-import eu.equalparts.cardbase.data.CardSetInformation;
-import eu.equalparts.cardbase.utils.MTGUniverse;
-
-/**
- * This provides a lightweight CLI for interacting with cardbase files.
- *
- * @author Eduardo Pedroni
- */
-public class CardbaseCLI {
-
- /**
- * Enum type to store actions.
- *
- * @author Eduardo Pedroni
- */
- private enum Action {
- ADD, REMOVE;
- public Card card;
- public Integer count;
- /**
- * Sets both fields at once.
- *
- * @param card the card last modified.
- * @param count the amount that was added or removed.
- */
- public void set(Card card, Integer count) {
- this.card = card;
- this.count = count;
- }
- }
-
- /**
- * Location of the help file.
- */
- private static final String HELP_FILE_PATH = "/help";
- /**
- * The last action performed by the user.
- */
- private Action lastAction = null;
- /**
- * The currently selected set, from which new cards are added.
- */
- private FullCardSet selectedSet = null;
- /**
- * The actual cardbase being interfaced with.
- */
- private Cardbase cardbase;
- /**
- * Printed to the console when the user enters the help command.
- */
- private String help = "Not available, check project page on GitHub.";
- /**
- * The cardbase file off which we are currently working, if any.
- */
- private File cardbaseFile = null;
- /**
- * Save flag is raised when cards are added or removed and causes a prompt to be shown
- * if the user tries to exit with unsaved changed.
- */
- private boolean savePrompt = false;
- /**
- * Exit flag, program breaks out of the main loop when true.
- */
- private boolean exit = false;
-
- /**
- * Execute the interface.
- *
- * @param args the first argument is the cardbase file. Further arguments are ignored.
- */
- public static void main(String... args) {
- new CardbaseCLI(args).startInterface();
- }
-
- /**
- * Reads in an optional cardbase JSON and initialises other necessary components.
- * This does not actually produce the CLI, for that use {@code startInterface()}
- * on the constructed object.
- *
- * @param args a list of arguments. Only the first argument is used, as a cardbase JSON.
- */
- private CardbaseCLI(String... args) {
- System.out.println("Welcome to Cardbase CLI!");
-
- // set debug flag if we are debugging
- if (Cardbase.DEBUG) System.out.println("Debug mode is on.");
-
- // make the CardbaseManager
- if (args.length > 0) {
- File cardbaseFile = new File(args[0]);
- if (cardbaseFile.exists() && cardbaseFile.isFile() && cardbaseFile.canRead()) {
- System.out.println("Loading cardbase from \"" + args[0] + "\".");
- try {
- cardbase = new Cardbase(cardbaseFile);
- } catch (JsonParseException e) {
- System.out.println("Error: poorly formatted cardbase, check the syntax and try again.");
- // although the problem could also be with the upstream CardSetList json.
- if (Cardbase.DEBUG) e.printStackTrace();
- System.exit(1);
- } catch (JsonMappingException e) {
- System.out.println("Error: unexpected fields found in cardbase, it may be from an old version?");
- if (Cardbase.DEBUG) e.printStackTrace();
- System.exit(1);
- } catch (IOException e) {
- System.out.println("Error: something went wrong reading cardbase file, abort...");
- if (Cardbase.DEBUG) e.printStackTrace();
- System.exit(1);
- }
- } else {
- System.out.println(args[0] + " appears to be invalid.");
- System.exit(0);
- }
- } else {
- System.out.println("No cardbase file was provided, creating a clean cardbase.");
- cardbase = new Cardbase();
- }
-
- // load help information
- InputStream is = CardbaseCLI.class.getResourceAsStream(HELP_FILE_PATH);
- if (is != null) {
- help = new Scanner(is).useDelimiter("\\Z").next();
- } else {
- System.out.println("Help file was not found, check the project page on GitHub for help instead.");
- }
-
- }
-
- /**
- * Read stdin for user input, sanitise and interpret any commands entered.
- */
- private void startInterface() {
- BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
- try {
- // the main loop
- while (!exit) {
- // print prompt
- System.out.print(selectedSet == null ? "> " : selectedSet.getCode() + " > ");
- // condition input and interpret
- String[] raw = consoleReader.readLine().trim().split("[ \t]+");
- String command = raw[0];
- String[] args = Arrays.copyOfRange(raw, 1, raw.length);
-
- if (command.equalsIgnoreCase("help")) {
- help();
- } else if (command.equalsIgnoreCase("write")
- || command.equalsIgnoreCase("save")) {
- write(args);
- } else if (command.equalsIgnoreCase("exit")) {
- exit();
- } else if (command.equalsIgnoreCase("sets")) {
- sets();
- } else if (command.equalsIgnoreCase("set")) {
- set(args);
- } else if (command.equalsIgnoreCase("glance")) {
- glance();
- } else if (command.equalsIgnoreCase("peruse")) {
- peruse(args);
- } else if (command.equalsIgnoreCase("undo")) {
- undo();
- } else if (command.equalsIgnoreCase("remove")
- || command.equalsIgnoreCase("rm")) {
- remove(args);
- } else {
- add(command, args);
- }
- }
- } catch (IOException e) {
- System.out.println("Error: something went wrong with stdin, exiting...");
- if (Cardbase.DEBUG) e.printStackTrace();
- }
- }
-
- /**
- * Print help to console.
- */
- public void help() {
- System.out.println(help);
- }
-
- /**
- * Write current cardbase to file.
- *
- * @param args optionally the file to which to write.
- */
- public void write(String[] args) {
- File outputFile;
- // user-provided file overrides everything else
- if (args.length > 0) {
- outputFile = new File(sanitiseFileName(args[0]));
- } else {
- outputFile = cardbaseFile;
- }
-
- if (outputFile != null) {
- if (outputFile.exists() && (!outputFile.isFile() || !outputFile.canWrite())) {
- System.out.println("Could not write to \"" + outputFile.getAbsolutePath() + "\".");
- } else {
- // handle these exceptions locally - they don't necessarily mean the program should exit
- try {
- cardbase.writeCardbase(outputFile);
- // we are now working off outputFile, which may or may not be the same as cardbaseFile at this point
- cardbaseFile = outputFile;
- System.out.println("Cardbase was saved to \"" + outputFile.getAbsolutePath() + "\". "
- + "Subsequent writes will be done to this same file unless otherwise requested.");
- savePrompt = false;
- } catch (JsonGenerationException | JsonMappingException e) {
- System.out.println("Error: something terrible happened to the internal cardbase data structure. Oops.");
- if (Cardbase.DEBUG) e.printStackTrace();
- } catch (IOException e) {
- System.out.println("Error: lost contact with the output file, try again?");
- if (Cardbase.DEBUG) e.printStackTrace();
- }
- }
- } else {
- System.out.println("Please provide a file name.");
- }
- }
-
- /**
- * Exit procedure.
- */
- public void exit() {
- if (savePrompt) {
- System.out.println("Don't forget to save. If you really wish to quit without saving, type \"exit\" again.");
- savePrompt = false;
- } else {
- exit = true;
- }
- }
-
- /**
- * Print a list of valid set codes.
- */
- public void sets() {
- for (CardSetInformation set : MTGUniverse.getCardSetList()) {
- // CardSet has an overridden toString()
- System.out.println(set);
- }
- }
-
- /**
- * Select a set.
- *
- * @param args the code of the chosen set.
- */
- public void set(String[] args) {
- if (args.length > 0) {
- try {
- selectedSet = MTGUniverse.getFullCardSet(args[0]);
- // if the set code is invalid, null is returned
- if (selectedSet != null) {
- System.out.println("Selected set: " + selectedSet.getName() + ".");
- // undoing is not allowed if the set is changed - it would get tricky
- lastAction = null;
- } else {
- System.out.println("\"" + args[0] + "\" does not correspond to any set (use \"sets\" to see all valid set codes).");
- }
- } catch (JsonParseException e) {
- System.out.println("Error: JSON fetched from upstream was not formatted properly.");
- if (Cardbase.DEBUG) e.printStackTrace();
- } catch (JsonMappingException e) {
- System.out.println("Error: JSON fetched from upstream does not match the data structure used internally.");
- if (Cardbase.DEBUG) e.printStackTrace();
- } catch (IOException e) {
- System.out.println("Error: JSON could not be fetched from upstream.");
- if (Cardbase.DEBUG) e.printStackTrace();
- }
- } else {
- System.out.println("Please enter a set code (use \"sets\" to see all valid set codes).");
- }
- }
-
- /**
- * Print a brief list of the whole cardbase.
- */
- public void glance() {
- int total = 0;
- for (Card card : cardbase.getCards()) {
- printGlance(card);
- total += card.count;
- }
- System.out.println("Total: " + total);
- }
-
- /**
- * Print detailed information of a single card or the whole cardbase.
- *
- * @param args optionally a card within the set (by number) to peruse.
- */
- public void peruse(String[] args) {
- // if a card is specified, peruse only that
- if (args.length > 0) {
- if (selectedSet != null) {
- Card card = cardbase.getCard(selectedSet.getCode(), args[0]);
- if (card != null) {
- printPerusal(card);
- } else {
- System.out.println("Card not in cardbase.");
- }
- } else {
- System.out.println("Please select a set before perusing a specific card.");
- }
- } else {
- // peruse all cards in cardbase
- int total = 0;
- for (Card card : cardbase.getCards()) {
- printPerusal(card);
- total += card.count;
- }
- System.out.println("Total: " + total);
- }
- }
-
- /**
- * Undo previous action.
- */
- public void undo() {
- if (lastAction != null) {
- if (lastAction == Action.ADD) {
- removeCard(lastAction.card, lastAction.count);
- } else if (lastAction == Action.REMOVE) {
- addCard(lastAction.card, lastAction.count);
- }
- // can only undo once
- lastAction = null;
- } else {
- System.out.println("Nothing to undo.");
- }
- }
-
- /**
- * Remove one or more of a card.
- *
- * @param args the set number of the card to remove and optionally the count to be removed.
- */
- public void remove(String[] args) {
- if (selectedSet != null) {
- if (args.length > 0) {
- Card cardToRemove = selectedSet.getCardByNumber(args[0]);
- if (cardToRemove != null) {
- Integer count = 1;
- if (args.length > 1 && args[1].matches("[0-9]+")) {
- count = Integer.valueOf(args[1]);
- if (count <= 0) {
- System.out.println("Can't remove " + count + " cards.");
- return;
- }
- }
- removeCard(cardToRemove, count);
- } else {
- System.out.println(args[0] + " does not correspond to a card in " + selectedSet.getName() + ".");
- }
- } else {
- System.out.println("Please specify a card number to remove.");
- }
- } else {
- System.out.println("Select a set before removing cards.");
- }
- }
-
- /**
- * Add one or more of a card.
- *
- * @param number the number of the card to add.
- * @param args optionally the count to add.
- */
- public void add(String number, String[] args) {
- if (selectedSet != null) {
- // a blank line after adding a card repeats the addition unlimitedly
- if (number.isEmpty()) {
- if (lastAction == Action.ADD)
- addCard(lastAction.card, lastAction.count);
- } else {
- Card cardToAdd = selectedSet.getCardByNumber(number);
- if (cardToAdd != null) {
- Integer count = 1;
- if (args.length > 0 && args[0].matches("[0-9]+")) {
- count = Integer.valueOf(args[0]);
- if (count <= 0) {
- System.out.println("Can't add " + count + " cards.");
- return;
- }
- }
- addCard(cardToAdd, count);
- } else {
- System.out.println(number + " does not correspond to a card in " + selectedSet.getName() + ".");
- }
- }
- } else {
- System.out.println("Select a set before adding cards.");
- }
- }
-
- /**
- * Add the specified count of the specified card
- * to the cardbase.
- *
- * @param card the card to add.
- * @param count the number of times to add it.
- */
- private void addCard(Card card, Integer count) {
- cardbase.addCard(card, count);
- System.out.println("Added " + count + "x " + card.name + ".");
- savePrompt = true;
- lastAction = Action.ADD;
- lastAction.set(card, count);
- }
-
- /**
- * Remove the specified count of the specified card
- * from the cardbase.
- *
- * @param card the card to remove.
- * @param count the number of times to remove it.
- */
- private void removeCard(Card card, Integer count) {
- Integer removed = cardbase.removeCard(card, count);
- if (removed > 0) {
- System.out.println("Removed " + removed + "x " + card.name + ".");
- savePrompt = true;
- lastAction = Action.REMOVE;
- lastAction.set(card, removed);
- } else {
- System.out.println(card.name + " is not in the cardbase.");
- }
-
- }
-
- /**
- * Return a {@code String} that is guaranteed to be a legal file name.
- *
- * @param name the file name candidate to sanitise.
- * @return the sanitised name.
- */
- private String sanitiseFileName(String name) {
- // POSIX-compliant valid filename characters
- name = name.replaceAll("[^-_.A-Za-z0-9]", "");
- // extension is not indispensable, but good practice
- if (!name.endsWith(".cb")) {
- name = name.concat(".cb");
- }
- return name;
- }
-
- /**
- * Prints a glance of the specified card. A glance contains simply
- * the card count, name, set code and set number.
- *
- * @param card the card to glance.
- */
- private void printGlance(Card card) {
- System.out.println(String.format("%1$-4d %2$s (%3$s, %4$s)", card.count, card.name, card.setCode, card.number));
- }
-
- /**
- * Prints a perusal of the specified card. A perusal contains more
- * information than a glance, but not every single field the card has
- * as that would be too verbose while adding little value.
- *
- * @param card the card to peruse.
- */
- private void printPerusal(Card card) {
- printGlance(card);
- if (card.type != null) System.out.println("\t" + card.type);
- if (card.manaCost != null) System.out.println("\tCost: " + card.manaCost);
- if (card.power != null && card.toughness != null) System.out.println("\t" + card.power + "/" + card.toughness);
- if (card.loyalty != null) System.out.println("\tLoyalty: " + card.loyalty);
-
- if (card.text != null) System.out.println("\t" + card.text.replaceAll("\n", "\n\t"));
- if (card.flavor != null) System.out.println("\t" + card.flavor.replaceAll("\n", "\n\t"));
-
- if (card.rarity != null) System.out.println("\t" + card.rarity);
- if (card.multiverseid != null) System.out.println("\tMID: " + card.multiverseid);
- if (card.artist != null) System.out.println("\tIllus. " + card.artist);
- }
-}