Merge branch 'devel'

This commit is contained in:
Sebastien 2018-09-24 18:57:22 +03:00
commit 011359c4ea
23 changed files with 826 additions and 225 deletions

View File

@ -7,6 +7,7 @@ import net.Broken.MainBot;
import net.Broken.SpringContext; import net.Broken.SpringContext;
import net.Broken.Tools.EmbedMessageUtils; import net.Broken.Tools.EmbedMessageUtils;
import net.Broken.Tools.MessageTimeOut; import net.Broken.Tools.MessageTimeOut;
import net.Broken.Tools.SettingsUtils;
import net.Broken.audio.AudioM; import net.Broken.audio.AudioM;
import net.Broken.audio.NotConnectedException; import net.Broken.audio.NotConnectedException;
import net.Broken.audio.NullMusicManager; import net.Broken.audio.NullMusicManager;
@ -37,7 +38,7 @@ public class Settings implements Commande {
@Override @Override
public void action(String[] args, MessageReceivedEvent event) { public void action(String[] args, MessageReceivedEvent event) {
if(args.length == 0){ if(args.length == 0){
GuildPreferenceEntity guildPref = getPreference(event.getGuild()); GuildPreferenceEntity guildPref = SettingsUtils.getInstance().getPreference(event.getGuild());
MessageEmbed message = EmbedMessageUtils.getPref(guildPref); MessageEmbed message = EmbedMessageUtils.getPref(guildPref);
event.getTextChannel().sendMessage(message).complete(); event.getTextChannel().sendMessage(message).complete();
@ -89,22 +90,8 @@ public class Settings implements Commande {
} }
private GuildPreferenceEntity getPreference(Guild guild){
List<GuildPreferenceEntity> guildPrefList = guildPreferenceRepository.findByGuildId(guild.getId());
GuildPreferenceEntity guildPref;
if(guildPrefList.isEmpty()){
logger.info("Generate default pref for " + guild.getName());
guildPref = GuildPreferenceEntity.getDefault(guild);
guildPreferenceRepository.save(guildPref);
}
else
guildPref = guildPrefList.get(0);
return guildPref;
}
private void set(MessageReceivedEvent event, String key, String value){ private void set(MessageReceivedEvent event, String key, String value){
GuildPreferenceEntity pref = getPreference(event.getGuild()); GuildPreferenceEntity pref = SettingsUtils.getInstance().getPreference(event.getGuild());
switch (key){ switch (key){
case "anti_spam": case "anti_spam":
value = value.replaceAll(" ", ""); value = value.replaceAll(" ", "");

View File

@ -0,0 +1,30 @@
package net.Broken.RestApi.Data.Settings;
import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.List;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GetSettingsData {
public String name;
public String id;
public TYPE type;
public List<Value> values;
public String current;
public GetSettingsData() {
}
public GetSettingsData(String name, String id, TYPE type, List<Value> values, String current) {
this.name = name;
this.id = id;
this.type = type;
this.values = values;
this.current = current;
}
public enum TYPE{
BOOL,LIST,STRING
}
}

View File

@ -0,0 +1,7 @@
package net.Broken.RestApi.Data.Settings;
import java.util.List;
public class ListPostSetting {
public List<PostSetSettings> settings;
}

View File

@ -0,0 +1,6 @@
package net.Broken.RestApi.Data.Settings;
public class PostSetSettings {
public String id;
public String val;
}

View File

@ -0,0 +1,14 @@
package net.Broken.RestApi.Data.Settings;
public class Value {
public String name;
public String id;
public Value() {
}
public Value(String name, String id) {
this.name = name;
this.id = id;
}
}

View File

@ -3,9 +3,12 @@ package net.Broken.RestApi.Data.UserManager;
public class GuildInfo { public class GuildInfo {
public String name; public String name;
public String id; public String id;
public boolean isAdmin;
public GuildInfo(String name, String id) { public GuildInfo(String name, String id, boolean isAdmin) {
this.name = name; this.name = name;
this.id = id; this.id = id;
this.isAdmin = isAdmin;
} }
} }

View File

@ -0,0 +1,87 @@
package net.Broken.RestApi;
import net.Broken.DB.Entity.GuildPreferenceEntity;
import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.GuildPreferenceRepository;
import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot;
import net.Broken.RestApi.Data.Settings.GetSettingsData;
import net.Broken.RestApi.Data.Settings.ListPostSetting;
import net.Broken.RestApi.Data.Settings.PostSetSettings;
import net.Broken.RestApi.Data.Settings.Value;
import net.Broken.Tools.SettingsUtils;
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Role;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.RegEx;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/api")
public class SettingAPIController {
private Logger logger = LogManager.getLogger();
final
UserRepository userRepository;
@Autowired
public SettingAPIController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@RequestMapping(value = "/settings", method = RequestMethod.GET)
public ResponseEntity<ArrayList<GetSettingsData>> getSettings(@CookieValue("token") String token, @CookieValue("guild") String guild){
SettingsUtils settingUtils = SettingsUtils.getInstance();
if(settingUtils.checkPermission(token, guild)){
Guild jdaGuild = MainBot.jda.getGuildById(guild);
return new ResponseEntity<>( settingUtils.extractSettings(jdaGuild), HttpStatus.OK);
}
else{
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
@RequestMapping(value = "/settings", method = RequestMethod.POST)
public ResponseEntity<String> setSetting(@CookieValue("token") String token, @CookieValue("guild") String guild, @RequestBody ListPostSetting settings){
SettingsUtils settingUtils = SettingsUtils.getInstance();
if(settingUtils.checkPermission(token, guild)){
Guild jdaGuild = MainBot.jda.getGuildById(guild);
try {
UserEntity user = UserUtils.getInstance().getUserWithApiToken(userRepository,token);
logger.info(user.getName() + " change config of " + jdaGuild.getName());
} catch (UnknownTokenException e) {
e.printStackTrace();
}
if(settingUtils.setSettings(jdaGuild, settings.settings)){
return new ResponseEntity<>(HttpStatus.OK);
}else{
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
else{
logger.warn("Try to change setting, UNAUTHORIZED. TOKEN: " + token + " GUILD: " + guild);
return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
}
}
}

View File

@ -9,6 +9,7 @@ import net.Broken.RestApi.Data.UserManager.*;
import net.Broken.Tools.UserManager.Exceptions.*; import net.Broken.Tools.UserManager.Exceptions.*;
import net.Broken.Tools.UserManager.Oauth; import net.Broken.Tools.UserManager.Oauth;
import net.Broken.Tools.UserManager.UserUtils; import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.User; import net.dv8tion.jda.core.entities.User;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -108,7 +109,8 @@ public class UserManagerAPIController {
List<GuildInfo> temp = new ArrayList<>(); List<GuildInfo> temp = new ArrayList<>();
for (Guild guild : user.getMutualGuilds()){ for (Guild guild : user.getMutualGuilds()){
temp.add(new GuildInfo(guild.getName(), guild.getId()));
temp.add(new GuildInfo(guild.getName(), guild.getId(), guild.getMember(user).hasPermission(Permission.ADMINISTRATOR)));
} }
return new ResponseEntity<>(temp, HttpStatus.OK); return new ResponseEntity<>(temp, HttpStatus.OK);

View File

@ -0,0 +1,285 @@
package net.Broken.Tools;
import net.Broken.DB.Entity.GuildPreferenceEntity;
import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.GuildPreferenceRepository;
import net.Broken.DB.Repository.PendingPwdResetRepository;
import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot;
import net.Broken.RestApi.Data.Settings.GetSettingsData;
import net.Broken.RestApi.Data.Settings.PostSetSettings;
import net.Broken.RestApi.Data.Settings.Value;
import net.Broken.SpringContext;
import net.Broken.Tools.UserManager.Exceptions.UnknownTokenException;
import net.Broken.Tools.UserManager.UserUtils;
import net.dv8tion.jda.core.Permission;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Role;
import net.dv8tion.jda.core.entities.TextChannel;
import net.dv8tion.jda.core.entities.User;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.ArrayList;
import java.util.List;
public class SettingsUtils {
private static SettingsUtils INSTANCE;
private Logger logger = LogManager.getLogger();
public static SettingsUtils getInstance(){
return (INSTANCE == null) ? new SettingsUtils() : INSTANCE;
}
GuildPreferenceRepository guildPreferenceRepository;
UserRepository userRepository;
private SettingsUtils() {
ApplicationContext context = SpringContext.getAppContext();
guildPreferenceRepository = (GuildPreferenceRepository) context.getBean("guildPreferenceRepository");
userRepository = (UserRepository) context.getBean("userRepository");
}
public ArrayList<GetSettingsData> extractSettings(Guild guild){
ArrayList<GetSettingsData> list = new ArrayList<>();
List<GuildPreferenceEntity> guildPrefList = guildPreferenceRepository.findByGuildId(guild.getId());
GuildPreferenceEntity guildPref;
if(guildPrefList.isEmpty()){
guildPref = GuildPreferenceEntity.getDefault(guild);
guildPreferenceRepository.save(guildPref);
}
else
guildPref = guildPrefList.get(0);
list.add(new GetSettingsData(
"Enable Welcome Message",
"welcome",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isWelcome())
));
list.add(new GetSettingsData(
"Welcome Message chanel",
"welcome_chanel_id",
GetSettingsData.TYPE.LIST,
getTextChannels(guild),
guildPref.getWelcomeChanelID()
));
list.add(new GetSettingsData(
"Welcome Message",
"welcome_message",
GetSettingsData.TYPE.STRING,
null,
guildPref.getWelcomeMessage()
));
list.add(new GetSettingsData(
"Enable Default Role",
"default_role",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isDefaultRole())
));
list.add(new GetSettingsData(
"Default Role",
"default_role_id",
GetSettingsData.TYPE.LIST,
getRoles(guild),
guildPref.getDefaultRoleId()
));
list.add(new GetSettingsData(
"Enable Anti Spam",
"anti_spam",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isAntiSpam())
));
list.add(new GetSettingsData(
"Enable Daily Madame Message",
"daily_madame",
GetSettingsData.TYPE.BOOL,
null,
Boolean.toString(guildPref.isDailyMadame())
));
return list;
}
public boolean checkPermission(String token, String guild){
if(token == null || guild == null){
return false;
}
else{
try {
UserEntity user = UserUtils.getInstance().getUserWithApiToken(userRepository, token);
User jdaUser = MainBot.jda.getUserById(user.getJdaId());
Guild jdaGuild = MainBot.jda.getGuildById(guild);
if(jdaGuild == null){
return false;
}
if(!jdaGuild.getMember(jdaUser).hasPermission(Permission.ADMINISTRATOR)){
return false;
}
return true;
} catch (Exception e) {
logger.warn("Unknown Token! " + token);
return false;
}
}
}
public boolean setSettings(Guild guild, List<PostSetSettings> settings){
GuildPreferenceEntity pref = getPreference(guild);
for (PostSetSettings setting : settings){
String value = setting.val;
logger.debug(setting.id + " : " + value);
switch (setting.id) {
case "anti_spam":
if (value.toLowerCase().equals("true") || value.toLowerCase().equals("false")) {
boolean result = Boolean.parseBoolean(value);
pref.setAntiSpam(result);
pref = guildPreferenceRepository.save(pref);
} else {
logger.error("anti_spam error. Key: " + setting.id + " Val: " + setting.val);
return false;
}
break;
case "default_role":
if (value.toLowerCase().equals("true") || value.toLowerCase().equals("false")) {
boolean result = Boolean.parseBoolean(value);
pref.setDefaultRole(result);
pref = guildPreferenceRepository.save(pref);
} else {
logger.error("default_role error. Key: " + setting.id + " Val: " + setting.val);
return false;
}
break;
case "default_role_id":
try {
Role role = guild.getRoleById(value);
if (role != null) {
pref.setDefaultRoleId(role.getId());
pref = guildPreferenceRepository.save(pref);
} else {
throw new NumberFormatException();
}
} catch (NumberFormatException e) {
logger.error("default_role_id error. Key: " + setting.id + " Val: " + setting.val);
return false;
}
break;
case "welcome":
if (value.toLowerCase().equals("true") || value.toLowerCase().equals("false")) {
boolean result = Boolean.parseBoolean(value);
pref.setWelcome(result);
pref = guildPreferenceRepository.save(pref);
} else {
logger.error("welcome error. Key: " + setting.id + " Val: " + setting.val);
return false;
}
break;
case "welcome_chanel_id":
try {
TextChannel chanel = guild.getTextChannelById(value);
if (chanel != null) {
pref.setWelcomeChanelID(chanel.getId());
pref = guildPreferenceRepository.save(pref);
} else {
throw new NumberFormatException();
}
} catch (NumberFormatException e) {
logger.error("welcome_chanel_id error. Key: " + setting.id + " Val: " + setting.val);
return false;
}
break;
case "welcome_message":
pref.setWelcomeMessage(value);
pref = guildPreferenceRepository.save(pref);
break;
case "daily_madame":
if (value.toLowerCase().equals("true") || value.toLowerCase().equals("false")) {
boolean result = Boolean.parseBoolean(value);
pref.setDailyMadame(result);
pref = guildPreferenceRepository.save(pref);
} else {
logger.error("daily_madame error. Key: " + setting.id + " Val: " + setting.val);
return false;
}
break;
}
}
return true;
}
private List<Value> getTextChannels(Guild guild){
List<Value> channels = new ArrayList<>();
for(TextChannel channel : guild.getTextChannels()){
channels.add(new Value(channel.getName(), channel.getId()));
}
return channels;
}
private List<Value> getRoles(Guild guild){
List<Value> roles = new ArrayList<>();
for(Role role : guild.getRoles()){
roles.add(new Value(role.getName(), role.getId()));
}
return roles;
}
public GuildPreferenceEntity getPreference(Guild guild){
List<GuildPreferenceEntity> guildPrefList = guildPreferenceRepository.findByGuildId(guild.getId());
GuildPreferenceEntity guildPref;
if(guildPrefList.isEmpty()){
logger.info("Generate default pref for " + guild.getName());
guildPref = GuildPreferenceEntity.getDefault(guild);
guildPreferenceRepository.save(guildPref);
}
else
guildPref = guildPrefList.get(0);
return guildPref;
}
}

View File

@ -6,13 +6,17 @@ import net.Broken.DB.Entity.UserEntity;
import net.Broken.DB.Repository.UserRepository; import net.Broken.DB.Repository.UserRepository;
import net.Broken.MainBot; import net.Broken.MainBot;
import net.Broken.RestApi.Commands.Play; import net.Broken.RestApi.Commands.Play;
import net.Broken.Tools.SettingsUtils;
import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Guild;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -23,15 +27,20 @@ import java.util.List;
@Controller @Controller
public class GeneralWebView { public class GeneralWebView {
@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {}
@RequestMapping("/") @RequestMapping("/")
public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId){ public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId, @CookieValue(value = "token", defaultValue = "") String token){
Guild guild = MainBot.jda.getGuildById(guildId); Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null) if(guild != null)
model.addAttribute("guild_name", guild.getName()); model.addAttribute("guild_name", guild.getName());
else else
model.addAttribute("guild_name", ""); model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL")); model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
return CheckPage.getPageIfReady("index"); return CheckPage.getPageIfReady("index");
@ -51,6 +60,28 @@ public class GeneralWebView {
return "oauthCallback"; return "oauthCallback";
} }
@RequestMapping("/settings")
public String settings(Model model, @CookieValue(value = "guild", defaultValue = "") String guildId, @CookieValue(value = "token", defaultValue = "") String token){
SettingsUtils settingsUtils = SettingsUtils.getInstance();
if(settingsUtils.checkPermission(token, guildId)){
Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null)
model.addAttribute("guild_name", guild.getName());
else
model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("settings", SettingsUtils.getInstance().extractSettings(guild));
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
return CheckPage.getPageIfReady("settings");
}
else
throw new ForbiddenException();
}

View File

@ -1,6 +1,7 @@
package net.Broken.webView; package net.Broken.webView;
import net.Broken.MainBot; import net.Broken.MainBot;
import net.Broken.Tools.SettingsUtils;
import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.Guild;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -13,14 +14,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
@Controller @Controller
public class MusicWebView { public class MusicWebView {
@RequestMapping("/music") @RequestMapping("/music")
public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId){ public String music(Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId, @CookieValue(value = "token", defaultValue = "1") String token){
Guild guild = MainBot.jda.getGuildById(guildId); Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null) if(guild != null)
model.addAttribute("guild_name", guild.getName()); model.addAttribute("guild_name", guild.getName());
else else
model.addAttribute("guild_name", ""); model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL")); model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("isAdmin", SettingsUtils.getInstance().checkPermission(token, guildId));
return CheckPage.getPageIfReady("music"); return CheckPage.getPageIfReady("music");
} }

View File

@ -0,0 +1,42 @@
package net.Broken.webView;
import net.Broken.MainBot;
import net.dv8tion.jda.core.entities.Guild;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.RequestDispatcher;
@Controller
public class MyErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError(HttpServletRequest request, Model model, @CookieValue(value = "guild", defaultValue = "1") String guildId){
Guild guild = MainBot.jda.getGuildById(guildId);
if(guild != null)
model.addAttribute("guild_name", guild.getName());
else
model.addAttribute("guild_name", "");
model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error/404";
}
}
return "error";
}
@Override
public String getErrorPath() {
return "/error";
}
}

View File

@ -15,6 +15,8 @@ public class RegisterWebView {
public String music(@RequestParam(value="id", required = true, defaultValue = "") String id, Model model){ public String music(@RequestParam(value="id", required = true, defaultValue = "") String id, Model model){
model.addAttribute("id", id); model.addAttribute("id", id);
model.addAttribute("redirect_url", System.getenv("OAUTH_URL")); model.addAttribute("redirect_url", System.getenv("OAUTH_URL"));
model.addAttribute("isAdmin",false);
return CheckPage.getPageIfReady("register"); return CheckPage.getPageIfReady("register");
} }
} }

View File

@ -1,198 +0,0 @@
<!DOCTYPE html>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Claptrap Bot</title>
<link rel="icon"
type="image/x-icon"
href="favicon.png"/>
<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="/css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="/css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>
</head>
<body class="blue-grey lighten-5" >
<nav class="blue-grey darken-4 z-depth-3" role="navigation" >
<div class="nav-wrapper container">
<a id="logo-container" href="/" class="brand-logo">Claptrap Bot</a>
<ul class="right hide-on-med-and-down">
<li class="" th:classappend="(${page} == 'home')? 'active' : ''">
<a class="waves-effect waves-light" href="/">Home</a>
</li>
<li class="" th:classappend="(${page} == 'music')? 'active' : ''">
<a class="waves-effect waves-light" href="/music">Music Control</a>
</li>
<li id="nav-bar-account">
<a class="dropdown-account dropdown-trigger" data-target="dropdown_connected"><i class="material-icons">account_box</i></a>
</li>
</ul>
<a href="#" data-target="nav-mobile" class="sidenav-trigger"><i class="material-icons">menu</i></a>
</div>
</nav>
<ul id="nav-mobile" class="sidenav">
<li class="center" th:classappend="(${page} == 'home')? 'active' : ''">
<a class="waves-effect waves-light sidenav-trigger" href="/" data-target="slide-out">Home</a>
</li>
<li class="center" th:classappend="(${page} == 'music')? 'active' : ''">
<a class="waves-effect waves-light" href="/music">Music Control</a>
</li>
<li><div class="divider"></div></li>
<li><a class="center nav-change-guild">Change Guild</a></li>
<li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a>
</li>
<li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Playlists</a>
</li>
<li class="divider"></li>
<li><a class="center red-text nav-disconnect" style="font-weight: bold">Disconnect</a></li>
</ul>
<!-- Dropdown connected -->
<ul id="dropdown_connected" class="dropdown-content ">
<li>
<a class="center blue-grey-text text-darken-4 tooltipped" data-position="left" data-delay="50" data-tooltip="It's you !" id="nav-name" style="font-weight: bold"></a>
</li>
<li class="divider"></li>
<li><a class="center nav-change-guild" >Change Guild</a></li>
<li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a>
</li>
<li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Playlists</a>
</li>
<li class="divider"></li>
<li><a class="center red-text nav-disconnect" style="font-weight: bold">Disconnect</a></li>
</ul>
<!--________________________________________-->
<!-- Connection modal -->
<!--________________________________________-->
<div id="modal_connection" class="modal">
<div class="modal-content">
<div class="row center">
<div class="col s12">
<h3 class="" style="font-weight: bold">Sign in</h3>
</div>
</div>
<div class="row center" style="margin-bottom: 0px">
<form name="login_form" id="login_form" action="javascript:void(0);" onsubmit="tryConnection()">
<div class="row" style="margin-bottom: 0px">
<div class="input-field col s6 offset-s3">
<i class="material-icons prefix">account_box</i>
<input name="username" id="user_input" type="text" class="validate"/>
<label for="user_input" >User Name</label>
<span class="helper-text" data-error="User not registered!"></span>
</div>
</div>
<div class="row">
<div class="input-field col s6 offset-s3">
<i class="material-icons prefix">security</i>
<input name="password" id="password_input" type="password" class="validate"/>
<label for="password_input">Password</label>
<span class="helper-text" data-error="Wrong password!"></span>
</div>
</div>
<div class="row" style="margin-bottom: 10px">
<button id="btn-submit-connect" class="btn waves-effect waves-light light-green darken-1 scale-transition scale-out" type="submit" name="action" >
Submit<i class="material-icons right">send</i>
</button>
</div>
<div class="row">
<a class="btn waves-effect waves-light brown" href="/register">
Create account<i class="material-icons right">person_add</i>
</a>
</div>
</form>
</div>
</div>
</div>
<!--________________________________________-->
<!-- Guild modal -->
<!--________________________________________-->
<div id="modal_guild" class="modal">
<div class="modal-content" style="padding-bottom: 0px">
<div class="row" style="margin-bottom: 0px">
<h3 class="col s12 center">Guild Selection</h3>
<div class="col offset-s4 s4 center">
<form id="guild_form" action="#" class="left-align">
</form>
</div>
</div>
</div>
<div class="modal-footer">
<a href="#" id="btn_ok_guild" class="modal-action modal-close waves-effect waves-green btn-flat disabled">Ok</a>
</div>
</div>
<p id="radioTemplateGuild" class="" style="visibility: hidden; display: none ">
<label>
<input name="guildRadio" class="with-gap" type="radio" value="@id" id="@id"/>
<span>@name</span>
</label>
</p>
<!--__________________________________________________________-->
<!-- -->
<!-- END -->
<!-- -->
<!--__________________________________________________________-->
<div class="section no-pad-bot main" id="index-banner">
<div class="center row">
<div class="row center valign-wrapper">
<div class="col s6">
<h1 class="red-text text-darken-2 "><b>Oops!</b></h1>
<h2 class=" blue-grey-text "><b>Page not found!</b></h2>
<a class="btn btn-large light-green darken-3 waves-effect" href="/">
<i class="large material-icons">home</i>
</a>
</div>
<div class="col s6">
<img class="" src="/img/404.gif" style="border:none;outline: none">
</div>
</div>
<div class="row">
</div>
</div>
</div>
<!-- Scripts-->
<script src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
<script src="/js/materialize.js"></script>
<script src="/js/navabar.js"></script>
<script src="/js/js.cookie.js"></script>
</body>
</html>

View File

@ -0,0 +1,64 @@
var post_json = {settings : []};
$(document).ready(function(){
$('select').formSelect();
modal_loading = $('#modal_loading');
modal_loading.modal({
dismissible: false
});
$('#sendBtn').click(function () {
var select = $('.collect-select');
select.each(function(){
var val = $(this).find("select").val();
var id = $(this).attr("id");
if(val != null){
post_json["settings"].push({"id" : id, "val" : val});
}
});
var switch_collected = $('.collect-switch');
switch_collected.each(function(){
var val = $(this).is(':checked').toString();
var id = $(this).attr("id");
if(val != null){
post_json["settings"].push({"id" : id, "val" : val});
}
});
var text = $('.collect-text');
text.each(function(){
var val = $(this).val();
var id = $(this).attr("id");
if(val != null){
post_json["settings"].push({"id" : id, "val" : val});
}
});
modal_loading.modal('open');
$.ajax({
type: "POST",
contentType: 'application/json',
url: "/api/settings",
data: JSON.stringify(post_json)
}).done(function (data) {
console.log("ok");
M.toast({html: '<i class="small material-icons" style="margin-right: 0.3em">done</i>Save Successful ! ', classes: 'rounded green'});
modal_loading.modal('close');
}).fail(function (data) {
console.log(data);
modal_loading.modal('close');
M.toast({html: '<i class="small material-icons" style="margin-right: 0.3em">report</i>Save Failed ! ', classes: 'rounded red'});
});
})
});

View File

@ -6,6 +6,9 @@ var urlsToCache = [
'/oauthCallback', '/oauthCallback',
'/css/materialize.css', '/css/materialize.css',
'/js/navabar.js', '/js/navabar.js',
'/js/materialize.js',
'/js/jquery-3.3.1.min.js',
'/js/js.cookie.js',
'/manifest.json' '/manifest.json'
]; ];
@ -23,7 +26,6 @@ self.addEventListener('install', function (event) {
}); });
self.addEventListener('fetch', function (event) { self.addEventListener('fetch', function (event) {
console.log("fetch");
event.respondWith( event.respondWith(
caches.match(event.request) caches.match(event.request)
.then(function (response) { .then(function (response) {

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Claptrap Bot</title>
<link rel="icon"
type="image/x-icon"
href="/favicon.png"/>
<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link rel="manifest" href="/manifest.json"/>
<meta name="theme-color" content="#263238"/>
</head>
<body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div>
<div class="section no-pad-bot main" id="index-banner">
<div class="center row">
<div class="row center">
<div class="col l6 m12 s12">
<h1 class="red-text text-darken-2 "><b>Oops!</b></h1>
<h2 class=" blue-grey-text "><b>Page not found!</b></h2>
<a class="btn btn-large light-green darken-3 waves-effect" href="/">
<i class="large material-icons">home</i>
</a>
</div>
<div class="col l6 m12 s12">
<img class="" src="/img/404.gif" style="border:none;outline: none"/>
</div>
</div>
<div class="row">
</div>
</div>
</div>
<script>
var needLogin = true;
</script>
<!-- Scripts-->
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
<script th:src="@{/js/materialize.js}"></script>
<script th:src="@{/js/navabar.js}"></script>
<script th:src="@{/js/js.cookie.js}"></script>
<script src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" crossorigin="anonymous"></script>
<script th:src="@{/js/workerRegister.js}"></script>
</body>
</html>

View File

@ -12,7 +12,7 @@
<!-- LOGIN --> <!-- LOGIN -->
<!--__________________________________________________________--> <!--__________________________________________________________-->
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/> <link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<div th:fragment="header (page, guild_name, redirect_url)"> <div th:fragment="header (page, guild_name, redirect_url, isAdmin)">
<nav class="blue-grey darken-4 z-depth-3" role="navigation" > <nav class="blue-grey darken-4 z-depth-3" role="navigation" >
<div class="nav-wrapper container"> <div class="nav-wrapper container">
<a id="logo-container" href="/" class="brand-logo" style="white-space: nowrap">Claptrap Bot</a> <a id="logo-container" href="/" class="brand-logo" style="white-space: nowrap">Claptrap Bot</a>
@ -56,8 +56,12 @@
<a class="waves-effect waves-light" href="/music">Music Control</a> <a class="waves-effect waves-light" href="/music">Music Control</a>
</li> </li>
<li><div class="divider"></div></li> <li><div class="divider"></div></li>
<li><a class="center nav-change-guild">Change Guild</a></li> <li><a class="center nav-change-guild">Change Guild</a></li>
<li class="center bot-settings" th:classappend="(${page} == 'settings')? 'active' : ''" th:style="${isAdmin} ? '' : 'visibility: hidden; display: none;'">
<a class="waves-effect waves-light" href="/settings">Bot Settings</a>
</li>
<li> <li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a> <a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a>
</li> </li>
@ -82,6 +86,9 @@
</li> </li>
<li class="divider"></li> <li class="divider"></li>
<li><a class="center nav-change-guild" >Change Guild</a></li> <li><a class="center nav-change-guild" >Change Guild</a></li>
<li class="bot-settings" th:style="${isAdmin} ? '' : 'visibility: hidden; display: none;'">
<a class=" center waves-effect waves-light " href="/settings" >Bot Settings</a>
</li>
<li> <li>
<a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a> <a class="center tooltipped" data-position="left" data-delay="50" data-tooltip="Under Development!">My Account</a>
</li> </li>

View File

@ -20,7 +20,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div> <div th:replace="header :: header ('home',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner"> <div class="section no-pad-bot main" id="index-banner">
<div class="center center-align"> <div class="center center-align">

View File

@ -19,7 +19,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('music',${guild_name},${redirect_url})">...</div> <div th:replace="header :: header ('music',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner"> <div class="section no-pad-bot main" id="index-banner">
<div class="row"> <div class="row">

View File

@ -19,7 +19,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('home',${guild_name},${redirect_url})">...</div> <div th:replace="header :: header ('home',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner"> <div class="section no-pad-bot main" id="index-banner">
<div class="row center" > <div class="row center" >

View File

@ -16,7 +16,7 @@
<body class="blue-grey lighten-5" > <body class="blue-grey lighten-5" >
<div th:replace="header :: header ('','',${redirect_url})">...</div> <div th:replace="header :: header ('','',${redirect_url},${isAdmin})">...</div>

View File

@ -0,0 +1,159 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0"/>
<title>Claptrap Bot</title>
<link rel="icon"
type="image/x-icon"
href="/favicon.png"/>
<!-- CSS -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
<link href="css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen,projection"/>
<link rel="manifest" href="/manifest.json"/>
<meta name="theme-color" content="#263238"/>
</head>
<body class="blue-grey lighten-5" >
<!--/*@thymesVar id="guild_name" type="java.lang.String"*/-->
<!--/*@thymesVar id="redirect_url" type="java.lang.String"*/-->
<!--/*@thymesVar id="settings" type="java.util.ArrayList<net.Broken.RestApi.Data.Settings.GetSettingsData>"*/-->
<!--/*@thymesVar id="isAdmin" type="java.lang.Boolean"*/-->
<div th:replace="header :: header ('settings',${guild_name},${redirect_url}, ${isAdmin})">...</div>
<div class="section no-pad-bot main" id="index-banner">
<h2 class="center" th:text="${guild_name}"></h2>
<div th:each="setting : ${settings}">
<div class="section row">
<div class="col l6 offset-l3 m10 offset-m1 s10 offset-s1">
<h5 th:text="${setting.name}" style="font-weight: bold"></h5>
<div class="switch" th:if="${setting.type.toString() == 'BOOL'}">
<label>
Off
<input class="collect-switch" type="checkbox" th:id="${setting.id}" th:checked="${setting.current}"/>
<span class="lever"></span>
On
</label>
</div>
<div th:id="${setting.id}" class="input-field col l12 m12 s12 collect-select" th:if="${setting.type.toString() == 'LIST'}">
<select>
<option disabled="disabled" th:selected="${setting.current} == ' '" value="" >Choose your option</option>
<option th:each="val : ${setting.values}" th:value="${val.id}" th:text="${#strings.capitalize(val.name)}" th:selected="${setting.current} == ${val.id}"></option>
</select>
</div>
<div class="input-field col l12 m12 s12 collect" th:if="${setting.type.toString() == 'STRING'}">
<input th:id="${setting.id}" placeholder="Use @name variable" th:value="${setting.current}" id="first_name" type="text" class="validate collect-text"/>
</div>
</div>
</div>
<div class="row">
<div class="divider col l6 offset-l3"></div>
</div>
</div>
<div class="row">
<div class="col s12 center">
<a id="sendBtn" class="waves-effect waves-light btn green">Save<i class="material-icons left">save</i></a>
</div>
</div>
</div>
<div id="modal_loading" class="modal valign-wrapper">
<div class="modal-content" >
<div class="row center">
<h3 class="col l12 m12 s12 center">Please wait</h3>
</div>
<div class="row center" >
<div class="preloader-wrapper big active">
<div class="spinner-layer spinner-blue">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
<div class="spinner-layer spinner-red">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
<div class="spinner-layer spinner-yellow">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
<div class="spinner-layer spinner-green">
<div class="circle-clipper left">
<div class="circle"></div>
</div>
<div class="gap-patch">
<div class="circle"></div>
</div>
<div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var needLogin = true;
</script>
<!-- Scripts-->
<script th:src="@{/js/jquery-3.3.1.min.js}"></script>
<script th:src="@{/js/materialize.js}"></script>
<script th:src="@{/js/navabar.js}"></script>
<script th:src="@{/js/js.cookie.js}"></script>
<script th:src="@{/js/settings.js}"></script>
<script src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" crossorigin="anonymous"></script>
<script th:src="@{/js/workerRegister.js}"></script>
</body>
</html>