Skip to content

Commit

Permalink
Merge #876 into 3.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
quanticc committed Mar 28, 2021
2 parents b683809 + b25064e commit b469e45
Show file tree
Hide file tree
Showing 12 changed files with 759 additions and 4 deletions.
14 changes: 14 additions & 0 deletions core/src/main/java/discord4j/core/GatewayDiscordClient.java
Expand Up @@ -28,6 +28,7 @@
import discord4j.core.event.domain.Event;
import discord4j.core.object.Invite;
import discord4j.core.object.Region;
import discord4j.core.object.GuildTemplate;
import discord4j.core.object.entity.*;
import discord4j.core.object.entity.channel.Channel;
import discord4j.core.object.entity.channel.GuildChannel;
Expand Down Expand Up @@ -270,6 +271,19 @@ public Flux<Region> getRegions() {
.map(data -> new Region(this, data));
}

/**
* Requests to retrieve the template represented by the supplied code.
*
* @param templateCode The code of the template.
* @return A {@link Mono} where, upon successful completion, emits the {@link GuildTemplate} as represented by the
* supplied code. If an error is received, it is emitted through the {@code Mono}.
*/
public Mono<GuildTemplate> getTemplateByCode(String templateCode) {
return getRestClient().getTemplateService()
.getTemplate(templateCode)
.map(data -> new GuildTemplate(this, data));
}

/**
* Gets the bot user's ID.
*
Expand Down
226 changes: 226 additions & 0 deletions core/src/main/java/discord4j/core/object/GuildTemplate.java
@@ -0,0 +1,226 @@
/*
* This file is part of Discord4J.
*
* Discord4J is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Discord4J is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Discord4J. If not, see <http://www.gnu.org/licenses/>.
*/
package discord4j.core.object;

import discord4j.common.util.Snowflake;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.entity.Guild;
import discord4j.core.object.entity.User;
import discord4j.core.spec.GuildTemplateEditSpec;
import discord4j.core.spec.GuildCreateFromTemplateSpec;
import discord4j.discordjson.json.SerializedSourceGuildData;
import discord4j.discordjson.json.TemplateData;
import reactor.core.publisher.Mono;

import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;

/**
* A Discord Guild Template.
*
* @see <a href="https://discord.com/developers/docs/resources/template">Template Resource</a>
*/
public final class GuildTemplate implements DiscordObject {

/** The gateway associated to this object. */
private final GatewayDiscordClient gateway;

/** The raw data as represented by Discord. */
private final TemplateData data;

/** The ID of the guild this template is associated to. */
private final long guildId;

/**
* Constructs a {@code GuildTemplate} with an associated {@link GatewayDiscordClient} and Discord data.
*
* @param gateway The {@link GatewayDiscordClient} associated to this object, must be non-null.
* @param data The raw data as represented by Discord, must be non-null.
*/
public GuildTemplate(final GatewayDiscordClient gateway, final TemplateData data) {
this.gateway = Objects.requireNonNull(gateway);
this.data = Objects.requireNonNull(data);
this.guildId = Snowflake.asLong(data.sourceGuildId());
}

@Override
public GatewayDiscordClient getClient() {
return this.gateway;
}

/**
* Gets the data of the template.
*
* @return The data of the template.
*/
public TemplateData getData() {
return data;
}

/**
* Gets the template code (unique ID).
*
* @return The template code (unique ID).
*/
public String getCode() {
return data.code();
}

/**
* Gets the ID of the guild this template is associated with.
*
* @return The source guild ID.
*/
public Snowflake getGuildId() {
return Snowflake.of(guildId);
}

/**
* Gets the name of the template.
*
* @return The template name.
*/
public String getName() {
return data.name();
}

/**
* Gets the description of the template, if present.
*
* @return The template description.
*/
public Optional<String> getDescription() {
return data.description();
}

/**
* Gets the number of times the template has been used.
*
* @return The number of times the template has been used.
*/
public int getUsageCount() {
return data.usageCount();
}

/**
* Gets the ID of the user who created the template.
*
* @return The ID of the user who created the template.
*/
public Snowflake getCreatorId() {
return Snowflake.of(data.creatorId());
}

/**
* Gets the user who created the template.
*
* @return The user who created the template.
*/
public User getCreator() {
return new User(gateway, data.creator());
}

/**
* Gets when the template was created.
*
* @return When the template was created.
*/
public Instant getCreatedAt() {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(data.createdAt(), Instant::from);
}

/**
* Gets when the template was last updated.
*
* @return When the template was last updated.
*/
public Instant getUpdatedAt() {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(data.updatedAt(), Instant::from);
}

/**
* Gets the guild snapshot of the template.
*
* @return The guild snapshot.
*/
public SerializedSourceGuildData getSourceGuild() {
return data.serializedSourceGuild();
}

/**
* Requests to create a new guild from this template.
*
* @param spec A {@link Consumer} that provides a "blank" {@link GuildTemplateEditSpec} to be operated on.
* @return A {@link Mono} where, upon successful completion, emits the {@link Guild created guild}. If an error is
* received, it is emitted through the {@code Mono}.
*/
public Mono<Guild> createGuild(final Consumer<? super GuildCreateFromTemplateSpec> spec) {
return Mono.defer(
() -> {
GuildCreateFromTemplateSpec mutatedSpec = new GuildCreateFromTemplateSpec();
spec.accept(mutatedSpec);
return gateway.getRestClient().getTemplateService()
.createGuild(getCode(), mutatedSpec.asRequest());
})
.map(data -> new Guild(gateway, data));
}

/**
* Requests to sync this template with the guild's current state.
*
* @return a {@link Mono} that, upon subscription, syncs a template with its guild. If an error is received, it
* will be emitted through the Mono.
*/
public Mono<GuildTemplate> sync() {
return gateway.getRestClient().getTemplateService()
.syncTemplate(guildId, getCode())
.map(data -> new GuildTemplate(gateway, data));
}

/**
* Requests to edit this guild template.
*
* @param spec A {@link Consumer} that provides a "blank" {@link GuildTemplateEditSpec} to be operated on.
* @return A {@link Mono} where, upon successful completion, emits the edited {@link GuildTemplate}. If an error is
* received, it is emitted through the {@code Mono}.
*/
public Mono<GuildTemplate> edit(final Consumer<? super GuildTemplateEditSpec> spec) {
return Mono.defer(
() -> {
GuildTemplateEditSpec mutatedSpec = new GuildTemplateEditSpec();
spec.accept(mutatedSpec);
return gateway.getRestClient().getTemplateService()
.modifyTemplate(guildId, getCode(), mutatedSpec.asRequest());
})
.map(data -> new GuildTemplate(gateway, data));
}

/**
* Requests to delete this template.
*
* @return A {@link Mono} where, upon successful completion, emits the deleted template. If an error is received,
* it is emitted through the {@code Mono}.
*/
public Mono<GuildTemplate> delete() {
return gateway.getRestClient().getTemplateService()
.deleteTemplate(guildId, getCode())
.map(data -> new GuildTemplate(gateway, data));
}
}
35 changes: 31 additions & 4 deletions core/src/main/java/discord4j/core/object/entity/Guild.java
Expand Up @@ -19,10 +19,7 @@
import discord4j.common.store.action.read.ReadActions;
import discord4j.common.util.Snowflake;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.Ban;
import discord4j.core.object.ExtendedInvite;
import discord4j.core.object.Region;
import discord4j.core.object.VoiceState;
import discord4j.core.object.*;
import discord4j.core.object.audit.AuditLogEntry;
import discord4j.core.object.entity.channel.*;
import discord4j.core.object.presence.Presence;
Expand Down Expand Up @@ -974,6 +971,24 @@ public Mono<GuildEmoji> createEmoji(final Consumer<? super GuildEmojiCreateSpec>
.map(data -> new GuildEmoji(gateway, data, getId().asLong()));
}

/**
* Requests to create a template based on this guild.
*
* @param spec A {@link Consumer} that provides a "blank" {@link GuildTemplateCreateSpec} to be operated on.
* @return A {@link Mono} where, upon subscription, emits the created {@link GuildTemplate} on success. If an error
* is received, it is emitted through the {@code Mono}.
*/
public Mono<GuildTemplate> createTemplate(final Consumer<? super GuildTemplateCreateSpec> spec) {
return Mono.defer(
() -> {
GuildTemplateCreateSpec mutatedSpec = new GuildTemplateCreateSpec();
spec.accept(mutatedSpec);
return gateway.getRestClient().getTemplateService()
.createTemplate(getId().asLong(), mutatedSpec.asRequest());
})
.map(data -> new GuildTemplate(gateway, data));
}

/**
* Requests to create a role.
*
Expand Down Expand Up @@ -1332,6 +1347,18 @@ public Flux<ExtendedInvite> getInvites() {
.map(data -> new ExtendedInvite(gateway, data));
}

/**
* Requests to retrieve the templates of the guild.
*
* @return A {@link Flux} that continually emits the {@link GuildTemplate templates} of the guild. If an error is
* received, it is emitted through the {@code Flux}.
*/
public Flux<GuildTemplate> getTemplates() {
return gateway.getRestClient().getTemplateService()
.getTemplates(getId().asLong())
.map(data -> new GuildTemplate(gateway, data));
}

/**
* Requests to change the bot user's nickname in this guild.
*
Expand Down
@@ -0,0 +1,62 @@
/*
* This file is part of Discord4J.
*
* Discord4J is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Discord4J is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Discord4J. If not, see <http://www.gnu.org/licenses/>.
*/
package discord4j.core.spec;

import discord4j.discordjson.json.TemplateCreateGuildRequest;
import discord4j.discordjson.possible.Possible;
import discord4j.rest.util.Image;

/**
* Spec used to create a guild from a template.
*
* @see discord4j.core.object.GuildTemplate#createGuild(java.util.function.Consumer)
*/
public class GuildCreateFromTemplateSpec implements Spec<TemplateCreateGuildRequest> {

private String name = null;
private Possible<String> icon = Possible.absent();

/**
* Sets the name for the created guild.
*
* @param name The name of the guild.
* @return This spec.
*/
public GuildCreateFromTemplateSpec setName(String name) {
this.name = name;
return this;
}

/**
* Sets the icon for the created guild.
*
* @param icon The icon of the guild.
* @return This spec.
*/
public GuildCreateFromTemplateSpec setIcon(Image icon) {
this.icon = Possible.of(icon.getDataUri());
return this;
}

@Override
public TemplateCreateGuildRequest asRequest() {
return TemplateCreateGuildRequest.builder()
.name(name)
.icon(icon)
.build();
}
}

0 comments on commit b469e45

Please sign in to comment.