#6 Initial work on implementing playlists
This commit is contained in:
		@@ -0,0 +1,48 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Project: Eight Track, File: GuildSongRepository.java
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2019-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 org.springframework.data.jpa.repository.Query;
 | 
			
		||||
import org.springframework.data.repository.CrudRepository;
 | 
			
		||||
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.DiscordGuild;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.GuildPlaylist;
 | 
			
		||||
 | 
			
		||||
public interface GuildPlaylistRepository extends CrudRepository<GuildPlaylist, Long> {
 | 
			
		||||
  
 | 
			
		||||
  GuildPlaylist findByGuildAndUserIdAndPlaylist(DiscordGuild guild, Long userId, String playlist);
 | 
			
		||||
  
 | 
			
		||||
  @Query("SELECT gpl FROM GuildPlaylist gpl WHERE gpl.guild.guildId = ?1 AND gpl.userId = ?2 AND gpl.playlist = ?3 ")
 | 
			
		||||
  GuildPlaylist findByGuildAndUserIdAndPlaylist(Long guild, Long userId, String playlist);
 | 
			
		||||
  
 | 
			
		||||
  GuildPlaylist findByGuildAndUserId(DiscordGuild guild, Long userId);
 | 
			
		||||
  
 | 
			
		||||
  @Query("SELECT gpl FROM GuildPlaylist gpl WHERE gpl.guild.guildId = ?1 AND gpl.userId = ?2 AND gpl.playlist = ?3 ")
 | 
			
		||||
  GuildPlaylist findByGuildAndUserId(Long guild, Long userId);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,42 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * Project: Eight Track, File: GuildSongRepository.java
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2019-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 org.springframework.data.repository.CrudRepository;
 | 
			
		||||
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.GuildPlaylist;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.GuildPlaylistSong;
 | 
			
		||||
 | 
			
		||||
public interface GuildPlaylistSongRepository extends CrudRepository<GuildPlaylistSong, Long> {
 | 
			
		||||
  
 | 
			
		||||
  List<GuildPlaylistSong> findByGuildPlaylist(GuildPlaylist gpl);
 | 
			
		||||
  
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
@@ -58,6 +58,7 @@ import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
 | 
			
		||||
import net.dv8tion.jda.api.managers.AudioManager;
 | 
			
		||||
import net.locusworks.crypto.utils.HashUtils;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.DiscordGuild;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.GuildPlaylist;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.GuildSong;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.entities.Song;
 | 
			
		||||
import net.locusworks.discord.eighttrack.scheduler.TrackScheduler;
 | 
			
		||||
@@ -98,11 +99,11 @@ public class GuildMusicHandler {
 | 
			
		||||
    this.ts = new TrackScheduler();
 | 
			
		||||
    player.addListener(ts);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  public Long getCurrentVoiceChannelId() {
 | 
			
		||||
    return voiceChannelId;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  public OffsetDateTime getLastPlayed() {
 | 
			
		||||
    return lastPlayed;
 | 
			
		||||
  }
 | 
			
		||||
@@ -114,7 +115,7 @@ public class GuildMusicHandler {
 | 
			
		||||
  public void isPlaying(boolean playing) {
 | 
			
		||||
    this.playing.set(playing);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  public void upNext(GuildMessageReceivedEvent event) throws Exception {
 | 
			
		||||
    upNext(event, null);
 | 
			
		||||
  }
 | 
			
		||||
@@ -152,7 +153,7 @@ public class GuildMusicHandler {
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  public void next(GuildMessageReceivedEvent event) throws Exception {
 | 
			
		||||
    next(event, null);
 | 
			
		||||
  }
 | 
			
		||||
@@ -181,14 +182,14 @@ public class GuildMusicHandler {
 | 
			
		||||
    player.stopTrack();
 | 
			
		||||
    voiceChannelId = null;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  public void play(GuildMessageReceivedEvent event) throws Exception {
 | 
			
		||||
    play(event, null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void play(GuildMessageReceivedEvent event, List<String> commands) throws Exception {
 | 
			
		||||
    if (playing.get()) return;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    VoiceChannel vc = event.getMember().getVoiceState().getChannel();
 | 
			
		||||
    if (vc == null) {
 | 
			
		||||
      event.getChannel().sendMessage(String.format("<@%s> you are not in a voice channel to play music", event.getMember().getId())).queue();
 | 
			
		||||
@@ -200,7 +201,7 @@ public class GuildMusicHandler {
 | 
			
		||||
          event.getMember().getId(), vc.getName())).queue();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    Long tmpId = vc.getIdLong();
 | 
			
		||||
    if (voiceChannelId != null && voiceChannelId != tmpId) {
 | 
			
		||||
      String channelName = event.getGuild().getVoiceChannelById(voiceChannelId).getName();
 | 
			
		||||
@@ -208,14 +209,14 @@ public class GuildMusicHandler {
 | 
			
		||||
          event.getMember().getId(), channelName)).queue();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    voiceChannelId = tmpId;
 | 
			
		||||
 | 
			
		||||
    AudioManager manager = event.getGuild().getAudioManager();
 | 
			
		||||
    manager.openAudioConnection(vc);
 | 
			
		||||
 | 
			
		||||
    manager.setSendingHandler(new EightTrackAudioSendHandler(player));
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (commands != null && !commands.isEmpty()) {
 | 
			
		||||
      String uuid = commands.remove(0);
 | 
			
		||||
      boolean foundSong = findSong(uuid);
 | 
			
		||||
@@ -225,7 +226,7 @@ public class GuildMusicHandler {
 | 
			
		||||
      }
 | 
			
		||||
      stop(event);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (!ts.hasTracks()) {
 | 
			
		||||
      loadRandomSong();
 | 
			
		||||
    }
 | 
			
		||||
@@ -285,7 +286,7 @@ public class GuildMusicHandler {
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  private MessageEmbed error(GuildMessageReceivedEvent event, Throwable ex, String fileName) {
 | 
			
		||||
    return new EmbedBuilder()
 | 
			
		||||
        .setTitle("Unable to upload file: " + fileName)
 | 
			
		||||
@@ -348,9 +349,9 @@ public class GuildMusicHandler {
 | 
			
		||||
    gs.setDateAdded(new Date());
 | 
			
		||||
    gs.setGuild(guild);
 | 
			
		||||
    gs.setSong(song);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    String[] uuidArray = UUID.randomUUID().toString().split("-");
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    gs.setUuid(uuidArray[uuidArray.length - 1]);
 | 
			
		||||
 | 
			
		||||
    guildSongRepoService.getGuildSongRepo().save(gs);
 | 
			
		||||
@@ -373,71 +374,108 @@ public class GuildMusicHandler {
 | 
			
		||||
 | 
			
		||||
    return embed;
 | 
			
		||||
  } 
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  public void list(GuildMessageReceivedEvent event) {
 | 
			
		||||
    List<GuildSong> gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    if (gsList == null || gsList.isEmpty()) {
 | 
			
		||||
      event.getChannel().sendMessage("There is no music for this guild.").queue();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    int longestSong = 0;
 | 
			
		||||
    int longestArtist = 0;
 | 
			
		||||
    for(GuildSong gs : gsList) {
 | 
			
		||||
      if (gs.getSong().getTitle().length() > longestSong) longestSong = gs.getSong().getTitle().length();
 | 
			
		||||
      if (gs.getSong().getArtist().length() > longestArtist) longestArtist = gs.getSong().getArtist().length();
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    String fmt = "%6s | %-" + longestSong +"s | %-" + longestArtist +"s | %s%n"; 
 | 
			
		||||
    int count = 0;
 | 
			
		||||
    StringBuilder sb = new StringBuilder();
 | 
			
		||||
    sb.append("**" + "Currently available songs for " + event.getGuild().getName() + "**\n\n```");
 | 
			
		||||
    sb.append(String.format(fmt, "Track", "Title", "Artist", "id"));
 | 
			
		||||
    sb.append(StringUtils.repeat("-", 27 + longestSong + longestArtist)).append("\n");
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    for(GuildSong gs : gsList) {
 | 
			
		||||
      sb.append(String.format(fmt, ++count, gs.getSong().getTitle(), gs.getSong().getArtist(), gs.getUuid()));
 | 
			
		||||
    }
 | 
			
		||||
    sb.append("```");
 | 
			
		||||
    event.getChannel().sendMessage(sb.toString()).queue();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  private void loadRandomSong() throws Exception {
 | 
			
		||||
    List<GuildSong> gsList = guildSongRepoService.getGuildSongRepo().findByGuild(guildId);
 | 
			
		||||
    if (gsList == null || gsList.isEmpty()) return;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    Random random = new Random(System.currentTimeMillis());
 | 
			
		||||
    int item = random.nextInt(gsList.size());
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    GuildSong song = gsList.get(item);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    apm.loadItem(song.getSong().getFilePath(), ts).get();
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  private boolean findSong(String uuid) throws Exception {
 | 
			
		||||
    GuildSong gs = guildSongRepoService.getGuildSongRepo().findByUuid(uuid);
 | 
			
		||||
    if (gs == null) return false;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    apm.loadItem(gs.getSong().getFilePath(), ts).get();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void playlist(GuildMessageReceivedEvent event, List<String> commands) {
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    String command = commands.remove(0);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    switch(command) {
 | 
			
		||||
      case "add":
 | 
			
		||||
        addPlayList(event, commands);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void addPlayList(GuildMessageReceivedEvent event, List<String> commands) {
 | 
			
		||||
    // TODO Auto-generated method stub
 | 
			
		||||
    
 | 
			
		||||
    if (commands == null || commands.isEmpty()) {
 | 
			
		||||
      event.getChannel().sendMessage(event.getAuthor().getAsMention() + " you have to provide the playlist to create a new playlist (no spaces in name) and optionally a list of uuids for songs to add").queue();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Long guildId = event.getGuild().getIdLong();
 | 
			
		||||
 | 
			
		||||
    DiscordGuild guild = guildSongRepoService.getGuildRepo().findByGuildId(guildId);
 | 
			
		||||
    if (guild == null) {
 | 
			
		||||
      event.getChannel().sendMessage("Unable to find guild in local database. Please contact administrator").queue();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    String playlist = commands.remove(0);
 | 
			
		||||
 | 
			
		||||
    long userId = event.getMember().getIdLong();
 | 
			
		||||
 | 
			
		||||
    GuildPlaylist gpl = guildSongRepoService.getGuildPlaylistRepo().findByGuildAndUserIdAndPlaylist(guild, userId, playlist);
 | 
			
		||||
    boolean newList = false;
 | 
			
		||||
    if (gpl != null && commands.isEmpty()) {
 | 
			
		||||
      event.getChannel().sendMessage(event.getAuthor().getAsMention() + " a playlist with the name " + playlist + " already exist for you.").queue();
 | 
			
		||||
      return;
 | 
			
		||||
    } else {
 | 
			
		||||
      newList = true;
 | 
			
		||||
      gpl = new GuildPlaylist();
 | 
			
		||||
      gpl.setDateAdded(new Date());
 | 
			
		||||
      gpl.setGuild(guild);
 | 
			
		||||
      gpl.setPlaylist(playlist);
 | 
			
		||||
      gpl.setUserId(userId);
 | 
			
		||||
      guildSongRepoService.getGuildPlaylistRepo().save(gpl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (commands.isEmpty() && newList) {
 | 
			
		||||
      event.getChannel().sendMessage(event.getAuthor().getAsMention() + " playlist " + playlist + " successfully created.").queue();
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,8 @@ package net.locusworks.discord.eighttrack.services;
 | 
			
		||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.repos.GuildPlaylistRepository;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.repos.GuildPlaylistSongRepository;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.repos.GuildRepository;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.repos.GuildSongRepository;
 | 
			
		||||
import net.locusworks.discord.eighttrack.database.repos.SongRepository;
 | 
			
		||||
@@ -43,6 +45,12 @@ public class GuildSongRepoService {
 | 
			
		||||
  @Autowired
 | 
			
		||||
  private GuildSongRepository guildSongRepo;
 | 
			
		||||
  
 | 
			
		||||
  @Autowired 
 | 
			
		||||
  private GuildPlaylistRepository guildPlaylistRepo;
 | 
			
		||||
  
 | 
			
		||||
  @Autowired
 | 
			
		||||
  private GuildPlaylistSongRepository guildPlaylistSongRepo;
 | 
			
		||||
  
 | 
			
		||||
  @Autowired
 | 
			
		||||
  private SongRepository songRepo;
 | 
			
		||||
 | 
			
		||||
@@ -60,6 +68,20 @@ public class GuildSongRepoService {
 | 
			
		||||
    return guildSongRepo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @return the guildPlaylistRepo
 | 
			
		||||
   */
 | 
			
		||||
  public final GuildPlaylistRepository getGuildPlaylistRepo() {
 | 
			
		||||
    return guildPlaylistRepo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @return the guildPlaylistSongRepo
 | 
			
		||||
   */
 | 
			
		||||
  public final GuildPlaylistSongRepository getGuildPlaylistSongRepo() {
 | 
			
		||||
    return guildPlaylistSongRepo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @return the songRepo
 | 
			
		||||
   */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user