Work on Dashboard, settings, web API, etc etc
12
pom.xml
@@ -110,6 +110,18 @@
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.21</version>
|
||||
</dependency>
|
||||
|
||||
<!--Thymeleaf-->
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf</groupId>
|
||||
<artifactId>thymeleaf</artifactId>
|
||||
<version>3.0.9.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-java8time</artifactId>
|
||||
<version>3.0.1.RELEASE</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.cloudcraftgaming.discal;
|
||||
|
||||
import com.cloudcraftgaming.discal.api.database.DatabaseManager;
|
||||
import com.cloudcraftgaming.discal.api.file.ReadFile;
|
||||
import com.cloudcraftgaming.discal.api.message.MessageManager;
|
||||
import com.cloudcraftgaming.discal.api.network.google.Authorization;
|
||||
import com.cloudcraftgaming.discal.api.object.BotSettings;
|
||||
@@ -9,14 +8,17 @@ import com.cloudcraftgaming.discal.bot.internal.consolecommand.ConsoleCommandExe
|
||||
import com.cloudcraftgaming.discal.bot.internal.network.discordpw.UpdateListData;
|
||||
import com.cloudcraftgaming.discal.bot.listeners.ReadyEventListener;
|
||||
import com.cloudcraftgaming.discal.bot.module.command.*;
|
||||
import com.cloudcraftgaming.discal.web.endpoints.v1.*;
|
||||
import com.cloudcraftgaming.discal.web.utils.SparkUtils;
|
||||
import sx.blah.discord.api.ClientBuilder;
|
||||
import sx.blah.discord.api.IDiscordClient;
|
||||
import sx.blah.discord.api.events.EventDispatcher;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.util.DiscordException;
|
||||
|
||||
import static spark.Spark.*;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 1/2/2017.
|
||||
@@ -27,25 +29,23 @@ import static spark.Spark.*;
|
||||
public class Main {
|
||||
public static String version = "1.1.0";
|
||||
public static IDiscordClient client;
|
||||
public static BotSettings botSettings;
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 1) // Needs a bot token provided
|
||||
throw new IllegalArgumentException("BotSettings file has not been specified!!");
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
//Get bot settings
|
||||
botSettings = ReadFile.readBotSettings(args[0]);
|
||||
Properties p = new Properties();
|
||||
p.load(new FileReader(new File("settings.properties")));
|
||||
BotSettings.init(p);
|
||||
|
||||
client = createClient(botSettings.getBotToken());
|
||||
client = createClient(BotSettings.TOKEN.get());
|
||||
if (client == null)
|
||||
throw new NullPointerException("Failed to log in! Client cannot be null!");
|
||||
|
||||
UpdateListData.init(botSettings);
|
||||
UpdateListData.init();
|
||||
|
||||
Authorization.getAuth().init(botSettings);
|
||||
Authorization.getAuth().init();
|
||||
|
||||
//Connect to MySQL
|
||||
DatabaseManager.getManager().connectToMySQL(botSettings);
|
||||
DatabaseManager.getManager().connectToMySQL();
|
||||
DatabaseManager.getManager().createTables();
|
||||
|
||||
//Register events
|
||||
@@ -69,49 +69,8 @@ public class Main {
|
||||
//Load language files.
|
||||
MessageManager.loadLangs();
|
||||
|
||||
//Register Spark endpoints...
|
||||
if (botSettings.shouldRunWebAPI()) {
|
||||
before("/api/*", (request, response) -> {
|
||||
if (!request.requestMethod().equalsIgnoreCase("POST")) {
|
||||
System.out.println("Denied '" + request.requestMethod() + "' access from: " + request.ip());
|
||||
halt(405, "Method not allowed");
|
||||
}
|
||||
//Check authorization
|
||||
if (request.headers().contains("Authorization") && !request.headers("Authorization").equals("API_KEY")) {
|
||||
halt(401, "Unauthorized");
|
||||
}
|
||||
if (!request.contentType().equalsIgnoreCase("application/json")) {
|
||||
halt(400, "Bad Request");
|
||||
}
|
||||
});
|
||||
|
||||
path("/api/v1/discal", () -> {
|
||||
before("/*", (q, a) -> System.out.println("Received API call from: " + q.ip() + "; Host:" + q.host()));
|
||||
path("/guild", () -> {
|
||||
path("/settings", () -> {
|
||||
post("/get", GuildEndpoint::getSettings);
|
||||
post("/update", GuildEndpoint::updateSettings);
|
||||
});
|
||||
path("/info", () -> post("/from-user/list", GuildEndpoint::getUserGuilds));
|
||||
});
|
||||
path("/announcement", () -> {
|
||||
post("/get", AnnouncementEndpoint::getAnnouncement);
|
||||
post("/create", AnnouncementEndpoint::createAnnouncement);
|
||||
post("/update", AnnouncementEndpoint::updateAnnouncement);
|
||||
post("/delete", AnnouncementEndpoint::deleteAnnouncement);
|
||||
post("/list", AnnouncementEndpoint::listAnnouncements);
|
||||
});
|
||||
path("/calendar", () -> {
|
||||
post("/get", CalendarEndpoint::getCalendar);
|
||||
post("/list", CalendarEndpoint::listCalendars);
|
||||
post("time", TimeEndpoint::getTime);
|
||||
});
|
||||
path("/rsvp", () -> {
|
||||
post("/get", RsvpEndpoint::getRsvp);
|
||||
post("/update", RsvpEndpoint::updateRsvp);
|
||||
});
|
||||
});
|
||||
}
|
||||
//Start spark
|
||||
SparkUtils.initSpark();
|
||||
|
||||
//Accept commands
|
||||
ConsoleCommandExecutor.init();
|
||||
|
||||
@@ -43,11 +43,10 @@ public class DatabaseManager {
|
||||
/**
|
||||
* Connects to the MySQL server specified.
|
||||
*
|
||||
* @param bs The BotSettings with Db info to connect to.
|
||||
*/
|
||||
public void connectToMySQL(BotSettings bs) {
|
||||
public void connectToMySQL() {
|
||||
try {
|
||||
MySQL mySQL = new MySQL(bs.getDbHostName(), bs.getDbPort(), bs.getDbDatabase(), bs.getDbPrefix(), bs.getDbUser(), bs.getDbPass());
|
||||
MySQL mySQL = new MySQL(BotSettings.SQL_HOST.get(), BotSettings.SQL_PORT.get(), BotSettings.SQL_DB.get(), BotSettings.SQL_PREFIX.get(), BotSettings.SQL_USER.get(), BotSettings.SQL_PASSWORD.get());
|
||||
|
||||
Connection mySQLConnection = mySQL.openConnection();
|
||||
databaseInfo = new DatabaseInfo(mySQL, mySQLConnection, mySQL.getPrefix());
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.cloudcraftgaming.discal.api.file;
|
||||
|
||||
import com.cloudcraftgaming.discal.Main;
|
||||
import com.cloudcraftgaming.discal.api.object.BotSettings;
|
||||
import com.cloudcraftgaming.discal.api.utils.ExceptionHandler;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -17,77 +17,12 @@ import java.util.Map;
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
public class ReadFile {
|
||||
public static BotSettings readBotSettings(String fileAndPath) {
|
||||
BotSettings settings = new BotSettings();
|
||||
try {
|
||||
// Open the file that is the first
|
||||
FileInputStream fstream = new FileInputStream(fileAndPath);
|
||||
// Get the object of DataInputStream
|
||||
DataInputStream in = new DataInputStream(fstream);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
String strLine;
|
||||
//Read File Line By Line
|
||||
|
||||
int line = 0;
|
||||
while ((strLine = br.readLine()) != null) {
|
||||
if (line == 0) {
|
||||
settings.setBotToken(strLine);
|
||||
}
|
||||
if (line == 1) {
|
||||
settings.setDbHostName(strLine);
|
||||
}
|
||||
if (line == 2) {
|
||||
settings.setDbPort(strLine);
|
||||
}
|
||||
if (line == 3) {
|
||||
settings.setDbDatabase(strLine);
|
||||
}
|
||||
if (line == 4) {
|
||||
settings.setDbPrefix(strLine);
|
||||
}
|
||||
if (line == 5) {
|
||||
settings.setDbUser(strLine);
|
||||
}
|
||||
if (line == 6) {
|
||||
settings.setDbPass(strLine);
|
||||
}
|
||||
if (line == 7) {
|
||||
settings.setLangPath(strLine);
|
||||
}
|
||||
if (line == 9) {
|
||||
settings.setBotsPwToken(strLine);
|
||||
}
|
||||
if (line == 10) {
|
||||
settings.setGoogleClientId(strLine);
|
||||
}
|
||||
if (line == 11) {
|
||||
settings.setGoogleClientSecret(strLine);
|
||||
}
|
||||
if (line == 12) {
|
||||
settings.setRunDatabaseUpdater(strLine.equalsIgnoreCase("true"));
|
||||
}
|
||||
if (line == 13) {
|
||||
settings.setRunWebAPI(strLine.equalsIgnoreCase("true"));
|
||||
}
|
||||
line++;
|
||||
|
||||
}
|
||||
//Close the input stream
|
||||
br.close();
|
||||
in.close();
|
||||
fstream.close();
|
||||
} catch (Exception e) {//Catch exception if any
|
||||
System.err.println("Error: " + e.getMessage());
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "ConstantConditions"})
|
||||
public static Map<String, Map<String, String>> readAllLangFiles() {
|
||||
Map<String, Map<String, String>> langs = new HashMap<>();
|
||||
|
||||
try {
|
||||
File langDir = new File(Main.botSettings.getLangPath());
|
||||
File langDir = new File(BotSettings.LANG_PATH.get());
|
||||
|
||||
for (File f : langDir.listFiles()) {
|
||||
// Open the file
|
||||
@@ -106,4 +41,4 @@ public class ReadFile {
|
||||
}
|
||||
return langs;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,8 @@ public class Authorization {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void init(BotSettings settings) {
|
||||
clientData = new ClientData(settings.getGoogleClientId(), settings.getGoogleClientSecret());
|
||||
public void init() {
|
||||
clientData = new ClientData(BotSettings.GOOGLE_CLIENT_ID.get(), BotSettings.GOOGLE_CLIENT_SECRET.get());
|
||||
}
|
||||
|
||||
public void requestCode(MessageReceivedEvent event, GuildSettings settings) {
|
||||
|
||||
@@ -1,134 +1,34 @@
|
||||
package com.cloudcraftgaming.discal.api.object;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 11/10/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
public class BotSettings {
|
||||
private String botToken;
|
||||
public enum BotSettings {
|
||||
SQL_HOST, SQL_USER, SQL_PASSWORD,
|
||||
SQL_DB, SQL_PORT, SQL_PREFIX, TOKEN, SECRET,
|
||||
LANG_PATH, PW_TOKEN, GOOGLE_CLIENT_ID,
|
||||
GOOGLE_CLIENT_SECRET, RUN_API;
|
||||
|
||||
private String dbHostName;
|
||||
private String dbPort;
|
||||
private String dbDatabase;
|
||||
private String dbPrefix;
|
||||
private String dbUser;
|
||||
private String dbPass;
|
||||
private String val;
|
||||
|
||||
private String langPath;
|
||||
|
||||
private String botsPwToken;
|
||||
|
||||
private String googleClientId;
|
||||
private String googleClientSecret;
|
||||
|
||||
private boolean runDatabaseUpdater;
|
||||
|
||||
private boolean runWebAPI;
|
||||
|
||||
//Getters
|
||||
public String getBotToken() {
|
||||
return botToken;
|
||||
BotSettings() {
|
||||
}
|
||||
|
||||
public String getDbHostName() {
|
||||
return dbHostName;
|
||||
public static void init(Properties properties) {
|
||||
for (BotSettings s : values()) {
|
||||
s.set(properties.getProperty(s.name()));
|
||||
}
|
||||
}
|
||||
|
||||
public String getDbPort() {
|
||||
return dbPort;
|
||||
public String get() {
|
||||
return val;
|
||||
}
|
||||
|
||||
public String getDbDatabase() {
|
||||
return dbDatabase;
|
||||
}
|
||||
|
||||
public String getDbPrefix() {
|
||||
return dbPrefix;
|
||||
}
|
||||
|
||||
public String getDbUser() {
|
||||
return dbUser;
|
||||
}
|
||||
|
||||
public String getDbPass() {
|
||||
return dbPass;
|
||||
}
|
||||
|
||||
public String getLangPath() {
|
||||
return langPath;
|
||||
}
|
||||
|
||||
public String getBotsPwToken() {
|
||||
return botsPwToken;
|
||||
}
|
||||
|
||||
public String getGoogleClientId() {
|
||||
return googleClientId;
|
||||
}
|
||||
|
||||
public String getGoogleClientSecret() {
|
||||
return googleClientSecret;
|
||||
}
|
||||
|
||||
public boolean shouldRunDatabaseUpdater() {
|
||||
return runDatabaseUpdater;
|
||||
}
|
||||
|
||||
public boolean shouldRunWebAPI() {
|
||||
return runWebAPI;
|
||||
}
|
||||
|
||||
//Setters
|
||||
public void setBotToken(String _botToken) {
|
||||
botToken = _botToken;
|
||||
}
|
||||
|
||||
public void setDbHostName(String _dbHostName) {
|
||||
dbHostName = _dbHostName;
|
||||
}
|
||||
|
||||
public void setDbPort(String _port) {
|
||||
dbPort = _port;
|
||||
}
|
||||
|
||||
public void setDbDatabase(String _database) {
|
||||
dbDatabase = _database;
|
||||
}
|
||||
|
||||
public void setDbPrefix(String _prefix) {
|
||||
dbPrefix = _prefix;
|
||||
}
|
||||
|
||||
public void setDbUser(String _user) {
|
||||
dbUser = _user;
|
||||
}
|
||||
|
||||
public void setDbPass(String _pass) {
|
||||
dbPass = _pass;
|
||||
}
|
||||
|
||||
public void setLangPath(String _path) {
|
||||
langPath = _path;
|
||||
}
|
||||
|
||||
public void setBotsPwToken(String _token) {
|
||||
botsPwToken = _token;
|
||||
}
|
||||
|
||||
public void setGoogleClientId(String _id) {
|
||||
googleClientId = _id;
|
||||
}
|
||||
|
||||
public void setGoogleClientSecret(String _secret) {
|
||||
googleClientSecret = _secret;
|
||||
}
|
||||
|
||||
public void setRunDatabaseUpdater(boolean _run) {
|
||||
runDatabaseUpdater = _run;
|
||||
}
|
||||
|
||||
public void setRunWebAPI(boolean _run) {
|
||||
runWebAPI = _run;
|
||||
public void set(String val) {
|
||||
this.val = val;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.cloudcraftgaming.discal.api.object.web;
|
||||
|
||||
import com.cloudcraftgaming.discal.Main;
|
||||
import com.cloudcraftgaming.discal.api.database.DatabaseManager;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
public class WebGuild {
|
||||
private String id;
|
||||
private String name;
|
||||
private String iconUrl;
|
||||
|
||||
//Bot settings
|
||||
private String botNick;
|
||||
private String prefix;
|
||||
|
||||
//Getters
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return iconUrl;
|
||||
}
|
||||
|
||||
public String getBotNick() {
|
||||
return botNick;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
//Setters
|
||||
public void setId(String _id) {
|
||||
id = _id;
|
||||
}
|
||||
|
||||
public void setName(String _name) {
|
||||
name = _name;
|
||||
}
|
||||
|
||||
public void setIcon(String _url) {
|
||||
iconUrl = _url;
|
||||
}
|
||||
|
||||
public void setBotNick(String _nick) {
|
||||
botNick = _nick;
|
||||
}
|
||||
|
||||
public void setPrefix(String _prefix) {
|
||||
prefix = _prefix;
|
||||
}
|
||||
|
||||
//Functions
|
||||
public WebGuild fromGuild(IGuild g) {
|
||||
id = g.getStringID();
|
||||
name = g.getName();
|
||||
iconUrl = g.getIconURL();
|
||||
|
||||
botNick = Main.getSelfUser().getNicknameForGuild(g);
|
||||
prefix = DatabaseManager.getManager().getSettings(g.getLongID()).getPrefix();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.cloudcraftgaming.discal.api.utils;
|
||||
|
||||
import com.cloudcraftgaming.discal.Main;
|
||||
import com.cloudcraftgaming.discal.api.object.web.WebGuild;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
public class GuildUtils {
|
||||
public static List<WebGuild> getGuilds(String userId) {
|
||||
List<WebGuild> guilds = new ArrayList<>();
|
||||
for (IGuild g : Main.client.getGuilds()) {
|
||||
if (g.getUserByID(Long.valueOf(userId)) != null) {
|
||||
guilds.add(new WebGuild().fromGuild(g));
|
||||
}
|
||||
}
|
||||
return guilds;
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,12 @@ import org.json.JSONObject;
|
||||
* For Project: DisCal
|
||||
*/
|
||||
public class UpdateListData {
|
||||
private static String token;
|
||||
|
||||
/**
|
||||
* Initiates the data updater with a valid token.
|
||||
*
|
||||
* @param settings BotSettings containing the API token.
|
||||
*/
|
||||
public static void init(BotSettings settings) {
|
||||
token = settings.getBotsPwToken();
|
||||
public static void init() {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +31,7 @@ public class UpdateListData {
|
||||
|
||||
JSONObject json = new JSONObject().put("server_count", serverCount);
|
||||
|
||||
HttpResponse<JsonNode> response = Unirest.post("https://bots.discord.pw/api/bots/265523588918935552/stats").header("Authorization", token).header("Content-Type", "application/json").body(json).asJson();
|
||||
HttpResponse<JsonNode> response = Unirest.post("https://bots.discord.pw/api/bots/265523588918935552/stats").header("Authorization", BotSettings.PW_TOKEN.get()).header("Content-Type", "application/json").body(json).asJson();
|
||||
} catch (Exception e) {
|
||||
//Handle issue.
|
||||
System.out.println("Failed to update Discord PW list metadata!");
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.cloudcraftgaming.discal.web.handler;
|
||||
|
||||
import com.cloudcraftgaming.discal.Main;
|
||||
import com.cloudcraftgaming.discal.api.database.DatabaseManager;
|
||||
import com.cloudcraftgaming.discal.api.object.GuildSettings;
|
||||
import com.cloudcraftgaming.discal.api.object.web.WebGuild;
|
||||
import org.json.JSONException;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import sx.blah.discord.handle.obj.IGuild;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static spark.Spark.halt;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "ThrowableNotThrown"})
|
||||
public class DashboardHandler {
|
||||
public static String handleGuildSelect(Request request, Response response) {
|
||||
try {
|
||||
String guildId = request.queryParams("guild");
|
||||
|
||||
WebGuild wg = new WebGuild().fromGuild(Main.client.getGuildByID(Long.valueOf(guildId)));
|
||||
|
||||
Map m = DiscordAccountHandler.getHandler().getAccount(request.session().id());
|
||||
|
||||
if (m.containsKey("selected")) {
|
||||
m.remove("selected");
|
||||
}
|
||||
|
||||
m.put("selected", wg);
|
||||
|
||||
if (m.containsKey("settings")) {
|
||||
m.remove("settings");
|
||||
}
|
||||
|
||||
if (m.containsKey("ext")) {
|
||||
m.remove("ext");
|
||||
}
|
||||
|
||||
DiscordAccountHandler.getHandler().appendAccount(m, request.session().id());
|
||||
|
||||
response.redirect("/dashboard/guild");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
response.redirect("/dashboard");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
halt(500, "Internal Server Exception");
|
||||
}
|
||||
return response.body();
|
||||
}
|
||||
|
||||
public static String handleSettingsSelect(Request request, Response response) {
|
||||
try {
|
||||
String settings = request.queryParams("settings");
|
||||
|
||||
Map m = new HashMap();
|
||||
m.put("settings", settings);
|
||||
|
||||
if (settings.equalsIgnoreCase("ext")) {
|
||||
//Extension handling
|
||||
String ext = request.queryParams("ext");
|
||||
m.put("ext", ext);
|
||||
}
|
||||
|
||||
DiscordAccountHandler.getHandler().appendAccount(m, request.session().id());
|
||||
|
||||
response.redirect("/dashboard/guild");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
response.redirect("/dashboard");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
halt(500, "Internal Server Exception");
|
||||
}
|
||||
return response.body();
|
||||
}
|
||||
|
||||
public static String handleSettingsUpdate(Request request, Response response) {
|
||||
try {
|
||||
if (request.queryParams().contains("bot-nick")) {
|
||||
//Update bot nickname...
|
||||
Map m = DiscordAccountHandler.getHandler().getAccount(request.session().id());
|
||||
WebGuild g = (WebGuild) m.get("selected");
|
||||
|
||||
g.setBotNick(request.queryParams("bot-nick"));
|
||||
|
||||
//TODO: Set Bot nickname!!!
|
||||
|
||||
IGuild guild = Main.client.getGuildByID(Long.valueOf(g.getId()));
|
||||
guild.setUserNickname(Main.getSelfUser(), g.getBotNick());
|
||||
} else if (request.queryParams().contains("prefix")) {
|
||||
//Update prefix...
|
||||
Map m = DiscordAccountHandler.getHandler().getAccount(request.session().id());
|
||||
WebGuild g = (WebGuild) m.get("selected");
|
||||
|
||||
g.setPrefix(request.queryParams("prefix"));
|
||||
|
||||
GuildSettings settings = DatabaseManager.getManager().getSettings(Long.valueOf(g.getId()));
|
||||
|
||||
settings.setPrefix(g.getPrefix());
|
||||
|
||||
DatabaseManager.getManager().updateSettings(settings);
|
||||
}
|
||||
|
||||
//Finally redirect back to the dashboard
|
||||
response.redirect("/dashboard/guild");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
halt(500, "Internal Server Exception");
|
||||
}
|
||||
return response.body();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.cloudcraftgaming.discal.web.handler;
|
||||
|
||||
import com.cloudcraftgaming.discal.api.utils.GuildUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class DiscordAccountHandler {
|
||||
private static DiscordAccountHandler instance;
|
||||
|
||||
private HashMap<String, Map> discordAccounts = new HashMap<>();
|
||||
|
||||
//Instance handling
|
||||
private DiscordAccountHandler() {
|
||||
} //Prevent initialization
|
||||
|
||||
public static DiscordAccountHandler getHandler() {
|
||||
if (instance == null) {
|
||||
instance = new DiscordAccountHandler();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
//Boolean/checkers
|
||||
public boolean hasAccount(String sessionId) {
|
||||
return discordAccounts.containsKey(sessionId);
|
||||
}
|
||||
|
||||
//Getters
|
||||
public Map getAccount(String sessionId) {
|
||||
if (discordAccounts.containsKey(sessionId)) {
|
||||
return discordAccounts.get(sessionId);
|
||||
} else {
|
||||
//Not logged in...
|
||||
Map m = new HashMap();
|
||||
m.put("loggedIn", false);
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
||||
public Map findAccount(String userId) {
|
||||
for (Map m : discordAccounts.values()) {
|
||||
if (m.containsKey("id")) {
|
||||
if (m.get("id").equals(userId)) {
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//Functions
|
||||
public void addAccount(Map m, String sessionId) {
|
||||
if (discordAccounts.containsKey(sessionId)) {
|
||||
discordAccounts.remove(sessionId);
|
||||
}
|
||||
discordAccounts.put(sessionId, m);
|
||||
}
|
||||
|
||||
public void appendAccount(Map m, String sessionId) {
|
||||
if (discordAccounts.containsKey(sessionId)) {
|
||||
Map exist = discordAccounts.get(sessionId);
|
||||
exist.putAll(m);
|
||||
} else {
|
||||
discordAccounts.put(sessionId, m);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAccount(String userId) {
|
||||
Map m = findAccount(userId);
|
||||
if (m != null) {
|
||||
m.remove("guilds");
|
||||
m.put("guilds", GuildUtils.getGuilds(userId));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAccount(String sessionId) {
|
||||
if (hasAccount(sessionId)) {
|
||||
discordAccounts.remove(sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.cloudcraftgaming.discal.web.oauth;
|
||||
|
||||
import com.cloudcraftgaming.discal.Main;
|
||||
import com.cloudcraftgaming.discal.api.object.BotSettings;
|
||||
import com.cloudcraftgaming.discal.api.utils.GuildUtils;
|
||||
import com.cloudcraftgaming.discal.web.handler.DiscordAccountHandler;
|
||||
import com.mashape.unirest.http.HttpResponse;
|
||||
import com.mashape.unirest.http.JsonNode;
|
||||
import com.mashape.unirest.http.Unirest;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static spark.Spark.halt;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
@SuppressWarnings({"ThrowableNotThrown", "unchecked"})
|
||||
public class DiscordLoginHandler {
|
||||
public static String handleDiscordCode(Request request, Response response) {
|
||||
try {
|
||||
String code = request.queryParams("code");
|
||||
|
||||
//POST request to discord for access...
|
||||
HttpResponse<JsonNode> httpResponse = Unirest.post("https://discordapp.com/api/v6/oauth2/token").header("Content-Type", "application/x-www-form-urlencoded").field("client_id", Main.client.getApplicationClientID()).field("client_secret", BotSettings.SECRET.get()).field("grant_type", "authorization_code").field("code", code).field("redirect_uri", "http://localhost:4567/account/login").asJson();
|
||||
|
||||
JSONObject info = new JSONObject(httpResponse.getBody()).getJSONObject("object");
|
||||
|
||||
//GET request for user info...
|
||||
HttpResponse<JsonNode> userDataResponse = Unirest.get("https://discordapp.com/api/v6/users/@me").header("Authorization", "Bearer " + info.getString("access_token")).asJson();
|
||||
|
||||
JSONObject userInfo = new JSONObject(userDataResponse.getBody()).getJSONObject("object");
|
||||
|
||||
//Saving session info and access info to memory until moved into the database...
|
||||
Map m = new HashMap();
|
||||
m.put("loggedIn", true);
|
||||
|
||||
m.put("id", userInfo.getString("id"));
|
||||
m.put("username", userInfo.getString("username"));
|
||||
m.put("discrim", userInfo.getString("discriminator"));
|
||||
|
||||
//Get guilds...
|
||||
m.put("guilds", GuildUtils.getGuilds(userInfo.getString("id")));
|
||||
|
||||
DiscordAccountHandler.getHandler().addAccount(m, request.session().id());
|
||||
|
||||
//Finally redirect to the dashboard seamlessly.
|
||||
response.redirect("/dashboard");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
response.redirect("/dashboard");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
halt(500, "Internal Server Exception");
|
||||
}
|
||||
return response.body();
|
||||
}
|
||||
|
||||
public static String handleLogout(Request request, Response response) {
|
||||
try {
|
||||
DiscordAccountHandler.getHandler().removeAccount(request.session().id());
|
||||
|
||||
response.redirect("/");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
halt(500, "Internal Server Exception");
|
||||
}
|
||||
return response.body();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.cloudcraftgaming.discal.web.utils;
|
||||
|
||||
import com.cloudcraftgaming.discal.web.endpoints.v1.*;
|
||||
import com.cloudcraftgaming.discal.web.handler.DashboardHandler;
|
||||
import com.cloudcraftgaming.discal.web.handler.DiscordAccountHandler;
|
||||
import com.cloudcraftgaming.discal.web.oauth.DiscordLoginHandler;
|
||||
import spark.ModelAndView;
|
||||
|
||||
import static spark.Spark.*;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
public class SparkUtils {
|
||||
@SuppressWarnings("ThrowableNotThrown")
|
||||
public static void initSpark() {
|
||||
staticFileLocation("/web/public"); // Main site location
|
||||
|
||||
//Register the API Endpoints
|
||||
before("/api/*", (request, response) -> {
|
||||
if (!request.requestMethod().equalsIgnoreCase("POST")) {
|
||||
System.out.println("Denied '" + request.requestMethod() + "' access from: " + request.ip());
|
||||
halt(405, "Method not allowed");
|
||||
}
|
||||
//Check authorization
|
||||
if (request.headers().contains("Authorization") && !request.headers("Authorization").equals("API_KEY")) {
|
||||
//TODO: Actually check auth!!! < Just lazy right now
|
||||
halt(401, "Unauthorized");
|
||||
}
|
||||
//Only accept json because its easier to parse and handle.
|
||||
if (!request.contentType().equalsIgnoreCase("application/json")) {
|
||||
halt(400, "Bad Request");
|
||||
}
|
||||
});
|
||||
|
||||
//API endpoints
|
||||
path("/api/v1", () -> {
|
||||
before("/*", (q, a) -> System.out.println("Received API call from: " + q.ip() + "; Host:" + q.host()));
|
||||
path("/guild", () -> {
|
||||
path("/settings", () -> {
|
||||
post("/get", GuildEndpoint::getSettings);
|
||||
post("/update", GuildEndpoint::updateSettings);
|
||||
});
|
||||
path("/info", () -> post("/from-user/list", GuildEndpoint::getUserGuilds));
|
||||
});
|
||||
path("/announcement", () -> {
|
||||
post("/get", AnnouncementEndpoint::getAnnouncement);
|
||||
post("/create", AnnouncementEndpoint::createAnnouncement);
|
||||
post("/update", AnnouncementEndpoint::updateAnnouncement);
|
||||
post("/delete", AnnouncementEndpoint::deleteAnnouncement);
|
||||
post("/list", AnnouncementEndpoint::listAnnouncements);
|
||||
});
|
||||
path("/calendar", () -> {
|
||||
post("/get", CalendarEndpoint::getCalendar);
|
||||
post("/list", CalendarEndpoint::listCalendars);
|
||||
post("time", TimeEndpoint::getTime);
|
||||
});
|
||||
path("/rsvp", () -> {
|
||||
post("/get", RsvpEndpoint::getRsvp);
|
||||
post("/update", RsvpEndpoint::updateRsvp);
|
||||
});
|
||||
});
|
||||
|
||||
//Various endpoints for thyme because yeah...
|
||||
path("/account", () -> {
|
||||
get("/login", DiscordLoginHandler::handleDiscordCode);
|
||||
get("/logout", DiscordLoginHandler::handleLogout);
|
||||
|
||||
path("/dashboard", () -> {
|
||||
get("/select", DashboardHandler::handleGuildSelect);
|
||||
get("/guild", DashboardHandler::handleSettingsSelect);
|
||||
get("/update", DashboardHandler::handleSettingsUpdate);
|
||||
});
|
||||
});
|
||||
|
||||
//Templates and pages...
|
||||
get("/", (rq, rs) -> new ModelAndView(DiscordAccountHandler.getHandler().getAccount(rq.session().id()), "pages/index"), new ThymeleafTemplateEngine());
|
||||
get("/home", (rq, rs) -> new ModelAndView(DiscordAccountHandler.getHandler().getAccount(rq.session().id()), "pages/index"), new ThymeleafTemplateEngine());
|
||||
get("/dashboard", (rq, rs) -> new ModelAndView(DiscordAccountHandler.getHandler().getAccount(rq.session().id()), "pages/dashboard/dashboard"), new ThymeleafTemplateEngine());
|
||||
get("/dashboard/guild", (rq, rs) -> new ModelAndView(DiscordAccountHandler.getHandler().getAccount(rq.session().id()), "pages/dashboard/guild"), new ThymeleafTemplateEngine());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package com.cloudcraftgaming.discal.web.utils;
|
||||
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
|
||||
import org.thymeleaf.templatemode.TemplateMode;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
import spark.ModelAndView;
|
||||
import spark.TemplateEngine;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Nova Fox on 12/17/17.
|
||||
* Website: www.cloudcraftgaming.com
|
||||
* For Project: DisCal-Discord-Bot
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ThymeleafTemplateEngine extends TemplateEngine {
|
||||
|
||||
private static final String DEFAULT_PREFIX = "web/public/";
|
||||
private static final String DEFAULT_SUFFIX = ".html";
|
||||
private static final long DEFAULT_CACHE_TTL_MS = 3600000L;
|
||||
|
||||
private org.thymeleaf.TemplateEngine templateEngine;
|
||||
|
||||
/**
|
||||
* Constructs a default thymeleaf template engine.
|
||||
* Defaults prefix (template directory in resource path) to templates/ and suffix to .html
|
||||
*/
|
||||
public ThymeleafTemplateEngine() {
|
||||
this(DEFAULT_PREFIX, DEFAULT_SUFFIX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a thymeleaf template engine with specified prefix and suffix
|
||||
*
|
||||
* @param prefix the prefix (template directory in resource path)
|
||||
* @param suffix the suffix (e.g. .html)
|
||||
*/
|
||||
public ThymeleafTemplateEngine(String prefix, String suffix) {
|
||||
ITemplateResolver defaultTemplateResolver = createDefaultTemplateResolver(prefix, suffix);
|
||||
initialize(defaultTemplateResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a thymeleaf template engine with a proprietary initialize
|
||||
*
|
||||
* @param templateResolver the template resolver.
|
||||
*/
|
||||
public ThymeleafTemplateEngine(ITemplateResolver templateResolver) {
|
||||
initialize(templateResolver);
|
||||
}
|
||||
|
||||
private static ITemplateResolver createDefaultTemplateResolver(String prefix, String suffix) {
|
||||
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
|
||||
templateResolver.setTemplateMode(TemplateMode.HTML);
|
||||
|
||||
templateResolver.setPrefix(
|
||||
prefix != null ? prefix : DEFAULT_PREFIX
|
||||
);
|
||||
|
||||
templateResolver.setSuffix(
|
||||
suffix != null ? suffix : DEFAULT_SUFFIX
|
||||
);
|
||||
|
||||
templateResolver.setCacheTTLMs(DEFAULT_CACHE_TTL_MS);
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes and sets the template resolver
|
||||
*/
|
||||
private void initialize(ITemplateResolver templateResolver) {
|
||||
templateEngine = new org.thymeleaf.TemplateEngine();
|
||||
templateEngine.setTemplateResolver(templateResolver);
|
||||
templateEngine.addDialect(new Java8TimeDialect());
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public String render(ModelAndView modelAndView) {
|
||||
return render(modelAndView, Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the specified template (usually the template name).
|
||||
* Output will be written into a String that will be returned from calling this method,
|
||||
* once template processing has finished.
|
||||
*
|
||||
* @param modelAndView model and view
|
||||
* @param locale A Locale object represents a specific geographical, political, or cultural region
|
||||
* @return processed template
|
||||
*/
|
||||
public String render(ModelAndView modelAndView, Locale locale) {
|
||||
Object model = modelAndView.getModel();
|
||||
|
||||
if (model instanceof Map) {
|
||||
Context context = new Context(locale);
|
||||
context.setVariables((Map<String, Object>) model);
|
||||
return templateEngine.process(modelAndView.getViewName(), context);
|
||||
} else {
|
||||
throw new IllegalArgumentException("modelAndView.getModel() must return a java.util.Map");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 634 KiB |
|
After Width: | Height: | Size: 909 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 581 KiB |
|
After Width: | Height: | Size: 100 KiB |
BIN
src/main/resources/web/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
160
src/main/resources/web/public/pages/about.html
Normal file
@@ -0,0 +1,160 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/styles/global.css">
|
||||
<title>About - DisCal Bot</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DISCAL BOT</h1>
|
||||
<a href="/index.html">Home</a>
|
||||
<a class="active" href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1>DisCal Bot - About</h1>
|
||||
|
||||
<div id="invite">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/logos/discord-logo-white.png" style="max-width: 300px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>Invite To Discord Server</h3>
|
||||
<p>
|
||||
Seen enough of this amazing bot? Add it to your Discord server by clicking the button below!
|
||||
<br><br>
|
||||
Once you add, scroll down to the "DisCal Setup" Button and click it!
|
||||
</p>
|
||||
<a href="https://discordapp.com/oauth2/authorize?client_id=265523588918935552&scope=bot&permissions=201845824redirect_uri=https%3A%2F%2Fwww.discalbot.com%2Fpages%2Fsetup.html"
|
||||
target="_blank">
|
||||
<button>Invite to Server Now!</button>
|
||||
</a>
|
||||
|
||||
<p>
|
||||
Need to see more to convince you? Scroll down the page! You'll learn just how useful DisCal really
|
||||
is and why you need it!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="commands">
|
||||
<div class="image-wrapper" style="float: right">
|
||||
<img src="/assets/images/examples/DisCal-Event-Creation.jpg"
|
||||
style="max-width: 300px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>Commands</h3>
|
||||
<p>
|
||||
DisCal is designed to be intuitive and powerful.
|
||||
<br><br><br>
|
||||
Discal uses simple to understand commands. With a customizable prefix, ability to mention DisCal
|
||||
directly, and more DisCal's command system is designed for users in mind.
|
||||
<br><br><br>
|
||||
Because of this, DisCal has a ton of commands that allow you to fully utilize it! View all of the
|
||||
documentation on the commands for DisCal by clicking the button below!
|
||||
</p>
|
||||
<a href="/pages/commands.html">
|
||||
<button>View Commands</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="trello">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/other/discal-trello.png" style="max-width: 450px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>Trello & To-Do</h3>
|
||||
<p>
|
||||
DisCal is meant to be useful, collaborative, and easy to use.
|
||||
<br><br><br>
|
||||
We use Trello to track everything we are currently working on. This way, you can see what our
|
||||
progress is, comment on what you want us to work on, or add suggestions and requests.
|
||||
<br><br><br>
|
||||
</p>
|
||||
<a href="https://trello.com/b/OuFo5aXu/discal" target="_blank">
|
||||
<button>Check out DisCal's Trello</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="support">
|
||||
<div class="image-wrapper" style="float: right">
|
||||
<img src="/assets/images/other/support-server.png" style="max-width: 450px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>Official Support Server</h3>
|
||||
<p>
|
||||
If DisCal was meant to be useful, so are we! Join our official DisCal Discord server for extra info
|
||||
and help.
|
||||
<br><br><br>
|
||||
Need help with something? Visit our support channel!
|
||||
<br><br>
|
||||
Want to request a feature we somehow didn't think to add? Send us a message in our feature request
|
||||
channel!
|
||||
<br><br><br>
|
||||
Just want to be part of the amazing community using this Bot? Join the discord!
|
||||
</p>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">
|
||||
<button>Join The Support Server</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="source">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/other/discal-github.jpg" style="max-width: 450px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>Source Code</h3>
|
||||
<p>
|
||||
DisCal was built upon open source APIs. It wouldn't be fair if we didn't open source DisCal.
|
||||
<br><br><br>
|
||||
All of the source code behind this amazing bot can be found on the GitHub repo linked below!
|
||||
<br><br><br>
|
||||
We encourage those who can to fork the repository and help code DisCal! We are community driven and
|
||||
really love any help we can get. Even just a simple typo fix.
|
||||
<br><br>
|
||||
And of course, we will credit you with the changes and even give you a special contributor role!!!
|
||||
</p>
|
||||
<a href="https://github.com/NovaFox161/DisCal-Discord-Bot" target="_blank">
|
||||
<button>DisCal GitHub</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="patreon">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/other/novafox-patreon-page.png"
|
||||
style="max-width: 450px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>Become a Patron Today!</h3>
|
||||
<p>
|
||||
DisCal is developed freely, open source, and completely unlimited. However, we still need to support
|
||||
ourselves.
|
||||
<br> <br>
|
||||
Rather than making DisCal limited for free users, we decided to open a patreon, by becoming a patron
|
||||
you help support and fund the further development and support for DisCal. Please consider becoming a
|
||||
patron!
|
||||
</p>
|
||||
<a target="_blank" href="https://www.patreon.com/Novafox">
|
||||
<button>Become a Patron!</button>
|
||||
</a>
|
||||
<p>
|
||||
By becoming a patron, you not only support us and DisCal's development, but will get exclusive
|
||||
access to features early before anyone else!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© Nova Maday 2017. All rights reserved. <a href="/pages/policy/privacy.html">Privacy Policy</a></p>
|
||||
</footer>
|
||||
</html>
|
||||
704
src/main/resources/web/public/pages/commands.html
Normal file
@@ -0,0 +1,704 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/styles/global.css">
|
||||
<title>Commands - DisCal Bot</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DISCAL BOT</h1>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a class="active" href="/pages/commands.html">Commands</a>
|
||||
<a href="setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1>DisCal Bot - About</h1>
|
||||
<p>
|
||||
Below is full documentation on DisCal commands.
|
||||
<br> <br> <br>
|
||||
This documentation includes the command, acceptable arguments, an example, and an explanation for each
|
||||
and every command DisCal has to offer.
|
||||
<br> <br>
|
||||
Since many commands have sub-commands and functions, this page will be split into sections for each.
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<div class="image-wrapper" style="max-width: 900px; position: center;">
|
||||
<img src="/assets/images/examples/event_demo.gif"
|
||||
style="max-width: 300px; max-height: 300px; padding: 10px;">
|
||||
<img src="/assets/images/examples/calendar_demo.gif"
|
||||
style="max-width: 300px; max-height: 300px; padding: 10px;">
|
||||
<img src="/assets/images/examples/announcement_demo.gif"
|
||||
style="max-width: 300px; max-height: 300px; padding: 10px;">
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="calendar">
|
||||
<h2>!calendar commands</h2>
|
||||
<h3>Alias: !cal</h3>
|
||||
|
||||
<table style="border-color: #ef0813;" border="#ef0813" cellspacing="0" cellpadding="4">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Command</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Acceptable Arguments</strong></span>
|
||||
</h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Example</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Description</strong></span></h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !calendar create</td>
|
||||
<td style="text-align: center;"> !calendar create <name, spaces allowed></td>
|
||||
<td style="text-align: center;"> !calendar create example Calendar</td>
|
||||
<td style="text-align: center;"> Creates a calendar with the specified name (and starts the
|
||||
creation process). DisCal will walk you through this process as well.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !calendar edit</td>
|
||||
<td style="text-align: center;"> !calendar edit</td>
|
||||
<td style="text-align: center;"> !calendar edit</td>
|
||||
<td style="text-align: center;"> This launches the calendar editor if you have already
|
||||
created a calendar. Use this to change any calendar values with the regular calendar
|
||||
creation commands if you entered something wrong.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !calendar description</td>
|
||||
<td style="text-align: center;"> !calendar description <desc, spaces allowed)</td>
|
||||
<td style="text-align: center;"> !calendar create My example calendar</td>
|
||||
<td style="text-align: center;"> Sets the description of the new calendar.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!calendar timezone </td>
|
||||
<td style="text-align: center;">!calendar timezone <timezone> </td>
|
||||
<td style="text-align: center;">!calendar timezone America/Chicago </td>
|
||||
<td style="text-align: center;"> Sets the calendar's timezone. Must be a valid timezone
|
||||
according to the <a
|
||||
href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List"
|
||||
target="_blank">TZ database.</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!calendar review</td>
|
||||
<td style="text-align: center;">!calendar review</td>
|
||||
<td style="text-align: center;">!calendar review</td>
|
||||
<td style="text-align: center;">Displays info about the calendar you are creating, allows
|
||||
verifying of correct date before creation.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!calendar cancel</td>
|
||||
<td style="text-align: center;">!calendar cancel</td>
|
||||
<td style="text-align: center;">!calendar cancel</td>
|
||||
<td style="text-align: center;">Cancels the creation of a calendar. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !calendar confirm</td>
|
||||
<td style="text-align: center;"> !calendar confirm</td>
|
||||
<td style="text-align: center;"> !calendar confirm</td>
|
||||
<td style="text-align: center;"> Confirms that the calendar info is correct and creates the
|
||||
new calendar
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!calendar delete</td>
|
||||
<td style="text-align: center;">!calendar delete</td>
|
||||
<td style="text-align: center;">!calendar delete</td>
|
||||
<td style="text-align: center;">Deletes the calendar from Google and DisCal's database.
|
||||
<br><br>
|
||||
<strong>NOTE: </strong>You must have the "MANAGE SERVER" permission in order to delete
|
||||
the calendar!!!
|
||||
<br><br>
|
||||
<strong>NOTE: </strong>Once deleted, you may create a new calendar.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!calendar remove</td>
|
||||
<td style="text-align: center;">!calendar remove</td>
|
||||
<td style="text-align: center;">!calendar remove</td>
|
||||
<td style="text-align: center;">Deletes the calendar from Google and DisCal's database.
|
||||
<br><br>
|
||||
<strong>NOTE: </strong>You must have the "MANAGE SERVER" permission in order to delete
|
||||
the calendar!!!
|
||||
<br><br>
|
||||
<strong>NOTE: </strong>Once deleted, you may create a new calendar.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="event">
|
||||
<h2>!event commands</h2>
|
||||
|
||||
<table style="border-color: #ef0813;" border="#ef0813" cellspacing="0" cellpadding="4">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Command</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Acceptable Arguments</strong></span>
|
||||
</h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Example</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Description</strong></span></h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !event create</td>
|
||||
<td style="text-align: center;">!event create<br>!event create <name/summary> </td>
|
||||
<td style="text-align: center;"> !event create<br>!event create My event name/summary</td>
|
||||
<td style="text-align: center;">Begins creation of a new event. DisCal will walk you through
|
||||
this process as well! The event summary is technically it's name according to google!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !event edit</td>
|
||||
<td style="text-align: center;">!event edit <event ID> </td>
|
||||
<td style="text-align: center;"> !event edit 9aiifsgpbaqfjh00iufeu2qsu8 </td>
|
||||
<td style="text-align: center;">Begins editing an already created event that has been confirmed.
|
||||
Use this to go back and change anything in the event with the same commands you used during
|
||||
creation.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event copy</td>
|
||||
<td style="text-align: center;">!event copy <event ID></td>
|
||||
<td style="text-align: center;">!event copy 9aiifsgpbaqfjh00iufeu2qsu8 </td>
|
||||
<td style="text-align: center;">Copies an event from the Guild's calendar. Once the event has
|
||||
been copied, DisCal will walk you through editing the event's settings to add it to the
|
||||
calendar.<br/><br/>NOTE: As of the latest version, this WILL NOT copy recurring event's
|
||||
recurring properties. This is a work in progress!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !event summary</td>
|
||||
<td style="text-align: center;">!event summary <summary, spaces allowed></td>
|
||||
<td style="text-align: center;">!event summary My event summary </td>
|
||||
<td style="text-align: center;">Sets the event's summary. This is technically its name according
|
||||
to Google!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event description </td>
|
||||
<td style="text-align: center;">!event description <description, spaces allowed></td>
|
||||
<td style="text-align: center;">!event description My example Event </td>
|
||||
<td style="text-align: center;">Sets the event's description. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event startDate <br/>!event start</td>
|
||||
<td style="text-align: center;">
|
||||
<p> !event startDate <date/time></p>
|
||||
<p>!event start <date/time></p>
|
||||
</td>
|
||||
<td style="text-align: center;">!event startDate 2017/01/31-10:00:00<br/>!event start
|
||||
2017/04/20-09:15:00
|
||||
</td>
|
||||
<td style="text-align: center;">Sets the event's start time. Format is shown. This is in
|
||||
military/24 hour time.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event endDate <br/>!event end</td>
|
||||
<td style="text-align: center;">!event endDate <date/Time><br/>!event end <date/Time>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p> !event endDate 2017/01/31-14:45:00<br/>!event end 2017/04/31-03:30:00</p>
|
||||
</td>
|
||||
<td style="text-align: center;">Sets the event's ending time and date. Format is shown. This is
|
||||
in military/24 hour time. <br>**NOTE** This is just how long the event lasts, like an hour
|
||||
or a day. In the event you want an event repeating over months etc, use the RECUR commands!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event review</td>
|
||||
<td style="text-align: center;">!event review </td>
|
||||
<td style="text-align: center;">!event review </td>
|
||||
<td style="text-align: center;"> Displays the event's info before entered onto the
|
||||
calendar.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event cancel </td>
|
||||
<td style="text-align: center;"> !event cancel</td>
|
||||
<td style="text-align: center;">!event cancel </td>
|
||||
<td style="text-align: center;">Cancels creation of a new event. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event confirm </td>
|
||||
<td style="text-align: center;">!event confirm</td>
|
||||
<td style="text-align: center;">!event confirm</td>
|
||||
<td style="text-align: center;">Confirms the event you have been creating and adds it to the
|
||||
calendar.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event delete </td>
|
||||
<td style="text-align: center;">!event delete <event id> </td>
|
||||
<td style="text-align: center;">!event delete 9aiifsgpbaqfjh00iufeu2qsu8 </td>
|
||||
<td style="text-align: center;"> Deletes the event with the given ID. This is the event Id
|
||||
from the calendar. found when the event is listed from the !events command.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !event view</td>
|
||||
<td style="text-align: center;">!event view <event id></td>
|
||||
<td style="text-align: center;">!event view 9aiifsgpbaqfjh00iufeu2qsu8 </td>
|
||||
<td style="text-align: center;">Prints out detailed info on the specified event. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event color</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event color <color name><br/>!event color <color ID><br/>!event color <hex><br/>!event
|
||||
color list</p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event color Mac_And_Cheese</p>
|
||||
<p>!event color 1<br/>!event color E1E1E1<br/>!event color list</p>
|
||||
</td>
|
||||
<td style="text-align: center;">Sets the event's color.<br/>At the moment this color is only
|
||||
reflected in the event and announcement embeds and does not appear on the google calendar
|
||||
itself.<br/>Please visit <a
|
||||
href="https://www.cloudcraftgaming.com/discal/command/event/color" target="_blank">here</a> to
|
||||
see all supported colors (Google supported colors only)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event image</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event image <image url>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event image http://i.imgur.com/b7r1f.jpg</p>
|
||||
</td>
|
||||
<td style="text-align: center;">This will add an image to the event which will be displayed
|
||||
during announcements as well as when the event is listed with the !events command. At the
|
||||
moment .jpg, .jpeg and .png image links are supported.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event recur</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event recur <true/false></p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event recur true</p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Sets whether or not the event should recur (repeat).</p>
|
||||
<p>If set to 'true' DisCal will walk you through the steps to configure its recurrence to
|
||||
how you would like.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event frequency</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event frequency <TYPE></p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event frequency DAILY</p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Sets the frequency of the recurring event.</p>
|
||||
<p>Valid types are: DAILY, WEEKLY, MONTHLY, YEARLY</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event count</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event count <amount></p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event count 10</p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Sets how many times the event should recur.</p>
|
||||
<p>NOTE: Use '-1' or '0' to make it infinitely recur.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!event interval</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event interval <number></p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!event interval 2</p>
|
||||
</td>
|
||||
<td style="text-align: center;">Sets how the event will recur based on it's respective
|
||||
frequency.<br/><br/>EXAMPLE: If frequency is MONTHLY, setting interval to '2' will make the
|
||||
event recur every OTHER month, whereas 1 will recur EVERY month.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!rsvp</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!rsvp <option> <eventId></p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!rsvp ontime rtk8sua2bolcs8votf02lgep9s</p>
|
||||
</td>
|
||||
<td style="text-align: center;">This allows you to set your rsvp status for an event. Status
|
||||
commands include: Ontime, Late, Unsure and Not. List may also be used to list all rsvps and
|
||||
remove may be used to remove your rsvp from the list.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="announcement">
|
||||
<h2>!announcement commands</h2>
|
||||
<h3>Aliases: !a !ann !announce !alert !alerts</h3>
|
||||
|
||||
<table style="border-color: #ef0813;" border="#ef0813" cellspacing="0" cellpadding="4">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Command</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Acceptable Arguments</strong></span>
|
||||
</h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Example</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Description</strong></span></h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement create</td>
|
||||
<td style="text-align: center;">!announcement create</td>
|
||||
<td style="text-align: center;">!announcement create</td>
|
||||
<td style="text-align: center;">Starts the Announcement Creator. DisCal will now walk you
|
||||
through the process of creating new announcements!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement edit</td>
|
||||
<td style="text-align: center;">!announcement edit <ID></td>
|
||||
<td style="text-align: center;">!announcement edit 55210ce8-8fed-43ca-9642-3225525baed9
|
||||
</td>
|
||||
<td style="text-align: center;">Edits an existing announcement that has already been confirmed.
|
||||
Use this to go back and change any announcement values with the normal creation commands.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement copy</td>
|
||||
<td style="text-align: center;">!announcement copy <ID></td>
|
||||
<td style="text-align: center;">!announcement copy 55210ce8-8fed-43ca-9642-3225525baed9
|
||||
</td>
|
||||
<td style="text-align: center;">Copies an existing announcement as a "template" so you may
|
||||
quickly create another announcement.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement type </td>
|
||||
<td style="text-align: center;">!announcement type <type></td>
|
||||
<td style="text-align: center;">!announcement type UNIVERSAL</td>
|
||||
<td style="text-align: center;">
|
||||
<p>The type of announcement this is.<br/>UNIVERSAL means it is for ALL future events.<br/>SPECIFIC
|
||||
means it is for one specific event (will auto delete once fired).<br/>COLOR (or COLOUR)
|
||||
means it will only fire for an event with the same color.<br/>RECUR functions like a
|
||||
SPECIFIC type but for recurring events (and does not auto delete).</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !announcement event</td>
|
||||
<td style="text-align: center;">!announcement event <id> </td>
|
||||
<td style="text-align: center;"> !announcement event 9aiifsgpbaqfjh00iufeu2qsu8</td>
|
||||
<td style="text-align: center;">Specifies the event this announcement is for.<br/>ONLY NEEDED IF
|
||||
TYPE = SPECIFIC or RECUR<br/><br/>If type is RECUR: Please specify the "base" ID which is a
|
||||
recurring event's ID without the "_" and everything that follows that. (If the underscore
|
||||
and following is specified, DisCal will parse it out and ignore it).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !announcement channel</td>
|
||||
<td style="text-align: center;">!announcement channel <channel name></td>
|
||||
<td style="text-align: center;">!announcement channel calendar</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Sets the channel the announcement will be sent in. This is the channel NAME not ID,
|
||||
DisCal handles that for you. </p>
|
||||
<p>**Please note: If the channel is deleted the announcement will silently fail to send.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement hours</td>
|
||||
<td style="text-align: center;">!announcement hours <amount></td>
|
||||
<td style="text-align: center;">!announcement hours 1</td>
|
||||
<td style="text-align: center;">The amount of hours PRIOR to the event this announcement will be
|
||||
fired.<br/>This number is added to the minutes in DisCal.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement minutes </td>
|
||||
<td style="text-align: center;">!announcement minutes <amount></td>
|
||||
<td style="text-align: center;">!announcement minutes 25</td>
|
||||
<td style="text-align: center;">The amount of minutes PRIOR to the event this announcement will
|
||||
be fired.<br/>This number is added to the hours in DisCal. The minimum amount of time an
|
||||
announcement can be set for is 1 minute.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement review </td>
|
||||
<td style="text-align: center;">!announcement review</td>
|
||||
<td style="text-align: center;">!announcement review</td>
|
||||
<td style="text-align: center;"> Allows you to review the Announcement info before
|
||||
completion, so you may correct any errors or alter the settings.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !announcement confirm</td>
|
||||
<td style="text-align: center;">!announcement confirm</td>
|
||||
<td style="text-align: center;">!announcement confirm</td>
|
||||
<td style="text-align: center;">Confirms and finishes Announcement creation.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !announcement delete</td>
|
||||
<td style="text-align: center;">!announcement delete <id></td>
|
||||
<td style="text-align: center;">!announcement delete 55210ce8-8fed-43ca-9642-3225525baed9
|
||||
</td>
|
||||
<td style="text-align: center;"> Deletes an existing announcement and stops it from being
|
||||
fired or used again.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement subscribe </td>
|
||||
<td style="text-align: center;">!announcement subscribe <id> (option)</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!announcement subscribe 55210ce8-8fed-43ca-9642-3225525baed9</p>
|
||||
<p>!announcement subscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 user1 user2 user3 etc</p>
|
||||
<p>!announcement subscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 role1 role2 user1 etc</p>
|
||||
<p>!announcement subscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 everyone</p>
|
||||
<p>!announcement subscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 here</p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Subscribes you to the announcement. Whenever this announcement sends, you will be
|
||||
mentioned at the top of it.</p>
|
||||
<p> </p>
|
||||
<p>Optionally, you may FORCE subscribe people or roles to announcements. Include their name,
|
||||
role or there is built in support for everyone and here mentions. No @ required. (At the
|
||||
time of writing this @ will actually not work at all)</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement unsubscribe</td>
|
||||
<td style="text-align: center;">!announcement unsubscribe <id> (option)</td>
|
||||
<td style="text-align: center;">
|
||||
<p>!announcement subscribe 55210ce8-8fed-43ca-9642-3225525baed9</p>
|
||||
<p>!announcement unsubscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 user1 user2</p>
|
||||
<p>!announcement unsubscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 role1 role2</p>
|
||||
<p>!announcement unsubscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 everyone</p>
|
||||
<p>!announcement unsubscribe </p>
|
||||
<p>55210ce8-8fed-43ca-9642-3225525baed9 here</p>
|
||||
</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Unsubscribes you from the announcement. Now whenever it sends, you will NO LONGER be
|
||||
mentioned. </p>
|
||||
<p> </p>
|
||||
<p>Optionally, you may FORCE unsubscribe people to announcements. Include their name, role
|
||||
or there is built in support for everyone and here mentions. No @ required. (At the time
|
||||
of writing this @ will actually not work at all)</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement view</td>
|
||||
<td style="text-align: center;">!announcement view <id></td>
|
||||
<td style="text-align: center;">!announcement view 55210ce8-8fed-43ca-9642-3225525baed9</td>
|
||||
<td style="text-align: center;">Displays info about the specif announcement, if the announcement
|
||||
with that ID exists.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement list</td>
|
||||
<td style="text-align: center;">!announcement list <amount OR all></td>
|
||||
<td style="text-align: center;">!announcement list 10<br/>or<br/>!announcement list ALL</td>
|
||||
<td style="text-align: center;">Will list either the amount of IDs specified or if "ALL" will
|
||||
list every announcement for your Guild.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!announcement color</td>
|
||||
<td style="text-align: center;">!announcement color <COLOR></td>
|
||||
<td style="text-align: center;">!announcement color BLUE</td>
|
||||
<td style="text-align: center;">Functions just like '!event color <COLOR>' and sets the
|
||||
announcement's color.<br/><br/>NOTE: Only applicable if type is COLOR
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="other">
|
||||
<h2>All Other Commands</h2>
|
||||
|
||||
<table style="border-color: #ef0813;" border="#ef0813" cellspacing="0" cellpadding="4">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Command</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Acceptable Arguments</strong></span>
|
||||
</h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Example</strong></span></h3>
|
||||
</td>
|
||||
<td style="max-width: 250px; text-align: center; vertical-align: top;" scope="col">
|
||||
<h3><span style="text-decoration: underline;"><strong>Description</strong></span></h3>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!linkCalendar </td>
|
||||
<td style="text-align: center;">!linkCalendar </td>
|
||||
<td style="text-align: center;">!linkCalendar<br>!linkcal </td>
|
||||
<td style="text-align: center;">Links the calendar associated with your Discord server so that
|
||||
you may open it in a web browser.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!time </td>
|
||||
<td style="text-align: center;">!time </td>
|
||||
<td style="text-align: center;">!!time </td>
|
||||
<td style="text-align: center;">Displays the current time based on the calendar timezone. Useful
|
||||
for ensuring you have selected the proper timezone, and useful for people to know what time
|
||||
events are compared to their local time.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;"> !events</td>
|
||||
<td style="text-align: center;">!events <amount></td>
|
||||
<td style="text-align: center;">!events 5</td>
|
||||
<td style="text-align: center;">Displays the next upcoming events. The amount is the amount you
|
||||
wish to display.!events 5
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!help </td>
|
||||
<td style="text-align: center;">!help </td>
|
||||
<td style="text-align: center;">!help</td>
|
||||
<td style="text-align: center;">Displays a list of valid commands and links you to our pages for
|
||||
extra help with DisCal.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal </td>
|
||||
<td style="text-align: center;">!discal </td>
|
||||
<td style="text-align: center;"> !discal</td>
|
||||
<td style="text-align: center;">Displays info about DisCal and links to the main page. This can
|
||||
be used to easily connect to pages like this without memorizing the URL or bookmarking.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal prefix </td>
|
||||
<td style="text-align: center;">!discal prefix <prefix> </td>
|
||||
<td style="text-align: center;">!discal prefix #</td>
|
||||
<td style="text-align: center;">This changes the prefix DisCal will respond too from the default
|
||||
! to the prefix of your choice. This allows you to prevent any mix ups with other Discord
|
||||
bots commands. @ Mentioning also functions as a prefix. Use `@Discal discal prefix !` to
|
||||
reset if something goes wrong.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal role </td>
|
||||
<td style="text-align: center;">!discal role <roleName or roleId> </td>
|
||||
<td style="text-align: center;">!discal role myAdminRole</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Sets the role a user most possess in order to control DisCal's event/calendar creation
|
||||
modules. By default, this will be the "@everyone" role (meaning all users can control
|
||||
all modules). Should you want to disable needing a specific role, simply use the command
|
||||
again by specify "everyone" as the role, this will reset it to allow all users proper
|
||||
access. </p>
|
||||
<p>**NOTE: If the role is deleted or does not exist, DisCal will reset to all everyone to
|
||||
use it.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal channel</td>
|
||||
<td style="text-align: center;">!discal channel <channelName></td>
|
||||
<td style="text-align: center;">!discal channel calendar</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Sets the channel discal will use and respond in. Should a discal message be used outside
|
||||
this channel, it will not recognise it.<br/>**Please note: By default, this is not set.
|
||||
DisCal will work in ALL channels until this is set.</p>
|
||||
<p>**ANOTHER NOTE: To reset, simply use "all" instead of a valid channel.</p>
|
||||
<p>**IF the channel does not exist or is deleted, DisCal will reset to use ALL channels.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal simpleAnnouncement</td>
|
||||
<td style="text-align: center;">!discal simpleAnnouncement</td>
|
||||
<td style="text-align: center;">!discal simpleAnnouncement</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Enables/Disables "simple announcements"<br/>Simple announcements will not list the event
|
||||
ID or announcement ID. This can be useful for making them more user friendly but the
|
||||
downside is you cannot debug the announcement should something fail (which rarely
|
||||
if ever happens).</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal invite</td>
|
||||
<td style="text-align: center;">!discal invite</td>
|
||||
<td style="text-align: center;">!discal invite</td>
|
||||
<td style="text-align: center;">
|
||||
<p>This command will have the bot output an invite link for the DisCal server. Need help?
|
||||
Come join us and we will get you fixed up. Just want to hang out? That's cool too! We
|
||||
appreciate all feedback and ideas :)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: center;">!discal settings</td>
|
||||
<td style="text-align: center;">!discal settings</td>
|
||||
<td style="text-align: center;">!discal settings</td>
|
||||
<td style="text-align: center;">
|
||||
<p>Display's the guild's DisCal settings in a pretty embed.<br/>Settings displayed include
|
||||
but are not limited to: max calendars, whether your guild is a patron guild, control
|
||||
role, channel, etc etc.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© Nova Maday 2017. All rights reserved. <a href="/pages/policy/privacy.html">Privacy Policy</a></p>
|
||||
</footer>
|
||||
</html>
|
||||
66
src/main/resources/web/public/pages/dashboard/dashboard.html
Normal file
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<!--Meta stuffs-->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="DisCal Bot brings Google Calendar integration seamlessly into Discord">
|
||||
<meta property="og:title" content="DisCal Bot"/>
|
||||
<meta property="og:url" content="https://www.discalbot.com"/>
|
||||
<meta property="og:description"
|
||||
content="DisCal Bot brings Google Calendar integration seamlessly into Discord"/>
|
||||
<!--meta property="og:image" content="I WILL PUT THE LOGO IN WHEN I MAKE IT SMALL"/-->
|
||||
<title>Dashboard - DisCal</title>
|
||||
|
||||
<!--Locally hosted-->
|
||||
<link href="styles/global.css" rel="stylesheet">
|
||||
|
||||
<!--Other stuffs-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Spectral+SC" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DisCal</h1>
|
||||
<a href="/">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a href="/pages/setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a class="active" href="/dashboard">Dashboard</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
|
||||
<a class="account" th:if="${loggedIn}" href="/account/logout">Log out</a>
|
||||
<!--TODO: Change this when bot goes live to proper auth url-->
|
||||
<a class="account" th:unless="${loggedIn}"
|
||||
href="https://discordapp.com/oauth2/authorize?client_id=348893450227286017&scope=guilds+identify&permissions=0&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4567%2Faccount%2Flogin">Log
|
||||
in</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<!--Check if logged in, if not, handle login...-->
|
||||
<div th:if="${loggedIn}">
|
||||
<h1 th:text="'Welcome, ' + ${username} + '!'"></h1>
|
||||
<h3>Select a guild below!</h3>
|
||||
|
||||
<!--TODO: IF YOU CAN MAKE THIS LOOP WORK WITH THE METHOD CALL I WILL PAY YOU-->
|
||||
<th:block th:each="guild : ${guilds}">
|
||||
<button onclick="goToGuild(this.id)" class="guild" th:id="${guild.id}"
|
||||
th:text="${guild.name}"></button>
|
||||
<br>
|
||||
</th:block>
|
||||
|
||||
</div>
|
||||
<div th:unless="${loggedIn}">
|
||||
<h1>YOU ARE NOT LOGGED IN!</h1>
|
||||
<p>Please login to continue.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer>
|
||||
|
||||
</footer>
|
||||
</html>
|
||||
108
src/main/resources/web/public/pages/dashboard/guild.html
Normal file
@@ -0,0 +1,108 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<!--Meta stuffs-->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="DisCal Bot brings Google Calendar integration seamlessly into Discord">
|
||||
<meta property="og:title" content="DisCal Bot"/>
|
||||
<meta property="og:url" content="https://www.discalbot.com"/>
|
||||
<meta property="og:description"
|
||||
content="DisCal Bot brings Google Calendar integration seamlessly into Discord"/>
|
||||
<!--meta property="og:image" content="I WILL PUT THE LOGO IN WHEN I MAKE IT SMALL"/-->
|
||||
<title>Dashboard - DisCal</title>
|
||||
|
||||
<!--Locally hosted-->
|
||||
<link href="styles/global.css" rel="stylesheet">
|
||||
|
||||
<!--Other stuffs-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Spectral+SC" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DisCal</h1>
|
||||
<a href="/">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a href="/pages/setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a class="active" href="/dashboard">Dashboard</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
|
||||
<a class="account" th:if="${loggedIn}" href="/account/logout">Log out</a>
|
||||
<!--TODO: Change this when bot goes live to proper auth url-->
|
||||
<a class="account" th:unless="${loggedIn}"
|
||||
href="https://discordapp.com/oauth2/authorize?client_id=348893450227286017&scope=guilds+identify&permissions=0&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4567%2Faccount%2Flogin">Log
|
||||
In</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<!--Check if logged in, if not, handle login...-->
|
||||
<div th:if="${loggedIn}">
|
||||
<div id="side-nav">
|
||||
<h4>Main Server Settings</h4>
|
||||
<a href="/account/dashboard/guild?settings=bot">
|
||||
<button>Bot Settings</button>
|
||||
</a>
|
||||
<br>
|
||||
<a href="/account/dashboard/guild?settings=guild">
|
||||
<button>Guild Settings</button>
|
||||
</a>
|
||||
<hr>
|
||||
<h4>Extensions</h4>
|
||||
<a href="/account/dashboard/guild?settings=ext?ext=test">
|
||||
<button>Example</button>
|
||||
</a>
|
||||
</div>
|
||||
<div style="display: flow-root">
|
||||
<!--suppress RequiredAttributes -->
|
||||
<img th:src="${selected.icon}"
|
||||
style="display: flex;float: left;max-width: 64px;margin-right: 15px;">
|
||||
<h3 th:text="'Managing Server: ' + ${selected.name}" style="text-align: left;"></h3>
|
||||
<hr>
|
||||
<p th:if="${settings} == null">Please select the settings to edit on the left.</p>
|
||||
<div th:if="${settings} != null">
|
||||
<div th:if="${settings} == bot">
|
||||
<h6>Bot Settings</h6>
|
||||
<form action="/account/dashboard/update" style="text-align: left">
|
||||
<label>Bot Nickname
|
||||
<br>
|
||||
<input type="text" name="bot-nick" maxlength="32" th:value="${selected.botnick}">
|
||||
</label>
|
||||
<input type="submit" class="submit" value="Update">
|
||||
</form>
|
||||
<br>
|
||||
<br>
|
||||
<form action="/account/dashboard/update" style="text-align: left">
|
||||
<label>Bot Prefix
|
||||
<br>
|
||||
<input type="text" name="prefix" maxlength="32" th:value="${selected.prefix}">
|
||||
<input type="submit" class="submit" value="Update">
|
||||
</label>
|
||||
</form>
|
||||
<br>
|
||||
</div>
|
||||
<div th:if="${settings} == guild">
|
||||
<h6>Guild Settings</h6>
|
||||
<p>I dunno if there really even will be settings here</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div th:unless="${loggedIn}">
|
||||
<h1>YOU ARE NOT LOGGED IN!</h1>
|
||||
<!--TODO: Change this when bot goes live to proper auth URL-->
|
||||
<a href="https://discordapp.com/oauth2/authorize?client_id=390210567639662614&scope=guilds+identify&permissions=0&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4567%2Faccount%2Flogin">
|
||||
<button>Login With Discord!</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer>
|
||||
|
||||
</footer>
|
||||
</html>
|
||||
90
src/main/resources/web/public/pages/index.html
Normal file
@@ -0,0 +1,90 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<!--Meta stuffs-->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="DisCal Bot brings Google Calendar integration seamlessly into Discord">
|
||||
<meta property="og:title" content="DisCal Bot"/>
|
||||
<meta property="og:url" content="https://www.discalbot.com"/>
|
||||
<meta property="og:description"
|
||||
content="DisCal Bot brings Google Calendar integration seamlessly into Discord"/>
|
||||
<!--meta property="og:image" content="I WILL PUT THE LOGO IN WHEN I MAKE IT SMALL"/-->
|
||||
<title>Home - DisCal</title>
|
||||
|
||||
<!--Locally hosted-->
|
||||
<link href="styles/global.css" rel="stylesheet">
|
||||
|
||||
<!--Other stuffs-->
|
||||
<link href="https://fonts.googleapis.com/css?family=Spectral+SC" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DISCAL BOT</h1>
|
||||
<a class="active" href="/index.html">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a href="/pages/setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a href="/dashboard">Dashboard</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
|
||||
<a class="account" th:if="${loggedIn}" href="/account/logout">Log out</a>
|
||||
<!--TODO: Change this when bot goes live to proper auth url-->
|
||||
<a class="account" th:unless="${loggedIn}"
|
||||
href="https://discordapp.com/oauth2/authorize?client_id=348893450227286017&scope=guilds+identify&permissions=0&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4567%2Faccount%2Flogin">Log
|
||||
in</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/logos/Dark/Opaque/Logo%20Dark%20+bg.png"
|
||||
style="max-width: 200px; max-height: 200px;">
|
||||
</div>
|
||||
<h1>DisCal Bot</h1>
|
||||
<h3>The Official Discord Calendar Bot</h3>
|
||||
|
||||
<p>
|
||||
DisCal is a powerful Discord bot allowing you to connect Google Calendar to Discord in a seamless
|
||||
fashion. With superior support and features such as custom calendars, events, automated
|
||||
announcements,
|
||||
RSVPs and more, DisCal is the ultimate calendar bot.
|
||||
</p>
|
||||
|
||||
<a href="https://discordapp.com/oauth2/authorize?client_id=265523588918935552&scope=bot&permissions=201845824redirect_uri=https%3A%2F%2Fwww.discalbot.com%2Fpages%2Fsetup.html"
|
||||
target="_blank">
|
||||
<button>Add To Discord!</button>
|
||||
</a>
|
||||
|
||||
<hr>
|
||||
<h2>See What Actual Users Are Saying</h2>
|
||||
<div class="quote-block">
|
||||
<div class="quote">
|
||||
<h4>Casey#8173</h4>
|
||||
<p>"Keep up the good work guys, this is so desperately needed!"</p>
|
||||
</div>
|
||||
|
||||
<div class="quote">
|
||||
<h4>ConfigSys.boy!#0189</h4>
|
||||
<p>"Kudos for finally doing something I've been waiting for since my first day in Discord. Our
|
||||
multi-game community has been using Google Docs, Images and Calendars for years and linking
|
||||
the
|
||||
Calendar to Discord will be a huge boon."</p>
|
||||
</div>
|
||||
|
||||
<div class="quote">
|
||||
<h4>Bank_CW [DD-R]#3927</h4>
|
||||
<p>"It is a bot that I see a great demand for"</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© Nova Maday 2017. All rights reserved. <a href="/pages/policy/privacy.html">Privacy Policy</a></p>
|
||||
</footer>
|
||||
</html>
|
||||
61
src/main/resources/web/public/pages/lazy-discal.html
Normal file
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/styles/global.css">
|
||||
|
||||
<title>Lazy DisCal - DisCal Bot</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DISCAL BOT</h1>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a href="/pages/setup.html">Setup</a>
|
||||
<a class="active" href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div id="about">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/lazy-discal/lazy-discal-program.jpg"
|
||||
style="max-width: 300px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>About Lazy DisCal</h3>
|
||||
<p>
|
||||
Lazy DisCal is an application scripted by Callador using Auto Hotkey. This application helps to make
|
||||
it easy to create events, announcements, and calendars for DisCal with a very simple and easy to use
|
||||
GUI.
|
||||
<br>
|
||||
<br>
|
||||
Built for one purpose: Making your life easier by remembering all the DisCal commands for you! Can't
|
||||
remember what format to put your start date? No problem!
|
||||
<br>
|
||||
<br>
|
||||
All you have to do is fill out the various fields in LD and then click one of the submit buttons. LD
|
||||
will wait a few seconds for you to bring up discord and then send all the appropriate commands to
|
||||
your channel for you.
|
||||
<br>
|
||||
<br>
|
||||
It supports saving and loading of events as text files for quick event creation. It can build events
|
||||
and announcements separately or together and has the capability to build up to 50 announcements at
|
||||
one time.
|
||||
</p>
|
||||
|
||||
<a download="" href="/assets/files/Lazy-DisCal/Windows/Lazy_Discal_GUI-1.0.8.0.exe">
|
||||
<button>Windows</button>
|
||||
</a>
|
||||
|
||||
<hr>
|
||||
<p>*Note: until Lazy DisCal is developed for linux/mac you can run it via Wine.</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© Nova Maday 2017. All rights reserved. <a href="/pages/policy/privacy.html">Privacy Policy</a></p>
|
||||
</footer>
|
||||
</html>
|
||||
494
src/main/resources/web/public/pages/policy/privacy.html
Normal file
@@ -0,0 +1,494 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/styles/global.css">
|
||||
<title>Privacy Policy - DisCal Bot</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DISCAL BOT</h1>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a href="/pages/setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1>Privacy Policy</h1>
|
||||
<p>
|
||||
This privacy policy has been compiled to better serve those who are concerned with how their 'Personally
|
||||
Identifiable
|
||||
Information' (PII) is being used online. PII, as described in US privacy law and information security,
|
||||
is
|
||||
information
|
||||
that can be used on its own or with other information to identify, contact, or locate a single person,
|
||||
or to
|
||||
identify an
|
||||
individual in context. Please read our privacy policy carefully to get a clear understanding of how we
|
||||
collect,
|
||||
use,
|
||||
protect or otherwise handle your Personally Identifiable Information in accordance with our website.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
What personal information do we collect from the people that visit our blog, website or app?<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
When ordering or registering on our site, as appropriate, you may be asked to enter your name, email
|
||||
address,
|
||||
mailing
|
||||
address, phone number, credit card information or other details to help you with your experience.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
When do we collect information?<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
We collect information from you when you place an order, subscribe to a newsletter, fill out a form or
|
||||
enter
|
||||
information
|
||||
on our site.<br>
|
||||
<br>
|
||||
<br>
|
||||
Provide us with feedback on our products or services Register with MineCash <br>
|
||||
<br>
|
||||
How do we use your information?<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
We may use the information we collect from you when you register, make a purchase, sign up for our
|
||||
newsletter,
|
||||
respond
|
||||
to a survey or marketing communication, surf the website, or use certain other site features in the
|
||||
following
|
||||
ways:<br>
|
||||
<br>
|
||||
<br>
|
||||
      • To personalize your experience and to allow us to
|
||||
deliver
|
||||
the
|
||||
type of
|
||||
content and product offerings in which you are most interested.<br>
|
||||
<br>
|
||||
      • To improve our website in order to better serve you.<br>
|
||||
<br>
|
||||
      • To allow us to better service you in responding to your
|
||||
customer
|
||||
service
|
||||
requests.<br>
|
||||
<br>
|
||||
      • To quickly process your transactions.<br>
|
||||
<br>
|
||||
      • To follow up with them after correspondence (live chat,
|
||||
email or
|
||||
phone
|
||||
inquiries)<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
How do we protect your information?<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Our website is scanned on a regular basis for security holes and known vulnerabilities in order to make
|
||||
your
|
||||
visit to
|
||||
our site as safe as possible.<br>
|
||||
<br>
|
||||
<br>
|
||||
We use regular Malware Scanning.<br>
|
||||
<br>
|
||||
<br>
|
||||
Your personal information is contained behind secured networks and is only accessible by a limited
|
||||
number of
|
||||
persons who
|
||||
have special access rights to such systems, and are required to keep the information confidential. In
|
||||
addition,
|
||||
all
|
||||
sensitive/credit information you supply is encrypted via Secure Socket Layer (SSL) technology.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
We implement a variety of security measures when a user places an order to maintain the safety of your
|
||||
personal
|
||||
information.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
All transactions are processed through a gateway provider and are not stored or processed on our
|
||||
servers.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Do we use 'cookies'?<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive
|
||||
through
|
||||
your
|
||||
Web browser (if you allow) that enables the site's or service provider's systems to recognize your
|
||||
browser
|
||||
and
|
||||
capture
|
||||
and remember certain information. For instance, we use cookies to help us remember and process the items
|
||||
in
|
||||
your
|
||||
shopping cart. They are also used to help us understand your preferences based on previous or current
|
||||
site
|
||||
activity,
|
||||
which enables us to provide you with improved services. We also use cookies to help us compile aggregate
|
||||
data
|
||||
about site
|
||||
traffic and site interaction so that we can offer better site experiences and tools in the future.<br>
|
||||
<br>
|
||||
<br>
|
||||
We use cookies to:<br>
|
||||
<br>
|
||||
      • Help remember and process the items in the shopping
|
||||
cart.<br>
|
||||
<br>
|
||||
      • Understand and save user's preferences for future
|
||||
visits.<br>
|
||||
<br>
|
||||
      • Compile aggregate data about site traffic and site
|
||||
interactions
|
||||
in order
|
||||
to offer better site experiences and tools in the future. We may also use trusted third-party services
|
||||
that
|
||||
track this
|
||||
information on our behalf.<br>
|
||||
<br>
|
||||
<br>
|
||||
You can choose to have your computer warn you each time a cookie is being sent, or you can choose to
|
||||
turn
|
||||
off
|
||||
all
|
||||
cookies. You do this through your browser settings. Since browser is a little different, look at your
|
||||
browser's
|
||||
Help
|
||||
Menu to learn the correct way to modify your cookies.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
If you turn cookies off, some features will be disabled. It won't affect the user's experience that make
|
||||
your
|
||||
site
|
||||
experience more efficient and may not function properly.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
However, you will still be able to place orders .<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Third-party disclosure<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
We do not sell, trade, or otherwise transfer to outside parties your Personally Identifiable Information
|
||||
unless
|
||||
we
|
||||
provide users with advance notice. This does not include website hosting partners and other parties who
|
||||
assist
|
||||
us in
|
||||
operating our website, conducting our business, or serving our users, so long as those parties agree to
|
||||
keep
|
||||
this
|
||||
information confidential. We may also release information when it's release is appropriate to comply
|
||||
with
|
||||
the
|
||||
law,
|
||||
enforce our site policies, or protect ours or others' rights, property or safety. <br>
|
||||
<br>
|
||||
However, non-personally identifiable visitor information may be provided to other parties for marketing,
|
||||
advertising, or
|
||||
other uses.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Third-party links<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Occasionally, at our discretion, we may include or offer third-party products or services on our
|
||||
website.
|
||||
These
|
||||
third-party sites have separate and independent privacy policies. We therefore have no responsibility or
|
||||
liability for
|
||||
the content and activities of these linked sites. Nonetheless, we seek to protect the integrity of our
|
||||
site
|
||||
and
|
||||
welcome
|
||||
any feedback about these sites.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Google<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Google's advertising requirements can be summed up by Google's Advertising Principles. They are put in
|
||||
place
|
||||
to
|
||||
provide
|
||||
a positive experience for users. https://support.google.com/adwordspolicy/answer/1316548?hl=en<br>
|
||||
<br>
|
||||
<br>
|
||||
We use Google AdSense Advertising on our website.<br>
|
||||
<br>
|
||||
<br>
|
||||
Google, as a third-party vendor, uses cookies to serve ads on our site. Google's use of the DART cookie
|
||||
enables
|
||||
it to
|
||||
serve ads to our users based on previous visits to our site and other sites on the Internet. Users may
|
||||
opt-out
|
||||
of the
|
||||
use of the DART cookie by visiting the Google Ad and Content Network privacy policy.<br>
|
||||
<br>
|
||||
<br>
|
||||
We have implemented the following:<br>
|
||||
<br>
|
||||
      • Remarketing with Google AdSense<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
We, along with third-party vendors such as Google use first-party cookies (such as the Google Analytics
|
||||
cookies)
|
||||
and
|
||||
third-party cookies (such as the DoubleClick cookie) or other third-party identifiers together to
|
||||
compile
|
||||
data
|
||||
regarding
|
||||
user interactions with ad impressions and other ad service functions as they relate to our website.<br>
|
||||
<br>
|
||||
<br>
|
||||
Opting out:<br>
|
||||
Users can set preferences for how Google advertises to you using the Google Ad Settings page.
|
||||
Alternatively,
|
||||
you
|
||||
can opt
|
||||
out by visiting the Network Advertising Initiative Opt Out page or by using the Google Analytics Opt Out
|
||||
Browser
|
||||
add on.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
California Online Privacy Protection Act<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
CalOPPA is the first state law in the nation to require commercial websites and online services to post
|
||||
a
|
||||
privacy
|
||||
policy. The law's reach stretches well beyond California to require any person or company in the United
|
||||
States
|
||||
(and
|
||||
conceivably the world) that operates websites collecting Personally Identifiable Information from
|
||||
California
|
||||
consumers
|
||||
to post a conspicuous privacy policy on its website stating exactly the information being collected and
|
||||
those
|
||||
individuals or companies with whom it is being shared. - See more at:
|
||||
http://consumercal.org/california-online-privacy-protection-act-caloppa/#sthash.0FdRbT51.dpuf<br>
|
||||
<br>
|
||||
<br>
|
||||
According to CalOPPA, we agree to the following:<br>
|
||||
<br>
|
||||
Users can visit our site anonymously.<br>
|
||||
<br>
|
||||
Once this privacy policy is created, we will add a link to it on our home page or as a minimum, on the
|
||||
first
|
||||
significant
|
||||
page after entering our website.<br>
|
||||
<br>
|
||||
Our Privacy Policy link includes the word 'Privacy' and can easily be found on the page specified above.<br>
|
||||
<br>
|
||||
<br>
|
||||
You will be notified of any Privacy Policy changes:<br>
|
||||
<br>
|
||||
      • On our Privacy Policy Page<br>
|
||||
<br>
|
||||
Can change your personal information:<br>
|
||||
<br>
|
||||
      • By emailing us<br>
|
||||
<br>
|
||||
      • By logging in to your account<br>
|
||||
<br>
|
||||
      • By chatting with us or by sending us a support
|
||||
ticket<br>
|
||||
<br>
|
||||
      • Others<br>
|
||||
<br>
|
||||
<br>
|
||||
How does our site handle Do Not Track signals?<br>
|
||||
<br>
|
||||
We honor Do Not Track signals and Do Not Track, plant cookies, or use advertising when a Do Not Track
|
||||
(DNT)
|
||||
browser
|
||||
mechanism is in place.<br>
|
||||
<br>
|
||||
<br>
|
||||
Does our site allow third-party behavioral tracking?<br>
|
||||
<br>
|
||||
It's also important to note that we do not allow third-party behavioral tracking<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
COPPA (Children Online Privacy Protection Act)<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
When it comes to the collection of personal information from children under the age of 13 years old, the
|
||||
Children's
|
||||
Online Privacy Protection Act (COPPA) puts parents in control. The Federal Trade Commission, United
|
||||
States'
|
||||
consumer
|
||||
protection agency, enforces the COPPA Rule, which spells out what operators of websites and online
|
||||
services
|
||||
must
|
||||
do to
|
||||
protect children's privacy and safety online.<br>
|
||||
<br>
|
||||
<br>
|
||||
We market to<br>
|
||||
<br>
|
||||
We do not collect information from children under 13<br>
|
||||
<br>
|
||||
children under 13.<br>
|
||||
<br>
|
||||
No<br>
|
||||
<br>
|
||||
<br>
|
||||
In order to remove your child's information please contact the following personnel:<br>
|
||||
<br>
|
||||
<br>
|
||||
We adhere to the following COPPA tenants:<br>
|
||||
<br>
|
||||
      • Parents can review, delete, manage or refuse with whom
|
||||
their
|
||||
child's
|
||||
information is shared through contacting us directly.<br>
|
||||
<br>
|
||||
or contacting us directly.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
Fair Information Practices<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
The Fair Information Practices Principles form the backbone of privacy law in the United States and the
|
||||
concepts
|
||||
they
|
||||
include have played a significant role in the development of data protection laws around the globe.
|
||||
Understanding the
|
||||
Fair Information Practice Principles and how they should be implemented is critical to comply with the
|
||||
various
|
||||
privacy
|
||||
laws that protect personal information.<br>
|
||||
<br>
|
||||
<br>
|
||||
In order to be in line with Fair Information Practices we will take the following responsive action,
|
||||
should
|
||||
a
|
||||
data
|
||||
breach occur:<br>
|
||||
<br>
|
||||
We will notify you via email<br>
|
||||
<br>
|
||||
      • Within 7 business days<br>
|
||||
<br>
|
||||
We will notify the users via in-site notification<br>
|
||||
<br>
|
||||
      • Within 7 business days<br>
|
||||
<br>
|
||||
<br>
|
||||
We also agree to the Individual Redress Principle which requires that individuals have the right to
|
||||
legally
|
||||
pursue
|
||||
enforceable rights against data collectors and processors who fail to adhere to the law. This principle
|
||||
requires
|
||||
not
|
||||
only that individuals have enforceable rights against data users, but also that individuals have
|
||||
recourse to
|
||||
courts or
|
||||
government agencies to investigate and/or prosecute non-compliance by data processors.<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
CAN SPAM Act<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
The CAN-SPAM Act is a law that sets the rules for commercial email, establishes requirements for
|
||||
commercial
|
||||
messages,
|
||||
gives recipients the right to have emails stopped from being sent to them, and spells out tough
|
||||
penalties
|
||||
for
|
||||
violations.<br>
|
||||
<br>
|
||||
<br>
|
||||
We collect your email address in order to:<br>
|
||||
<br>
|
||||
      • Send information, respond to inquiries, and/or other
|
||||
requests or
|
||||
questions<br>
|
||||
<br>
|
||||
      • Process orders and to send information and updates
|
||||
pertaining to
|
||||
orders.<br>
|
||||
<br>
|
||||
      • Send you additional information related to your product
|
||||
and/or
|
||||
service<br>
|
||||
<br>
|
||||
<br>
|
||||
To be in accordance with CANSPAM, we agree to the following:<br>
|
||||
<br>
|
||||
      • Not use false or misleading subjects or email addresses.<br>
|
||||
<br>
|
||||
      • Identify the message as an advertisement in some
|
||||
reasonable
|
||||
way.<br>
|
||||
<br>
|
||||
      • Include the physical address of our business or site
|
||||
headquarters.<br>
|
||||
<br>
|
||||
      • Monitor third-party email marketing services for
|
||||
compliance,
|
||||
if
|
||||
one is
|
||||
used.<br>
|
||||
<br>
|
||||
      • Honor opt-out/unsubscribe requests quickly.<br>
|
||||
<br>
|
||||
      • Allow users to unsubscribe by using the link at the
|
||||
bottom
|
||||
of
|
||||
each
|
||||
email.<br>
|
||||
<br>
|
||||
<br>
|
||||
If at any time you would like to unsubscribe from receiving future emails, you can email us at<br>
|
||||
<br>
|
||||
cloudcraftcontact@gmail.com and we will promptly remove you from ALL correspondence.<br>
|
||||
<br>
|
||||
<br>
|
||||
Last Edited on 2017-11-12
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© Nova Maday 2017. All rights reserved. <a href="/pages/policy/privacy.html">Privacy Policy</a></p>
|
||||
</footer>
|
||||
</html>
|
||||
111
src/main/resources/web/public/pages/setup.html
Normal file
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/styles/global.css">
|
||||
<title>Setup - DisCal Bot</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="top-nav">
|
||||
<h1>DISCAL BOT</h1>
|
||||
<a href="/index.html">Home</a>
|
||||
<a href="/pages/about.html">About</a>
|
||||
<a href="/pages/commands.html">Commands</a>
|
||||
<a class="active" href="setup.html">Setup</a>
|
||||
<a href="/pages/lazy-discal.html">Lazy DisCal</a>
|
||||
<a href="https://discord.gg/AmAMGeN" target="_blank">Support</a>
|
||||
<a href="https://www.patreon.com/Novafox" target="_blank">Patreon</a>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<h1>DisCal Bot - Setup</h1>
|
||||
<p>
|
||||
The following page is a step by step instruction for how to properly setup DisCal.
|
||||
<br><br>
|
||||
It's quite simple, but you must create a new calendar in order for DisCal to function fully.
|
||||
</p>
|
||||
|
||||
<div id="invite">
|
||||
<h3>1. Add DisCal to your Discord server</h3>
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/examples/DisCal-Invite-Perms.jpg"
|
||||
style="max-width: 300px; max-height: 300px;">
|
||||
</div>
|
||||
<p>
|
||||
<strong>Skip this step if you have just added DisCal to your server.</strong>
|
||||
<br><br><br>
|
||||
Click the button below to authorize DisCal and select the server you want it on.
|
||||
<br><br><br><br>
|
||||
You must have the "Manage Server" permission to add the bot. Contact the server owner or admin to
|
||||
invite DisCal if you cannot.
|
||||
<br><br><br>
|
||||
</p>
|
||||
<a href="https://discordapp.com/oauth2/authorize?client_id=265523588918935552&scope=bot&permissions=201845824redirect_uri=https%3A%2F%2Fwww.discalbot.com%2Fpages%2Fsetup.html"
|
||||
target="_blank">
|
||||
<button>Add DisCal to Discord Server</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="role">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/examples/DisCal-Role-Perms.jpg"
|
||||
style="max-width: 300px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>2. Give DisCal permissions at server level and not at channel level (channel permissions don't
|
||||
always work right)</h3>
|
||||
<p>
|
||||
If you have a Bot permission group, assign DisCal that permission.
|
||||
<br><br>
|
||||
If not, create a new permission role with the following permissions so that DisCal may read and send
|
||||
messages based on its commands:
|
||||
<br><br>
|
||||
- Read Messages*
|
||||
<br>
|
||||
- Send Messages
|
||||
<br>
|
||||
- Embed Links
|
||||
<br>
|
||||
- Mention Everyone
|
||||
<br>
|
||||
- Manager Messages
|
||||
<br>
|
||||
- Reactions/External Emojis
|
||||
<br><br><br>
|
||||
* DisCal will not log or save any messages.
|
||||
<br><br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div id="calendar">
|
||||
<div class="image-wrapper" style="float: left">
|
||||
<img src="/assets/images/examples/DisCal-Calendar-Creation.jpg"
|
||||
style="max-width: 300px; max-height: 300px;">
|
||||
</div>
|
||||
<h3>3. Create a Calendar for your Discord</h3>
|
||||
<p>
|
||||
DisCal currently only allows 1 calendar per server. Use the command "!calendar create [calendar
|
||||
name]" in any channel. (You can create a special channel just for DisCal commands if you want.)
|
||||
<br> <br>
|
||||
Once that command is issued, DisCal will handle the rest and walk you through a step by step guide
|
||||
into creating your new calendar!
|
||||
<br> <br>
|
||||
Optionally you may attach an external calendar. (This feature is currently in open testing for
|
||||
Patreon supporters. Visit our Discord server for more information.)
|
||||
<br><br><br>
|
||||
For all information on existing commands as well as some tutorial .gifs, click the button below.
|
||||
</p>
|
||||
<a href="commands.html">
|
||||
<button>View Commands</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<footer id="footer">
|
||||
<p>© Nova Maday 2017. All rights reserved. <a href="/pages/policy/privacy.html">Privacy Policy</a></p>
|
||||
</footer>
|
||||
</html>
|
||||
3
src/main/resources/web/public/scripts/dashboard/main.js
Normal file
@@ -0,0 +1,3 @@
|
||||
function goToGuild(guildId) {
|
||||
window.location.href = "/account/dashboard/select?guild=" + guildId;
|
||||
}
|
||||
241
src/main/resources/web/public/styles/global.css
Normal file
@@ -0,0 +1,241 @@
|
||||
/* The basics */
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #242428;
|
||||
|
||||
min-height: 100%;
|
||||
margin: 0 0 25px; /* bottom = footer height */
|
||||
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
text-align: center;
|
||||
color: #E67C3F;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 32pt;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 28pt;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 24pt
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
font-size: 20pt;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 18pt;
|
||||
color: white;
|
||||
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 18px;
|
||||
background-color: #E67C3F;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border: 2px black;
|
||||
margin: 10px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
color: black;
|
||||
}
|
||||
|
||||
hr {
|
||||
color: #E67C3F;
|
||||
background-color: #E67C3F;
|
||||
border-color: transparent;
|
||||
|
||||
height: 1px;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
height: 454px;
|
||||
max-width: 820px;
|
||||
border: #ef0813 2px;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
position: center;
|
||||
}
|
||||
|
||||
td {
|
||||
color: white;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
}
|
||||
|
||||
select {
|
||||
border: 1px solid black;
|
||||
border-radius: 2px;
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
input.submit {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
border: 1px solid #E67C3F;
|
||||
background: #E67C3F;
|
||||
}
|
||||
|
||||
input.submit:hover {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
border: 1px solid white;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
label {
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Wrappers */
|
||||
#content {
|
||||
margin-left: 5%;
|
||||
margin-right: 5%;
|
||||
margin-bottom: auto;
|
||||
background-color: #3c3d41;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
text-align: center;
|
||||
display: flow-root;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
position: center;
|
||||
margin: 10px;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.image-wrapper img {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.quote-block {
|
||||
width: auto;
|
||||
display: inline-flex;
|
||||
position: center;
|
||||
}
|
||||
|
||||
.quote {
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
float: left;
|
||||
display: inline-block;
|
||||
|
||||
background: #bcbcbc;
|
||||
border-radius: 6px;
|
||||
border: 4px #E67C3F;
|
||||
|
||||
max-width: 400px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.quote p {
|
||||
text-align: center;
|
||||
color: #242428;
|
||||
}
|
||||
|
||||
.quote h4 {
|
||||
color: #ef0813;
|
||||
}
|
||||
|
||||
#side-nav {
|
||||
margin-left: 0;
|
||||
margin-right: 10px;
|
||||
margin-bottom: auto;
|
||||
background-color: #3c3d41;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
text-align: center;
|
||||
|
||||
float: left;
|
||||
|
||||
border: #E67C3F 2px solid;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* Navigation bar */
|
||||
.top-nav {
|
||||
overflow: hidden;
|
||||
background-color: #E67C3F;
|
||||
}
|
||||
|
||||
.top-nav h1 {
|
||||
float: left;
|
||||
color: white;
|
||||
text-align: center;
|
||||
margin-left: 15px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
font-family: 'Spectral SC', serif;
|
||||
font-size: 25pt;
|
||||
}
|
||||
|
||||
.top-nav a {
|
||||
float: left;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 15px 18px;
|
||||
font-size: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-nav a:hover {
|
||||
background-color: white;
|
||||
color: #090809;
|
||||
|
||||
}
|
||||
|
||||
.top-nav a.active {
|
||||
background-color: #3c3d41;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.top-nav a.account {
|
||||
float: right;
|
||||
text-align: center;
|
||||
padding: 15px 18px;
|
||||
font-size: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-nav p.account {
|
||||
float: right;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 15px 18px;
|
||||
font-size: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||