mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-03 16:34:09 +00:00
added module responsible for accumulating the dependencies and resulting in a jar
added channels module added help info object to command configuration added description field to parameter added modules for commands (and packed modules), they are mapped by name added post command execution interface added support for optional parameters added support for using guildchannel as parameter added printing of modules to help command added service beans to wrap over the operations on the repository added synchronizing of channels/roles on startup (controlled by flag) added builder annotations to model classes added more model classes
This commit is contained in:
@@ -1,29 +0,0 @@
|
||||
package dev.sheldan.abstracto;
|
||||
|
||||
import dev.sheldan.abstracto.service.StartupManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = "dev.sheldan.abstracto")
|
||||
@EnableCaching
|
||||
public class Application implements CommandLineRunner {
|
||||
|
||||
@Autowired
|
||||
private StartupManager startup;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
startup.startBot();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package dev.sheldan.abstracto;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.SnowFlake;
|
||||
import net.dv8tion.jda.api.entities.ISnowflake;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SnowflakeUtils {
|
||||
public static Set<Long> getOwnItemsIds(List<? extends SnowFlake> elements){
|
||||
return elements.stream().map(SnowFlake::getId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static Set<Long> getSnowflakeIds(List<? extends ISnowflake> elements){
|
||||
return elements.stream().map(ISnowflake::getIdLong).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package dev.sheldan.abstracto.service;
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.AChannelType;
|
||||
import dev.sheldan.abstracto.repository.ChannelRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ChannelServiceBean implements ChannelService {
|
||||
|
||||
@Autowired
|
||||
private ChannelRepository repository;
|
||||
|
||||
@Override
|
||||
public AChannel loadChannel(Long id) {
|
||||
return repository.getOne(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AChannel createChannel(Long id, AChannelType type) {
|
||||
return repository.save(AChannel.builder().id(id).type(type).build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.commands.management.PostTargetException;
|
||||
import dev.sheldan.abstracto.core.models.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.PostTarget;
|
||||
import dev.sheldan.abstracto.repository.ChannelRepository;
|
||||
import dev.sheldan.abstracto.repository.PostTargetRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
@Service
|
||||
public class PostTargetServiceServiceBean implements PostTargetService {
|
||||
@Autowired
|
||||
private PostTargetRepository postTargetRepository;
|
||||
|
||||
@Autowired
|
||||
private ChannelRepository channelRepository;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void createPostTarget(String name, AChannel targetChannel) {
|
||||
if(!PostTarget.AVAILABLE_POST_TARGETS.contains(name)) {
|
||||
throw new PostTargetException("PostTarget not found");
|
||||
}
|
||||
postTargetRepository.save(PostTarget.builder().name(name).AChannel(targetChannel).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void createOrUpdate(String name, AChannel targetChannel) {
|
||||
PostTarget existing = postTargetRepository.findPostTargetByName(name);
|
||||
if(existing == null){
|
||||
this.createPostTarget(name, targetChannel);
|
||||
} else {
|
||||
this.updatePostTarget(existing, targetChannel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void updatePostTarget(PostTarget target, AChannel newTargetChannel) {
|
||||
postTargetRepository.getOne(target.getId()).setAChannel(newTargetChannel);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ARole;
|
||||
import dev.sheldan.abstracto.repository.RoleRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class RoleServiceBean implements RoleService {
|
||||
|
||||
@Autowired
|
||||
private RoleRepository repository;
|
||||
|
||||
@Override
|
||||
public ARole createRole(Long id) {
|
||||
return repository.save(ARole.builder().id(id).build());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.AServer;
|
||||
import dev.sheldan.abstracto.repository.ServerRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
@Service
|
||||
public class ServerServiceBean implements ServerService {
|
||||
|
||||
@Autowired
|
||||
private ServerRepository repository;
|
||||
|
||||
@Override
|
||||
public AServer createServer(Long id) {
|
||||
return repository.save(AServer.builder().id(id).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChannelToServer(AServer server, AChannel channel) {
|
||||
server.getChannels().add(channel);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package dev.sheldan.abstracto.core.service;
|
||||
|
||||
import dev.sheldan.abstracto.SnowflakeUtils;
|
||||
import dev.sheldan.abstracto.core.models.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.AChannelType;
|
||||
import dev.sheldan.abstracto.core.models.ARole;
|
||||
import dev.sheldan.abstracto.core.models.AServer;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.GuildChannel;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.apache.commons.collections4.SetUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Service
|
||||
public class StartupManager implements Startup {
|
||||
|
||||
@Autowired
|
||||
private BotService service;
|
||||
|
||||
@Autowired
|
||||
private List<? extends ListenerAdapter> listeners;
|
||||
|
||||
@Autowired
|
||||
private ServerService serverService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private RoleService roleService;
|
||||
|
||||
|
||||
@Override
|
||||
public void startBot() throws LoginException {
|
||||
service.login();
|
||||
listeners.forEach(o -> service.getInstance().addEventListener(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void synchronize() {
|
||||
synchronizeServers();
|
||||
}
|
||||
|
||||
private void synchronizeServers(){
|
||||
JDA instance = service.getInstance();
|
||||
List<Guild> onlineGuilds = instance.getGuilds();
|
||||
Set<Long> availableServers = SnowflakeUtils.getSnowflakeIds(onlineGuilds);
|
||||
availableServers.forEach(aLong -> {
|
||||
AServer newAServer = serverService.createServer(aLong);
|
||||
Guild newGuild = instance.getGuildById(aLong);
|
||||
if(newGuild != null){
|
||||
synchronizeRolesOf(newGuild, newAServer);
|
||||
synchronizeChannelsOf(newGuild, newAServer);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void synchronizeRolesOf(Guild guild, AServer existingAServer){
|
||||
List<Role> existingRoles = guild.getRoles();
|
||||
List<ARole> knownARoles = existingAServer.getRoles();
|
||||
Set<Long> knownRolesId = SnowflakeUtils.getOwnItemsIds(knownARoles);
|
||||
Set<Long> availableRoles = SnowflakeUtils.getSnowflakeIds(existingRoles);
|
||||
Set<Long> newRoles = SetUtils.disjunction(availableRoles, knownRolesId);
|
||||
newRoles.forEach(aLong -> {
|
||||
ARole newRole = roleService.createRole(aLong);
|
||||
existingAServer.getRoles().add(newRole);
|
||||
});
|
||||
}
|
||||
|
||||
private void synchronizeChannelsOf(Guild guild, AServer existingServer){
|
||||
List<GuildChannel> available = guild.getChannels();
|
||||
List<AChannel> knownChannels = existingServer.getChannels();
|
||||
Set<Long> knownChannelsIds = SnowflakeUtils.getOwnItemsIds(knownChannels);
|
||||
Set<Long> existingChannelsIds = SnowflakeUtils.getSnowflakeIds(available);
|
||||
Set<Long> newChannels = SetUtils.disjunction(existingChannelsIds, knownChannelsIds);
|
||||
newChannels.forEach(aLong -> {
|
||||
GuildChannel channel1 = available.stream().filter(channel -> channel.getIdLong() == aLong).findFirst().get();
|
||||
AChannelType type = AChannel.getAChannelType(channel1.getType());
|
||||
AChannel newChannel = channelService.createChannel(channel1.getIdLong(), type);
|
||||
serverService.addChannelToServer(existingServer, newChannel);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package dev.sheldan.abstracto.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.AServer;
|
||||
import dev.sheldan.abstracto.repository.ServerRepository;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
import net.dv8tion.jda.api.events.channel.text.TextChannelCreateEvent;
|
||||
import net.dv8tion.jda.api.events.channel.text.TextChannelDeleteEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class ChannelListener extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private ServerRepository serverRepository;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(ChannelListener.class);
|
||||
|
||||
@Override
|
||||
public void onTextChannelDelete(@Nonnull TextChannelDeleteEvent event) {
|
||||
AServer serverObject = serverRepository.getOne(event.getGuild().getIdLong());
|
||||
serverObject.getChannels().add(AChannel.builder().id(event.getChannel().getIdLong()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChannelCreate(@Nonnull TextChannelCreateEvent event) {
|
||||
AServer serverObject = serverRepository.getOne(event.getGuild().getIdLong());
|
||||
TextChannel createdChannel = event.getChannel();
|
||||
Optional<AChannel> possibleChannel = serverObject.getChannels().stream().filter(aChannel -> aChannel.id == createdChannel.getIdLong()).findAny();
|
||||
if(possibleChannel.isPresent()){
|
||||
serverObject.getChannels().remove(possibleChannel.get());
|
||||
logger.info("Adding channel {} with id {}", createdChannel.getName(), createdChannel.getIdLong());
|
||||
} else {
|
||||
logger.warn("Channel removed event for channel which was not in present");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package dev.sheldan.abstracto.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.service.StartupManager;
|
||||
import net.dv8tion.jda.api.events.ReadyEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
@Service
|
||||
public class ReadyListener extends ListenerAdapter {
|
||||
|
||||
@Autowired
|
||||
private StartupManager startup;
|
||||
|
||||
@Value("${abstracto.startup.synchronize}")
|
||||
private boolean synchronize;
|
||||
|
||||
@Override
|
||||
public void onReady(@Nonnull ReadyEvent event) {
|
||||
if(synchronize){
|
||||
startup.synchronize();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
package dev.sheldan.abstracto.models;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.Table;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
@Table
|
||||
@Builder
|
||||
public class Channel {
|
||||
|
||||
@Id
|
||||
@Getter
|
||||
public Long id;
|
||||
|
||||
@Getter
|
||||
@ManyToMany(mappedBy = "channels")
|
||||
private Set<ChannelGroup> groups;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package dev.sheldan.abstracto.models;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Set;
|
||||
|
||||
@Entity
|
||||
@Table
|
||||
public class ChannelGroup {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Getter
|
||||
private Long id;
|
||||
|
||||
@Column
|
||||
@Getter @Setter
|
||||
private String groupName;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "channel_in_group",
|
||||
joinColumns = @JoinColumn(name = "group_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "channel_id"))
|
||||
@Getter
|
||||
private Set<Channel> channels;
|
||||
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package dev.sheldan.abstracto.models;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
|
||||
import javax.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table
|
||||
public class PostTarget {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Getter
|
||||
private Long id;
|
||||
|
||||
@Column(unique = true)
|
||||
@Getter
|
||||
private String name;
|
||||
|
||||
@OneToOne(fetch = FetchType.LAZY, optional = false)
|
||||
@JoinColumn(name = "id", nullable = false)
|
||||
@Getter
|
||||
private Channel channel;
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package dev.sheldan.abstracto.models;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table
|
||||
public class Role {
|
||||
|
||||
@Id
|
||||
@Getter
|
||||
private Long id;
|
||||
|
||||
@Column(unique = true)
|
||||
@Getter @Setter
|
||||
private String name;
|
||||
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
package dev.sheldan.abstracto.repository;
|
||||
|
||||
import dev.sheldan.abstracto.models.Channel;
|
||||
import dev.sheldan.abstracto.core.models.AChannel;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ChannelRepository extends JpaRepository<Channel, Long> {
|
||||
public interface ChannelRepository extends JpaRepository<AChannel, Long> {
|
||||
List<AChannel> findAll();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.PostTarget;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PostTargetRepository extends JpaRepository<PostTarget, Long> {
|
||||
|
||||
PostTarget findPostTargetByName(String name);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package dev.sheldan.abstracto.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ARole;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface RoleRepository extends JpaRepository<ARole, Long> {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package dev.sheldan.abstracto.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.AServer;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface ServerRepository extends JpaRepository<AServer, Long> {
|
||||
List<AServer> findAll();
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package dev.sheldan.abstracto.service;
|
||||
|
||||
import dev.sheldan.abstracto.commands.management.CommandReceivedHandler;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class StartupManager implements Startup {
|
||||
|
||||
@Autowired
|
||||
private BotService service;
|
||||
|
||||
@Autowired
|
||||
private List<? extends ListenerAdapter> listeners;
|
||||
|
||||
@Override
|
||||
public void startBot() throws LoginException {
|
||||
service.login();
|
||||
listeners.forEach(o -> service.getInstance().addEventListener(o));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
spring.datasource.url=jdbc:postgresql://localhost:5432/abstracto
|
||||
spring.datasource.username= abstracto
|
||||
spring.datasource.password= abstracto
|
||||
|
||||
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
|
||||
spring.jpa.hibernate.ddl-auto = update
|
||||
Reference in New Issue
Block a user