use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class YouTubeCommand method onCommand.
public void onCommand(Sx4CommandEvent event, @Argument(value = "query", endless = true) String query, @Option(value = "channel", description = "Only return a channel") boolean channel, @Option(value = "playlist", description = "Only return a playlist") boolean playlist, @Option(value = "video", description = "Only return a video") boolean video) {
String type = channel ? "channel" : video ? "video" : playlist ? "playlist" : null;
Request request = new Request.Builder().url(String.format("https://www.googleapis.com/youtube/v3/search?key=%s&part=snippet&maxResults=50&safeSearch=none&q=%s%s", event.getConfig().getYouTube(), URLEncoder.encode(query, StandardCharsets.UTF_8), type == null ? "" : "&type=" + type)).build();
event.getHttpClient().newCall(request).enqueue((HttpCallback) response -> {
Document json = Document.parse(response.body().string());
List<Document> items = json.getList("items", Document.class);
if (items.isEmpty()) {
event.replyFailure("I could not find any results").queue();
return;
}
PagedResult<Document> paged = new PagedResult<>(event.getBot(), items).setAuthor("YouTube Results", null, "https://media-thumbs.golden.com/4hBhjfnhOC6J3uJZglZG0quRsPU=/200x200/smart/golden-media.s3.amazonaws.com%2Ftopic_images%2F6c3fdb0966b049eba2b9c2331da224f0.png").setAutoSelect(true).setDisplayFunction(data -> {
Document id = data.get("id", Document.class);
String kind = id.getString("kind");
return "[" + data.getEmbedded(List.of("snippet", "title"), String.class) + "](" + this.getUrlFromId(id) + ")" + " (" + StringUtility.title(kind.substring(kind.indexOf('#') + 1)) + ")";
});
paged.onSelect(select -> {
Document result = select.getSelected();
Document id = result.get("id", Document.class);
Document snippet = result.get("snippet", Document.class);
Document thumbnails = snippet.get("thumbnails", Document.class);
ZonedDateTime uploadedAt = ZonedDateTime.parse(snippet.getString("publishedAt"));
EmbedBuilder embed = new EmbedBuilder();
embed.setColor(16711680);
embed.setDescription(snippet.getString("description"));
embed.setImage(thumbnails.getEmbedded(List.of("high", "url"), String.class));
embed.setTitle(snippet.getString("title"), this.getUrlFromId(id));
String kind = id.getString("kind");
if (kind.equals("youtube#channel")) {
embed.addField("Created At", uploadedAt.format(this.formatter), true);
} else if (kind.equals("youtube#video")) {
String state = snippet.getString("liveBroadcastContent");
embed.addField("Uploaded By", "[" + snippet.getString("channelTitle") + "](https://www.youtube.com/channel/" + snippet.getString("channelId") + ")", true);
embed.addField("Uploaded At", uploadedAt.format(this.formatter), true);
embed.addField("State", state.equals("live") ? "Live Now" : state.equals("upcoming") ? "Scheduled" : "Uploaded", true);
Request metaDataRequest = new Request.Builder().url("https://api.jockiemusic.com/v1/youtube/videos/" + id.getString("videoId") + "/metadata").build();
event.reply(embed.build()).queue(message -> {
event.getHttpClient().newCall(metaDataRequest).enqueue((HttpCallback) metaDataResponse -> {
if (metaDataResponse.code() == 404) {
return;
}
Document data = Document.parse(metaDataResponse.body().string()).get("data", Document.class);
Document metaData = data.get("metadata", Document.class);
Document rating = metaData.get("rating", Document.class);
long likes = rating.get("likes", Number.class).longValue(), dislikes = rating.get("dislikes", Number.class).longValue();
double ratingPercent = ((double) likes / (likes + dislikes)) * 100D;
embed.addField("Duration", TimeUtility.getMusicTimeString(metaData.get("length", Number.class).longValue(), TimeUnit.MILLISECONDS), true);
embed.addField("Views", String.format("%,d", metaData.get("views", Number.class).longValue()), true);
embed.addField("Likes/Dislikes", String.format("%,d \\\uD83D\uDC4D\n%,d \\\uD83D\uDC4E", likes, dislikes), true);
embed.addField("Rating", NumberUtility.DEFAULT_DECIMAL_FORMAT.format(ratingPercent) + "%", true);
embed.setFooter("Views and Ratings last updated");
embed.setTimestamp(Instant.ofEpochSecond(data.get("lastUpdated", Number.class).longValue()));
message.editMessageEmbeds(embed.build()).queue();
});
});
return;
} else {
embed.addField("Uploaded By", "[" + snippet.getString("channelTitle") + "](https://www.youtube.com/channel/" + snippet.getString("channelId") + ")", true);
embed.addField("Uploaded At", uploadedAt.format(this.formatter), true);
}
event.reply(embed.build()).queue();
});
paged.execute(event);
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class AutoRoleCommand method fix.
@Command(value = "fix", description = "Will give missing members the auto role if needed")
@CommandId(458)
@Examples({ "auto role fix @Role", "auto role fix Role", "auto role fix 406240455622262784" })
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
@BotPermissions(permissions = { Permission.MANAGE_ROLES })
public void fix(Sx4CommandEvent event, @Argument(value = "role", endless = true) Role role) {
Document data = event.getMongo().getAutoRole(Filters.eq("roleId", role.getIdLong()), Projections.include("filters"));
if (data == null) {
event.replyFailure("That role is not an auto role").queue();
return;
}
if (!event.getSelfMember().canInteract(role)) {
event.replyFailure("That auto role is above my top role").queue();
return;
}
List<Document> filters = data.getList("filters", Document.class, Collections.emptyList());
List<Member> members = event.getGuild().getMemberCache().applyStream(stream -> stream.filter(member -> AutoRoleUtility.filtersMatch(member, filters) && !member.getRoles().contains(role) && !member.isPending()).collect(Collectors.toList()));
if (members.size() == 0) {
event.replyFailure("No users currently need that auto role").queue();
return;
}
if (!this.pending.add(event.getGuild().getIdLong())) {
event.replyFailure("You already have an auto role fix in progress").queue();
return;
}
event.replyFormat("Adding %s to **%,d** user%s, another message will be sent once this is done %s", role.getAsMention(), members.size(), members.size() == 1 ? "" : "s", event.getConfig().getSuccessEmote()).queue();
List<CompletableFuture<Integer>> futures = new ArrayList<>();
for (Member member : members) {
futures.add(event.getGuild().addRoleToMember(member, role).submit().handle((result, exception) -> exception == null ? 1 : 0));
}
FutureUtility.allOf(futures).whenComplete((completed, exception) -> {
this.pending.remove(event.getGuild().getIdLong());
int count = completed.stream().reduce(0, Integer::sum);
event.replyFormat("Successfully added the role %s to **%,d/%,d** user%s %s", role.getAsMention(), count, members.size(), count == 1 ? "" : "s", event.getConfig().getSuccessEmote()).queue();
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class LoggerCommand method toggle.
@Command(value = "toggle", aliases = { "enable", "disable" }, description = "Toggles the state of a logger")
@CommandId(56)
@AuthorPermissions(permissions = { Permission.MANAGE_SERVER })
@Examples({ "logger toggle #logs", "logger toggle" })
public void toggle(Sx4CommandEvent event, @Argument(value = "channel", endless = true, nullDefault = true) TextChannel channel) {
TextChannel effectiveChannel = channel == null ? event.getTextChannel() : channel;
List<Bson> guildPipeline = List.of(Aggregates.project(Projections.fields(Projections.computed("premium", Operators.lt(Operators.nowEpochSecond(), Operators.ifNull("$premium.endAt", 0L))), Projections.computed("guildId", "$_id"))), Aggregates.match(Filters.eq("guildId", event.getGuild().getIdLong())));
List<Bson> pipeline = List.of(Aggregates.match(Filters.and(Filters.eq("guildId", event.getGuild().getIdLong()), Filters.exists("enabled", false))), Aggregates.project(Projections.include("channelId")), Aggregates.group(null, Accumulators.push("loggers", Operators.ROOT)), Aggregates.unionWith("guilds", guildPipeline), Aggregates.group(null, Accumulators.max("loggers", "$loggers"), Accumulators.max("premium", "$premium")), Aggregates.project(Projections.fields(Projections.computed("premium", Operators.ifNull("$premium", false)), Projections.computed("count", Operators.size(Operators.ifNull("$loggers", Collections.EMPTY_LIST))), Projections.computed("disabled", Operators.isEmpty(Operators.filter(Operators.ifNull("$loggers", Collections.EMPTY_LIST), Operators.eq("$$this.channelId", effectiveChannel.getIdLong())))))));
event.getMongo().aggregateLoggers(pipeline).thenCompose(documents -> {
Document data = documents.isEmpty() ? null : documents.get(0);
boolean disabled = data == null || data.getBoolean("disabled");
int count = data == null ? 0 : data.getInteger("count");
if (data != null && disabled && count >= 3 && !data.getBoolean("premium")) {
throw new IllegalArgumentException("You need to have Sx4 premium to have more than 3 enabled loggers, you can get premium at <https://www.patreon.com/Sx4>");
}
if (count >= 25) {
throw new IllegalArgumentException("You can not have any more than 25 enabled loggers");
}
List<Bson> update = List.of(Operators.set("enabled", Operators.cond(Operators.exists("$enabled"), Operators.REMOVE, false)));
FindOneAndUpdateOptions options = new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER).projection(Projections.include("enabled"));
return event.getMongo().findAndUpdateLogger(Filters.eq("channelId", effectiveChannel.getIdLong()), update, options);
}).whenComplete((data, exception) -> {
Throwable cause = exception instanceof CompletionException ? exception.getCause() : exception;
if (cause instanceof IllegalArgumentException) {
event.replyFailure(cause.getMessage()).queue();
return;
}
if (ExceptionUtility.sendExceptionally(event, exception)) {
return;
}
if (data == null) {
event.replyFailure("There is not a logger in that channel").queue();
return;
}
event.replySuccess("The logger in " + effectiveChannel.getAsMention() + " is now **" + (data.get("enabled", true) ? "enabled" : "disabled") + "**").queue();
});
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class MoveCommand method onCommand.
public void onCommand(Sx4CommandEvent event, @Argument(value = "user", nullDefault = true) Member member, @Argument(value = "voice channel", nullDefault = true) VoiceChannel channel) {
if (member == null && channel == null) {
event.replyFailure("Either a user or voice channel needs to be provided").queue();
return;
}
Member effectiveMember = member == null ? event.getMember() : member;
VoiceChannel memberChannel = effectiveMember.getVoiceState().getChannel();
if (memberChannel == null) {
event.replyFailure("That user is not in a voice channel").queue();
return;
}
VoiceChannel effectiveChannel = channel == null ? event.getMember().getVoiceState().getChannel() : channel;
if (effectiveChannel == null) {
event.replyFailure("You are not in a voice channel").queue();
return;
}
if (memberChannel.getIdLong() == effectiveChannel.getIdLong()) {
event.replyFailure("You cannot move a user to the channel they are already connected to").queue();
return;
}
if (!PermissionUtility.canConnect(event.getSelfMember(), effectiveChannel)) {
event.replyFailure("I cannot move people to that voice channel").queue();
return;
}
if (!PermissionUtility.canConnect(event.getMember(), effectiveChannel)) {
event.replyFailure("You cannot move people to that voice channel").queue();
return;
}
event.getGuild().moveVoiceMember(effectiveMember, effectiveChannel).flatMap($ -> event.replySuccess("Moved **" + effectiveMember.getUser().getAsTag() + "** to `" + effectiveChannel.getName() + "`")).queue();
}
use of com.jockie.bot.core.argument.Argument in project Sx4 by sx4-discord-bot.
the class RegionCommand method onCommand.
public void onCommand(Sx4CommandEvent event, @Argument(value = "channel", nullDefault = true) VoiceChannel channel, @Argument(value = "region", endless = true) Region region) {
if (!Region.VOICE_CHANNEL_REGIONS.contains(region)) {
event.replyFailure("That region is not supported for voice channels").queue();
return;
}
VoiceChannel effectiveChannel = channel == null ? event.getMember().getVoiceState().getChannel() : channel;
if (effectiveChannel == null) {
event.replyFailure("You are not in a voice channel").queue();
return;
}
if (!event.getSelfMember().hasPermission(effectiveChannel, Permission.MANAGE_CHANNEL)) {
event.replyFailure("I do not have permission to edit the region of " + effectiveChannel.getAsMention()).queue();
return;
}
if (!event.getMember().hasPermission(effectiveChannel, Permission.MANAGE_CHANNEL)) {
event.replyFailure("You do not have permission to edit the region of " + effectiveChannel.getAsMention()).queue();
return;
}
if (region == effectiveChannel.getRegion()) {
event.replyFailure("The region is already set to that").queue();
return;
}
effectiveChannel.getManager().setRegion(region).flatMap($ -> event.replySuccess("Successfully changed the voice region to **" + (region == Region.AUTOMATIC ? "Automatic" : region.getName() + " " + region.getEmoji()) + "** for " + effectiveChannel.getAsMention())).queue();
}
Aggregations