Search in sources :

Example 36 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project gatk-protected by broadinstitute.

the class HDF5PCACoveragePoNCreationUtils method subsetReadCountsToUsableTargets.

/**
     * Subsets targets in the input count to the usable ones based on the percentile threshold indicated
     * by the user.
     *
     * <p>
     *     It returns a pair of object, where the left one is the updated read-counts with only the usable
     *     targets, and the right one is the corresponding target factors.
     * </p>
     *
     * @param readCounts the input read-counts.
     * @param targetFactorPercentileThreshold the minimum median count percentile under which targets are not considered useful.
     * @return never {@code null}.
     */
@VisibleForTesting
static Pair<ReadCountCollection, double[]> subsetReadCountsToUsableTargets(final ReadCountCollection readCounts, final double targetFactorPercentileThreshold, final Logger logger) {
    final double[] targetFactors = calculateTargetFactors(readCounts);
    final double threshold = new Percentile(targetFactorPercentileThreshold).evaluate(targetFactors);
    final List<Target> targetByIndex = readCounts.targets();
    final Set<Target> result = IntStream.range(0, targetFactors.length).filter(i -> targetFactors[i] >= threshold).mapToObj(targetByIndex::get).collect(Collectors.toCollection(LinkedHashSet::new));
    if (result.size() == targetByIndex.size()) {
        logger.info(String.format("All %d targets are kept", targetByIndex.size()));
        return new ImmutablePair<>(readCounts, targetFactors);
    } else {
        final int discardedCount = targetFactors.length - result.size();
        logger.info(String.format("Discarded %d target(s) out of %d with factors below %.2g (%.2f percentile)", discardedCount, targetFactors.length, threshold, targetFactorPercentileThreshold));
        final double[] targetFactorSubset = DoubleStream.of(targetFactors).filter(i -> i >= threshold).toArray();
        return new ImmutablePair<>(readCounts.subsetTargets(result), targetFactorSubset);
    }
}
Also used : IntStream(java.util.stream.IntStream) DefaultRealMatrixChangingVisitor(org.apache.commons.math3.linear.DefaultRealMatrixChangingVisitor) SVD(org.broadinstitute.hellbender.utils.svd.SVD) java.util(java.util) JavaSparkContext(org.apache.spark.api.java.JavaSparkContext) MatrixSummaryUtils(org.broadinstitute.hellbender.utils.MatrixSummaryUtils) ParamUtils(org.broadinstitute.hellbender.utils.param.ParamUtils) Pair(org.apache.commons.lang3.tuple.Pair) Median(org.apache.commons.math3.stat.descriptive.rank.Median) HDF5File(org.broadinstitute.hdf5.HDF5File) IOUtils(org.broadinstitute.hellbender.utils.io.IOUtils) org.broadinstitute.hellbender.tools.exome(org.broadinstitute.hellbender.tools.exome) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) File(java.io.File) DoubleStream(java.util.stream.DoubleStream) Percentile(org.apache.commons.math3.stat.descriptive.rank.Percentile) Logger(org.apache.logging.log4j.Logger) MathUtils(org.broadinstitute.hellbender.utils.MathUtils) UserException(org.broadinstitute.hellbender.exceptions.UserException) SVDFactory(org.broadinstitute.hellbender.utils.svd.SVDFactory) Utils(org.broadinstitute.hellbender.utils.Utils) RealMatrix(org.apache.commons.math3.linear.RealMatrix) VisibleForTesting(com.google.common.annotations.VisibleForTesting) LogManager(org.apache.logging.log4j.LogManager) Percentile(org.apache.commons.math3.stat.descriptive.rank.Percentile) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 37 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project gatk by broadinstitute.

the class EvaluateCopyNumberTriStateCalls method buildAndAnnotateTruthOverlappingGenotype.

private Genotype buildAndAnnotateTruthOverlappingGenotype(final String sample, final TargetCollection<Target> targets, final Genotype truthGenotype, final int truthCopyNumber, final CopyNumberTriStateAllele truthAllele, final List<Pair<VariantContext, Genotype>> calls) {
    final Set<CopyNumberTriStateAllele> calledAlleles = calls.stream().map(pair -> CopyNumberTriStateAllele.valueOf(pair.getRight().getAllele(0))).collect(Collectors.toSet());
    final Allele calledAllele = calledAlleles.size() == 1 ? calledAlleles.iterator().next() : Allele.NO_CALL;
    final GenotypeBuilder builder = new GenotypeBuilder(sample);
    // Set the call allele.
    builder.alleles(Collections.singletonList(calledAllele));
    // Set the truth allele.
    builder.attribute(VariantEvaluationContext.TRUTH_GENOTYPE_KEY, CopyNumberTriStateAllele.ALL_ALLELES.indexOf(truthAllele));
    // Annotate the genotype with the number of calls.
    builder.attribute(VariantEvaluationContext.CALLED_SEGMENTS_COUNT_KEY, calls.size());
    // When there is more than one qualified type of event we indicate how many.
    builder.attribute(VariantEvaluationContext.CALLED_ALLELE_COUNTS_KEY, CopyNumberTriStateAllele.ALL_ALLELES.stream().mapToInt(allele -> (int) calls.stream().filter(pair -> pair.getRight().getAllele(0).equals(allele, true)).count()).toArray());
    // Calculate the length in targets of the call as the sum across all calls.
    builder.attribute(VariantEvaluationContext.CALLED_TARGET_COUNT_KEY, calls.stream().mapToInt(pair -> getTargetCount(targets, pair.getLeft(), pair.getRight())).sum());
    // Calculate call quality-- if there is more than one overlapping call we take the maximum qual one.
    builder.attribute(VariantEvaluationContext.CALL_QUALITY_KEY, calls.stream().mapToDouble(pair -> GATKProtectedVariantContextUtils.calculateGenotypeQualityFromPLs(pair.getRight())).max().orElse(0.0));
    // Calculate the truth copy fraction.
    builder.attribute(VariantEvaluationContext.TRUTH_COPY_FRACTION_KEY, truthGenotype.getExtendedAttribute(GS_COPY_NUMBER_FRACTION_KEY));
    // Calculate the truth call quality.
    final double truthQuality = calculateTruthQuality(truthGenotype, truthCopyNumber);
    builder.attribute(VariantEvaluationContext.TRUTH_QUALITY_KEY, truthQuality);
    // Set genotype filters:
    final boolean truthPassQualityMinimum = truthQuality >= filterArguments.minimumTruthSegmentQuality;
    builder.filter(truthPassQualityMinimum ? EvaluationFilter.PASS : EvaluationFilter.LowQuality.acronym);
    // Calculate the evaluation class (TP, FN, etc.). Only if there is actually either a truth or a call that is not ref.
    if (calledAlleles.contains(CopyNumberTriStateAllele.DEL) || calledAlleles.contains(CopyNumberTriStateAllele.DUP) || truthAllele != CopyNumberTriStateAllele.REF) {
        final EvaluationClass evaluationClass;
        if (calledAlleles.isEmpty() || (calledAlleles.size() == 1 && calledAlleles.contains(CopyNumberTriStateAllele.REF))) {
            evaluationClass = EvaluationClass.FALSE_NEGATIVE;
        } else if (calledAlleles.size() == 1) {
            evaluationClass = calledAlleles.contains(truthAllele) ? EvaluationClass.TRUE_POSITIVE : truthAllele == CopyNumberTriStateAllele.REF ? EvaluationClass.FALSE_POSITIVE : /* else */
            EvaluationClass.DISCORDANT_POSITIVE;
        } else {
            evaluationClass = truthAllele == CopyNumberTriStateAllele.REF ? EvaluationClass.FALSE_POSITIVE : EvaluationClass.MIXED_POSITIVE;
        }
        builder.attribute(VariantEvaluationContext.EVALUATION_CLASS_KEY, evaluationClass.acronym);
    }
    return builder.make();
}
Also used : Genotype(htsjdk.variant.variantcontext.Genotype) DocumentedFeature(org.broadinstitute.barclay.help.DocumentedFeature) Allele(htsjdk.variant.variantcontext.Allele) htsjdk.variant.vcf(htsjdk.variant.vcf) CommandLineProgramProperties(org.broadinstitute.barclay.argparser.CommandLineProgramProperties) java.util(java.util) CopyNumberProgramGroup(org.broadinstitute.hellbender.cmdline.programgroups.CopyNumberProgramGroup) Argument(org.broadinstitute.barclay.argparser.Argument) VariantContextWriterBuilder(htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder) StandardArgumentDefinitions(org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions) ArgumentCollection(org.broadinstitute.barclay.argparser.ArgumentCollection) TargetArgumentCollection(org.broadinstitute.hellbender.tools.exome.TargetArgumentCollection) Function(java.util.function.Function) Pair(org.apache.commons.lang3.tuple.Pair) StreamSupport(java.util.stream.StreamSupport) TargetCollection(org.broadinstitute.hellbender.tools.exome.TargetCollection) org.broadinstitute.hellbender.utils(org.broadinstitute.hellbender.utils) Locatable(htsjdk.samtools.util.Locatable) CommandLineProgram(org.broadinstitute.hellbender.cmdline.CommandLineProgram) GenotypeBuilder(htsjdk.variant.variantcontext.GenotypeBuilder) IOException(java.io.IOException) CopyNumberTriStateAllele(org.broadinstitute.hellbender.tools.exome.germlinehmm.CopyNumberTriStateAllele) Collectors(java.util.stream.Collectors) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) File(java.io.File) HMMPostProcessor(org.broadinstitute.hellbender.utils.hmm.segmentation.HMMPostProcessor) XHMMSegmentGenotyper(org.broadinstitute.hellbender.tools.exome.germlinehmm.xhmm.XHMMSegmentGenotyper) Stream(java.util.stream.Stream) UserException(org.broadinstitute.hellbender.exceptions.UserException) VariantContextWriter(htsjdk.variant.variantcontext.writer.VariantContextWriter) Target(org.broadinstitute.hellbender.tools.exome.Target) XHMMSegmentCaller(org.broadinstitute.hellbender.tools.exome.germlinehmm.xhmm.XHMMSegmentCaller) VariantContext(htsjdk.variant.variantcontext.VariantContext) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) CopyNumberTriStateAllele(org.broadinstitute.hellbender.tools.exome.germlinehmm.CopyNumberTriStateAllele) Allele(htsjdk.variant.variantcontext.Allele) CopyNumberTriStateAllele(org.broadinstitute.hellbender.tools.exome.germlinehmm.CopyNumberTriStateAllele) GenotypeBuilder(htsjdk.variant.variantcontext.GenotypeBuilder)

Example 38 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project gatk by broadinstitute.

the class EvaluateCopyNumberTriStateCalls method buildAndAnnotateTruthOverlappingGenotype.

private Genotype buildAndAnnotateTruthOverlappingGenotype(final String sample, final VariantContext truth, final List<VariantContext> calls, final TargetCollection<Target> targets) {
    final Genotype truthGenotype = truth.getGenotype(sample);
    // if there is no truth genotype for that sample, we output the "empty" genotype.
    if (truthGenotype == null) {
        return GenotypeBuilder.create(sample, Collections.emptyList());
    }
    final int truthCopyNumber = GATKProtectedVariantContextUtils.getAttributeAsInt(truthGenotype, GS_COPY_NUMBER_FORMAT_KEY, truthNeutralCopyNumber);
    final CopyNumberTriStateAllele truthAllele = copyNumberToTrueAllele(truthCopyNumber);
    final List<Pair<VariantContext, Genotype>> allCalls = calls.stream().map(vc -> new ImmutablePair<>(vc, vc.getGenotype(sample))).filter(pair -> pair.getRight() != null).filter(pair -> GATKProtectedVariantContextUtils.getAttributeAsString(pair.getRight(), XHMMSegmentGenotyper.DISCOVERY_KEY, XHMMSegmentGenotyper.DISCOVERY_FALSE).equals(XHMMSegmentGenotyper.DISCOVERY_TRUE)).collect(Collectors.toList());
    final List<Pair<VariantContext, Genotype>> qualifiedCalls = composeQualifyingCallsList(targets, allCalls);
    return buildAndAnnotateTruthOverlappingGenotype(sample, targets, truthGenotype, truthCopyNumber, truthAllele, qualifiedCalls);
}
Also used : Genotype(htsjdk.variant.variantcontext.Genotype) DocumentedFeature(org.broadinstitute.barclay.help.DocumentedFeature) Allele(htsjdk.variant.variantcontext.Allele) htsjdk.variant.vcf(htsjdk.variant.vcf) CommandLineProgramProperties(org.broadinstitute.barclay.argparser.CommandLineProgramProperties) java.util(java.util) CopyNumberProgramGroup(org.broadinstitute.hellbender.cmdline.programgroups.CopyNumberProgramGroup) Argument(org.broadinstitute.barclay.argparser.Argument) VariantContextWriterBuilder(htsjdk.variant.variantcontext.writer.VariantContextWriterBuilder) StandardArgumentDefinitions(org.broadinstitute.hellbender.cmdline.StandardArgumentDefinitions) ArgumentCollection(org.broadinstitute.barclay.argparser.ArgumentCollection) TargetArgumentCollection(org.broadinstitute.hellbender.tools.exome.TargetArgumentCollection) Function(java.util.function.Function) Pair(org.apache.commons.lang3.tuple.Pair) StreamSupport(java.util.stream.StreamSupport) TargetCollection(org.broadinstitute.hellbender.tools.exome.TargetCollection) org.broadinstitute.hellbender.utils(org.broadinstitute.hellbender.utils) Locatable(htsjdk.samtools.util.Locatable) CommandLineProgram(org.broadinstitute.hellbender.cmdline.CommandLineProgram) GenotypeBuilder(htsjdk.variant.variantcontext.GenotypeBuilder) IOException(java.io.IOException) CopyNumberTriStateAllele(org.broadinstitute.hellbender.tools.exome.germlinehmm.CopyNumberTriStateAllele) Collectors(java.util.stream.Collectors) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) File(java.io.File) HMMPostProcessor(org.broadinstitute.hellbender.utils.hmm.segmentation.HMMPostProcessor) XHMMSegmentGenotyper(org.broadinstitute.hellbender.tools.exome.germlinehmm.xhmm.XHMMSegmentGenotyper) Stream(java.util.stream.Stream) UserException(org.broadinstitute.hellbender.exceptions.UserException) VariantContextWriter(htsjdk.variant.variantcontext.writer.VariantContextWriter) Target(org.broadinstitute.hellbender.tools.exome.Target) XHMMSegmentCaller(org.broadinstitute.hellbender.tools.exome.germlinehmm.xhmm.XHMMSegmentCaller) VariantContext(htsjdk.variant.variantcontext.VariantContext) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) CopyNumberTriStateAllele(org.broadinstitute.hellbender.tools.exome.germlinehmm.CopyNumberTriStateAllele) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair) Genotype(htsjdk.variant.variantcontext.Genotype) Pair(org.apache.commons.lang3.tuple.Pair) ImmutablePair(org.apache.commons.lang3.tuple.ImmutablePair)

Example 39 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project RFToolsDimensions by McJty.

the class GuiDimletWorkbench method updateList.

private void updateList() {
    if (!listDirty) {
        return;
    }
    listDirty = false;
    itemList.removeChildren();
    Map<DimletKey, Settings> dimlets = KnownDimletConfiguration.getKnownDimlets();
    String filter = searchBar.getText().toLowerCase();
    // First remove all dimlets with the same name and also apply the filter already
    Map<Pair<DimletType, String>, DimletKey> uniquelyNamedDimlets = new HashMap<>();
    for (DimletKey key : dimlets.keySet()) {
        String name = KnownDimletConfiguration.getDisplayName(key);
        if (dimletMatches(filter, key, name)) {
            Pair<DimletType, String> k = Pair.of(key.getType(), name);
            if (!uniquelyNamedDimlets.containsKey(k)) {
                uniquelyNamedDimlets.put(k, key);
            }
        }
    }
    List<DimletKey> keys = new ArrayList<>(uniquelyNamedDimlets.values());
    keys.sort((a, b) -> {
        int rc = a.getType().compareTo(b.getType());
        if (rc == 0) {
            return a.getId().compareTo(b.getId());
        } else {
            return rc;
        }
    });
    keys.stream().forEach(key -> addItemToList(key, itemList));
    if (itemList.getFirstSelected() >= itemList.getChildCount()) {
        itemList.setFirstSelected(0);
    }
}
Also used : HashMap(java.util.HashMap) DimletType(mcjty.rftoolsdim.dimensions.dimlets.types.DimletType) ArrayList(java.util.ArrayList) DimletKey(mcjty.rftoolsdim.dimensions.dimlets.DimletKey) Settings(mcjty.rftoolsdim.config.Settings) Pair(org.apache.commons.lang3.tuple.Pair)

Example 40 with Pair

use of org.apache.beam.repackaged.core.org.apache.commons.lang3.tuple.Pair in project MantaroBot by Mantaro.

the class CustomCmds method custom.

@Subscribe
public void custom(CommandRegistry cr) {
    String any = "[\\d\\D]*?";
    cr.register("custom", new SimpleCommand(Category.UTILS) {

        @Override
        public void call(GuildMessageReceivedEvent event, String content, String[] args) {
            if (args.length < 1) {
                onHelp(event);
                return;
            }
            String action = args[0];
            if (action.equals("list") || action.equals("ls")) {
                if (!MantaroCore.hasLoadedCompletely()) {
                    event.getChannel().sendMessage("The bot hasn't been fully booted up yet... custom commands will be available shortly!").queue();
                    return;
                }
                String filter = event.getGuild().getId() + ":";
                List<String> commands = customCommands.keySet().stream().filter(s -> s.startsWith(filter)).map(s -> s.substring(filter.length())).collect(Collectors.toList());
                EmbedBuilder builder = new EmbedBuilder().setAuthor("Commands for this guild", null, event.getGuild().getIconUrl()).setColor(event.getMember().getColor());
                builder.setDescription(commands.isEmpty() ? "There is nothing here, just dust." : checkString(forType(commands)));
                event.getChannel().sendMessage(builder.build()).queue();
                return;
            }
            if (action.equals("view")) {
                if (args.length < 2) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "You need to specify the command and the response number!").queue();
                    return;
                }
                String cmd = args[1];
                CustomCommand command = db().getCustomCommand(event.getGuild(), cmd);
                if (command == null) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "There isn't a custom command with that name here!").queue();
                    return;
                }
                int number;
                try {
                    number = Integer.parseInt(args[2]) - 1;
                } catch (NumberFormatException e) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "That's not a number...").queue();
                    return;
                }
                if (command.getValues().size() < number) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "This commands has less responses than the number you specified...").queue();
                    return;
                }
                event.getChannel().sendMessage(String.format("**Response `%d` for custom command `%s`:** \n```\n%s```", (number + 1), command.getName(), command.getValues().get(number))).queue();
                return;
            }
            if (action.equals("raw")) {
                if (args.length < 2) {
                    onHelp(event);
                    return;
                }
                String cmd = args[1];
                if (!NAME_PATTERN.matcher(cmd).matches()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                    return;
                }
                CustomCommand custom = db().getCustomCommand(event.getGuild(), cmd);
                if (custom == null) {
                    event.getChannel().sendMessage(EmoteReference.ERROR2 + "There's no Custom Command ``" + cmd + "`` in this Guild.").queue();
                    return;
                }
                Pair<String, Integer> pair = DiscordUtils.embedList(custom.getValues(), Object::toString);
                String pasted = null;
                if (pair.getRight() < custom.getValues().size()) {
                    AtomicInteger i = new AtomicInteger();
                    pasted = Utils.paste(custom.getValues().stream().map(s -> i.incrementAndGet() + s).collect(Collectors.joining("\n")));
                }
                EmbedBuilder embed = baseEmbed(event, "Command \"" + cmd + "\":").setDescription(pair.getLeft()).setFooter("(Showing " + pair.getRight() + " responses of " + custom.getValues().size() + ")", null);
                if (pasted != null && pasted.contains("hastebin.com")) {
                    embed.addField("Pasted content", pasted, false);
                }
                event.getChannel().sendMessage(embed.build()).queue();
                return;
            }
            if (db().getGuild(event.getGuild()).getData().isCustomAdminLock() && !CommandPermission.ADMIN.test(event.getMember())) {
                event.getChannel().sendMessage("This guild only accepts custom command creation, edits, imports and eval from administrators.").queue();
                return;
            }
            if (action.equals("clear")) {
                if (!CommandPermission.ADMIN.test(event.getMember())) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "You cannot do that, silly.").queue();
                    return;
                }
                List<CustomCommand> customCommands = db().getCustomCommands(event.getGuild());
                if (customCommands.isEmpty()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "There's no Custom Commands registered in this Guild, just dust.").queue();
                }
                int size = customCommands.size();
                customCommands.forEach(CustomCommand::deleteAsync);
                customCommands.forEach(c -> CustomCmds.customCommands.remove(c.getId()));
                event.getChannel().sendMessage(EmoteReference.PENCIL + "Cleared **" + size + " Custom Commands**!").queue();
                return;
            }
            if (args.length < 2) {
                onHelp(event);
                return;
            }
            String cmd = args[1];
            if (action.equals("make")) {
                if (!NAME_PATTERN.matcher(cmd).matches()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                    return;
                }
                List<String> responses = new ArrayList<>();
                boolean created = InteractiveOperations.create(event.getChannel(), 60, e -> {
                    if (!e.getAuthor().equals(event.getAuthor()))
                        return Operation.IGNORED;
                    String c = e.getMessage().getContentRaw();
                    if (!c.startsWith("&"))
                        return Operation.IGNORED;
                    c = c.substring(1);
                    if (c.startsWith("~>cancel") || c.startsWith("~>stop")) {
                        event.getChannel().sendMessage(EmoteReference.CORRECT + "Command Creation canceled.").queue();
                        return Operation.COMPLETED;
                    }
                    if (c.startsWith("~>save")) {
                        String arg = c.substring(6).trim();
                        String saveTo = !arg.isEmpty() ? arg : cmd;
                        if (!NAME_PATTERN.matcher(cmd).matches()) {
                            event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                            return Operation.RESET_TIMEOUT;
                        }
                        if (cmd.length() >= 100) {
                            event.getChannel().sendMessage(EmoteReference.ERROR + "Name is too long.").queue();
                            return Operation.RESET_TIMEOUT;
                        }
                        if (DefaultCommandProcessor.REGISTRY.commands().containsKey(saveTo) && !DefaultCommandProcessor.REGISTRY.commands().get(saveTo).equals(customCommand)) {
                            event.getChannel().sendMessage(EmoteReference.ERROR + "A command already exists with this name!").queue();
                            return Operation.RESET_TIMEOUT;
                        }
                        if (responses.isEmpty()) {
                            event.getChannel().sendMessage(EmoteReference.ERROR + "No responses were added. Stopping creation without saving...").queue();
                        } else {
                            CustomCommand custom = CustomCommand.of(event.getGuild().getId(), cmd, responses);
                            // save at DB
                            custom.saveAsync();
                            // reflect at local
                            customCommands.put(custom.getId(), custom.getValues());
                            // add mini-hack
                            DefaultCommandProcessor.REGISTRY.commands().put(cmd, customCommand);
                            event.getChannel().sendMessage(EmoteReference.CORRECT + "Saved to command ``" + cmd + "``!").queue();
                            // easter egg :D
                            TextChannelGround.of(event).dropItemWithChance(8, 2);
                        }
                        return Operation.COMPLETED;
                    }
                    responses.add(c.replace("@everyone", "[nice meme]").replace("@here", "[you tried]"));
                    e.getMessage().addReaction(EmoteReference.CORRECT.getUnicode()).queue();
                    return Operation.RESET_TIMEOUT;
                }) != null;
                if (created) {
                    event.getChannel().sendMessage(EmoteReference.PENCIL + "Started **\"Creation of Custom Command ``" + cmd + "``\"**!\nSend ``&~>stop`` to stop creation **without saving**.\nSend ``&~>save`` to stop creation an **save the new Command**. Send any text beginning with ``&`` to be added to the Command Responses.\nThis Interactive Operation ends without saving after 60 seconds of inactivity.").queue();
                } else {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "There's already an Interactive Operation happening on this channel.").queue();
                }
                return;
            }
            if (action.equals("eval")) {
                try {
                    runCustom(content.replace("eval ", ""), event);
                } catch (Exception e) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "There was an error while evaluating your command!" + (e.getMessage() == null ? "" : " (E: " + e.getMessage() + ")")).queue();
                }
                return;
            }
            if (action.equals("remove") || action.equals("rm")) {
                if (!NAME_PATTERN.matcher(cmd).matches()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                    return;
                }
                CustomCommand custom = db().getCustomCommand(event.getGuild(), cmd);
                if (custom == null) {
                    event.getChannel().sendMessage(EmoteReference.ERROR2 + "There's no Custom Command ``" + cmd + "`` in this Guild.").queue();
                    return;
                }
                // delete at DB
                custom.deleteAsync();
                // reflect at local
                customCommands.remove(custom.getId());
                // clear commands if none
                if (customCommands.keySet().stream().noneMatch(s -> s.endsWith(":" + cmd)))
                    DefaultCommandProcessor.REGISTRY.commands().remove(cmd);
                event.getChannel().sendMessage(EmoteReference.PENCIL + "Removed Custom Command ``" + cmd + "``!").queue();
                return;
            }
            if (action.equals("import")) {
                if (!NAME_WILDCARD_PATTERN.matcher(cmd).matches()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                    return;
                }
                Map<String, Guild> mapped = MantaroBot.getInstance().getMutualGuilds(event.getAuthor()).stream().collect(Collectors.toMap(ISnowflake::getId, g -> g));
                List<Pair<Guild, CustomCommand>> filtered = MantaroData.db().getCustomCommandsByName(("*" + cmd + "*").replace("*", any)).stream().map(customCommand -> {
                    Guild guild = mapped.get(customCommand.getGuildId());
                    return guild == null ? null : Pair.of(guild, customCommand);
                }).filter(Objects::nonNull).collect(Collectors.toList());
                if (filtered.size() == 0) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "There are no custom commands matching your search query.").queue();
                    return;
                }
                DiscordUtils.selectList(event, filtered, pair -> "``" + pair.getValue().getName() + "`` - Guild: ``" + pair.getKey() + "``", s -> baseEmbed(event, "Select the Command:").setDescription(s).setFooter("(You can only select custom commands from guilds that you are a member of)", null).build(), pair -> {
                    String cmdName = pair.getValue().getName();
                    List<String> responses = pair.getValue().getValues();
                    CustomCommand custom = CustomCommand.of(event.getGuild().getId(), cmdName, responses);
                    // save at DB
                    custom.saveAsync();
                    // reflect at local
                    customCommands.put(custom.getId(), custom.getValues());
                    event.getChannel().sendMessage(String.format("Imported custom command ``%s`` from guild `%s` with responses ``%s``", cmdName, pair.getKey().getName(), String.join("``, ``", responses))).queue();
                    // easter egg :D
                    TextChannelGround.of(event).dropItemWithChance(8, 2);
                });
                return;
            }
            if (args.length < 3) {
                onHelp(event);
                return;
            }
            String value = args[2];
            if (action.equals("edit")) {
                CustomCommand custom = db().getCustomCommand(event.getGuild(), cmd);
                if (custom == null) {
                    event.getChannel().sendMessage(EmoteReference.ERROR2 + "There's no Custom Command ``" + cmd + "`` in this Guild.").queue();
                    return;
                }
                String[] vals = StringUtils.splitArgs(value, 2);
                int where;
                try {
                    where = Math.abs(Integer.parseInt(vals[0]));
                } catch (NumberFormatException e) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "You need to specify a correct number to change!").queue();
                    return;
                }
                List<String> values = custom.getValues();
                if (where - 1 > values.size()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "You cannot edit a non-existent index!").queue();
                    return;
                }
                if (vals[1].isEmpty()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Cannot edit to an empty response!").queue();
                    return;
                }
                custom.getValues().set(where - 1, vals[1]);
                custom.saveAsync();
                customCommands.put(custom.getId(), custom.getValues());
                event.getChannel().sendMessage(EmoteReference.CORRECT + "Edited response **#" + where + "** of the command `" + custom.getName() + "` correctly!").queue();
                return;
            }
            if (action.equals("rename")) {
                if (!NAME_PATTERN.matcher(cmd).matches() || !NAME_PATTERN.matcher(value).matches()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                    return;
                }
                if (DefaultCommandProcessor.REGISTRY.commands().containsKey(value) && !DefaultCommandProcessor.REGISTRY.commands().get(value).equals(customCommand)) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "A command already exists with this name!").queue();
                    return;
                }
                CustomCommand oldCustom = db().getCustomCommand(event.getGuild(), cmd);
                if (oldCustom == null) {
                    event.getChannel().sendMessage(EmoteReference.ERROR2 + "There's no Custom Command ``" + cmd + "`` in this Guild.").queue();
                    return;
                }
                CustomCommand newCustom = CustomCommand.of(event.getGuild().getId(), value, oldCustom.getValues());
                // change at DB
                oldCustom.deleteAsync();
                newCustom.saveAsync();
                // reflect at local
                customCommands.remove(oldCustom.getId());
                customCommands.put(newCustom.getId(), newCustom.getValues());
                // add mini-hack
                DefaultCommandProcessor.REGISTRY.commands().put(value, customCommand);
                // clear commands if none
                if (customCommands.keySet().stream().noneMatch(s -> s.endsWith(":" + cmd)))
                    DefaultCommandProcessor.REGISTRY.commands().remove(cmd);
                event.getChannel().sendMessage(EmoteReference.CORRECT + "Renamed command ``" + cmd + "`` to ``" + value + "``!").queue();
                // easter egg :D
                TextChannelGround.of(event).dropItemWithChance(8, 2);
                return;
            }
            if (action.equals("add") || action.equals("new")) {
                if (!NAME_PATTERN.matcher(cmd).matches()) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Not allowed character.").queue();
                    return;
                }
                if (cmd.length() >= 100) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "Name is too long.").queue();
                    return;
                }
                if (DefaultCommandProcessor.REGISTRY.commands().containsKey(cmd) && !DefaultCommandProcessor.REGISTRY.commands().get(cmd).equals(customCommand)) {
                    event.getChannel().sendMessage(EmoteReference.ERROR + "A command already exists with this name!").queue();
                    return;
                }
                CustomCommand custom = CustomCommand.of(event.getGuild().getId(), cmd, Collections.singletonList(value.replace("@everyone", "[nice meme]").replace("@here", "[you tried]")));
                if (action.equals("add")) {
                    CustomCommand c = db().getCustomCommand(event, cmd);
                    if (c != null)
                        custom.getValues().addAll(c.getValues());
                }
                // save at DB
                custom.saveAsync();
                // reflect at local
                customCommands.put(custom.getId(), custom.getValues());
                // add mini-hack
                DefaultCommandProcessor.REGISTRY.commands().put(cmd, customCommand);
                event.getChannel().sendMessage(EmoteReference.CORRECT + "Saved to command ``" + cmd + "``!").queue();
                // easter egg :D
                TextChannelGround.of(event).dropItemWithChance(8, 2);
                return;
            }
            onHelp(event);
        }

        @Override
        public String[] splitArgs(String content) {
            return SPLIT_PATTERN.split(content, 3);
        }

        @Override
        public MessageEmbed help(GuildMessageReceivedEvent event) {
            return helpEmbed(event, "CustomCommand Manager").setDescription("**Manages the Custom Commands of the Guild.**").addField("Guide", "https://github.com/Mantaro/MantaroBot/wiki/Custom-Commands", false).addField("Usage:", "`~>custom` - Shows this help\n" + "`~>custom <list|ls>` - **List all commands. If detailed is supplied, it prints the responses of each command.**\n" + "`~>custom clear` - **Remove all Custom Commands from this Guild. (ADMIN-ONLY)**\n" + "`~>custom add <name> <response>` - **Creates or adds the response provided to a custom command.**\n" + "`~>custom make <name>` - **Starts a Interactive Operation to create a command with the specified name.**\n" + "`~>custom <remove|rm> <name>` - **Removes a command with an specific name.**\n" + "`~>custom import <search>` - **Imports a command from another guild you're in.**\n" + "`~>custom eval <response>` - **Tests how a custom command response will look**\n" + "`~>custom edit <name> <response number> <new content>` - **Edits one response of the specified command**\n" + "`~>custom view <name> <response number>` - **Views the content of one response**\n" + "`~>custom rename <previous name> <new name>` - **Renames a custom command**", false).addField("Considerations", "If you wish to dissallow normal people from making custom commands, run `~>opts admincustom true`", false).build();
        }
    });
}
Also used : CustomCommandStatsManager(net.kodehawa.mantarobot.commands.info.stats.manager.CustomCommandStatsManager) Module(net.kodehawa.mantarobot.core.modules.Module) java.util(java.util) DefaultCommandProcessor(net.kodehawa.mantarobot.core.processor.DefaultCommandProcessor) PostLoadEvent(net.kodehawa.mantarobot.core.listeners.events.PostLoadEvent) StringUtils(net.kodehawa.mantarobot.utils.StringUtils) Async(br.com.brjdevs.java.utils.async.Async) URL(java.net.URL) Utils(net.kodehawa.mantarobot.utils.Utils) DiscordUtils(net.kodehawa.mantarobot.utils.DiscordUtils) CategoryStatsManager(net.kodehawa.mantarobot.commands.info.stats.manager.CategoryStatsManager) MantaroBot(net.kodehawa.mantarobot.MantaroBot) GuildMessageReceivedEvent(net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent) Pair(org.apache.commons.lang3.tuple.Pair) CommandRegistry(net.kodehawa.mantarobot.core.CommandRegistry) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ISnowflake(net.dv8tion.jda.core.entities.ISnowflake) Subscribe(com.google.common.eventbus.Subscribe) CommandStatsManager(net.kodehawa.mantarobot.commands.info.stats.manager.CommandStatsManager) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) MessageEmbed(net.dv8tion.jda.core.entities.MessageEmbed) MantaroCore(net.kodehawa.mantarobot.core.MantaroCore) TextChannelGround(net.kodehawa.mantarobot.commands.currency.TextChannelGround) CustomCommand(net.kodehawa.mantarobot.db.entities.CustomCommand) MantaroData.db(net.kodehawa.mantarobot.data.MantaroData.db) ConditionalCustoms(net.kodehawa.mantarobot.commands.custom.ConditionalCustoms) InteractiveOperations(net.kodehawa.mantarobot.core.listeners.operations.InteractiveOperations) AbstractCommand(net.kodehawa.mantarobot.core.modules.commands.base.AbstractCommand) Category(net.kodehawa.mantarobot.core.modules.commands.base.Category) SPLIT_PATTERN(net.kodehawa.mantarobot.utils.StringUtils.SPLIT_PATTERN) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Mapifier.map(net.kodehawa.mantarobot.commands.custom.Mapifier.map) GsonDataManager(net.kodehawa.mantarobot.utils.data.GsonDataManager) Collectors(java.util.stream.Collectors) EmbedBuilder(net.dv8tion.jda.core.EmbedBuilder) Guild(net.dv8tion.jda.core.entities.Guild) Slf4j(lombok.extern.slf4j.Slf4j) CommandPermission(net.kodehawa.mantarobot.core.modules.commands.base.CommandPermission) CollectionUtils.random(br.com.brjdevs.java.utils.collections.CollectionUtils.random) Mapifier.dynamicResolve(net.kodehawa.mantarobot.commands.custom.Mapifier.dynamicResolve) EmoteReference(net.kodehawa.mantarobot.utils.commands.EmoteReference) EmbedJSON(net.kodehawa.mantarobot.commands.custom.EmbedJSON) MantaroData(net.kodehawa.mantarobot.data.MantaroData) HelpUtils.forType(net.kodehawa.mantarobot.commands.info.HelpUtils.forType) Pattern(java.util.regex.Pattern) Operation(net.kodehawa.mantarobot.core.listeners.operations.core.Operation) MessageEmbed(net.dv8tion.jda.core.entities.MessageEmbed) Guild(net.dv8tion.jda.core.entities.Guild) EmbedBuilder(net.dv8tion.jda.core.EmbedBuilder) CustomCommand(net.kodehawa.mantarobot.db.entities.CustomCommand) SimpleCommand(net.kodehawa.mantarobot.core.modules.commands.SimpleCommand) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) GuildMessageReceivedEvent(net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent) Pair(org.apache.commons.lang3.tuple.Pair) ISnowflake(net.dv8tion.jda.core.entities.ISnowflake) Subscribe(com.google.common.eventbus.Subscribe)

Aggregations

Pair (org.apache.commons.lang3.tuple.Pair)685 ArrayList (java.util.ArrayList)209 List (java.util.List)154 Test (org.junit.Test)150 ImmutablePair (org.apache.commons.lang3.tuple.ImmutablePair)142 HashMap (java.util.HashMap)123 Collectors (java.util.stream.Collectors)123 Map (java.util.Map)112 Message (com.microsoft.azure.sdk.iot.device.Message)71 IOException (java.io.IOException)70 MutablePair (org.apache.commons.lang3.tuple.MutablePair)64 java.util (java.util)55 IotHubTransportMessage (com.microsoft.azure.sdk.iot.device.transport.IotHubTransportMessage)52 Set (java.util.Set)49 StringUtils (org.apache.commons.lang3.StringUtils)48 File (java.io.File)46 Optional (java.util.Optional)45 Arrays (java.util.Arrays)44 HashSet (java.util.HashSet)40 Test (org.junit.jupiter.api.Test)39