diff --git a/.gitignore b/.gitignore
index 0d44024..0955990 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,6 @@
/nbactions.xml
.bin
/bin/
+/key.bin
+/logs/
+/conf/
diff --git a/pom.xml b/pom.xml
index 6e99497..45168e0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -148,7 +148,7 @@
net.locusworks
crypto
- 1.0.3-RELEASE
+ 1.0.5-RELEASE
diff --git a/src/main/java/net/locusworks/discord/eighttrack/database/config/EightTrackBeanConfiguration.java b/src/main/java/net/locusworks/discord/eighttrack/database/config/EightTrackBeanConfiguration.java
new file mode 100644
index 0000000..9366796
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/database/config/EightTrackBeanConfiguration.java
@@ -0,0 +1,156 @@
+/**
+ *
+ * Project: Eight Track, File: EightTrackBeanConfiguration.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.database.config;
+
+import java.util.HashSet;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.flywaydb.core.Flyway;
+import org.flywaydb.core.api.configuration.FluentConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.JpaVendorAdapter;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.orm.jpa.vendor.Database;
+import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+@Configuration(value="net.locusworks.discord.eighttrack.database.config.EightTrackBeanConfiguration")
+@EnableTransactionManagement
+@EnableJpaRepositories(
+ basePackages = {"net.locusworks.discord.eighttrack.database.repos"},
+ entityManagerFactoryRef = "eighttrackEntityManagerFactory",
+ transactionManagerRef = "eighttrackTransactionManager"
+ )
+public class EightTrackBeanConfiguration {
+ public static final String PERSISTENCE_UNIT = "eighttrack_pu";
+
+ public static final HashSet cacheNames = new HashSet<>();
+
+ private static final String[] PACKAGES_TO_SCAN = {
+ "net.locusworks.discord.eighttrack.database.entities"
+ };
+
+ private static final Properties hibernateProperties;
+ static {
+ hibernateProperties = new Properties();
+ hibernateProperties.setProperty("hibernate.connection.zeroDateTimeBehavior", "convertToNull");
+ hibernateProperties.setProperty("hibernate.dbcp.maxActive", "50");
+ hibernateProperties.setProperty("hibernate.dbcp.maxIdle", "10");
+ hibernateProperties.setProperty("hibernate.dbcp.maxWait", "5000");
+ hibernateProperties.setProperty("hibernate.jdbc.batch_size property", "50");
+ hibernateProperties.setProperty("hibernate.connection.charSet", "utf8");
+ hibernateProperties.setProperty("hibernate.connection.characterEncoding", "utf8");
+ hibernateProperties.setProperty("hibernate.connection.useUnicode", "true");
+ hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
+ }
+
+ @Autowired
+ private DataSource dataSource;
+
+ @Autowired
+ private DataSource flywayDataSource;
+
+ /**
+ * Create the entity manager factory bean used in the database connection
+ * @return entityManagerFactoryBean
+ */
+ @Primary
+ @Bean
+ @DependsOn("flyway")
+ public LocalContainerEntityManagerFactoryBean eighttrackEntityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
+ lef.setDataSource(dataSource);
+ lef.setJpaVendorAdapter(eighttrackJpaVendorAdapter());
+ lef.setPackagesToScan(PACKAGES_TO_SCAN);
+ lef.setJpaProperties(hibernateProperties);
+ lef.setPersistenceUnitName(PERSISTENCE_UNIT);
+ return lef;
+ }
+
+ /**
+ * Create the session factory bean
+ * @return sessionFactoryBean
+ */
+ @Bean
+ public LocalSessionFactoryBean pseduobotSessionFactory() {
+ LocalSessionFactoryBean sessionBean = new LocalSessionFactoryBean();
+ sessionBean.setDataSource(dataSource);
+ sessionBean.setPackagesToScan(PACKAGES_TO_SCAN);
+ sessionBean.setHibernateProperties(hibernateProperties);
+ return sessionBean;
+ }
+
+ /**
+ * Create the JPA Vendor adaptor bean that is used in the entity manager factory
+ * @return jpaVendorAdaptor
+ */
+ @Primary
+ @Bean
+ public JpaVendorAdapter eighttrackJpaVendorAdapter() {
+ HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
+ hibernateJpaVendorAdapter.setShowSql(false);
+ hibernateJpaVendorAdapter.setGenerateDdl(false);
+ hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
+ return hibernateJpaVendorAdapter;
+ }
+
+ /**
+ * Create the transaction manager bean
+ * @return transactionManager
+ */
+ @Primary
+ @Bean
+ public PlatformTransactionManager eighttrackTransactionManager() {
+ JpaTransactionManager manager = new JpaTransactionManager();
+ manager.setEntityManagerFactory(eighttrackEntityManagerFactory().getObject());
+ return new JpaTransactionManager();
+ }
+
+ @Bean(name="flyway", initMethod="migrate")
+ public Flyway flyway() {
+ FluentConfiguration fc = Flyway.configure();
+ fc.schemas("eighttrack");
+ fc.table("_flyway_migration");
+ fc.locations("database/migration");
+ fc.outOfOrder(false);
+ fc.dataSource(flywayDataSource);
+
+ return fc.load();
+ }
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/database/config/EightTrackDataSource.java b/src/main/java/net/locusworks/discord/eighttrack/database/config/EightTrackDataSource.java
new file mode 100644
index 0000000..db14060
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/database/config/EightTrackDataSource.java
@@ -0,0 +1,162 @@
+/**
+ *
+ * Project: Eight Track, File: EightTrackDataSource.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.database.config;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
+import java.util.stream.Collectors;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp2.ConnectionFactory;
+import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp2.PoolableConnection;
+import org.apache.commons.dbcp2.PoolableConnectionFactory;
+import org.apache.commons.dbcp2.PoolingDataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.pool2.impl.AbandonedConfig;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.mariadb.jdbc.MariaDbDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import net.locusworks.discord.eighttrack.services.ConfigurationService;
+
+@Primary
+@Component
+public class EightTrackDataSource {
+
+ private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
+
+ private static final String JNDI_STRING = "jdbc:mysql://%s:%d%s";
+
+ private static Map mysqlProperties;
+ static {
+ mysqlProperties = new LinkedHashMap<>();
+ mysqlProperties.put("rewriteBatchedStatements", "true");
+ mysqlProperties.put("zeroDateTimeBehavior", "CONVERT_TO_NULL");
+ mysqlProperties.put("useSSL", "false");
+ mysqlProperties.put("serverTimezone", TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT));
+ }
+
+ private Logger logger = LoggerFactory.getLogger(EightTrackDataSource.class);
+
+ @Autowired
+ private ConfigurationService confService;
+
+ /**
+ * Create the data source bean
+ * @return the data source bean
+ * @throws Exception
+ */
+ @Bean
+ public DataSource dataSource() throws Exception {
+ return getDataSource(false);
+ }
+
+ @Bean
+ public DataSource flywayDataSource() throws Exception {
+ logger.debug("Logging in with flyway for migrations");
+
+ String user = confService.getDatabaseRootUsername();
+ String passwd = confService.getDatabaseRootPassword();
+
+ String url = String.format("jdbc:mariadb://%s:%d?user=%s&password=%s",
+ confService.getDatabaseHost(), confService.getDatabasePort(),
+ user, passwd);
+
+ MariaDbDataSource mariadbDS = new MariaDbDataSource(url);
+
+ return mariadbDS;
+ }
+
+ private DataSource getDataSource(Boolean isFlyway) throws Exception {
+ logger.debug("Gettind datasource");
+ Class.forName(DRIVER).getDeclaredConstructor().newInstance();
+
+ String user = confService.getDatabaseUsername();
+ String passwd = confService.getDatabasePassword();
+
+ Properties props = new Properties();
+ props.setProperty("user", user);
+ props.setProperty("password", passwd);
+
+ List params = mysqlProperties
+ .entrySet()
+ .stream()
+ .map(prop -> String.format("%s=%s", prop.getKey(), prop.getValue()))
+ .collect(Collectors.toList());
+
+ String host = confService.getDatabaseHost();
+ int port = confService.getDatabasePort();
+
+ String url = String.format(JNDI_STRING, host, port, "/eighttrack");
+
+ url = String.format("%s?%s", url, StringUtils.join(params, "&"));
+
+ logger.debug("Database connection string: %s", url);
+
+ ConnectionFactory cf = new DriverManagerConnectionFactory(url, props);
+ //Create the poolable connection factory
+ PoolableConnectionFactory pcf = new PoolableConnectionFactory(cf, null);
+ pcf.setValidationQuery("SELECT 1");
+ pcf.setDefaultAutoCommit(true);
+
+ GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig<>();
+ poolConfig.setMinIdle(10);
+ poolConfig.setMaxTotal(100);
+
+ AbandonedConfig abandonConfig = new AbandonedConfig();
+ abandonConfig.setRemoveAbandonedTimeout(60);
+ abandonConfig.setLogAbandoned(false);
+ abandonConfig.setRemoveAbandonedOnBorrow(true);
+ abandonConfig.setRemoveAbandonedOnMaintenance(true);
+
+ //Create the pool of connections
+ GenericObjectPool connectionPool = new GenericObjectPool<>(pcf, poolConfig);
+ connectionPool.setTestOnBorrow(true);
+ connectionPool.setTestWhileIdle(true);
+ connectionPool.setTimeBetweenEvictionRunsMillis(10000);
+ connectionPool.setMinEvictableIdleTimeMillis(1000);
+ connectionPool.setAbandonedConfig(abandonConfig);
+ pcf.setPool(connectionPool);
+
+ //Pooling data source itself
+ PoolingDataSource dataSource = new PoolingDataSource<>(connectionPool);
+ return dataSource;
+ }
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/database/entities/DiscordGuild.java b/src/main/java/net/locusworks/discord/eighttrack/database/entities/DiscordGuild.java
new file mode 100644
index 0000000..1f79f3c
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/database/entities/DiscordGuild.java
@@ -0,0 +1,145 @@
+/**
+ *
+ * Project: Eight Track, File: DiscordGuild.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.locusworks.discord.eighttrack.database.entities;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ *
+ * @author isaac
+ */
+@Entity
+@Table(name = "discord_guild", catalog = "eighttrack", schema = "")
+@NamedQueries({
+ @NamedQuery(name = "DiscordGuild.findAll", query = "SELECT d FROM DiscordGuild d")})
+public class DiscordGuild implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Basic(optional = false)
+ @Column(name = "id")
+ private Long id;
+ @Basic(optional = false)
+ @Column(name = "guild_id")
+ private long guildId;
+ @Basic(optional = false)
+ @Column(name = "guild_name")
+ private String guildName;
+ @Column(name = "date_joined")
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date dateJoined;
+
+ public DiscordGuild() {
+ }
+
+ public DiscordGuild(Long id) {
+ this.id = id;
+ }
+
+ public DiscordGuild(Long id, long guildId, String guildName) {
+ this.id = id;
+ this.guildId = guildId;
+ this.guildName = guildName;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public long getGuildId() {
+ return guildId;
+ }
+
+ public void setGuildId(long guildId) {
+ this.guildId = guildId;
+ }
+
+ public String getGuildName() {
+ return guildName;
+ }
+
+ public void setGuildName(String guildName) {
+ this.guildName = guildName;
+ }
+
+ public Date getDateJoined() {
+ return dateJoined;
+ }
+
+ public void setDateJoined(Date dateJoined) {
+ this.dateJoined = dateJoined;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 0;
+ hash += (id != null ? id.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ // TODO: Warning - this method won't work in the case the id fields are not set
+ if (!(object instanceof DiscordGuild)) {
+ return false;
+ }
+ DiscordGuild other = (DiscordGuild) object;
+ if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "net.locusworks.discord.pseudobot.database.entities.DiscordGuild[ id=" + id + " ]";
+ }
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildRepository.java b/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildRepository.java
new file mode 100644
index 0000000..95e09d8
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/database/repos/GuildRepository.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Project: Eight Track, File: GuildRepository.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.database.repos;
+
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import net.locusworks.discord.eighttrack.database.entities.DiscordGuild;
+
+public interface GuildRepository extends CrudRepository {
+
+ DiscordGuild findByGuildId(Long serverId);
+
+ @Query("SELECT g FROM DiscordGuild g WHERE g.guildId NOT IN ?1")
+ List findGuildsNoLongerJoined(Set serverIds);
+
+ @Query("DELETE FROM DiscordGuild g WHERE g.guildId NOT IN ?1")
+ @Modifying
+ @Transactional
+ void deleteGuildsNoLongerJoined(Set guildIds);
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/enums/Configuration.java b/src/main/java/net/locusworks/discord/eighttrack/enums/Configuration.java
new file mode 100644
index 0000000..de7ec76
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/enums/Configuration.java
@@ -0,0 +1,127 @@
+/**
+ *
+ * Project: Eight Track, File: Configuration.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.enums;
+
+public enum Configuration {
+ DB_ROOT_USER("dbAdmin"),
+ DB_ROOT_PASSWORD("dbAdminPassword"),
+ DB_USER("dbUser"),
+ DB_PASSWORD("dbUserPassword"),
+ DB_HOST("dbHost"),
+ DB_PORT("dbPort"),
+ LOG_LEVEL("logLevel"),
+ MUSIC_DIR("musicDir"),
+ DISCORD_TOKEN("discordToken");
+
+ private String value;
+
+ private Configuration(String value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the current value of the enumeration
+ * @return value
+ */
+ public String getValue() {
+ return this.value;
+ }
+
+ @Override
+ public String toString() {
+ return this.value;
+ }
+
+ /**
+ * Checks to see if the configuration is of a certain value
+ * @param confTypes types to check against
+ * @return true if the current configuration is of a certain enumeration, false otherwise
+ */
+ public boolean is(Configuration... confTypes) {
+ for (Configuration confType : confTypes) {
+ if (this == confType) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks to see if the configuration is not of a certain value
+ * @param confTypes Types to check against
+ * @return true if the current configuration is not of a certain enuermation, false otherwise
+ */
+ public boolean isNot(Configuration... confTypes) {
+ return !is(confTypes);
+ }
+
+ /**
+ * Finds a specific enumeration
+ * @param value Value to find
+ * @return the found enumeration or null if nothing is found
+ */
+ public static Configuration findEnum(String value) {
+ for (Configuration conf: values()) {
+ if (conf.getValue().equalsIgnoreCase(value)) {
+ return conf;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks to see if a specific value is in a set of configuration types
+ * @param value Value to look for
+ * @param confTypes types to compare against
+ * @return true if the string value is in a certain set of configuration enumerations, false otherwise
+ */
+ public static boolean in(String value, Configuration... confTypes) {
+ Configuration ft = findEnum(value);
+ if (ft == null) {
+ return false;
+ }
+
+ for (Configuration confType : confTypes) {
+ if (ft == confType) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks to see if a specific value is not in a set of configuration types
+ * @param value Value to look for
+ * @param confTypes types to compare against
+ * @return true if the string value is not in a certain set of configuration enumerations, false otherwise
+ */
+ public static boolean notIn(String value, Configuration... confTypes) {
+ return !in(value, confTypes);
+ }
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java
similarity index 53%
rename from src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java
rename to src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java
index 1a7113e..c6844e4 100644
--- a/src/main/java/net/locusworks/discord/eighttrack/adaptors/MusicListenerAdaptor.java
+++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/DiscordEventHandler.java
@@ -1,6 +1,6 @@
/**
*
- * Project: Eight Track, File: MusicListenerAdaptor.java
+ * Project: Eight Track, File: DiscordEventHandler.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
@@ -25,66 +25,71 @@
* IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*/
-package net.locusworks.discord.eighttrack.adaptors;
+package net.locusworks.discord.eighttrack.handlers;
import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.Path;
-import java.time.Duration;
-import java.time.OffsetDateTime;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+import java.util.Date;
+import javax.annotation.PostConstruct;
-import net.dv8tion.jda.api.JDA;
-import net.dv8tion.jda.api.entities.Guild;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import net.dv8tion.jda.api.events.guild.GuildJoinEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
-import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler;
+import net.locusworks.discord.eighttrack.database.entities.DiscordGuild;
+import net.locusworks.discord.eighttrack.database.repos.GuildRepository;
+import net.locusworks.discord.eighttrack.services.ConfigurationService;
+import net.locusworks.discord.eighttrack.services.GuildMusicService;
import net.locusworks.logger.ApplicationLogger;
import net.locusworks.logger.ApplicationLoggerFactory;
-public class MusicListenerAdaptor extends ListenerAdapter {
+@Service
+public class DiscordEventHandler extends ListenerAdapter {
private Path musicDir;
- private ApplicationLogger logger;
-
- private Map playerMap;
- private JDA client;
- public MusicListenerAdaptor(Path musicDir, JDA client) throws IOException {
- this.logger = ApplicationLoggerFactory.getLogger(MusicListenerAdaptor.class);
- this.playerMap = new ConcurrentHashMap<>();
- this.musicDir = musicDir;
- this.client = client;
-
- ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
- executor.scheduleWithFixedDelay(()->checkPlayers(), 1, 1, TimeUnit.MINUTES);
-
+ private ApplicationLogger logger = ApplicationLoggerFactory.getLogger(DiscordEventHandler.class);
+
+ @Autowired
+ private ConfigurationService confService;
+
+ @Autowired
+ private GuildRepository guildRepo;
+
+ @Autowired
+ private GuildMusicService musicService;
+
+ @Autowired
+ private Mp3UploadHandler uploadHandler;
+
+ @PostConstruct
+ private void init() throws IOException {
+ this.musicDir = confService.getMusicDirectory();
+ if (!Files.exists(this.musicDir.toAbsolutePath())) {
+ Files.createDirectories(this.musicDir.toAbsolutePath());
+ }
}
- private void checkPlayers() {
- logger.debug("Checking players to see if anyone is listening");
- OffsetDateTime now = OffsetDateTime.now();
- for(Iterator> iterator = playerMap.entrySet().iterator(); iterator.hasNext();) {
- Entry entry = iterator.next();
- GuildMusicHandler gmh = entry.getValue();
- long guildId = entry.getKey();
-
- OffsetDateTime lastPlayed = gmh.getLastPlayed();
- Duration duration = Duration.between(lastPlayed, now);
- if (duration.getSeconds() > 300) {
- Guild guild = client.getGuildById(guildId);
- if (guild == null) {
- iterator.remove();
- continue;
- }
- guild.getAudioManager().closeAudioConnection();
- iterator.remove();
- }
+ @Override
+ public void onGuildJoin(GuildJoinEvent event) {
+ try {
+ long guildId = event.getGuild().getIdLong();
+ DiscordGuild discordGuild = guildRepo.findByGuildId(guildId);
+ if (discordGuild != null) return;
+
+ logger.debug("Joining Server: " + event.getGuild().getName());
+
+ discordGuild = new DiscordGuild();
+ discordGuild.setGuildId(guildId);
+ discordGuild.setGuildName(event.getGuild().getName());
+ discordGuild.setDateJoined(new Date());
+
+ guildRepo.save(discordGuild);
+ } catch (Exception ex) {
+ logger.error("Unable to persist server information to database: " + ex.getMessage(), ex);
}
}
@@ -100,13 +105,21 @@ public class MusicListenerAdaptor extends ListenerAdapter {
private void onGuildMessageReceivedHelper(GuildMessageReceivedEvent event) throws IOException {
- if (!playerMap.containsKey(event.getGuild().getIdLong())) {
- playerMap.put(event.getGuild().getIdLong(), new GuildMusicHandler(musicDir));
+ if (!musicService.containsKey(event.getGuild().getIdLong())) {
+ musicService.put(event.getGuild().getIdLong(), new GuildMusicHandler(musicDir, uploadHandler));
}
- GuildMusicHandler gmh = playerMap.get(event.getGuild().getIdLong());
- gmh.accept((id) -> playerMap.remove(id));
+ GuildMusicHandler gmh = musicService.get(event.getGuild().getIdLong());
+ gmh.accept((id) -> musicService.remove(id));
String command = event.getMessage().getContentRaw().trim().toLowerCase();
+
+ switch(command) {
+ case "-upload":
+ gmh.upload(event);
+ return;
+ }
+
+ /*
switch (command) {
case "-play":
gmh.isPlaying(true);
@@ -132,5 +145,6 @@ public class MusicListenerAdaptor extends ListenerAdapter {
default:
return;
}
+ */
}
}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java
index 177e862..315bbde 100644
--- a/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java
+++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/GuildMusicHandler.java
@@ -27,6 +27,7 @@
*/
package net.locusworks.discord.eighttrack.handlers;
+import java.awt.Color;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -45,6 +46,7 @@ import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.entities.GuildChannel;
+import net.dv8tion.jda.api.entities.Message.Attachment;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
@@ -66,13 +68,14 @@ public class GuildMusicHandler {
private OffsetDateTime lastPlayed;
private Consumer callback;
+ private Mp3UploadHandler uploadHandler;
- public GuildMusicHandler(Path musicDir) throws IOException {
+ public GuildMusicHandler(Path musicDir, Mp3UploadHandler uploadHandler) throws IOException {
this.logger = ApplicationLoggerFactory.getLogger(GuildMusicHandler.class);
this.playing = new AtomicBoolean(false);
this.musicDir = musicDir;
this.lastPlayed = OffsetDateTime.now();
-
+ this.uploadHandler = uploadHandler;
this.apm = new DefaultAudioPlayerManager();
AudioSourceManagers.registerLocalSource(apm);
@@ -80,7 +83,6 @@ public class GuildMusicHandler {
this.ts = new TrackScheduler();
player.addListener(ts);
- indexFiles();
}
public OffsetDateTime getLastPlayed() {
@@ -200,4 +202,38 @@ public class GuildMusicHandler {
ts.trackLoaded(track);
}
}
+
+ public void upload(GuildMessageReceivedEvent event) {
+ if (!event.getMessage().getMember().hasPermission(Permission.ADMINISTRATOR, Permission.MANAGE_SERVER)) {
+ event.getChannel().sendMessage(String.format("Sorry <@%s> i can't do that. *psst: you have to have manage server, or administrator role*", event.getMember().getIdLong())).queue();
+ return;
+ }
+
+ for(Attachment attachment : event.getMessage().getAttachments()) {
+ attachment.retrieveInputStream().thenAccept((in) -> {
+ try {
+ Mp3UploadResults res = uploadHandler.parse(in);
+
+ MessageEmbed embed = new EmbedBuilder()
+ .setColor(Color.GREEN)
+ .setTitle("Upload Results")
+ .setDescription(res.toString())
+ .setTimestamp(OffsetDateTime.now())
+ .setFooter(event.getGuild().getSelfMember().getEffectiveName(), event.getGuild().getSelfMember().getUser().getAvatarUrl())
+ .build();
+
+ event.getChannel().sendMessage(embed).queue();
+ } catch (Exception ex) {
+ logger.error("Unable to get file information: %s", ex.getMessage());
+ logger.error(ex);
+ } finally {
+ event.getMessage().delete().queue();
+ }
+
+ }).exceptionally((err) ->{
+ return null;
+ });
+ }
+
+ }
}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadHandler.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadHandler.java
index 294ae90..be6ed7e 100644
--- a/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadHandler.java
+++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadHandler.java
@@ -1,3 +1,30 @@
+/**
+ *
+ * Project: Eight Track, File: Mp3UploadHandler.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
package net.locusworks.discord.eighttrack.handlers;
import java.io.IOException;
@@ -9,52 +36,41 @@ import java.nio.file.Paths;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
-import org.apache.tika.parser.mp3.LyricsHandler;
import org.apache.tika.parser.mp3.Mp3Parser;
import org.apache.tika.sax.BodyContentHandler;
+import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;
+@Component
public class Mp3UploadHandler {
-
- private Path file;
-
- public Mp3UploadHandler(Path file) {
- this.file = file;
- }
-
- public void parse() throws IOException, SAXException, TikaException {
-
- InputStream is = Files.newInputStream(file);
-
- BodyContentHandler handler = new BodyContentHandler();
- Metadata metadata = new Metadata();
- ParseContext context = new ParseContext();
-
- Mp3Parser parser = new Mp3Parser();
-
- parser.parse(is, handler, metadata, context);
-
- LyricsHandler lyrics = new LyricsHandler(is, handler);
-
- while(lyrics.hasLyrics()) {
- System.out.println(lyrics.toString());
- }
-
- System.out.println("Contents of the document:" + handler.toString());
- System.out.println("Metadata of the document:");
- String[] metadataNames = metadata.names();
- for(String name : metadataNames) {
- System.out.println(name + ": " + metadata.get(name));
+ public Mp3UploadResults parse(Path file) throws IOException {
+ InputStream is = Files.newInputStream(file);
+ return parse(is);
+ }
+
+ public Mp3UploadResults parse(InputStream is) throws IOException {
+ try {
+ BodyContentHandler handler = new BodyContentHandler();
+ Metadata metadata = new Metadata();
+ ParseContext context = new ParseContext();
+
+ Mp3Parser parser = new Mp3Parser();
+
+ parser.parse(is, handler, metadata, context);
+
+ return new Mp3UploadResults(metadata);
+ } catch (Exception ex) {
+ throw new IOException(ex);
}
}
-
+
public static void main(String args[]) throws IOException, SAXException, TikaException {
- String file = "S:\\Music\\Alan Walker\\01 Diamond Heart.mp3";
+ String file = "E:\\Music2\\Alan Walker\\Itinerary_ Dallas.pdf";
Path path = Paths.get(file);
-
- Mp3UploadHandler fuh = new Mp3UploadHandler(path);
- fuh.parse();
+
+ Mp3UploadHandler fuh = new Mp3UploadHandler();
+ fuh.parse(path);
}
}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadResults.java b/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadResults.java
index 138351e..cb016be 100644
--- a/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadResults.java
+++ b/src/main/java/net/locusworks/discord/eighttrack/handlers/Mp3UploadResults.java
@@ -1,15 +1,203 @@
+/**
+ *
+ * Project: Eight Track, File: Mp3UploadResults.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
package net.locusworks.discord.eighttrack.handlers;
import org.apache.tika.metadata.Metadata;
public class Mp3UploadResults {
+ private enum MetaDataField {
+ GENRE("xmpDM:genre"),
+ COMPOSER("xmpDM:composer"),
+ ALBUM("xmpDM:album"),
+ TRACK_NUMBER("xmpDM:trackNumber"),
+ DISC_NUMBER("xmpDM:discNumber"),
+ ARTIST("xmpDM:artist"),
+ TITLE("title"),
+ RELEASE_DATE("xmpDM:releaseDate"),
+ DURATION("xmpDM:duration");
+
+ private String value;
+
+ private MetaDataField(String value) {
+ this.value = value;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+ }
+
+ private String genre;
+ private String composure;
+ private String album;
+ private String trackNumber;
+ private String discNumber;
+ private String artist;
+ private String title;
+ private String releaseDate;
+ private Long duration;
+
+
public Mp3UploadResults( Metadata metadata) {
parseResults(metadata);
}
private void parseResults(Metadata metadata) {
+ genre = metadata.get(MetaDataField.GENRE.getValue());
+ composure = metadata.get(MetaDataField.COMPOSER.getValue());
+ album = metadata.get(MetaDataField.ALBUM.getValue());
+ trackNumber = metadata.get(MetaDataField.TRACK_NUMBER.getValue());
+ discNumber = metadata.get(MetaDataField.DISC_NUMBER.getValue());
+ artist = metadata.get(MetaDataField.ARTIST.getValue());
+ title = metadata.get(MetaDataField.TITLE.getValue());
+ releaseDate = metadata.get(MetaDataField.RELEASE_DATE.getValue());
+ String durationStr = metadata.get(MetaDataField.DURATION.getValue()).trim();
+ if (durationStr != null) {
+ duration = Double.valueOf(metadata.get(MetaDataField.DURATION.getValue())).longValue();
+ }
+ }
+
+ /**
+ * @return the genre
+ */
+ public final String getGenre() {
+ return genre;
+ }
+
+ /**
+ * @return the composure
+ */
+ public final String getComposure() {
+ return composure;
+ }
+
+ /**
+ * @return the album
+ */
+ public final String getAlbum() {
+ return album;
+ }
+
+ /**
+ * @return the trackNumber
+ */
+ public final String getTrackNumber() {
+ return trackNumber;
+ }
+
+ /**
+ * @return the discNumber
+ */
+ public final String getDiscNumber() {
+ return discNumber;
+ }
+
+ /**
+ * @return the artist
+ */
+ public final String getArtist() {
+ return artist;
+ }
+
+ /**
+ * @return the title
+ */
+ public final String getTitle() {
+ return title;
+ }
+
+ /**
+ * @return the releaseDate
+ */
+ public final String getReleaseDate() {
+ return releaseDate;
+ }
+
+ /**
+ * @return the duration
+ */
+ public final Long getDuration() {
+ return duration;
+ }
+
+ public boolean validFile() {
+ return getTitle() != null && !getTitle().isEmpty();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("```");
+ if (getTitle() != null)
+ sb.append(String.format("%-10s: %s%n", "Title", getTitle()));
+
+ if (getArtist() != null)
+ sb.append(String.format("%-10s: %s%n", "Artist", getArtist()));
+
+ if (getAlbum() != null)
+ sb.append(String.format("%-10s: %s%n", "Album", getAlbum()));
+
+ if (getTrackNumber() != null)
+ sb.append(String.format("%-10s: %s%n", "Track", getTrackNumber()));
+
+ if (getDiscNumber() != null)
+ sb.append(String.format("%-10s: %s%n", "Disc", getDiscNumber()));
+
+ if (getReleaseDate() != null)
+ sb.append(String.format("%-10s: %s%n", "Year", getReleaseDate()));
+
+ if (getGenre() != null)
+ sb.append(String.format("%-10s: %s%n", "Genre", getGenre()));
+
+ if (duration != null)
+ sb.append(String.format("%-10s: %s%n", "Duration", dateFormat(getDuration())));
+
+ sb.append("```");
+ return sb.toString();
+ }
+
+ private String dateFormat(long timeInMilliSeconds) {
+ long seconds = timeInMilliSeconds / 1000;
+ long minutes = seconds / 60;
+ long hours = minutes / 60;
+ long days = hours / 24;
+
+ long sec = seconds % 60;
+ long min = minutes % 60;
+ long hr = hours % 24;
+
+ String time = "" + sec;
+ if (min > 0) time = min + ":" + time;
+ if (hr > 0) time = hr + ":" + time;
+ if (days > 0) time = days + ":" + time;
+
+ return time;
}
}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/main/EightTrackLauncher.java b/src/main/java/net/locusworks/discord/eighttrack/main/EightTrackLauncher.java
index 1f2f2d7..7c09013 100644
--- a/src/main/java/net/locusworks/discord/eighttrack/main/EightTrackLauncher.java
+++ b/src/main/java/net/locusworks/discord/eighttrack/main/EightTrackLauncher.java
@@ -1,6 +1,6 @@
/**
*
- * Project: Eight Track, File: Entry.java
+ * Project: Eight Track, File: EightTrackLauncher.java
*
* Copyright 2019 Locusworks LLC.
* All rights reserved. Federal copyright law prohibits unauthorized reproduction by
@@ -28,33 +28,53 @@
package net.locusworks.discord.eighttrack.main;
import java.io.IOException;
-import java.nio.file.Paths;
import javax.security.auth.login.LoginException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.scheduling.annotation.EnableScheduling;
-import net.dv8tion.jda.api.AccountType;
-import net.dv8tion.jda.api.JDA;
-import net.dv8tion.jda.api.JDABuilder;
-import net.locusworks.discord.eighttrack.adaptors.MusicListenerAdaptor;
+import net.locusworks.discord.eighttrack.services.ConfigurationService;
+import net.locusworks.discord.eighttrack.services.EightTrackService;
import net.locusworks.logger.ApplicationLogger;
import net.locusworks.logger.ApplicationLoggerFactory;
+import net.locusworks.logger.ApplicationLoggerInitializer;
+import net.locusworks.logger.LogLevel;
-@SpringBootApplication(scanBasePackages = {"net.locusworks.discord.pseudobot"})
+@SpringBootApplication(scanBasePackages = {"net.locusworks.discord.eighttrack"})
@EnableAutoConfiguration
@EnableScheduling
-public class EightTrackLauncher {
+public class EightTrackLauncher implements ApplicationRunner {
+
+ @Autowired
+ private ConfigurationService confService;
+
+ @Autowired
+ private EightTrackService service;
public static void main(String[] args) throws LoginException, IOException {
- if (args.length < 1) throw new RuntimeException("no token provided");
+ new SpringApplicationBuilder(EightTrackLauncher.class).headless(true).run(args);
+ }
+ @Override
+ public void run(ApplicationArguments args) throws Exception {
+ ApplicationLoggerFactory.init(new ApplicationLoggerInitializer() {
+
+ @Override
+ public LogLevel initialize() {
+ return LogLevel.getEnum(confService.getLogLevel());
+ }
+ });
+
ApplicationLogger logger = ApplicationLoggerFactory.getLogger(EightTrackLauncher.class);
logger.info("Starting Eight-Track");
-
- JDA client = new JDABuilder(AccountType.BOT).setToken(args[0]).build();
-
- client.addEventListener(new MusicListenerAdaptor(Paths.get(args[1])));
+
+ service.begin();
+
+
}
}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/services/AESService.java b/src/main/java/net/locusworks/discord/eighttrack/services/AESService.java
new file mode 100644
index 0000000..1351190
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/services/AESService.java
@@ -0,0 +1,74 @@
+/**
+ *
+ * Project: Eight Track, File: AESService.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.services;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.stereotype.Service;
+
+import net.locusworks.crypto.AES;
+
+@Service
+public class AESService {
+ private AES aes;
+
+ @PostConstruct
+ private void init() throws IOException {
+ Path keyFile = Paths.get("key.bin");
+ if (!Files.exists(keyFile)) {
+ throw new IOException("Unable to find key.bin in local directory");
+ }
+
+ byte[] key = IOUtils.toByteArray(Files.newInputStream(keyFile));
+
+ this.aes = AES.createInstance(key);
+ }
+
+ public String encrypt(String plainText) {
+ return aes.encrypt(plainText);
+ }
+
+ public String decrypt(String encryptedText) {
+ return aes.decrypt(encryptedText);
+ }
+
+ public static void main(String[] args) throws IOException {
+ AESService service = new AESService();
+ service.init();
+
+ System.out.println(service.encrypt("zeGAPgbH9HFbqmjRjmwzUDKv"));
+
+ }
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/services/ConfigurationService.java b/src/main/java/net/locusworks/discord/eighttrack/services/ConfigurationService.java
new file mode 100644
index 0000000..c2614f1
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/services/ConfigurationService.java
@@ -0,0 +1,229 @@
+/**
+ *
+ * Project: Eight Track, File: ConfigurationService.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.services;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import net.locusworks.crypto.configuration.PropertiesManager;
+import net.locusworks.discord.eighttrack.enums.Configuration;
+import net.locusworks.logger.ApplicationLogger;
+import net.locusworks.logger.ApplicationLoggerFactory;
+
+@Service
+public class ConfigurationService {
+ private Properties configuration;
+ private Properties defaults = null;
+ private Path eightTrackConf = null;
+ private long lastModified = 0;
+
+ private static final String PROPERTIES_FILE = "eighttrack.properties";
+
+ private static ApplicationLogger logger = ApplicationLoggerFactory.getLogger(ConfigurationService.class);
+
+ @Autowired
+ private AESService aesService;
+
+ /**
+ * Initialize the configuration service
+ * This happens during server start up
+ * @throws IOException If the file cannot be read
+ * @throws Exception any other exception thrown
+ */
+ @PostConstruct
+ private void init() throws IOException, Exception {
+
+ // load defaults when the webapp loads
+ try {
+ defaults = PropertiesManager.loadConfiguration(this.getClass(), PROPERTIES_FILE);
+ } catch (IOException ex) {
+ logger.error(String.format("Failed to load default %s: %s", PROPERTIES_FILE, ex.getMessage()));
+ throw ex;
+ }
+
+ // create portalConf File object
+ eightTrackConf = Paths.get("conf").resolve(PROPERTIES_FILE);
+
+ if (!Files.exists(eightTrackConf.getParent())) {
+ Files.createDirectories(eightTrackConf.getParent());
+ }
+
+ // initial config load
+ loadConf();
+ }
+
+ /**
+ * Load the configuration file
+ * @throws IOException
+ */
+ private void loadConf() throws IOException {
+
+ // load the active config file
+ // ignore read error, we can continue with an empty configuration map
+ // and all default items will be added below and the file created
+ logger.info("Loading config file: " + eightTrackConf);
+ try {
+ configuration = PropertiesManager.loadConfiguration(eightTrackConf);
+ } catch (Exception e) {
+ logger.info("Config file: " + eightTrackConf + " will be created from template");
+ configuration = new Properties();
+ }
+
+ Map results = PropertiesManager.addConfiguration(configuration, defaults);
+ boolean changed = !results.isEmpty();
+ if (!results.isEmpty()) {
+ logger.info(results, new StringBuilder("Added new configuration items:%n"));
+ }
+
+ results = PropertiesManager.removeConfiguration(configuration, defaults);
+ changed |= !results.isEmpty();
+ if (!results.isEmpty()) {
+ logger.info(results, new StringBuilder("Removed unused configuration items:%n"));
+ }
+
+ if (changed) {
+ PropertiesManager.saveConfiguration(configuration, eightTrackConf, "Patch Repository properties file");
+ }
+
+ lastModified = Files.getLastModifiedTime(eightTrackConf).toMillis();
+ }
+
+ public String getLogLevel() {
+ return configuration.getProperty(Configuration.LOG_LEVEL.getValue());
+ }
+
+ /**
+ * Save the configuration values to file
+ * @param confs Configuration property values to save
+ * @throws Exception general exception
+ */
+ public void saveToConf(Properties confs) throws Exception {
+ PropertiesManager.saveConfiguration(confs, eightTrackConf, "Patch Repository properties file");
+ logger.info("Saved config file: " + eightTrackConf + ", " + confs.size() + " entries");
+ loadConf();
+ }
+
+ /**
+ * Get the database root user name.
+ * It first checks the catalina.properties file for the root user
+ * then checks the patchrepo.properties file
+ * @return root database username
+ */
+ public String getDatabaseRootUsername() {
+ return configuration.getProperty(Configuration.DB_ROOT_USER.getValue());
+ }
+
+ /**
+ * Get the database root user password
+ * It first checks the catalina.properties file for the password
+ * then checks the patchrepo.properties file.
+ * The password must be encrypted in both locations
+ * @return root database password
+ */
+ public String getDatabaseRootPassword() {
+ String dbPasswd = configuration.getProperty(Configuration.DB_ROOT_PASSWORD.getValue());
+ try {
+ return aesService.decrypt(dbPasswd);
+ } catch (Exception ex) {
+ logger.error("Unable to get db root password " + ex.getMessage());
+ return null;
+ }
+ }
+
+
+ /**
+ * Get the standard database user name
+ * @return portal database username
+ */
+ public String getDatabaseUsername() {
+ return configuration.getProperty(Configuration.DB_USER.getValue());
+ }
+
+ /**
+ * Get the standard database password.
+ * The password is encrypted in the properties file
+ * @return patchrepo database password
+ */
+ public String getDatabasePassword() {
+ String dbPasswd = configuration.getProperty(Configuration.DB_PASSWORD.getValue());
+ try {
+ return aesService.decrypt(dbPasswd);
+ } catch (Exception ex) {
+ logger.error("Unable to get db password " + ex.getMessage());
+ return null;
+ }
+ }
+
+ /**
+ * Get the database host url
+ * @return database host url
+ */
+ public String getDatabaseHost() {
+ return configuration.getProperty(Configuration.DB_HOST.getValue());
+ }
+
+ /**
+ * Get the database host port
+ * @return the database port
+ */
+ public Integer getDatabasePort() {
+ return Integer.parseInt(configuration.getProperty(Configuration.DB_PORT.getValue()));
+ }
+
+ /**
+ * Get the discord token
+ * @return discord token
+ */
+ public String getDiscordToken() {
+ String token = configuration.getProperty(Configuration.DISCORD_TOKEN.getValue(), "");
+ return token;
+ }
+
+ public Path getMusicDirectory() {
+ String dir = configuration.getProperty(Configuration.MUSIC_DIR.getValue(), "");
+ return Paths.get(dir);
+ }
+
+ /**
+ * Get the last time the configuration file was modified
+ * @return last modified
+ */
+ public long getLastModified() {
+ return lastModified;
+ }
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/services/DatabaseCleanupService.java b/src/main/java/net/locusworks/discord/eighttrack/services/DatabaseCleanupService.java
new file mode 100644
index 0000000..8ef52c3
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/services/DatabaseCleanupService.java
@@ -0,0 +1,113 @@
+/**
+ *
+ * Project: Eight Track, File: DatabaseCleanupService.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.services;
+
+import java.time.Duration;
+import java.time.OffsetDateTime;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.entities.Guild;
+import net.locusworks.discord.eighttrack.database.repos.GuildRepository;
+import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler;
+
+@Service
+public class DatabaseCleanupService {
+
+ private static final long SECOND = 1000;
+ private static final long MINUTE = 60 * SECOND;
+ private static final long HOUR = 60 * MINUTE;
+ private static final long DAY = 24 * HOUR;
+
+ private Logger logger = LoggerFactory.getLogger(DatabaseCleanupService.class);
+
+ @Autowired
+ private GuildRepository guildRepo;
+
+ @Autowired
+ private GuildMusicService musicService;
+
+ private JDA client;
+
+ public void setClient(JDA client) {
+ this.client = client;
+ }
+
+ @Scheduled(fixedRate = 5 * MINUTE)
+ private void checkPlayers() {
+ if (client == null) {
+ logger.warn("Discord client is null. Unable to do cleanup");
+ return;
+ }
+
+ logger.debug("Checking players to see if anyone is listening");
+ OffsetDateTime now = OffsetDateTime.now();
+ for(Iterator> iterator = musicService.entrySet().iterator(); iterator.hasNext();) {
+ Entry entry = iterator.next();
+ GuildMusicHandler gmh = entry.getValue();
+ long guildId = entry.getKey();
+
+ OffsetDateTime lastPlayed = gmh.getLastPlayed();
+ Duration duration = Duration.between(lastPlayed, now);
+ if (duration.getSeconds() > 300) {
+ Guild guild = client.getGuildById(guildId);
+ if (guild == null) {
+ iterator.remove();
+ continue;
+ }
+ guild.getAudioManager().closeAudioConnection();
+ iterator.remove();
+ }
+ }
+ }
+
+ @Scheduled(fixedRate = DAY)
+ private void cleanDatabase() {
+ if (client == null) {
+ logger.warn("Discord client is null. Unable to do cleanup");
+ return;
+ }
+
+ Set currentGuildsIds = client.getSelfUser().getMutualGuilds().stream().map(guild -> guild.getIdLong()).collect(Collectors.toSet());
+
+ try {
+ guildRepo.deleteGuildsNoLongerJoined(currentGuildsIds);
+ } catch (Exception ex) {
+ logger.error("Unable to clean up servers: " + ex.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/services/EightTrackService.java b/src/main/java/net/locusworks/discord/eighttrack/services/EightTrackService.java
new file mode 100644
index 0000000..2ccf575
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/services/EightTrackService.java
@@ -0,0 +1,69 @@
+/**
+ *
+ * Project: Eight Track, File: EightTrackService.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.services;
+
+import javax.security.auth.login.LoginException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import net.dv8tion.jda.api.AccountType;
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.JDABuilder;
+import net.locusworks.discord.eighttrack.handlers.DiscordEventHandler;
+import net.locusworks.logger.ApplicationLogger;
+import net.locusworks.logger.ApplicationLoggerFactory;
+
+@Service
+public class EightTrackService {
+
+ private ApplicationLogger logger = ApplicationLoggerFactory.getLogger(EightTrackService.class);
+
+ private JDA client;
+
+ @Autowired
+ private ConfigurationService confService;
+
+ @Autowired
+ private DiscordEventHandler eventListener;
+
+ @Autowired
+ private DatabaseCleanupService dcs;
+
+ public void begin() throws LoginException {
+ String token = confService.getDiscordToken();
+ logger.debug("Logging in with token %s", token);
+
+ client = new JDABuilder(AccountType.BOT).setToken(token).build();
+ client.addEventListener(eventListener);
+
+ dcs.setClient(client);
+ }
+
+
+}
diff --git a/src/main/java/net/locusworks/discord/eighttrack/services/GuildMusicService.java b/src/main/java/net/locusworks/discord/eighttrack/services/GuildMusicService.java
new file mode 100644
index 0000000..fede33a
--- /dev/null
+++ b/src/main/java/net/locusworks/discord/eighttrack/services/GuildMusicService.java
@@ -0,0 +1,41 @@
+/**
+ *
+ * Project: Eight Track, File: GuildMusicService.java
+ *
+ * Copyright 2019 Locusworks LLC.
+ * All rights reserved. Federal copyright law prohibits unauthorized reproduction by
+ * any means and imposes fines up to $25,000 for violation. No part of this material
+ * may be reproduced, transmitted, transcribed, stored in a retrieval system, copied,
+ * modified, duplicated, adapted or translated into another program language in any
+ * form or by any means, electronic, mechanical, photocopying, recording, or
+ * otherwise, without the prior written permission from Locusworks. Locusworks
+ * affirms that Eight-Track(R) software and data is subject to United States
+ * Government Purpose Rights. Contact Locusworks, 1313 Lawnview Drive
+ * Forney TX 75126, (802) 488-0438, for commercial licensing opportunities.
+ *
+ * IN NO EVENT SHALL LOCUSWORKS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
+ * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF LOCUSWORKS HAS BEEN
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NO RESPONSIBILITY IS ASSUMED BY
+ * LOCUSWORKS FOR ITS USE, OR FOR ANY INFRINGEMENTS OF PATENTS OR OTHER RIGHTS OF
+ * THIRD PARTIES RESULTING FROM ITS USE. LOCUSWORKS SPECIFICALLY DISCLAIMS ANY
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ * ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS
+ * IS". LOCUSWORKS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ */
+package net.locusworks.discord.eighttrack.services;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.stereotype.Service;
+
+import net.locusworks.discord.eighttrack.handlers.GuildMusicHandler;
+
+@Service
+public class GuildMusicService extends ConcurrentHashMap {
+
+ private static final long serialVersionUID = -120204711554552975L;
+
+}
diff --git a/src/main/resources/database/migration/mariadb/afterMigrate.sql b/src/main/resources/database/migration/mariadb/afterMigrate.sql
index 629d102..57a53a8 100644
--- a/src/main/resources/database/migration/mariadb/afterMigrate.sql
+++ b/src/main/resources/database/migration/mariadb/afterMigrate.sql
@@ -13,11 +13,11 @@ BEGIN
DECLARE foo BIGINT DEFAULT 0;
SELECT COUNT(*) INTO foo FROM mysql.user WHERE User = 'eighttrackAdmin' and Host = 'localhost';
IF foo = 0 THEN
- CREATE USER 'eighttrackAdmin'@'localhost' IDENTIFIED BY 'eighttrackAdmin2017!';
+ CREATE USER 'eighttrackAdmin'@'localhost' IDENTIFIED BY 'zeGAPgbH9HFbqmjRjmwzUDKv';
END IF;
SELECT COUNT(*) INTO foo FROM mysql.user WHERE User = 'eighttrackAdmin' and Host = '%';
IF foo = 0 THEN
- CREATE USER 'eighttrackAdmin'@'%' IDENTIFIED BY 'eighttrackAdmin2017!';
+ CREATE USER 'eighttrackAdmin'@'%' IDENTIFIED BY 'zeGAPgbH9HFbqmjRjmwzUDKv';
END IF;
END ;$$
@@ -29,6 +29,6 @@ DROP PROCEDURE set_optimizer_switch_on;
CALL create_user();
DROP PROCEDURE create_user;
-GRANT SELECT,INSERT,UPDATE,DELETE ON pseudobot.* TO 'eighttrackAdmin'@'localhost';
-GRANT SELECT,INSERT,UPDATE,DELETE ON pseudobot.* TO 'eighttrackAdmin'@'%';
+GRANT SELECT,INSERT,UPDATE,DELETE ON eighttrack.* TO 'eighttrackAdmin'@'localhost';
+GRANT SELECT,INSERT,UPDATE,DELETE ON eighttrack.* TO 'eighttrackAdmin'@'%';
FLUSH PRIVILEGES;
\ No newline at end of file
diff --git a/src/main/resources/eighttrack.properties b/src/main/resources/eighttrack.properties
new file mode 100644
index 0000000..9d405df
--- /dev/null
+++ b/src/main/resources/eighttrack.properties
@@ -0,0 +1,10 @@
+dbAdmin=root
+dbAdminPassword=gSkjsvZbQTQtogOrPYqorCuuzp4WUpGFVtPYtMVj47U=
+dbUser=eighttrackAdmin
+dbUserPassword=RaamWDMgA2p09R3kAiKHqauu6mmKU2HLQ4nAfEGMNOs=
+dbHost=devops.locusworks.net
+dbPort=3306
+logLevel=INFO
+musicDir=E:/Music
+discordToken=NjI5MTQ0OTk1ODA2MzE0NTA5.XZVlRQ.7hiB0u4Zp5pxPrPfvdOdyr4TCh4
+
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 2ae8612..756ed17 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -3,7 +3,6 @@
- ${sys:LOG_LEVEL:-INFO}
%d{dd-MMM-yyyy HH:mm:ss.SSS} [%-5p] [%c{1}] %m%n
@@ -11,8 +10,8 @@
+ fileName="logs/eighttrack.log"
+ filePattern="logs/eighttrack-%d{yyyy-MM-dd}.log.gz">
@@ -22,8 +21,8 @@
-
-
+
+