diff --git a/src/main/java/nl/andrewlalis/human_task_distributor/FileParser.java b/src/main/java/nl/andrewlalis/human_task_distributor/FileParser.java index e517238..d78d7ad 100644 --- a/src/main/java/nl/andrewlalis/human_task_distributor/FileParser.java +++ b/src/main/java/nl/andrewlalis/human_task_distributor/FileParser.java @@ -5,8 +5,11 @@ import org.apache.commons.csv.CSVRecord; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static nl.andrewlalis.human_task_distributor.HumanTaskDistributor.CSV_FORMAT; @@ -74,4 +77,20 @@ public class FileParser { } return previousDistributions; } + + public Set parseTaskList(String path, String regex) { + try { + String contents = String.join(" ", Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8)); + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(contents); + Set tasks = new HashSet<>(); + while (matcher.find()) { + tasks.add(new Task(matcher.group())); + } + return tasks; + } catch (Exception e) { + e.printStackTrace(); + return new HashSet<>(); + } + } } diff --git a/src/main/java/nl/andrewlalis/human_task_distributor/FileWriter.java b/src/main/java/nl/andrewlalis/human_task_distributor/FileWriter.java new file mode 100644 index 0000000..9a190f7 --- /dev/null +++ b/src/main/java/nl/andrewlalis/human_task_distributor/FileWriter.java @@ -0,0 +1,38 @@ +package nl.andrewlalis.human_task_distributor; + +import org.apache.commons.csv.CSVPrinter; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; + +import static nl.andrewlalis.human_task_distributor.HumanTaskDistributor.CSV_FORMAT; + +public class FileWriter { + + public void write(Map> taskDistributions, String filePath) throws IOException { + CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(Paths.get(filePath), StandardCharsets.UTF_8), CSV_FORMAT); + for (Map.Entry> entry : taskDistributions.entrySet()) { + Human human = entry.getKey(); + Set assignedTasks = entry.getValue(); + List sortedTasks = assignedTasks.stream().sorted(Comparator.comparing(Task::getName)).collect(Collectors.toList()); + for (Task task : sortedTasks) { + printer.printRecord(human.getName(), task.getName()); + } + } + printer.close(true); + } + + public void write(Set tasks, String filePath) throws IOException { + CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(Paths.get(filePath), StandardCharsets.UTF_8), CSV_FORMAT); + List orderedTasks = new ArrayList<>(tasks); + orderedTasks.sort(Task::compareTo); + for (Task t : orderedTasks) { + printer.printRecord(t.getName()); + } + printer.close(true); + } +} diff --git a/src/main/java/nl/andrewlalis/human_task_distributor/HumanTaskDistributor.java b/src/main/java/nl/andrewlalis/human_task_distributor/HumanTaskDistributor.java index 63021e1..c9694a5 100644 --- a/src/main/java/nl/andrewlalis/human_task_distributor/HumanTaskDistributor.java +++ b/src/main/java/nl/andrewlalis/human_task_distributor/HumanTaskDistributor.java @@ -2,13 +2,10 @@ package nl.andrewlalis.human_task_distributor; import org.apache.commons.cli.*; import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVPrinter; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; +import java.util.List; +import java.util.Map; +import java.util.Set; public class HumanTaskDistributor { public static final CSVFormat CSV_FORMAT = CSVFormat.RFC4180; @@ -17,8 +14,28 @@ public class HumanTaskDistributor { final Options options = getOptions(); CommandLineParser cmdParser = new DefaultParser(); try { - CommandLine cmd = cmdParser.parse(options, args); FileParser fileParser = new FileParser(); + FileWriter fileWriter = new FileWriter(); + CommandLine cmd = cmdParser.parse(options, args); + if (cmd.hasOption("ptl")) { + String[] values = cmd.getOptionValues("ptl"); + if (values.length != 2) { + throw new IllegalArgumentException("Expected exactly 2 parameters for ptl arg."); + } + String filePath = values[0].trim(); + String regex = values[1].trim(); + Set tasks = fileParser.parseTaskList(filePath, regex); + System.out.println("Read " + tasks.size() + " tasks from file."); + String outFilePath = filePath.replaceFirst("\\..*", ".csv"); + fileWriter.write(tasks, outFilePath); + System.out.println("Wrote tasks to " + outFilePath); + return; + } + + if (!cmd.hasOption("hl") || !cmd.hasOption("tl")) { + throw new IllegalArgumentException("When not preparing a tasks-list, hl and tl are required."); + } + Map nameWeightMap = fileParser.parseHumanList(cmd.getOptionValue("hl")); Set tasks = fileParser.parseTaskList(cmd.getOptionValue("tl")); String[] previousDistributionPaths = cmd.getOptionValues("prev"); @@ -36,18 +53,8 @@ public class HumanTaskDistributor { ); // Write to a file. - String filePath = cmd.hasOption("o") ? cmd.getOptionValue("o") : "distribution.csv"; - CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(Paths.get(filePath), StandardCharsets.UTF_8), CSV_FORMAT); - for (Map.Entry> entry : taskDistributions.entrySet()) { - Human human = entry.getKey(); - Set assignedTasks = entry.getValue(); - List sortedTasks = assignedTasks.stream().sorted(Comparator.comparing(Task::getName)).collect(Collectors.toList()); - for (Task task : sortedTasks) { - printer.printRecord(human.getName(), task.getName()); - } - } - printer.close(true); - + final String filePath = cmd.hasOption("o") ? cmd.getOptionValue("o") : "distribution.csv"; + fileWriter.write(taskDistributions, filePath); System.out.println("Wrote task distribution data to " + filePath); } catch (Exception e) { @@ -65,16 +72,25 @@ public class HumanTaskDistributor { .longOpt("humans-list") .hasArg(true) .desc("Path to a CSV file containing list of humans to distribute tasks to. First column should be the name of the person, and second column can be empty, or contain a floating-point weight.") - .required(true) + .required(false) .numberOfArgs(1) .type(String.class) .build() ); + options.addOption(Option.builder("ptl") + .longOpt("prepare-tasks-list") + .desc("Prepares a tasks-list CSV from a TXT file with one task for each item that matches the given Regex.") + .required(false) + .numberOfArgs(2) + .valueSeparator(',') + .type(String.class) + .build() + ); options.addOption(Option.builder("tl") .longOpt("tasks-list") .hasArg(true) .desc("Path to a CSV file containing list of tasks that can be distributed to humans. First column should be unique task name.") - .required(true) + .required(false) .numberOfArgs(1) .type(String.class) .build() diff --git a/src/main/java/nl/andrewlalis/human_task_distributor/Task.java b/src/main/java/nl/andrewlalis/human_task_distributor/Task.java index 1b91e6c..01726ba 100644 --- a/src/main/java/nl/andrewlalis/human_task_distributor/Task.java +++ b/src/main/java/nl/andrewlalis/human_task_distributor/Task.java @@ -5,7 +5,7 @@ import lombok.Getter; import java.util.Objects; @Getter -public class Task { +public class Task implements Comparable { private final String name; public Task(String name) { @@ -24,4 +24,9 @@ public class Task { public int hashCode() { return Objects.hash(getName()); } + + @Override + public int compareTo(Task o) { + return this.getName().compareToIgnoreCase(o.getName()); + } }