Huge progress on the API. Push for other computer

Not done yet.
This commit is contained in:
NovaFox161
2019-12-06 22:22:31 -06:00
parent af4ab3f4ab
commit 775ccdfe6e
60 changed files with 4757 additions and 405 deletions

View File

@@ -1,6 +1,6 @@
package org.dreamexposure.discal.core.enums.event;
import java.awt.*;
import java.awt.Color;
/**
* Created by Nova Fox on 11/10/17.
@@ -93,7 +93,7 @@ public enum EventColor {
return c;
} else {
try {
int i = Integer.valueOf(nameOrHexOrID);
int i = Integer.parseInt(nameOrHexOrID);
if (c.getId() == i)
return c;
} catch (NumberFormatException e) {

View File

@@ -39,6 +39,8 @@ public enum BotSettings {
USE_REDIS_STORES, USE_WEBHOOKS, UPDATE_SITES, RUN_API,
BOT_API_TOKEN,
PROFILE;

View File

@@ -1,16 +1,18 @@
package org.dreamexposure.discal.core.object;
import discord4j.core.object.util.Snowflake;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
* For Project: DisCal-Discord-Bot
*/
@SuppressWarnings("DuplicatedCode")
public class GuildSettings {
private Snowflake guildID;
@@ -213,41 +215,80 @@ public class GuildSettings {
public JSONObject toJson() {
JSONObject data = new JSONObject();
data.put("GuildId", guildID.asString());
data.put("ExternalCalendar", externalCalendar);
data.put("PrivateKey", privateKey);
data.put("AccessToken", encryptedAccessToken);
data.put("RefreshToken", encryptedRefreshToken);
data.put("ControlRole", controlRole);
data.put("DisCalChannel", discalChannel);
data.put("SimpleAnnouncements", simpleAnnouncements);
data.put("Lang", lang);
data.put("Prefix", prefix);
data.put("PatronGuild", patronGuild);
data.put("DevGuild", devGuild);
data.put("MaxCalendars", maxCalendars);
data.put("TwelveHour", twelveHour);
data.put("Branded", branded);
data.put("guild_id", guildID.asString());
data.put("external_calendar", externalCalendar);
data.put("private_key", privateKey);
data.put("access_token", encryptedAccessToken);
data.put("refresh_token", encryptedRefreshToken);
data.put("control_role", controlRole);
data.put("discal_channel", discalChannel);
data.put("simple_announcements", simpleAnnouncements);
data.put("lang", lang);
data.put("prefix", prefix);
data.put("patron_guild", patronGuild);
data.put("dev_guild", devGuild);
data.put("max_calendars", maxCalendars);
data.put("twelve_hour", twelveHour);
data.put("branded", branded);
return data;
}
public JSONObject toJsonSecure() {
JSONObject data = new JSONObject();
data.put("guild_id", guildID.asString());
data.put("external_calendar", externalCalendar);
data.put("control_role", controlRole);
data.put("discal_channel", discalChannel);
data.put("simple_announcement", simpleAnnouncements);
data.put("lang", lang);
data.put("prefix", prefix);
data.put("patron_guild", patronGuild);
data.put("dev_guild", devGuild);
data.put("max_calendars", maxCalendars);
data.put("twelve_hour", twelveHour);
data.put("branded", branded);
return data;
}
public GuildSettings fromJson(JSONObject data) {
guildID = Snowflake.of(data.getLong("GuildId"));
externalCalendar = data.getBoolean("ExternalCalendar");
privateKey = data.getString("PrivateKey");
encryptedAccessToken = data.getString("AccessToken");
encryptedRefreshToken = data.getString("RefreshToken");
controlRole = data.getString("ControlRole");
discalChannel = data.getString("DisCalChannel");
simpleAnnouncements = data.getBoolean("SimpleAnnouncements");
lang = data.getString("Lang");
prefix = data.getString("Prefix");
patronGuild = data.getBoolean("PatronGuild");
devGuild = data.getBoolean("DevGuild");
maxCalendars = data.getInt("MaxCalendars");
twelveHour = data.getBoolean("TwelveHour");
branded = data.getBoolean("Branded");
guildID = Snowflake.of(data.getLong("guild_id"));
externalCalendar = data.getBoolean("external_calendar");
privateKey = data.getString("private_key");
encryptedAccessToken = data.getString("access_token");
encryptedRefreshToken = data.getString("refresh_token");
controlRole = data.getString("control_role");
discalChannel = data.getString("discal_channel");
simpleAnnouncements = data.getBoolean("simple_announcement");
lang = data.getString("lang");
prefix = data.getString("prefix");
patronGuild = data.getBoolean("patron_guild");
devGuild = data.getBoolean("dev_guild");
maxCalendars = data.getInt("max_calendars");
twelveHour = data.getBoolean("twelve_hour");
branded = data.getBoolean("branded");
return this;
}
public GuildSettings fromJsonSecure(JSONObject data) {
guildID = Snowflake.of(data.getLong("guild_id"));
externalCalendar = data.getBoolean("external_calendar");
//privateKey = data.getString("PrivateKey");
//encryptedAccessToken = data.getString("AccessToken");
//encryptedRefreshToken = data.getString("RefreshToken");
controlRole = data.getString("control_role");
discalChannel = data.getString("discal_channel");
simpleAnnouncements = data.getBoolean("simple_announcement");
lang = data.getString("lang");
prefix = data.getString("prefix");
patronGuild = data.getBoolean("patron_guild");
devGuild = data.getBoolean("dev_guild");
maxCalendars = data.getInt("max_calendars");
twelveHour = data.getBoolean("twelve_hours");
branded = data.getBoolean("branded");
return this;
}

View File

@@ -1,7 +1,5 @@
package org.dreamexposure.discal.core.object.announcement;
import discord4j.core.object.entity.Message;
import discord4j.core.object.util.Snowflake;
import org.dreamexposure.discal.core.enums.announcement.AnnouncementType;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.json.JSONArray;
@@ -11,6 +9,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.UUID;
import discord4j.core.object.entity.Message;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.dreamexposure.org
@@ -395,57 +396,57 @@ public class Announcement {
public JSONObject toJson() {
JSONObject data = new JSONObject();
data.put("GuildId", guildId.asLong());
data.put("Id", announcementId.toString());
data.put("guild_id", guildId.asLong());
data.put("id", announcementId.toString());
JSONArray roles = new JSONArray();
for (String s : subscriberRoleIds) {
roles.put(s);
}
data.put("Roles", roles);
data.put("subscriber_roles", roles);
JSONArray users = new JSONArray();
for (String s : subscriberUserIds) {
users.put(s);
}
data.put("Users", users);
data.put("subscriber_users", users);
data.put("ChannelId", announcementChannelId);
data.put("Type", type.getName());
data.put("EventId", eventId);
data.put("EventColor", eventColor.getName());
data.put("Hours", hoursBefore);
data.put("Minutes", minutesBefore);
data.put("Info", info);
data.put("Enabled", enabled);
data.put("InfoOnly", infoOnly);
data.put("channel_id", announcementChannelId);
data.put("type", type.getName());
data.put("event_id", eventId);
data.put("event_color", eventColor.getName());
data.put("hours", hoursBefore);
data.put("minutes", minutesBefore);
data.put("info", info);
data.put("enabled", enabled);
data.put("info_only", infoOnly);
return data;
}
public Announcement fromJson(JSONObject data) {
guildId = Snowflake.of(data.getLong("GuildId"));
announcementId = UUID.fromString(data.getString("Id"));
guildId = Snowflake.of(data.getLong("guild_id"));
announcementId = UUID.fromString(data.getString("id"));
JSONArray roles = data.getJSONArray("Roles");
JSONArray roles = data.getJSONArray("subscriber_roles");
for (int i = 0; i < roles.length(); i++) {
subscriberRoleIds.add(roles.getString(i));
}
JSONArray users = data.getJSONArray("Users");
JSONArray users = data.getJSONArray("subscriber_users");
for (int i = 0; i < users.length(); i++) {
subscriberUserIds.add(users.getString(i));
}
announcementChannelId = data.getString("ChannelId");
type = AnnouncementType.fromValue(data.getString("Type"));
eventId = data.getString("EventId");
eventColor = EventColor.valueOf(data.getString("EventColor"));
hoursBefore = data.getInt("Hours");
minutesBefore = data.getInt("Minutes");
info = data.getString("Info");
enabled = data.getBoolean("Enabled");
infoOnly = data.getBoolean("InfoOnly");
announcementChannelId = data.getString("channel_id");
type = AnnouncementType.fromValue(data.getString("type"));
eventId = data.getString("event_id");
eventColor = EventColor.valueOf(data.getString("event_color"));
hoursBefore = data.getInt("hours");
minutesBefore = data.getInt("minutes");
info = data.getString("info");
enabled = data.getBoolean("enabled");
infoOnly = data.getBoolean("info_only");
return this;
}

View File

@@ -1,5 +1,7 @@
package org.dreamexposure.discal.core.object.calendar;
import org.json.JSONObject;
import discord4j.core.object.util.Snowflake;
/**
@@ -8,8 +10,8 @@ import discord4j.core.object.util.Snowflake;
* For Project: DisCal-Discord-Bot
*/
public class CalendarData {
private final Snowflake guildId;
private final int calendarNumber;
private Snowflake guildId;
private int calendarNumber;
private String calendarId;
private String calendarAddress;
@@ -26,6 +28,10 @@ public class CalendarData {
external = false;
}
public CalendarData() {
}
//Getters
public Snowflake getGuildId() {
return guildId;
@@ -59,4 +65,27 @@ public class CalendarData {
public void setExternal(boolean _external) {
external = _external;
}
public JSONObject toJson() {
JSONObject json = new JSONObject();
json.put("guild_id", guildId.asLong());
json.put("calendar_number", calendarNumber);
json.put("calendar_id", calendarId);
json.put("calendar_address", calendarAddress);
json.put("external", external);
return json;
}
public CalendarData fromJson(JSONObject json) {
guildId = Snowflake.of(json.getLong("guild_id"));
calendarNumber = json.getInt("calendar_number");
calendarId = json.getString("calendar_id");
calendarAddress = json.getString("calendar_address");
external = json.getBoolean("external");
return this;
}
}

View File

@@ -1,9 +1,11 @@
package org.dreamexposure.discal.core.object.event;
import discord4j.core.object.util.Snowflake;
import org.json.JSONObject;
import javax.annotation.Nullable;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
@@ -54,4 +56,23 @@ public class EventData {
public boolean shouldBeSaved() {
return imageLink != null;
}
public JSONObject toJson() {
JSONObject json = new JSONObject();
json.put("guild_id", guildId.asLong());
json.put("event_id", eventId);
json.put("event_end", eventEnd);
json.put("image_link", imageLink);
return json;
}
public EventData fromJson(JSONObject json) {
eventId = json.getString("event_id");
eventEnd = json.getLong("event_end");
imageLink = json.getString("image_link");
return this;
}
}

View File

@@ -2,6 +2,7 @@ package org.dreamexposure.discal.core.object.event;
import org.dreamexposure.discal.core.enums.event.EventFrequency;
import org.dreamexposure.discal.core.utils.GlobalConst;
import org.json.JSONObject;
/**
* Created by Nova Fox on 11/10/17.
@@ -119,7 +120,7 @@ public class Recurrence {
} else if (c.contains("INTERVAL=")) {
String inter = c.replaceAll("INTERVAL=", "");
try {
interval = Integer.valueOf(inter);
interval = Integer.parseInt(inter);
} catch (NumberFormatException e) {
//Not valid number, safe to ignore error.
interval = 1;
@@ -127,7 +128,7 @@ public class Recurrence {
} else if (c.contains("COUNT=")) {
String con = c.replaceAll("COUNT=", "");
try {
count = Integer.valueOf(con);
count = Integer.parseInt(con);
} catch (NumberFormatException e) {
//Not valid number, can ignore.
count = -1;
@@ -136,4 +137,22 @@ public class Recurrence {
}
return this;
}
public JSONObject toJson() {
JSONObject json = new JSONObject();
json.put("frequency", frequency.getName());
json.put("interval", interval);
json.put("count", count);
return json;
}
public Recurrence fromJson(JSONObject json) {
frequency = EventFrequency.fromValue(json.getString("frequency"));
interval = json.getInt("interval");
count = json.getInt("count");
return this;
}
}

View File

@@ -1,10 +1,13 @@
package org.dreamexposure.discal.core.object.event;
import discord4j.core.object.util.Snowflake;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
@@ -160,4 +163,57 @@ public class RsvpData {
public boolean shouldBeSaved() {
return goingOnTime.size() > 0 || goingLate.size() > 0 || notGoing.size() > 0 || undecided.size() > 0;
}
public JSONObject toJson() {
JSONObject json = new JSONObject();
json.put("guild_id", guildId.asLong());
json.put("event_id", eventId);
json.put("event_end", eventEnd);
JSONArray jOnTime = new JSONArray();
for (String s : goingOnTime)
jOnTime.put(s);
json.put("on_time", jOnTime);
JSONArray jLate = new JSONArray();
for (String s : goingLate)
jLate.put(s);
json.put("late", jLate);
JSONArray jNot = new JSONArray();
for (String s : notGoing)
jNot.put(s);
json.put("not_going", jNot);
JSONArray jUndecided = new JSONArray();
for (String s : undecided)
jUndecided.put(s);
json.put("undecided", jUndecided);
return json;
}
public RsvpData fromJson(JSONObject json) {
eventId = json.getString("event_id");
eventEnd = json.getLong("event_end");
JSONArray jOnTime = json.getJSONArray("on_time");
for (int i = 0; i < jOnTime.length(); i++)
goingOnTime.add(jOnTime.getString(i));
JSONArray jLate = json.getJSONArray("late");
for (int i = 0; i < jLate.length(); i++)
goingLate.add(jLate.getString(i));
JSONArray jNot = json.getJSONArray("not_going");
for (int i = 0; i < jNot.length(); i++)
notGoing.add(jNot.getString(i));
JSONArray jUndecided = json.getJSONArray("undecided");
for (int i = 0; i < jUndecided.length(); i++)
undecided.add(jUndecided.getString(i));
return this;
}
}

View File

@@ -1,5 +1,7 @@
package org.dreamexposure.discal.core.object.network.discal;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -72,4 +74,16 @@ public class ConnectedClient {
public void setMemUsed(double _mem) {
memUsed = _mem;
}
public JSONObject toJson() {
JSONObject json = new JSONObject();
json.put("index", clientIndex);
json.put("servers", connectedServers);
json.put("keep_alive", lastKeepAlive);
json.put("uptime", uptime);
json.put("memory", memUsed);
return json;
}
}

View File

@@ -3,6 +3,8 @@ package org.dreamexposure.discal.core.object.network.discal;
import org.dreamexposure.discal.core.logger.Logger;
import org.joda.time.Interval;
import org.joda.time.Period;
import org.json.JSONArray;
import org.json.JSONObject;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
@@ -95,4 +97,21 @@ public class NetworkInfo {
public void setAnnouncementCount(int announcementCount) {
this.announcementCount = announcementCount;
}
public JSONObject toJson() {
JSONObject json = new JSONObject();
json.put("uptime", getUptime());
json.put("announcements", getAnnouncementCount());
json.put("guilds", getTotalGuildCount());
json.put("calendars", getCalendarCount());
JSONArray jClients = new JSONArray();
for (ConnectedClient c : clients)
jClients.put(c.toJson());
json.put("clients", jClients);
return json;
}
}

View File

@@ -7,6 +7,10 @@ public class AuthenticationState {
private String reason;
private boolean fromDiscalNetwork;
private String keyUsed;
public AuthenticationState(boolean _success) {
success = _success;
}
@@ -23,6 +27,14 @@ public class AuthenticationState {
return reason;
}
public String getKeyUsed() {
return keyUsed;
}
public boolean isFromDiscalNetwork() {
return fromDiscalNetwork;
}
public AuthenticationState setStatus(int _status) {
status = _status;
return this;
@@ -33,6 +45,16 @@ public class AuthenticationState {
return this;
}
public AuthenticationState setKeyUsed(String _key) {
keyUsed = _key;
return this;
}
public AuthenticationState setFromDisCalNetwork(boolean _fromDisCal) {
fromDiscalNetwork = _fromDisCal;
return this;
}
public String toJson() {
return "{\"Message\": \"" + reason + "\"}";
}

View File

@@ -1,6 +1,7 @@
package org.dreamexposure.discal.core.object.web;
import com.google.api.services.calendar.model.Calendar;
import org.dreamexposure.discal.core.calendar.CalendarAuth;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
@@ -112,27 +113,27 @@ public class WebCalendar {
public JSONObject toJson() {
JSONObject data = new JSONObject();
data.put("Id", id);
data.put("Address", address);
data.put("Link", link);
data.put("Name", name);
data.put("id", id);
data.put("address", address);
data.put("link", link);
data.put("name", name);
if (description != null)
data.put("Description", description);
data.put("Timezone", timezone);
data.put("External", external);
data.put("description", description);
data.put("timezone", timezone);
data.put("external", external);
return data;
}
public WebCalendar fromJson(JSONObject data) {
id = data.getString("Id");
address = data.getString("Address");
link = data.getString("Link");
name = data.getString("Name");
if (data.has("Description"))
description = data.getString("Description");
timezone = data.getString("Timezone");
external = data.getBoolean("External");
id = data.getString("id");
address = data.getString("address");
link = data.getString("link");
name = data.getString("name");
if (data.has("description"))
description = data.getString("description");
timezone = data.getString("timezone");
external = data.getBoolean("external");
return this;
}

View File

@@ -1,9 +1,10 @@
package org.dreamexposure.discal.core.object.web;
import discord4j.core.object.entity.TextChannel;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.json.JSONObject;
import discord4j.core.object.entity.TextChannel;
/**
* Created by Nova Fox on 1/6/18.
* Website: www.cloudcraftgaming.com
@@ -54,17 +55,17 @@ public class WebChannel {
public JSONObject toJson() {
JSONObject data = new JSONObject();
data.put("Id", id);
data.put("Name", name);
data.put("DisCalChannel", discalChannel);
data.put("id", id);
data.put("name", name);
data.put("discal_channel", discalChannel);
return data;
}
public WebChannel fromJson(JSONObject data) {
id = data.getLong("Id");
name = data.getString("Name");
discalChannel = data.getBoolean("DisCalChannel");
id = data.getLong("id");
name = data.getString("name");
discalChannel = data.getBoolean("discal_channel");
return this;
}

View File

@@ -1,8 +1,5 @@
package org.dreamexposure.discal.core.object.web;
import discord4j.core.object.entity.*;
import discord4j.core.object.util.Image;
import discord4j.core.object.util.Snowflake;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.announcement.Announcement;
@@ -12,6 +9,14 @@ import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import discord4j.core.object.entity.Guild;
import discord4j.core.object.entity.GuildChannel;
import discord4j.core.object.entity.Member;
import discord4j.core.object.entity.Role;
import discord4j.core.object.entity.TextChannel;
import discord4j.core.object.util.Image;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 12/19/17.
* Website: www.cloudcraftgaming.com
@@ -19,7 +24,7 @@ import java.util.List;
*/
@SuppressWarnings("ConstantConditions")
public class WebGuild {
private String id;
private long id;
private String name;
private String iconUrl;
@@ -39,7 +44,7 @@ public class WebGuild {
private WebCalendar calendar;
//Getters
public String getId() {
public long getId() {
return id;
}
@@ -100,7 +105,7 @@ public class WebGuild {
}
//Setters
public void setId(String _id) {
public void setId(long _id) {
id = _id;
}
@@ -135,7 +140,7 @@ public class WebGuild {
//Functions
public WebGuild fromGuild(Guild g) {
id = g.getId().asString();
id = g.getId().asLong();
name = g.getName();
if (g.getIconUrl(Image.Format.PNG).isPresent())
iconUrl = g.getIconUrl(Image.Format.PNG).get();
@@ -167,68 +172,68 @@ public class WebGuild {
public JSONObject toJson() {
JSONObject data = new JSONObject();
data.put("Id", id);
data.put("Name", name);
data.put("id", id);
data.put("name", name);
if (iconUrl != null)
data.put("IconUrl", iconUrl);
data.put("Settings", settings.toJson());
data.put("icon_url", iconUrl);
data.put("settings", settings.toJson());
if (botNick != null && !botNick.equals(""))
data.put("BotNick", botNick);
data.put("ManageServer", manageServer);
data.put("DiscalRole", discalRole);
data.put("bot_nick", botNick);
data.put("manage_server", manageServer);
data.put("discal_role", discalRole);
JSONArray jRoles = new JSONArray();
for (WebRole wr : roles) {
jRoles.put(wr.toJson());
}
data.put("Roles", jRoles);
data.put("roles", jRoles);
JSONArray jChannels = new JSONArray();
for (WebChannel wc : channels) {
jChannels.put(wc.toJson());
}
data.put("Channels", jChannels);
data.put("channels", jChannels);
JSONArray jAnnouncements = new JSONArray();
for (Announcement a : announcements) {
jAnnouncements.put(a.toJson());
}
data.put("Announcements", jAnnouncements);
data.put("announcements", jAnnouncements);
data.put("Calendar", calendar.toJson());
data.put("calendar", calendar.toJson());
return data;
}
public WebGuild fromJson(JSONObject data) {
id = data.getString("Id");
name = data.getString("Name");
if (data.has("IconUrl"))
iconUrl = data.getString("IconUrl");
settings = new GuildSettings(Snowflake.of(id)).fromJson(data.getJSONObject("Settings"));
if (data.has("BotNick"))
botNick = data.getString("BotNick");
id = data.getLong("id");
name = data.getString("name");
if (data.has("icon_url"))
iconUrl = data.getString("icon_url");
settings = new GuildSettings(Snowflake.of(id)).fromJson(data.getJSONObject("settings"));
if (data.has("bot_nick"))
botNick = data.getString("bot_nick");
else
botNick = "";
manageServer = data.getBoolean("ManageServer");
discalRole = data.getBoolean("DiscalRole");
manageServer = data.getBoolean("manage_server");
discalRole = data.getBoolean("discal_role");
JSONArray jRoles = data.getJSONArray("Roles");
JSONArray jRoles = data.getJSONArray("roles");
for (int i = 0; i < jRoles.length(); i++) {
roles.add(new WebRole().fromJson(jRoles.getJSONObject(i)));
}
JSONArray jChannels = data.getJSONArray("Channels");
JSONArray jChannels = data.getJSONArray("channels");
for (int i = 0; i < jChannels.length(); i++) {
channels.add(new WebChannel().fromJson(jChannels.getJSONObject(i)));
}
JSONArray jAnnouncements = data.getJSONArray("Announcements");
JSONArray jAnnouncements = data.getJSONArray("announcements");
for (int i = 0; i < jAnnouncements.length(); i++) {
announcements.add(new Announcement(Snowflake.of(id)).fromJson(jAnnouncements.getJSONObject(i)));
}
calendar = new WebCalendar().fromJson(data.getJSONObject("Calendar"));
calendar = new WebCalendar().fromJson(data.getJSONObject("calendar"));
return this;
}

View File

@@ -1,9 +1,10 @@
package org.dreamexposure.discal.core.object.web;
import discord4j.core.object.entity.Role;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.json.JSONObject;
import discord4j.core.object.entity.Role;
/**
* Created by Nova Fox on 1/6/18.
* Website: www.cloudcraftgaming.com
@@ -82,21 +83,21 @@ public class WebRole {
public JSONObject toJson() {
JSONObject data = new JSONObject();
data.put("Id", id);
data.put("Name", name);
data.put("Managed", managed);
data.put("ControlRole", controlRole);
data.put("Everyone", everyone);
data.put("id", id);
data.put("name", name);
data.put("managed", managed);
data.put("control_role", controlRole);
data.put("everyone", everyone);
return data;
}
public WebRole fromJson(JSONObject data) {
id = data.getLong("Id");
name = data.getString("Name");
managed = data.getBoolean("Managed");
controlRole = data.getBoolean("ControlRole");
everyone = data.getBoolean("Everyone");
id = data.getLong("id");
name = data.getString("name");
managed = data.getBoolean("managed");
controlRole = data.getBoolean("control_role");
everyone = data.getBoolean("everyone");
return this;
}

View File

@@ -0,0 +1,58 @@
package org.dreamexposure.discal.core.utils;
import com.google.api.services.calendar.model.Event;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.event.EventData;
import org.dreamexposure.discal.core.object.event.Recurrence;
import org.json.JSONObject;
public class JsonUtils {
public static String getJsonResponseMessage(String msg) {
return "{\"message\": \"" + msg + "\"}";
}
public static JSONObject convertEventToJson(Event event, GuildSettings settings) {
JSONObject json = new JSONObject();
json.put("id", event.getId());
json.put("epoch_start", event.getStart().getDateTime().getValue());
json.put("epoch_end", event.getEnd().getDateTime().getValue());
//These 3 are optional values
if (event.getSummary() != null)
json.put("summary", event.getSummary());
if (event.getDescription() != null)
json.put("description", event.getDescription());
if (event.getLocation() != null)
json.put("location", event.getLocation());
json.put("is_parent", !(event.getId().contains("_")));
json.put("color", EventColor.fromNameOrHexOrID(event.getColorId()).name());
if (event.getRecurrence() != null && event.getRecurrence().size() > 0) {
json.put("recur", true);
Recurrence r = new Recurrence().fromRRule(event.getRecurrence().get(0));
JSONObject recurrence = new JSONObject();
recurrence.put("frequency", r.getFrequency().name());
recurrence.put("count", r.getCount());
recurrence.put("interval", r.getInterval());
json.put("recurrence", recurrence); //Optional
} else
json.put("recur", false);
EventData ed = DatabaseManager.getManager()
.getEventData(settings.getGuildID(), event.getId());
//Event image is also optional
if (ed.getImageLink() != null)
json.put("image", ed.getImageLink());
return json;
}
}

View File

@@ -1,14 +1,13 @@
package org.dreamexposure.discal.server.api.endpoints.v1;
import discord4j.core.object.util.Snowflake;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.enums.announcement.AnnouncementType;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.announcement.Announcement;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.dreamexposure.discal.server.utils.ResponseUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
@@ -16,11 +15,14 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
@@ -71,20 +73,20 @@ public class AnnouncementEndpoint {
} else {
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Announcement not found.");
return JsonUtils.getJsonResponseMessage("Announcement not found.");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal get announcement error", e, true, AnnouncementEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -132,20 +134,20 @@ public class AnnouncementEndpoint {
} else {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal create announcement error", e, true, AnnouncementEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -193,29 +195,29 @@ public class AnnouncementEndpoint {
if (DatabaseManager.getManager().updateAnnouncement(a)) {
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Successfully updated announcement");
return JsonUtils.getJsonResponseMessage("Successfully updated announcement");
} else {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
} else {
response.setContentType("application/json");
response.setStatus(404);
return ResponseUtils.getJsonResponseMessage("Announcement not found");
return JsonUtils.getJsonResponseMessage("Announcement not found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal update announcement error", e, true, AnnouncementEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -239,29 +241,29 @@ public class AnnouncementEndpoint {
if (DatabaseManager.getManager().deleteAnnouncement(announcementId)) {
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Successfully deleted announcement");
return JsonUtils.getJsonResponseMessage("Successfully deleted announcement");
} else {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
} else {
response.setContentType("application/json");
response.setStatus(404);
return ResponseUtils.getJsonResponseMessage("Announcement not found");
return JsonUtils.getJsonResponseMessage("Announcement not found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal delete announcement error", e, true, AnnouncementEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -339,13 +341,13 @@ public class AnnouncementEndpoint {
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal list announcements error", e, true, AnnouncementEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -1,12 +1,11 @@
package org.dreamexposure.discal.server.api.endpoints.v1;
import discord4j.core.object.util.Snowflake;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.dreamexposure.discal.server.utils.ResponseUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
@@ -14,9 +13,12 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
@@ -59,20 +61,20 @@ public class CalendarEndpoint {
} else {
response.setContentType("application/json");
response.setStatus(404);
return ResponseUtils.getJsonResponseMessage("Calendar not found");
return JsonUtils.getJsonResponseMessage("Calendar not found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal get calendar error", e, true, CalendarEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -116,13 +118,13 @@ public class CalendarEndpoint {
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal list calendars error", e, true, CalendarEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -19,8 +19,8 @@ import org.dreamexposure.discal.core.object.event.Recurrence;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.EventUtils;
import org.dreamexposure.discal.core.utils.ImageUtils;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.dreamexposure.discal.server.utils.ResponseUtils;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -96,7 +96,7 @@ public class EventEndpoint {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -194,7 +194,7 @@ public class EventEndpoint {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -278,7 +278,7 @@ public class EventEndpoint {
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Successfully updated event!");
return JsonUtils.getJsonResponseMessage("Successfully updated event!");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB] Failed to update event!", e, true, EventEndpoint.class);
@@ -417,13 +417,13 @@ public class EventEndpoint {
//Deleted!
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Successfully deleted event!");
return JsonUtils.getJsonResponseMessage("Successfully deleted event!");
} else {
//Oh nos! we failed >.<
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -1,12 +1,11 @@
package org.dreamexposure.discal.server.api.endpoints.v1;
import discord4j.core.object.util.Snowflake;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.dreamexposure.discal.server.utils.ResponseUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
@@ -17,6 +16,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
@@ -64,13 +65,13 @@ public class GuildEndpoint {
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal get guild settings error", e, true, GuildEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -106,22 +107,22 @@ public class GuildEndpoint {
if (DatabaseManager.getManager().updateSettings(settings)) {
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Successfully updated guild settings!");
return JsonUtils.getJsonResponseMessage("Successfully updated guild settings!");
} else {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal update guild settings error", e, true, GuildEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -179,12 +180,12 @@ public class GuildEndpoint {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal get guilds from users error", e, true, GuildEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -1,12 +1,11 @@
package org.dreamexposure.discal.server.api.endpoints.v1;
import discord4j.core.object.util.Snowflake;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.event.RsvpData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.dreamexposure.discal.server.utils.ResponseUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
@@ -17,6 +16,8 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
@@ -59,13 +60,13 @@ public class RsvpEndpoint {
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal get RSVP data error", e, true, RsvpEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -122,24 +123,24 @@ public class RsvpEndpoint {
if (DatabaseManager.getManager().updateRsvpData(rsvp)) {
response.setContentType("application/json");
response.setStatus(200);
return ResponseUtils.getJsonResponseMessage("Successfully updated RSVP data");
return JsonUtils.getJsonResponseMessage("Successfully updated RSVP data");
} else {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return ResponseUtils.getJsonResponseMessage("Bad Request");
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB-API] Internal update RSVP data error", e, true, RsvpEndpoint.class);
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,55 @@
package org.dreamexposure.discal.server.api.endpoints.v2;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.DisCalServer;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/v2/status")
public class StatusEndpoint {
@PostMapping(value = "/get", produces = "application/json")
public String getStatus(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject();
body.put("status", DisCalServer.getNetworkInfo().toJson());
response.setContentType("application/json");
response.setStatus(200);
return body.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal get status error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,62 @@
package org.dreamexposure.discal.server.api.endpoints.v2.account;
import org.dreamexposure.discal.core.crypto.KeyGenerator;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/v2/account")
public class LoginEndpoint {
@GetMapping(value = "/login")
public String loginForKey(HttpServletRequest request, HttpServletResponse response) {
//Check auth, must be from within DisCal network, as this is generating an API key...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
} else if (!authState.isFromDiscalNetwork()) {
response.setStatus(401);
response.setContentType("application/json");
return JsonUtils.getJsonResponseMessage("Unauthorized to use this Endpoint.");
}
try {
//Generate temporary API key. This key should only be valid for 48 hours unless refreshed..
String key = KeyGenerator.csRandomAlphaNumericString(64);
//Save key to memory... so it can be used for authentication just like the others
Authentication.saveTempKey(key);
//Return key to web....
JSONObject responseBody = new JSONObject();
responseBody.put("key", key);
response.setContentType("application/json");
response.setStatus(200);
return responseBody.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal login for key exception", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,49 @@
package org.dreamexposure.discal.server.api.endpoints.v2.account;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/v2/account")
public class LogoutEndpoint {
@GetMapping(value = "/logout")
public String logoutOfAccount(HttpServletRequest request, HttpServletResponse response) {
//Check auth
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
try {
//If this is a temp key, it will be removed...
Authentication.removeTempKey(authState.getKeyUsed());
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("Logged Out");
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal logout of account exception", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,91 @@
package org.dreamexposure.discal.server.api.endpoints.v2.announcement;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.enums.announcement.AnnouncementType;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.announcement.Announcement;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/announcement")
public class CreateEndpoint {
@PostMapping(value = "/create", produces = "application/json")
public String createAnnouncement(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject(requestBody);
Snowflake guildId = Snowflake.of(body.getLong("guild_id"));
Announcement a = new Announcement(guildId);
a.setAnnouncementChannelId(body.getString("channel"));
a.setAnnouncementType(AnnouncementType.fromValue(body.getString("type")));
if (a.getAnnouncementType().equals(AnnouncementType.COLOR))
a.setEventColor(EventColor.fromNameOrHexOrID(body.getString("color")));
if (a.getAnnouncementType().equals(AnnouncementType.RECUR) ||
a.getAnnouncementType().equals(AnnouncementType.SPECIFIC))
a.setEventId(body.getString("event_id"));
a.setHoursBefore(body.getInt("hours"));
a.setMinutesBefore(body.getInt("minutes"));
if (body.has("info"))
a.setInfo(body.getString("info"));
else
a.setInfo("N/a");
if (body.has("info_only"))
a.setInfoOnly(body.getBoolean("info_only"));
if (DatabaseManager.getManager().updateAnnouncement(a)) {
JSONObject responseBody = new JSONObject();
responseBody.put("message", "Announcement successfully created");
responseBody.put("announcement_id", a.getAnnouncementId().toString());
response.setContentType("application/json");
response.setStatus(200);
return responseBody.toString();
}
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal create announcement error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,70 @@
package org.dreamexposure.discal.server.api.endpoints.v2.announcement;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/announcement")
public class DeleteEndpoint {
@PostMapping(value = "/delete", produces = "application/json")
public String deleteAnnouncement(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject(requestBody);
Snowflake guildId = Snowflake.of(body.getLong("guild_id"));
UUID announcementId = UUID.fromString(body.getString("announcement_id"));
if (DatabaseManager.getManager().getAnnouncement(announcementId, guildId) != null) {
if (DatabaseManager.getManager().deleteAnnouncement(announcementId.toString())) {
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("Announcement successfully deleted");
}
} else {
response.setContentType("application/json");
response.setStatus(404);
return JsonUtils.getJsonResponseMessage("Announcement not Found");
}
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal delete announcement error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,71 @@
package org.dreamexposure.discal.server.api.endpoints.v2.announcement;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.announcement.Announcement;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/announcement")
public class GetEndpoint {
@PostMapping(value = "/get", produces = "application/json")
public String getAnnouncement(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject(requestBody);
Snowflake guildId = Snowflake.of(body.getLong("guild_id"));
UUID announcementId = UUID.fromString(body.getString("announcement_id"));
Announcement a = DatabaseManager.getManager().getAnnouncement(announcementId, guildId);
if (a != null) {
JSONObject responseBody = new JSONObject();
responseBody.put("announcement", a.toJson());
response.setContentType("application/json");
response.setStatus(200);
return responseBody.toString();
} else {
response.setContentType("application/json");
response.setStatus(404);
return JsonUtils.getJsonResponseMessage("Announcement not found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal get announcement error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,77 @@
package org.dreamexposure.discal.server.api.endpoints.v2.announcement;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.announcement.Announcement;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/announcement")
public class ListEndpoint {
@PostMapping(value = "/list", produces = "application/json")
public String listAnnouncements(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject(requestBody);
Snowflake guildId = Snowflake.of(body.getLong("guild_id"));
int amount = body.getInt("amount");
JSONArray jAnnouncements = new JSONArray();
if (amount < 1) {
for (Announcement a : DatabaseManager.getManager().getAnnouncements(guildId))
jAnnouncements.put(a.toJson());
} else {
int i = 0;
for (Announcement a : DatabaseManager.getManager().getAnnouncements(guildId)) {
if (i < amount) {
jAnnouncements.put(a.toJson());
i++;
} else
break;
}
}
JSONObject responseBody = new JSONObject();
responseBody.put("message", "Listed announcements successfully");
responseBody.put("announcements", jAnnouncements);
response.setContentType("application/json");
response.setStatus(200);
return responseBody.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal list announcements error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,119 @@
package org.dreamexposure.discal.server.api.endpoints.v2.announcement;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.enums.announcement.AnnouncementType;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.announcement.Announcement;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/announcement")
public class UpdateEndpoint {
@PostMapping(value = "/update", produces = "application/json")
public String updateAnnouncement(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject(requestBody);
Snowflake guildId = Snowflake.of(body.getLong("guild_id"));
UUID announcementId = UUID.fromString(body.getString("announcement_id"));
Announcement a = DatabaseManager.getManager().getAnnouncement(announcementId, guildId);
if (a != null) {
if (body.has("channel"))
a.setAnnouncementChannelId(body.getString("channel"));
if (body.has("event_id"))
a.setEventId(body.getString("event_id"));
if (body.has("event_color"))
a.setEventColor(EventColor.fromNameOrHexOrID(body.getString("event_color")));
if (body.has("type"))
a.setAnnouncementType(AnnouncementType.fromValue(body.getString("type")));
if (body.has("hours"))
a.setHoursBefore(body.getInt("hours"));
if (body.has("minutes"))
a.setMinutesBefore(body.getInt("minutes"));
if (body.has("info"))
a.setInfo(body.getString("info"));
if (body.has("info_only"))
a.setInfoOnly(body.getBoolean("info_only"));
if (body.has("enabled"))
a.setEnabled(body.getBoolean("enabled"));
//Handle subscribers....
if (body.has("remove_subscriber_roles")) {
JSONArray jRemoveRoles = body.getJSONArray("remove_subscriber_roles");
for (int i = 0; i < jRemoveRoles.length(); i++)
a.getSubscriberRoleIds().remove(jRemoveRoles.getString(i));
}
if (body.has("remove_subscriber_users")) {
JSONArray jRemoveUsers = body.getJSONArray("remove_subscriber_users");
for (int i = 0; i < jRemoveUsers.length(); i++)
a.getSubscriberUserIds().remove(jRemoveUsers.getString(i));
}
if (body.has("add_subscriber_roles")) {
JSONArray rAddRoles = body.getJSONArray("add_subscriber_roles");
for (int i = 0; i < rAddRoles.length(); i++)
a.getSubscriberRoleIds().add(rAddRoles.getString(i));
}
if (body.has("add_subscriber_users")) {
JSONArray rAddUsers = body.getJSONArray("add_subscriber_users");
for (int i = 0; i < rAddUsers.length(); i++)
a.getSubscriberUserIds().add(rAddUsers.getString(i));
}
//Update in database now.
if (DatabaseManager.getManager().updateAnnouncement(a)) {
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("Announcement successfully updated");
}
} else {
response.setContentType("application/json");
response.setStatus(404);
return JsonUtils.getJsonResponseMessage("Announcement not Found");
}
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal update announcement error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,69 @@
package org.dreamexposure.discal.server.api.endpoints.v2.calendar;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/calendar")
public class GetEndpoint {
@PostMapping(value = "/get", produces = "application/json")
public String getCalendar(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject jsonMain = new JSONObject(requestBody);
long guildId = jsonMain.getLong("guild_id");
int calNumber = jsonMain.getInt("number");
CalendarData calendar = DatabaseManager.getManager().getCalendar(Snowflake.of(guildId), calNumber);
if (!calendar.getCalendarAddress().equalsIgnoreCase("primary")) {
JSONObject body = new JSONObject();
body.put("calendar", calendar.toJson());
response.setContentType("application/json");
response.setStatus(200);
return body.toString();
} else {
response.setContentType("application/json");
response.setStatus(404);
return JsonUtils.getJsonResponseMessage("Calendar not found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal get calendar error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,66 @@
package org.dreamexposure.discal.server.api.endpoints.v2.calendar;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/calendar")
public class ListEndpoint {
@PostMapping(value = "/list", produces = "application/json")
public String listCalendars(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject jsonMain = new JSONObject(requestBody);
long guildId = jsonMain.getLong("guild_id");
JSONArray jCals = new JSONArray();
for (CalendarData cal : DatabaseManager.getManager().getAllCalendars(Snowflake.of(guildId))) {
if (!cal.getCalendarAddress().equalsIgnoreCase("primary"))
jCals.put(cal.toJson());
}
JSONObject body = new JSONObject();
body.put("calendars", jCals);
response.setContentType("application/json");
response.setStatus(200);
return body.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal list calendars error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,128 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.model.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import org.dreamexposure.discal.core.calendar.CalendarAuth;
import org.dreamexposure.discal.core.crypto.KeyGenerator;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.event.EventData;
import org.dreamexposure.discal.core.object.event.Recurrence;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.ImageUtils;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/events")
public class CreateEndpoint {
@PostMapping(value = "/create", produces = "application/json")
public String createEvent(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
int calNumber = requestBody.getInt("calendar_number");
//okay, lets actually create the event
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
CalendarData calData = DatabaseManager.getManager().getCalendar(settings.getGuildID(), calNumber);
com.google.api.services.calendar.Calendar service = CalendarAuth.getCalendarService(settings);
Calendar cal = service.calendars().get(calData.getCalendarId()).execute();
Event event = new Event();
event.setId(KeyGenerator.generateEventId());
event.setVisibility("public");
EventDateTime start = new EventDateTime();
start.setDateTime(new DateTime(requestBody.getLong("epoch_start")));
event.setStart(start.setTimeZone(cal.getTimeZone()));
EventDateTime end = new EventDateTime();
end.setDateTime(new DateTime(requestBody.getLong("epoch_end")));
event.setEnd(end.setTimeZone(cal.getTimeZone()));
if (requestBody.has("summary"))
event.setSummary(requestBody.getString("summary"));
if (requestBody.has("description"))
event.setDescription(requestBody.getString("description"));
if (requestBody.has("color"))
event.setColorId(EventColor.fromNameOrHexOrID(requestBody.getString("color")).getId() + "");
if (requestBody.has("location"))
event.setLocation(requestBody.getString("location"));
if (requestBody.has("recur") && requestBody.getBoolean("recur")) {
JSONObject recur = requestBody.getJSONObject("recurrence");
Recurrence recurrence = new Recurrence().fromJson(recur);
String[] rr = new String[]{recurrence.toRRule()};
event.setRecurrence(Arrays.asList(rr));
}
EventData eventData = new EventData(settings.getGuildID());
if (requestBody.has("image")) {
if (ImageUtils.validate(requestBody.getString("image"), settings.isPatronGuild())) {
//Link is good...
eventData.setEventId(event.getId());
eventData.setImageLink(requestBody.getString("image"));
eventData.setEventEnd(event.getEnd().getDateTime().getValue());
}
}
//Everything supported is now checked for, lets create this on google's end now.
Event confirmed = service.events().insert(cal.getId(), event).execute();
if (eventData.shouldBeSaved())
DatabaseManager.getManager().updateEventData(eventData);
//If we get here, nothing errored, and everything should be created correctly...
JSONObject responseBody = new JSONObject();
responseBody.put("message", "Event Successfully Created");
responseBody.put("event_id", confirmed.getId());
response.setContentType("application/json");
response.setStatus(200);
return responseBody.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to update event.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,82 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.EventUtils;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/events")
public class DeleteEndpoint {
@PostMapping(value = "/delete", produces = "application/json")
public String deleteEvent(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
//int calNumber = requestBody.getInt("calendar_number");
String eventId = requestBody.getString("event_id");
//okay, lets actually delete the event
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
if (EventUtils.eventExists(settings, eventId)) {
if (EventUtils.deleteEvent(settings, eventId)) {
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("Event successfully deleted");
}
//Something went wrong, but didn't error.... this should never happen...
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
} else {
response.setContentType("application/json");
response.setStatus(404);
return JsonUtils.getJsonResponseMessage("Event Not Found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to update event.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,5 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event;
public class GetEndpoint {
//TODO: Actually be smart and make this damn endpoint cuz I got distracted and forgot
}

View File

@@ -0,0 +1,127 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.model.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
import org.dreamexposure.discal.core.calendar.CalendarAuth;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.event.EventData;
import org.dreamexposure.discal.core.object.event.Recurrence;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.ImageUtils;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/events")
public class UpdateEndpoint {
@PostMapping(value = "/update", produces = "application/json")
public String updateEvent(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
int calNumber = requestBody.getInt("calendar_number");
String eventId = requestBody.getString("event_id");
//Handle actually updating the event
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
CalendarData calData = DatabaseManager.getManager().getCalendar(settings.getGuildID(), calNumber);
com.google.api.services.calendar.Calendar service = CalendarAuth.getCalendarService(settings);
Calendar cal = service.calendars().get(calData.getCalendarId()).execute();
Event event = service.events().get(calData.getCalendarId(), eventId).execute();
if (event != null) {
if (requestBody.has("epoch_start")) {
EventDateTime start = new EventDateTime();
start.setDateTime(new DateTime(requestBody.getLong("epoch_start")));
event.setStart(start.setTimeZone(cal.getTimeZone()));
}
if (requestBody.has("epoch_end")) {
EventDateTime end = new EventDateTime();
end.setDateTime(new DateTime(requestBody.getLong("epoch_end")));
event.setEnd(end.setTimeZone(cal.getTimeZone()));
}
if (requestBody.has("summary"))
event.setSummary(requestBody.getString("summary"));
if (requestBody.has("description"))
event.setDescription(requestBody.getString("description"));
if (requestBody.has("color"))
event.setColorId(EventColor.fromNameOrHexOrID(requestBody.getString("color")).getId() + "");
if (requestBody.has("location"))
event.setLocation(requestBody.getString("location"));
if (requestBody.has("recur") && requestBody.getBoolean("recur")) {
JSONObject recur = requestBody.getJSONObject("recurrence");
Recurrence recurrence = new Recurrence().fromJson(recur);
String[] rr = new String[]{recurrence.toRRule()};
event.setRecurrence(Arrays.asList(rr));
}
if (requestBody.has("image")) {
if (ImageUtils.validate(requestBody.getString("image"), settings.isPatronGuild())) {
//Link is good...
EventData ed = DatabaseManager.getManager().getEventData(settings.getGuildID(), eventId);
ed.setImageLink(requestBody.getString("image"));
ed.setEventEnd(event.getEnd().getDateTime().getValue());
DatabaseManager.getManager().updateEventData(ed);
}
}
//Everything supported is now checked for, lets update this on google's end now.
service.events().update(calData.getCalendarId(), eventId, event).execute();
//If we get here, nothing errored, and everything should be updated correctly...
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("Event updated Successfully");
} else {
response.setContentType("application/json");
response.setStatus(404);
return JsonUtils.getJsonResponseMessage("Event not found");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to update event.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,92 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import org.dreamexposure.discal.core.calendar.CalendarAuth;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.GlobalConst;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/events/list")
public class DateEndpoint {
@PostMapping(value = "/list/date", produces = "application/json")
public String getEventsForDate(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
int calNumber = requestBody.getInt("calendar_number");
long startEpoch = requestBody.getLong("start_epoch");
long endEpoch = startEpoch + GlobalConst.oneDayMs;
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
//okay, lets actually get the date's events.
Calendar service = CalendarAuth.getCalendarService(settings);
CalendarData calendarData = DatabaseManager.getManager().getCalendar(settings.getGuildID(), calNumber);
Events events = service.events().list(calendarData.getCalendarAddress())
.setTimeMin(new DateTime(startEpoch))
.setTimeMax(new DateTime(endEpoch))
.setOrderBy("startTime")
.setSingleEvents(true)
.setShowDeleted(false)
.execute();
List<Event> items = events.getItems();
JSONArray jEvents = new JSONArray();
for (Event e : items)
jEvents.put(JsonUtils.convertEventToJson(e, settings));
JSONObject body = new JSONObject();
body.put("events", jEvents);
response.setContentType("application/json");
response.setStatus(200);
return body.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to retrieve events for a date.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,93 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import org.dreamexposure.discal.core.calendar.CalendarAuth;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.GlobalConst;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/events/list")
public class MonthEndpoint {
@PostMapping(value = "/list/month", produces = "application/json")
public String getEventsForMonth(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
int calNumber = requestBody.getInt("calendar_number");
int daysInMonth = requestBody.getInt("days_in_month");
long startEpoch = requestBody.getInt("start_epoch");
long endEpoch = startEpoch + (GlobalConst.oneDayMs * daysInMonth);
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
//okay, lets actually get the month's events.
Calendar service = CalendarAuth.getCalendarService(settings);
CalendarData calendarData = DatabaseManager.getManager().getCalendar(settings.getGuildID(), calNumber);
Events events = service.events().list(calendarData.getCalendarAddress())
.setTimeMin(new DateTime(startEpoch))
.setTimeMax(new DateTime(endEpoch))
.setOrderBy("startTime")
.setSingleEvents(true)
.setShowDeleted(false)
.execute();
List<Event> items = events.getItems();
JSONArray jEvents = new JSONArray();
for (Event e : items)
jEvents.put(JsonUtils.convertEventToJson(e, settings));
JSONObject body = new JSONObject();
body.put("events", jEvents);
response.setContentType("application/json");
response.setStatus(200);
return body.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to retrieve events for a month.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,91 @@
package org.dreamexposure.discal.server.api.endpoints.v2.event.list;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;
import org.dreamexposure.discal.core.calendar.CalendarAuth;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.calendar.CalendarData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/events/list")
public class RangeEndpoint {
@PostMapping(value = "/list/range", produces = "application/json")
public String getEventsForRange(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
int calNumber = requestBody.getInt("calendar_number");
long startEpoch = requestBody.getLong("start_epoch");
long endEpoch = requestBody.getLong("end_epoch");
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
//okay, lets actually get the range's events.
Calendar service = CalendarAuth.getCalendarService(settings);
CalendarData calendarData = DatabaseManager.getManager().getCalendar(settings.getGuildID(), calNumber);
Events events = service.events().list(calendarData.getCalendarAddress())
.setTimeMin(new DateTime(startEpoch))
.setTimeMax(new DateTime(endEpoch))
.setOrderBy("startTime")
.setSingleEvents(true)
.setShowDeleted(false)
.execute();
List<Event> items = events.getItems();
JSONArray jEvents = new JSONArray();
for (Event e : items)
jEvents.put(JsonUtils.convertEventToJson(e, settings));
JSONObject body = new JSONObject();
body.put("events", jEvents);
response.setContentType("application/json");
response.setStatus(200);
return body.toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to retrieve events for range.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,62 @@
package org.dreamexposure.discal.server.api.endpoints.v2.guild.settings;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/guild/settings")
public class GetEndpoint {
@PostMapping(value = "/get", produces = "application/json")
public String getSettings(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject jsonMain = new JSONObject(requestBody);
long guildId = jsonMain.getLong("guild_id");
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
response.setContentType("application/json");
response.setStatus(200);
if (authState.isFromDiscalNetwork())
return settings.toJson().toString();
else
return settings.toJsonSecure().toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal get guild settings error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,88 @@
package org.dreamexposure.discal.server.api.endpoints.v2.guild.settings;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.GuildSettings;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/guild/settings")
public class UpdateEndpoint {
@PostMapping(value = "/update", produces = "application/json")
public String updateSettings(HttpServletRequest request, HttpServletResponse response, @RequestBody String requestBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject body = new JSONObject(requestBody);
long guildId = body.getLong("guild_id");
GuildSettings settings = DatabaseManager.getManager().getSettings(Snowflake.of(guildId));
//Handle various things that are allowed to change.
if (body.has("control_role"))
settings.setControlRole(body.getString("control_role"));
if (body.has("discal_channel"))
settings.setDiscalChannel(body.getString("discal_channel"));
if (body.has("simple_announcements"))
settings.setSimpleAnnouncements(body.getBoolean("simple_announcements"));
if (body.has("lang"))
settings.setLang(body.getString("lang"));
if (body.has("prefix"))
settings.setPrefix(body.getString("prefix"));
//Allow Official DisCal Shards to change some other things...
if (authState.isFromDiscalNetwork()) {
if (body.has("external_calendar"))
settings.setUseExternalCalendar(body.getBoolean("external_calendar"));
if (body.has("patron_guild"))
settings.setPatronGuild(body.getBoolean("patron_guild"));
if (body.has("dev_guild"))
settings.setDevGuild(body.getBoolean("dev_guild"));
if (body.has("branded"))
settings.setBranded(body.getBoolean("branded"));
}
if (DatabaseManager.getManager().updateSettings(settings)) {
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("Successfully updated guild settings!");
} else {
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Internal update guild settings error", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,63 @@
package org.dreamexposure.discal.server.api.endpoints.v2.rsvp;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.event.RsvpData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/rsvp")
public class GetEndpoint {
@PostMapping(value = "/get", produces = "application/json")
public String getRsvp(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
String eventId = requestBody.getString("event_id");
RsvpData rsvp = DatabaseManager.getManager().getRsvpData(Snowflake.of(guildId), eventId);
response.setContentType("application/json");
response.setStatus(200);
return rsvp.toJson().toString();
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to get RSVP data.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -0,0 +1,122 @@
package org.dreamexposure.discal.server.api.endpoints.v2.rsvp;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.event.RsvpData;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.server.utils.Authentication;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import discord4j.core.object.util.Snowflake;
@RestController
@RequestMapping("/v2/rsvp")
public class UpdateEndpoint {
@PostMapping(value = "/update", produces = "application/json")
public String updateRsvp(HttpServletRequest request, HttpServletResponse response, @RequestBody String rBody) {
//Authenticate...
AuthenticationState authState = Authentication.authenticate(request);
if (!authState.isSuccess()) {
response.setStatus(authState.getStatus());
response.setContentType("application/json");
return authState.toJson();
}
//Okay, now handle actual request.
try {
JSONObject requestBody = new JSONObject(rBody);
long guildId = requestBody.getLong("guild_id");
String eventId = requestBody.getString("event_id");
RsvpData rsvp = DatabaseManager.getManager().getRsvpData(Snowflake.of(guildId), eventId);
//Handle additions...
if (requestBody.has("to_add")) {
JSONObject jToAdd = requestBody.getJSONObject("to_add");
if (jToAdd.has("on_time")) {
JSONArray ar = jToAdd.getJSONArray("on_time");
for (int i = 0; i < jToAdd.length(); i++)
rsvp.getGoingOnTime().add(ar.getString(i));
}
if (jToAdd.has("late")) {
JSONArray ar = jToAdd.getJSONArray("late");
for (int i = 0; i < jToAdd.length(); i++)
rsvp.getGoingLate().add(ar.getString(i));
}
if (jToAdd.has("not_going")) {
JSONArray ar = jToAdd.getJSONArray("not_going");
for (int i = 0; i < jToAdd.length(); i++)
rsvp.getNotGoing().add(ar.getString(i));
}
if (jToAdd.has("undecided")) {
JSONArray ar = jToAdd.getJSONArray("undecided");
for (int i = 0; i < jToAdd.length(); i++)
rsvp.getUndecided().add(ar.getString(i));
}
}
//handle removals...
if (requestBody.has("to_remove")) {
JSONObject jToRemove = requestBody.getJSONObject("to_remove");
if (jToRemove.has("on_time")) {
JSONArray ar = jToRemove.getJSONArray("on_time");
for (int i = 0; i < jToRemove.length(); i++)
rsvp.getGoingOnTime().remove(ar.getString(i));
}
if (jToRemove.has("late")) {
JSONArray ar = jToRemove.getJSONArray("late");
for (int i = 0; i < jToRemove.length(); i++)
rsvp.getGoingLate().remove(ar.getString(i));
}
if (jToRemove.has("not_going")) {
JSONArray ar = jToRemove.getJSONArray("not_going");
for (int i = 0; i < jToRemove.length(); i++)
rsvp.getNotGoing().remove(ar.getString(i));
}
if (jToRemove.has("undecided")) {
JSONArray ar = jToRemove.getJSONArray("undecided");
for (int i = 0; i < jToRemove.length(); i++)
rsvp.getUndecided().remove(ar.getString(i));
}
}
if (DatabaseManager.getManager().updateRsvpData(rsvp)) {
response.setContentType("application/json");
response.setStatus(200);
return JsonUtils.getJsonResponseMessage("RSVP successfully updated");
}
//Shouldn't get here, but if we did, the update probably failed...
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
} catch (JSONException e) {
e.printStackTrace();
response.setContentType("application/json");
response.setStatus(400);
return JsonUtils.getJsonResponseMessage("Bad Request");
} catch (Exception e) {
Logger.getLogger().exception(null, "[API-v2] Failed to get RSVP data.", e, true, this.getClass());
response.setContentType("application/json");
response.setStatus(500);
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -1,60 +1,82 @@
package org.dreamexposure.discal.server.utils;
import org.dreamexposure.discal.core.database.DatabaseManager;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.BotSettings;
import org.dreamexposure.discal.core.object.web.AuthenticationState;
import org.dreamexposure.discal.core.object.web.UserAPIAccount;
import org.dreamexposure.discal.core.utils.GlobalConst;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class Authentication {
private static Map<String, Long> tempKeys = new HashMap<>();
//TODO: Still gotta figure out how to handle embed, but whatever...
public static AuthenticationState authenticate(HttpServletRequest request) {
if (!request.getMethod().equalsIgnoreCase("POST")) {
Logger.getLogger().api("Denied '" + request.getMethod() + "' access", request.getRemoteAddr());
return new AuthenticationState(false).setStatus(405).setReason("Method not allowed");
return new AuthenticationState(false)
.setStatus(405)
.setReason("Method not allowed");
}
//TODO: Fix this whole damn thing. Its really fucking dumb and broken!
/*
//Check authorization
if (DiscordAccountHandler.getHandler().hasAccount(request)) {
//User is logged in from website, no API key needed
Logger.getLogger().api("API Call from website", request.getRemoteAddr());
//Requires "Authorization Header
if (request.getHeader("Authorization") != null) {
String key = request.getHeader("Authorization");
return new AuthenticationState(true).setStatus(200).setReason("Success");
} else {
//Requires "Authorization Header
if (request.getHeader("Authorization") != null) {
String key = request.getHeader("Authorization");
//TODO: Handle this shit better but whatever
if (key.equals("EMBEDDED")) {
Logger.getLogger().api("User using embed", request.getRemoteAddr(), request.getServerName(), request.getPathInfo());
//TODO: Verify its using the correct /embed/ path!!!!
return new AuthenticationState(true).setStatus(200).setReason("Success");
} else {
UserAPIAccount acc = DatabaseManager.getManager().getAPIAccount(key);
if (acc != null) {
if (acc.isBlocked()) {
Logger.getLogger().api("Attempted to use blocked API Key: " + acc.getAPIKey(), request.getRemoteAddr());
return new AuthenticationState(false).setStatus(401).setReason("Unauthorized");
} else {
//Everything checks out!
acc.setUses(acc.getUses() + 1);
DatabaseManager.getManager().updateAPIAccount(acc);
return new AuthenticationState(true).setStatus(200).setReason("Success");
}
} else {
Logger.getLogger().api("Attempted to use invalid API Key: " + key, request.getRemoteAddr());
return new AuthenticationState(false).setStatus(401).setReason("Unauthorized");
}
}
} else {
Logger.getLogger().api("Attempted to use API without authorization header", request.getRemoteAddr());
return new AuthenticationState(false).setStatus(400).setReason("Bad Request");
//Check if this is from within the DisCal network...
if (key.equals(BotSettings.BOT_API_TOKEN.get())) {
return new AuthenticationState(true)
.setStatus(200)
.setReason("Success")
.setKeyUsed(key)
.setFromDisCalNetwork(true);
//Check if this is a temp key, granted for a logged in user...
} else if (tempKeys.containsKey(key)) {
return new AuthenticationState(true)
.setStatus(200)
.setReason("Success")
.setKeyUsed(key);
} else if (key.equals("teapot")) {
return new AuthenticationState(false)
.setStatus(418)
.setReason("I'm a teapot")
.setKeyUsed(key);
}
}
*/
return new AuthenticationState(true).setStatus(200).setReason("Success");
//Check if this key is in the database...
UserAPIAccount acc = DatabaseManager.getManager().getAPIAccount(key);
if (acc != null && !acc.isBlocked()) {
acc.setUses(acc.getUses() + 1);
DatabaseManager.getManager().updateAPIAccount(acc);
return new AuthenticationState(true)
.setStatus(200)
.setReason("Success")
.setKeyUsed(key);
}
//If we reach here, the API key does not exist or is blocked...
return new AuthenticationState(false)
.setStatus(405)
.setReason("Method not allowed");
} else {
Logger.getLogger().api("Attempted to use API without authorization header", request.getRemoteAddr());
return new AuthenticationState(false)
.setStatus(400)
.setReason("Bad Request");
}
}
public static void saveTempKey(String key) {
if (!tempKeys.containsKey(key))
tempKeys.put(key, System.currentTimeMillis() + GlobalConst.oneDayMs);
}
public static void removeTempKey(String key) {
tempKeys.remove(key);
}
}

View File

@@ -1,12 +0,0 @@
package org.dreamexposure.discal.server.utils;
/**
* Created by Nova Fox on 11/10/17.
* Website: www.cloudcraftgaming.com
* For Project: DisCal-Discord-Bot
*/
public class ResponseUtils {
public static String getJsonResponseMessage(String msg) {
return "{\"Message\": \"" + msg + "\"}";
}
}

View File

@@ -20,8 +20,8 @@ import org.dreamexposure.discal.core.object.web.WebGuild;
import org.dreamexposure.discal.core.object.web.WebRole;
import org.dreamexposure.discal.core.utils.CalendarUtils;
import org.dreamexposure.discal.core.utils.GlobalConst;
import org.dreamexposure.discal.core.utils.JsonUtils;
import org.dreamexposure.discal.web.DisCalWeb;
import org.dreamexposure.discal.web.utils.ResponseUtils;
import org.dreamexposure.novautils.network.pubsub.PubSubManager;
import org.json.JSONException;
import org.json.JSONObject;
@@ -131,7 +131,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -172,7 +172,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -310,7 +310,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -375,7 +375,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -422,7 +422,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -475,7 +475,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -505,7 +505,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -531,7 +531,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
@@ -577,7 +577,7 @@ public class DashboardHandler {
response.setContentType("application/json");
response.setStatus(500);
return ResponseUtils.getJsonResponseMessage("Internal Server Error");
return JsonUtils.getJsonResponseMessage("Internal Server Error");
}
}
}

View File

@@ -26,13 +26,13 @@ import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@SuppressWarnings({"unchecked", "RedundantCast", "Duplicates", "WeakerAccess", "unused", "ConstantConditions"})
@SuppressWarnings({"RedundantCast", "Duplicates", "WeakerAccess", "unused", "ConstantConditions"})
public class DiscordAccountHandler {
private static DiscordAccountHandler instance;
private static Timer timer;
private HashMap<String, Map> discordAccounts = new HashMap<>();
private HashMap<String, Map> embedMaps = new HashMap<>();
private HashMap<String, Map<String, Object>> discordAccounts = new HashMap<>();
private HashMap<String, Map<String, Object>> embedMaps = new HashMap<>();
//Instance handling
private DiscordAccountHandler() {
@@ -80,11 +80,11 @@ public class DiscordAccountHandler {
}
//Getters
public Map getAccount(HttpServletRequest request) {
public Map<String, Object> getAccount(HttpServletRequest request) {
if ((String) request.getSession(true).getAttribute("account") != null && discordAccounts.containsKey((String) request.getSession(true).getAttribute("account"))) {
Map m = discordAccounts.get((String) request.getSession(true).getAttribute("account"));
m.remove("lastUse");
m.put("lastUse", System.currentTimeMillis());
Map<String, Object> m = discordAccounts.get((String) request.getSession(true).getAttribute("account"));
m.remove("last_use");
m.put("last_use", System.currentTimeMillis());
m.remove("status");
m.put("status", DisCalWeb.getNetworkInfo());
@@ -96,12 +96,12 @@ public class DiscordAccountHandler {
} else {
//Not logged in...
Map m = new HashMap();
m.put("loggedIn", false);
Map<String, Object> m = new HashMap<>();
m.put("logged_in", false);
m.put("client", BotSettings.ID.get());
m.put("year", LocalDate.now().getYear());
m.put("redirect_uri", BotSettings.REDIR_URI.get());
m.put("bot_invite", BotSettings.INVITE_URL.get());
m.put("invite_url", BotSettings.INVITE_URL.get());
m.put("support_invite", BotSettings.SUPPORT_INVITE.get());
m.put("status", DisCalWeb.getNetworkInfo());
@@ -112,15 +112,15 @@ public class DiscordAccountHandler {
}
}
public Map getEmbedMap(HttpServletRequest request) {
public Map<String, Object> getEmbedMap(HttpServletRequest request) {
return embedMaps.get((String) request.getSession(true).getAttribute("embed"));
}
public Map getAccountForGuildEmbed(HttpServletRequest request, String guildId) {
public Map<String, Object> getAccountForGuildEmbed(HttpServletRequest request, String guildId) {
if ((String) request.getSession(true).getAttribute("account") != null && discordAccounts.containsKey((String) request.getSession(true).getAttribute("account"))) {
Map m = discordAccounts.get((String) request.getSession(true).getAttribute("account"));
m.remove("lastUse");
m.put("lastUse", System.currentTimeMillis());
Map<String, Object> m = discordAccounts.get((String) request.getSession(true).getAttribute("account"));
m.remove("last_use");
m.put("last_use", System.currentTimeMillis());
m.remove("status");
m.put("status", DisCalWeb.getNetworkInfo());
@@ -179,12 +179,12 @@ public class DiscordAccountHandler {
return m;
} else {
//Not logged in...
Map m = new HashMap();
m.put("loggedIn", false);
Map<String, Object> m = new HashMap<>();
m.put("logged_in", false);
m.put("client", BotSettings.ID.get());
m.put("year", LocalDate.now().getYear());
m.put("redirect_uri", BotSettings.REDIR_URI.get());
m.put("bot_invite", BotSettings.INVITE_URL.get());
m.put("invite_url", BotSettings.INVITE_URL.get());
m.put("support_invite", BotSettings.SUPPORT_INVITE.get());
m.put("status", DisCalWeb.getNetworkInfo());
@@ -244,12 +244,12 @@ public class DiscordAccountHandler {
}
}
public Map findAccount(String userId) {
for (Map m : discordAccounts.values()) {
public Map<String, Object> findAccount(String userId) {
for (Map<String, Object> m : discordAccounts.values()) {
if (m.containsKey("id")) {
if (m.get("id").equals(userId)) {
m.remove("lastUse");
m.put("lastUse", System.currentTimeMillis());
m.remove("last_use");
m.put("last_use", System.currentTimeMillis());
return m;
}
}
@@ -262,10 +262,10 @@ public class DiscordAccountHandler {
}
//Functions
public void addAccount(Map m, HttpServletRequest request) {
public void addAccount(Map<String, Object> m, HttpServletRequest request) {
discordAccounts.remove((String) request.getSession(true).getAttribute("account"));
m.remove("lastUse");
m.put("lastUse", System.currentTimeMillis());
m.remove("last_use");
m.put("last_use", System.currentTimeMillis());
discordAccounts.put((String) request.getSession(true).getAttribute("account"), m);
}
@@ -283,8 +283,8 @@ public class DiscordAccountHandler {
long limit = Long.parseLong(BotSettings.TIME_OUT.get());
final List<String> toRemove = new ArrayList<>();
for (String id : discordAccounts.keySet()) {
Map m = discordAccounts.get(id);
long lastUse = (long) m.get("lastUse");
Map<String, Object> m = discordAccounts.get(id);
long lastUse = (long) m.get("last_use");
if (System.currentTimeMillis() - lastUse > limit)
toRemove.remove(id); //Timed out, remove account info and require sign in.
}

View File

@@ -5,11 +5,9 @@ import org.dreamexposure.discal.core.enums.announcement.AnnouncementType;
import org.dreamexposure.discal.core.enums.event.EventColor;
import org.dreamexposure.discal.core.logger.Logger;
import org.dreamexposure.discal.core.object.BotSettings;
import org.dreamexposure.discal.core.object.network.discal.ConnectedClient;
import org.dreamexposure.discal.core.object.web.WebGuild;
import org.dreamexposure.discal.core.utils.GlobalConst;
import org.dreamexposure.discal.web.DisCalWeb;
import org.dreamexposure.discal.web.handler.DashboardHandler;
import org.dreamexposure.discal.web.handler.DiscordAccountHandler;
import org.json.JSONArray;
import org.json.JSONException;
@@ -25,39 +23,39 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import okhttp3.Credentials;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
@SuppressWarnings("ConstantConditions")
@RestController
public class DiscordLoginHandler {
@GetMapping("/account/login")
public static String handleDiscordCode(HttpServletRequest req, HttpServletResponse res, @RequestParam(value = "code") String code) throws IOException {
@GetMapping(value = "/account/login")
public String handleDiscordCode(HttpServletRequest req, HttpServletResponse res, @RequestParam(value = "code") String code) throws IOException {
OkHttpClient client = new OkHttpClient();
try {
//Handle getting discord account data....
RequestBody body = new FormBody.Builder()
.addEncoded("client_id", BotSettings.ID.get())
.addEncoded("client_secret", BotSettings.SECRET.get())
.addEncoded("grant_type", "authorization_code")
.addEncoded("code", code)
.addEncoded("redirect_uri", BotSettings.REDIR_URL.get())
.build();
.addEncoded("client_id", BotSettings.ID.get())
.addEncoded("client_secret", BotSettings.SECRET.get())
.addEncoded("grant_type", "authorization_code")
.addEncoded("code", code)
.addEncoded("redirect_uri", BotSettings.REDIR_URI.get())
.build();
okhttp3.Request httpRequest = new okhttp3.Request.Builder()
.url("https://discordapp.com/api/v6/oauth2/token")
.post(body)
.header("Content-Type", "application/x-www-form-urlencoded")
.build();
.url("https://discordapp.com/api/v6/oauth2/token")
.post(body)
.header("Content-Type", "application/x-www-form-urlencoded")
.build();
//POST request to discord for access...
okhttp3.Response httpResponse = client.newCall(httpRequest).execute();
@@ -68,124 +66,143 @@ public class DiscordLoginHandler {
if (info.has("access_token")) {
//GET request for user info...
Request userDataRequest = new Request.Builder()
.url("https://discordapp.com/api/v6/users/@me")
.header("Authorization", "Bearer " + info.getString("access_token"))
.build();
.url("https://discordapp.com/api/v6/users/@me")
.header("Authorization", "Bearer " + info.getString("access_token"))
.build();
Response userDataResponse = client.newCall(userDataRequest).execute();
Request userGuildsRequest = new Request.Builder()
.url("https://discordapp.com/api/v6/users/@me/guilds")
.header("Authorization", "Bearer " + info.getString("access_token"))
.build();
.url("https://discordapp.com/api/v6/users/@me/guilds")
.header("Authorization", "Bearer " + info.getString("access_token"))
.build();
Response userGuildsResponse = client.newCall(userGuildsRequest).execute();
JSONObject userInfo = new JSONObject(userDataResponse.body().string());
JSONArray jGuilds = new JSONArray(userGuildsResponse.body().string());
//Get list of guild IDs.
JSONArray servers = new JSONArray();
for (int i = 0; i < jGuilds.length(); i++) {
servers.put(jGuilds.getJSONObject(i).getLong("id"));
}
//We have the data we need, now map it, and request an API token for this session.
//Saving session info and access info to memory until moved into the database...
//Saving session info and access info to memory...
Map<String, Object> m = new HashMap<>();
m.put("loggedIn", true);
//The universal stuffs
m.put("logged_in", true);
m.put("client", BotSettings.ID.get());
m.put("year", LocalDate.now().getYear());
m.put("redirUri", BotSettings.REDIR_URI.get());
m.put("inviteUrl", BotSettings.INVITE_URL.get());
m.put("redirect_uri", BotSettings.REDIR_URI.get());
m.put("invite_url", BotSettings.INVITE_URL.get());
m.put("support_invite", BotSettings.SUPPORT_INVITE.get());
m.put("status", DisCalWeb.getNetworkInfo());
//More universal stuff, but for the dashboard only
m.put("good_timezones", GoodTimezone.values());
m.put("announcement_types", AnnouncementType.values());
m.put("event_colors", EventColor.values());
//User info
m.put("id", userInfo.getString("id"));
m.put("username", userInfo.getString("username"));
m.put("discrim", userInfo.getString("discriminator"));
List<WebGuild> guilds = new ArrayList<>();
try {
OkHttpClient clientWithTimeout = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS)
.build();
JSONObject comBody = new JSONObject();
comBody.put("member_id", Long.valueOf(m.get("id") + ""));
comBody.put("guilds", servers);
RequestBody httpRequestBody = RequestBody.create(GlobalConst.JSON, comBody.toString());
//TODO: Fix this shit. Really just remove it. Mirror what we did with Remx
for (ConnectedClient cc : DisCalWeb.getNetworkInfo().getClients()) {
try {
Request requestNew = new Request.Builder()
.url("https://" + BotSettings.COM_SUB_DOMAIN.get() + cc.getClientIndex() + ".discalbot.com/api/v1/com/website/dashboard/defaults")
.post(httpRequestBody)
.header("Content-Type", "application/json")
.header("Authorization", Credentials.basic(BotSettings.COM_USER.get(), BotSettings.COM_PASS.get()))
.build();
Response responseNew = clientWithTimeout.newCall(requestNew).execute();
if (responseNew.code() == 200) {
JSONObject responseBody = new JSONObject(responseNew.body().string());
JSONArray guildsData = responseBody.getJSONArray("guilds");
for (int i = 0; i < guildsData.length(); i++) {
guilds.add(new WebGuild().fromJson(guildsData.getJSONObject(i)));
}
} else if (responseNew.code() >= 500) {
//Client must be down... lets remove it...
DisCalWeb.getNetworkInfo().removeClient(cc.getClientIndex());
}
} catch (Exception e) {
Logger.getLogger().exception(null, "Client response error", e, true, DiscordAccountHandler.class);
//Remove client to be on the safe side. If client is still up, it'll be re-added on the next keepalive
DisCalWeb.getNetworkInfo().removeClient(cc.getClientIndex());
}
}
} catch (Exception e) {
Logger.getLogger().exception(null, "Failed to handle dashboard guild get", e, true, DashboardHandler.class);
if (userInfo.has("avatar") && !userInfo.isNull("avatar")) {
m.put("pfp", "https://cdn.discordapp.com/avatars/"
+ userInfo.getString("id")
+ "/"
+ userInfo.getString("avatar")
+ ".png");
} else {
m.put("pfp", "/assets/img/default/pfp.png");
}
//Guild stuffs
List<WebGuild> guilds = new ArrayList<>();
for (int i = 0; i < jGuilds.length(); i++) {
JSONObject jGuild = jGuilds.getJSONObject(i);
WebGuild wg = new WebGuild();
wg.setId(jGuild.getLong("id"));
wg.setName(jGuild.getString("name"));
if (jGuild.has("icon") && !jGuild.isNull("icon")) {
wg.setIcon("https://cdn.discordapp.com/icons/"
+ wg.getId()
+ "/"
+ jGuild.getString("icon")
+ ".png");
} else {
wg.setIcon("/assets/img/default/guild-icon.png");
}
guilds.add(wg);
}
m.put("guilds", guilds);
m.put("goodTz", GoodTimezone.values());
m.put("anTypes", AnnouncementType.values());
m.put("eventColors", EventColor.values());
String newSessionId = UUID.randomUUID().toString();
req.getSession(true).setAttribute("account", newSessionId);
DiscordAccountHandler.getHandler().addAccount(m, req);
//Request temporary API key....
RequestBody keyGrantRequestBody = RequestBody.create(GlobalConst.JSON, "");
Request keyGrantRequest = new Request.Builder()
.url("https://api.discalbot.com/v2/account/login")
.header("Authorization", BotSettings.BOT_API_TOKEN.get())
.post(keyGrantRequestBody)
.build();
Response keyGrantResponse = client.newCall(keyGrantRequest).execute();
//Handle response...
if (keyGrantResponse.code() == 200) {
JSONObject keyGrantResponseBody = new JSONObject(keyGrantResponse.body().toString());
//API key received, map....
m.put("key", keyGrantResponseBody.getString("key"));
DiscordAccountHandler.getHandler().addAccount(m, req);
} else {
//Something didn't work... just redirect back to the login page....
res.sendRedirect("/login");
return "redirect:/login";
}
//Finally redirect to the dashboard seamlessly.
res.sendRedirect("/dashboard");
return "redirect:/dashboard";
} else {
//Token not provided. Authentication denied or errored... Redirect to dashboard so user knows auth failed.
res.sendRedirect("/dashboard");
return "redirect:/dashboard";
//Token not provided. Authentication denied or errored... Redirect to login page so user knows auth failed.
res.sendRedirect("/login");
return "redirect:/login";
}
} catch (JSONException e) {
Logger.getLogger().exception(null, "[WEB] JSON || Discord login failed!", e, true, DiscordLoginHandler.class);
Logger.getLogger().exception(null, "[LOGIN-Discord] JSON || Discord login failed!", e, true, this.getClass());
res.sendRedirect("/dashboard");
return "redirect:/dashboard";
} catch (Exception e) {
Logger.getLogger().exception(null, "[WEB] Discord login failed!", e, true, DiscordLoginHandler.class);
Logger.getLogger().exception(null, "[LOGIN-Discord] Discord login failed!", e, true, this.getClass());
res.sendRedirect("/dashboard");
return "redirect:/dashboard";
}
}
@GetMapping("/account/logout")
public static String handleLogout(HttpServletRequest request, HttpServletResponse res) throws IOException {
public String handleLogout(HttpServletRequest request, HttpServletResponse res) throws IOException {
try {
//Tell the API server the user has logged out and to delete the temporary key.
OkHttpClient client = new OkHttpClient();
Map<String, Object> map = DiscordAccountHandler.getHandler().getAccount(request);
RequestBody logoutRequestBody = RequestBody.create(GlobalConst.JSON, "");
Request logoutRequest = new Request.Builder()
.url("https://api.discalbot.com/v2/account/logout")
.header("Authorization", (String) map.get("private_token"))
.post(logoutRequestBody)
.build();
//We don't need a return, if it fails, it will be auto-deleted anyway...
client.newCall(logoutRequest).execute();
DiscordAccountHandler.getHandler().removeAccount(request);
request.getSession().invalidate();

View File

@@ -9,7 +9,7 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
@SuppressWarnings({"unchecked", "unused", "SpringMVCViewInspection"})
@SuppressWarnings({"unused"})
@Controller
public class SpringController {
@@ -199,26 +199,4 @@ public class SpringController {
model.putAll(DiscordAccountHandler.getHandler().getAccount(req));
return "various/status";
}
//Error pages - Only here for testing reasons
@RequestMapping("/400")
public String badRequest(Map<String, Object> model, HttpServletRequest req) {
model.clear();
model.putAll(DiscordAccountHandler.getHandler().getAccount(req));
return "error/400";
}
@RequestMapping("/404")
public String notFound(Map<String, Object> model, HttpServletRequest req) {
model.clear();
model.putAll(DiscordAccountHandler.getHandler().getAccount(req));
return "error/404";
}
@RequestMapping("/500")
public String internalError(Map<String, Object> model, HttpServletRequest req) {
model.clear();
model.putAll(DiscordAccountHandler.getHandler().getAccount(req));
return "error/500";
}
}

View File

@@ -1,7 +0,0 @@
package org.dreamexposure.discal.web.utils;
public class ResponseUtils {
public static String getJsonResponseMessage(String msg) {
return "{\"Message\": \"" + msg + "\"}";
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -127,6 +127,46 @@
<span>RSVP</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v2 Endpoints Heading-->
<div class="sidebar-heading mx-3">v2 Endpoints</div>
<!-- Nav Item - v2 Announcement -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/announcement">
<i class="fas fa-fw fa-bullhorn"></i>
<span>Announcement</span></a>
</li>
<!-- Nav Item - v2 Calendar -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/calendar">
<i class="fas fa-fw fa-calendar-alt"></i>
<span>Calendar</span></a>
</li>
<!-- Nav Item - v2 Events -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/events">
<i class="fas fa-fw fa-calendar-day"></i>
<span>Events</span></a>
</li>
<!-- Nav Item - v2 Guild -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/guild">
<i class="fas fa-fw fa-server"></i>
<span>Guild</span></a>
</li>
<!-- Nav Item - v2 RSVP -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/rsvp">
<i class="fas fa-fw fa-calendar-check"></i>
<span>RSVP</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider my-0">
@@ -272,10 +312,33 @@
All requests and responses are done via HTTP POST and must be in JSON.
All requests must also contain an "Authorization" header with your API key.
You can get an API key by contacting the DisCal development team.
<br>
<br>
Current API version: v1
</p>
<hr>
<h2 class="text-center text-discal-blue">API Versions</h2>
<br>
<h4 class="text-center text-discal-blue">v2</h4>
<p class="text-left text-discord-full-white">
Endpoints can be accessed via: https://api.discalbot.com/v2/*
<br>
<br>
Status: Supported, Default
</p>
<br>
<h4 class="text-center text-discal-blue">v1</h4>
<p class="text-left text-discord-full-white">
Endpoints can be accessed via: https://api.discalbot.com/api/v1/*
<br>
<br>
Status: Deprecated
</p>
</div>
<!-- /.container-fluid -->

View File

@@ -130,7 +130,7 @@
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - get -->

View File

@@ -130,7 +130,7 @@
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - get -->

View File

@@ -130,7 +130,7 @@
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - get -->

View File

@@ -130,7 +130,7 @@
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - settings/get -->

View File

@@ -130,7 +130,7 @@
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - get -->

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,605 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!--Meta Stuffs-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="The Ultimate Discord Calendar Bot">
<meta property="og:title" content="DisCal"/>
<meta property="og:url" content="https://www.discalbot.com"/>
<meta property="og:description" content="The Ultimate Discord Calendar Bot"/>
<meta property="og:image" content="/assets/images/logos/Dark/Opaque/Logo%20Dark%20+bg.png">
<!-- ****** faviconit.com favicons ****** -->
<link rel="shortcut icon" href="/assets/img/favicon/favicon.ico">
<link rel="icon" sizes="16x16 32x32 64x64" href="/assets/img/favicon.ico">
<link rel="icon" type="image/png" sizes="196x196" href="/assets/img/favicon/favicon-192.png">
<link rel="icon" type="image/png" sizes="160x160" href="/assets/img/favicon/favicon-160.png">
<link rel="icon" type="image/png" sizes="96x96" href="/assets/img/favicon/favicon-96.png">
<link rel="icon" type="image/png" sizes="64x64" href="/assets/img/favicon/favicon-64.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicon/favicon-32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicon/favicon-16.png">
<link rel="apple-touch-icon" href="/assets/img/favicon/favicon-57.png">
<link rel="apple-touch-icon" sizes="114x114" href="/assets/img/favicon/favicon-114.png">
<link rel="apple-touch-icon" sizes="72x72" href="/assets/img/favicon/favicon-72.png">
<link rel="apple-touch-icon" sizes="144x144" href="/assets/img/favicon/favicon-144.png">
<link rel="apple-touch-icon" sizes="60x60" href="/assets/img/favicon/favicon-60.png">
<link rel="apple-touch-icon" sizes="120x120" href="/assets/img/favicon/favicon-120.png">
<link rel="apple-touch-icon" sizes="76x76" href="/assets/img/favicon/favicon-76.png">
<link rel="apple-touch-icon" sizes="152x152" href="/assets/img/favicon/favicon-152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicon/favicon-180.png">
<meta name="msapplication-TileColor" content="#FFFFFF">
<meta name="msapplication-TileImage" content="/assets/img/favicon/favicon-144.png">
<meta name="msapplication-config" content="/assets/img/favicon/browserconfig.xml">
<!-- ****** faviconit.com favicons ****** -->
<title>DisCal - API Docs</title>
<!-- Custom fonts for this template-->
<link href="/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<link
href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<!-- Custom styles for this template-->
<link href="/assets/css/sb-admin-2.min.css" rel="stylesheet">
</head>
<body id="page-top">
<!-- Page Wrapper -->
<div id="wrapper">
<!-- Sidebar -->
<ul class="navbar-nav bg-gradient-discal-dark-gray sidebar sidebar-dark accordion"
id="accordionSidebar">
<!-- Sidebar - Brand -->
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="/">
<div class="sidebar-brand-icon rotate-n-15">
<i class="fas fa-calendar"></i>
</div>
<div class="sidebar-brand-text mx-3">DISCAL</div>
</a>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<div class="sidebar-heading mx-3">API</div>
<!-- Nav Item - Overview -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/overview">
<i class="fas fa-fw fa-info-circle"></i>
<span>Overview</span></a>
</li>
<!-- Nav Item - Errors -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/errors">
<i class="fas fa-fw fa-exclamation-circle"></i>
<span>Errors</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v2 Endpoints Heading-->
<div class="sidebar-heading mx-3">v2 Endpoints</div>
<!-- Nav Item - v2 Announcements -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/announcement">
<i class="fas fa-fw fa-bullhorn"></i>
<span>Announcement</span></a>
</li>
<!-- Nav Item - v2 Calendar -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/calendar">
<i class="fas fa-fw fa-calendar-alt"></i>
<span>Calendar</span></a>
</li>
<!-- Nav Item - v2 Events -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/events">
<i class="fas fa-fw fa-calendar-day"></i>
<span>Events</span></a>
</li>
<!-- Nav Item - v2 Guild -->
<li class="nav-item active">
<a class="nav-link" href="/docs/api/v2/guild">
<i class="fas fa-fw fa-server"></i>
<span>Guild</span></a>
</li>
<!-- Nav Item - v2 RSVP -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/rsvp">
<i class="fas fa-fw fa-calendar-check"></i>
<span>RSVP</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - settings/get -->
<li class="nav-item">
<a class="nav-link" href="#settings-get">
<i class="fas fa-fw fa-hand-holding"></i>
<span>/settings/get</span></a>
</li>
<!-- Nav Item - Jump - settings/update -->
<li class="nav-item">
<a class="nav-link" href="#settings-update">
<i class="fas fa-fw fa-edit"></i>
<span>/settings/update</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider my-0">
<!-- Nav Item - Status -->
<li class="nav-item">
<a class="nav-link" href="/status">
<i class="fas fa-fw fa-info-circle"></i>
<span>Status</span></a>
</li>
<!-- Nav Item - Dashboard -->
<li class="nav-item">
<a class="nav-link" href="/dashboard">
<i class="fas fa-fw fa-tachometer-alt"></i>
<span>Dashboard</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Guilds list (only displayed if logged in) -->
<div th:if="${logged_in}">
<!-- Heading -->
<div class="sidebar-heading">
Guilds
</div>
<!-- Start Nav Item - Guild Container -->
<th:block th:each="guild : ${guilds}">
<div class="nav-item">
<a class="nav-link" th:href="'/dashboard/' + ${guild.id}">
<i class="fas fa-fw fa-chart-area"></i>
<span th:text="${guild.name}"></span>
</a>
</div>
</th:block>
<!-- End Nav Item - Guild Container -->
<!-- Divider -->
<hr class="sidebar-divider d-none d-md-block">
</div>
<!-- End Guilds list -->
<!-- Sidebar Toggler (Sidebar) -->
<div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button>
</div>
</ul>
<!-- End of Sidebar -->
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column bg-discal-not-black">
<!-- Main Content -->
<div id="content">
<!-- Topbar -->
<nav
class="navbar navbar-expand navbar-dark bg-discal-blue topbar mb-4 static-top shadow">
<!-- Sidebar Toggle (Topbar) -->
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
<i class="fa fa-bars text-discord-full-white"></i>
</button>
<!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto">
<!-- Nav Item - Support Link -->
<li class="nav-item">
<a class="nav-link text-discord-full-white" th:href="${support_invite}"
target="_blank">
<i class="fas fa-question-circle fa-sm fa-fw mr-2"></i>
Support
</a>
</li>
<!-- Nav Item - Patreon Link -->
<li class="nav-item">
<a class="nav-link text-discord-full-white"
href="https://www.patreon.com/Novafox" target="_blank">
<i class="fab fa-patreon fa-sm fa-fw mr-2"></i>
Patreon
</a>
</li>
<!-- Nav Item - Invite Link -->
<li class="nav-item">
<a class="nav-link text-discord-full-white" th:href="${bot_invite}"
target="_blank">
<i class="fas fa-envelope-open-text fa-sm fa-fw mr-2"></i>
Invite
</a>
</li>
<div class="topbar-divider d-none d-sm-block"></div>
<!-- Nav Item - User Information -->
<li th:if="${logged_in}" class="nav-item dropdown no-arrow">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="mr-2 d-lg-inline small" th:text="${username}"></span>
<img class="img-profile rounded-circle" th:src="${pfp}"
alt="pfp">
</a>
<!-- Dropdown - User Information -->
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
aria-labelledby="userDropdown">
<a class="dropdown-item text-discord-full-white" href="#"
data-toggle="modal" data-target="#logoutModal">
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2"></i>
Logout
</a>
</div>
</li>
<li th:unless="${logged_in}" class="nav-item">
<a class="nav-link text-discord-full-white" href="/login">
<i class="fas fa-sign-in-alt fa-sm fa-fw mr-2"></i>
Login
</a>
</li>
</ul>
</nav>
<!-- End of Topbar -->
<!-- Begin Page Content -->
<div class="container-fluid">
<h1 class="text-center text-discal-blue">API v2 Docs - Guild Endpoint</h1>
<p class="text-center text-discord-full-white">
The Guild endpoints allows you to get and edit guild settings for the
specified guild.
</p>
<br>
<hr>
<!-- Start settings/get endpoint-->
<h2 id="settings-get" class="text-center text-discal-blue">guild/settings/get</h2>
<p class="text-left text-discord-full-white">
Returns the specified guild's settings.
</p>
<br>
<h6 class="text-left text-discal-blue">Example Request Body</h6>
<pre class="code"><code>
{
"guild_id": 375357265198317579
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Example Response Body</h6>
<br>
<pre class="code"><code>
{
"guild_id": 375357265198317579,
"external_calendar": false,
"control_role": "everyone",
"discal_channel": "all",
"simple_announcements": false,
"lang": "ENGLISH",
"prefix": "!",
"patron_guild": false,
"dev_guild": true,
"max_calendars": 1,
"twelve_hour": true,
"branded": false
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Supported Values in Request</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
<th>Required</th>
</tr>
<tr>
<td>guild_id</td>
<td>long</td>
<td>The Guild ID</td>
<td>True</td>
</tr>
</tbody>
</table>
<br>
<h6 class="text-left text-discal-blue">Returned Values</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
</tr>
<tr>
<td>external_calendar</td>
<td>Boolean</td>
<td>Whether or not the guild has an external calendar</td>
</tr>
<tr>
<td>control_role</td>
<td>String</td>
<td>Role ID of the role required to use DisCal ("everyone") for no role</td>
</tr>
<tr>
<td>discal_channel</td>
<td>String</td>
<td>Channel ID of the channel DisCal can be used in. ("all" for no channel
limits)
</td>
</tr>
<tr>
<td>simple_announcements</td>
<td>Boolean</td>
<td>Whether or not the guild has simple announcements enabled</td>
</tr>
<tr>
<td>lang</td>
<td>String</td>
<td>The language DisCal will post messages in (default "ENGLISH")</td>
</tr>
<tr>
<td>prefix</td>
<td>String</td>
<td>Prefix to be used for DisCal commands (default "!")</td>
</tr>
<tr>
<td>patron_guild</td>
<td>Boolean</td>
<td>Whether or not the guild has access to patron only features</td>
</tr>
<tr>
<td>dev_guild</td>
<td>Boolean</td>
<td>Whether or not the guild has access to features currently being
developed
</td>
</tr>
<tr>
<td>max_calendars</td>
<td>int</td>
<td>The maximum amount of calendars the guild can have (default 1)</td>
</tr>
<tr>
<td>twelve_hour</td>
<td>Boolean</td>
<td>Whether the guild is using a 12 hour or 24 hour time format</td>
</tr>
<tr>
<td>branded</td>
<td>Boolean</td>
<td>Whether the server is using branding on embeds</td>
</tr>
</tbody>
</table>
<br>
<!-- End settings/get endpoint-->
<hr>
<!-- Start settings/update endpoint-->
<h2 id="settings-update" class="text-center text-discal-blue">
guild/settings/update</h2>
<p class="text-left text-discord-full-white">
Updates the specified guild's settings.
</p>
<br>
<h6 class="text-left text-discal-blue">Example Request Body</h6>
<pre class="code"><code>
{
"guild_id": 375357265198317579,
"control_role": "everyone",
"discal_channel": "all",
"simple_announcements": true,
"lang", "ENGLISH",
"prefix": "?"
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Example Response</h6>
<br>
<pre class="code"><code>
{
"Message": "Successfully updated guild settings"
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Supported Values in Request</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
<th>Required</th>
</tr>
<tr>
<td>guild_id</td>
<td>long</td>
<td>The Guild ID</td>
<td>True</td>
</tr>
<tr>
<td>control_role</td>
<td>String</td>
<td>Role ID of the role required to use DisCal ("everyone") for no role</td>
<td>False</td>
</tr>
<tr>
<td>discal_channel</td>
<td>String</td>
<td>Channel ID of the channel DisCal can be used in. ("all" for no channel
limits)
</td>
<td>False</td>
</tr>
<tr>
<td>simple_announcements</td>
<td>Boolean</td>
<td>Whether or not the guild has simple announcements enabled</td>
<td>False</td>
</tr>
<tr>
<td>lang</td>
<td>String</td>
<td>The language DisCal will post messages in (default "ENGLISH")</td>
<td>False</td>
</tr>
<tr>
<td>prefix</td>
<td>String</td>
<td>Prefix to be used for DisCal commands (default "!")</td>
<td>False</td>
</tr>
</tbody>
</table>
<br>
<h6 class="text-left text-discal-blue">Returned Values</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
</tr>
<tr>
<td>message</td>
<td>String</td>
<td>Status of settings update</td>
</tr>
</tbody>
</table>
<br>
<!-- End settings/update endpoint-->
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
<!-- Footer -->
<footer class="sticky-footer bg-discal-blue">
<div class="container my-auto">
<div class="copyright text-center text-discord-full-white my-auto">
<span th:text="'&copy; DreamExposure ' + ${year} + '. LGPL-3.'"></span>
</div>
</div>
</footer>
<!-- End of Footer -->
</div>
<!-- End of Content Wrapper -->
</div>
<!-- End of Page Wrapper -->
<!-- Scroll to Top Button-->
<a class="scroll-to-top rounded" href="#page-top">
<i class="fas fa-angle-up"></i>
</a>
<!-- Logout Modal-->
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">Select "Logout" below if you are ready to end your current
session.
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="/logout">Logout</a>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript-->
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="/vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Custom scripts for all pages-->
<script src="/assets/js/sb-admin-2.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,609 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!--Meta Stuffs-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="The Ultimate Discord Calendar Bot">
<meta property="og:title" content="DisCal"/>
<meta property="og:url" content="https://www.discalbot.com"/>
<meta property="og:description" content="The Ultimate Discord Calendar Bot"/>
<meta property="og:image" content="/assets/images/logos/Dark/Opaque/Logo%20Dark%20+bg.png">
<!-- ****** faviconit.com favicons ****** -->
<link rel="shortcut icon" href="/assets/img/favicon/favicon.ico">
<link rel="icon" sizes="16x16 32x32 64x64" href="/assets/img/favicon.ico">
<link rel="icon" type="image/png" sizes="196x196" href="/assets/img/favicon/favicon-192.png">
<link rel="icon" type="image/png" sizes="160x160" href="/assets/img/favicon/favicon-160.png">
<link rel="icon" type="image/png" sizes="96x96" href="/assets/img/favicon/favicon-96.png">
<link rel="icon" type="image/png" sizes="64x64" href="/assets/img/favicon/favicon-64.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/img/favicon/favicon-32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/img/favicon/favicon-16.png">
<link rel="apple-touch-icon" href="/assets/img/favicon/favicon-57.png">
<link rel="apple-touch-icon" sizes="114x114" href="/assets/img/favicon/favicon-114.png">
<link rel="apple-touch-icon" sizes="72x72" href="/assets/img/favicon/favicon-72.png">
<link rel="apple-touch-icon" sizes="144x144" href="/assets/img/favicon/favicon-144.png">
<link rel="apple-touch-icon" sizes="60x60" href="/assets/img/favicon/favicon-60.png">
<link rel="apple-touch-icon" sizes="120x120" href="/assets/img/favicon/favicon-120.png">
<link rel="apple-touch-icon" sizes="76x76" href="/assets/img/favicon/favicon-76.png">
<link rel="apple-touch-icon" sizes="152x152" href="/assets/img/favicon/favicon-152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/assets/img/favicon/favicon-180.png">
<meta name="msapplication-TileColor" content="#FFFFFF">
<meta name="msapplication-TileImage" content="/assets/img/favicon/favicon-144.png">
<meta name="msapplication-config" content="/assets/img/favicon/browserconfig.xml">
<!-- ****** faviconit.com favicons ****** -->
<title>DisCal - API Docs</title>
<!-- Custom fonts for this template-->
<link href="/vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<link
href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<!-- Custom styles for this template-->
<link href="/assets/css/sb-admin-2.min.css" rel="stylesheet">
</head>
<body id="page-top">
<!-- Page Wrapper -->
<div id="wrapper">
<!-- Sidebar -->
<ul class="navbar-nav bg-gradient-discal-dark-gray sidebar sidebar-dark accordion"
id="accordionSidebar">
<!-- Sidebar - Brand -->
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="/">
<div class="sidebar-brand-icon rotate-n-15">
<i class="fas fa-calendar"></i>
</div>
<div class="sidebar-brand-text mx-3">DISCAL</div>
</a>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v1 Endpoints Heading-->
<div class="sidebar-heading mx-3">API</div>
<!-- Nav Item - Overview -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/overview">
<i class="fas fa-fw fa-info-circle"></i>
<span>Overview</span></a>
</li>
<!-- Nav Item - Errors -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/errors">
<i class="fas fa-fw fa-exclamation-circle"></i>
<span>Errors</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- v2 Endpoints Heading-->
<div class="sidebar-heading mx-3">v2 Endpoints</div>
<!-- Nav Item - v2 Announcements -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/announcement">
<i class="fas fa-fw fa-bullhorn"></i>
<span>Announcement</span></a>
</li>
<!-- Nav Item - v2 Calendar -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/calendar">
<i class="fas fa-fw fa-calendar-alt"></i>
<span>Calendar</span></a>
</li>
<!-- Nav Item - v2 Events -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/events">
<i class="fas fa-fw fa-calendar-day"></i>
<span>Events</span></a>
</li>
<!-- Nav Item - v2 Guild -->
<li class="nav-item">
<a class="nav-link" href="/docs/api/v2/guild">
<i class="fas fa-fw fa-server"></i>
<span>Guild</span></a>
</li>
<!-- Nav Item - v2 RSVP -->
<li class="nav-item active">
<a class="nav-link" href="/docs/api/v2/rsvp">
<i class="fas fa-fw fa-calendar-check"></i>
<span>RSVP</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Jump Heading-->
<div class="sidebar-heading mx-3">Jump</div>
<!-- Nav Item - Jump - get -->
<li class="nav-item">
<a class="nav-link" href="#get">
<i class="fas fa-fw fa-hand-holding"></i>
<span>/get</span></a>
</li>
<!-- Nav Item - Jump - update -->
<li class="nav-item">
<a class="nav-link" href="#update">
<i class="fas fa-fw fa-edit"></i>
<span>/update</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider my-0">
<!-- Nav Item - Status -->
<li class="nav-item">
<a class="nav-link" href="/status">
<i class="fas fa-fw fa-info-circle"></i>
<span>Status</span></a>
</li>
<!-- Nav Item - Dashboard -->
<li class="nav-item">
<a class="nav-link" href="/dashboard">
<i class="fas fa-fw fa-tachometer-alt"></i>
<span>Dashboard</span></a>
</li>
<!-- Divider -->
<hr class="sidebar-divider">
<!-- Guilds list (only displayed if logged in) -->
<div th:if="${logged_in}">
<!-- Heading -->
<div class="sidebar-heading">
Guilds
</div>
<!-- Start Nav Item - Guild Container -->
<th:block th:each="guild : ${guilds}">
<div class="nav-item">
<a class="nav-link" th:href="'/dashboard/' + ${guild.id}">
<i class="fas fa-fw fa-chart-area"></i>
<span th:text="${guild.name}"></span>
</a>
</div>
</th:block>
<!-- End Nav Item - Guild Container -->
<!-- Divider -->
<hr class="sidebar-divider d-none d-md-block">
</div>
<!-- End Guilds list -->
<!-- Sidebar Toggler (Sidebar) -->
<div class="text-center d-none d-md-inline">
<button class="rounded-circle border-0" id="sidebarToggle"></button>
</div>
</ul>
<!-- End of Sidebar -->
<!-- Content Wrapper -->
<div id="content-wrapper" class="d-flex flex-column bg-discal-not-black">
<!-- Main Content -->
<div id="content">
<!-- Topbar -->
<nav
class="navbar navbar-expand navbar-dark bg-discal-blue topbar mb-4 static-top shadow">
<!-- Sidebar Toggle (Topbar) -->
<button id="sidebarToggleTop" class="btn btn-link d-md-none rounded-circle mr-3">
<i class="fa fa-bars text-discord-full-white"></i>
</button>
<!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto">
<!-- Nav Item - Support Link -->
<li class="nav-item">
<a class="nav-link text-discord-full-white" th:href="${support_invite}"
target="_blank">
<i class="fas fa-question-circle fa-sm fa-fw mr-2"></i>
Support
</a>
</li>
<!-- Nav Item - Patreon Link -->
<li class="nav-item">
<a class="nav-link text-discord-full-white"
href="https://www.patreon.com/Novafox" target="_blank">
<i class="fab fa-patreon fa-sm fa-fw mr-2"></i>
Patreon
</a>
</li>
<!-- Nav Item - Invite Link -->
<li class="nav-item">
<a class="nav-link text-discord-full-white" th:href="${bot_invite}"
target="_blank">
<i class="fas fa-envelope-open-text fa-sm fa-fw mr-2"></i>
Invite
</a>
</li>
<div class="topbar-divider d-none d-sm-block"></div>
<!-- Nav Item - User Information -->
<li th:if="${logged_in}" class="nav-item dropdown no-arrow">
<a class="nav-link dropdown-toggle" href="#" id="userDropdown" role="button"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="mr-2 d-lg-inline small" th:text="${username}"></span>
<img class="img-profile rounded-circle" th:src="${pfp}"
alt="pfp">
</a>
<!-- Dropdown - User Information -->
<div class="dropdown-menu dropdown-menu-right shadow animated--grow-in"
aria-labelledby="userDropdown">
<a class="dropdown-item text-discord-full-white" href="#"
data-toggle="modal" data-target="#logoutModal">
<i class="fas fa-sign-out-alt fa-sm fa-fw mr-2"></i>
Logout
</a>
</div>
</li>
<li th:unless="${logged_in}" class="nav-item">
<a class="nav-link text-discord-full-white" href="/login">
<i class="fas fa-sign-in-alt fa-sm fa-fw mr-2"></i>
Login
</a>
</li>
</ul>
</nav>
<!-- End of Topbar -->
<!-- Begin Page Content -->
<div class="container-fluid">
<h1 class="text-center text-discal-blue">API v2 Docs - RSVP Endpoint</h1>
<p class="text-center text-discord-full-white">
The RSVP endpoints allows you to get and edit RSVP status for events in a guild.
</p>
<br>
<hr>
<!-- Start get endpoint-->
<h2 id="get" class="text-center text-discal-blue">rsvp/get</h2>
<p class="text-left text-discord-full-white">
Returns the specified event's RSVP details.
</p>
<br>
<h6 class="text-left text-discal-blue">Example Request Body</h6>
<pre class="code"><code>
{
"guild_id": 375357265198317579,
"event_id": "divq9ihqhoq9hbm2tncj8set04"
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Example Response</h6>
<br>
<pre class="code"><code>
{
"on_time": ["130510525770629121"],
"late": ["233611560545812480", "142107863307780097"],
"undecided": [],
"not_going": []
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Supported Values in Request</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
<th>Required</th>
</tr>
<tr>
<td>guild_id</td>
<td>long</td>
<td>The Guild ID</td>
<td>True</td>
</tr>
<tr>
<td>event_id</td>
<td>String</td>
<td>The Event ID</td>
<td>True</td>
</tr>
</tbody>
</table>
<br>
<h6 class="text-left text-discal-blue">Returned Values</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
</tr>
<tr>
<td>guild_id</td>
<td>Long</td>
<td>The ID of the guild the RSVP data belongs to</td>
</tr>
<tr>
<td>event_id</td>
<td>String</td>
<td>The ID of the event this RSVP object is for</td>
</tr>
<tr>
<td>event_id</td>
<td>Long</td>
<td>Unix time of when the event ends</td>
</tr>
<tr>
<td>on_time</td>
<td>List (of Strings)</td>
<td>List of users that RSVPed as "on time"</td>
</tr>
<tr>
<td>on_time</td>
<td>List (of Strings)</td>
<td>List of users that RSVPed as "on time"</td>
</tr>
<tr>
<td>late</td>
<td>List (of Strings)</td>
<td>List of users that RSVPed as "late"</td>
</tr>
<tr>
<td>undecided</td>
<td>List (of Strings)</td>
<td>List of users that RSVPed as "unsure"/"undecided"</td>
</tr>
<tr>
<td>not_going</td>
<td>List (of Strings)</td>
<td>List of users that RSVPed as "not going"</td>
</tr>
</tbody>
</table>
<br>
<!-- End get endpoint-->
<hr>
<!-- Start update endpoint-->
<h2 id="update" class="text-center text-discal-blue">rsvp/update</h2>
<p class="text-left text-discord-full-white">
Updates the specified event's RSVP data.
</p>
<br>
<h6 class="text-left text-discal-blue">Example Request Body</h6>
<pre class="code"><code>
{
"guild_id": 375357265198317579,
"event_id": "divq9ihqhoq9hbm2tncj8set04",
"to_add": {
"on_time": ["130510525770629121"],
"late": ["233611560545812480"]
},
"to_remove": {
"not_going": ["142107863307780097"],
"undecided: ["130510525770629121"]
}
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Example Response</h6>
<br>
<pre class="code"><code>
{
"message": "RSVP successfully updated"
}
</code></pre>
<br>
<h6 class="text-left text-discal-blue">Supported Values in Request</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
<th>Required</th>
</tr>
<tr>
<td>guild_id</td>
<td>long</td>
<td>The Guild ID</td>
<td>True</td>
</tr>
<tr>
<td>event_id</td>
<td>String</td>
<td>The Event ID</td>
<td>True</td>
</tr>
<tr>
<td>to_add.on_time</td>
<td>List (of Strings)</td>
<td>List of users to add that RSVPed as "on time"</td>
<td>False</td>
</tr>
<tr>
<td>to_add.late</td>
<td>List (of Strings)</td>
<td>List of users to add that RSVPed as "late"</td>
<td>False</td>
</tr>
<tr>
<td>to_add.undecided</td>
<td>List (of Strings)</td>
<td>List of users to add that RSVPed as "unsure"/"undecided"</td>
<td>False</td>
</tr>
<tr>
<td>to_add.not_going</td>
<td>List (of Strings)</td>
<td>List of users to remove that RSVPed as "not going"</td>
<td>False</td>
</tr>
<tr>
<td>to_remove.on_time</td>
<td>List (of Strings)</td>
<td>List of users to remove that RSVPed as "on time"</td>
<td>False</td>
</tr>
<tr>
<td>to_remove.late</td>
<td>List (of Strings)</td>
<td>List of users to remove that RSVPed as "late"</td>
<td>False</td>
</tr>
<tr>
<td>to_remove.undecided</td>
<td>List (of Strings)</td>
<td>List of users to remove that RSVPed as "unsure"/"undecided"</td>
<td>False</td>
</tr>
<tr>
<td>to_remove.not_going</td>
<td>List (of Strings)</td>
<td>List of users to remove that RSVPed as "not going"</td>
<td>False</td>
</tr>
</tbody>
</table>
<br>
<h6 class="text-left text-discal-blue">Returned Values</h6>
<table style="border-color: #bcbcbc"
border="#bcbcbc" cellpadding="4" cellspacing="0">
<tbody>
<tr>
<th>Key</th>
<th>Value Type</th>
<th>Info</th>
</tr>
<tr>
<td>message</td>
<td>String</td>
<td>Status of the update</td>
</tr>
</tbody>
</table>
<br>
<!-- End update endpoint-->
</div>
<!-- /.container-fluid -->
</div>
<!-- End of Main Content -->
<!-- Footer -->
<footer class="sticky-footer bg-discal-blue">
<div class="container my-auto">
<div class="copyright text-center text-discord-full-white my-auto">
<span th:text="'&copy; DreamExposure ' + ${year} + '. LGPL-3.'"></span>
</div>
</div>
</footer>
<!-- End of Footer -->
</div>
<!-- End of Content Wrapper -->
</div>
<!-- End of Page Wrapper -->
<!-- Scroll to Top Button-->
<a class="scroll-to-top rounded" href="#page-top">
<i class="fas fa-angle-up"></i>
</a>
<!-- Logout Modal-->
<div class="modal fade" id="logoutModal" tabindex="-1" role="dialog"
aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Ready to Leave?</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">Select "Logout" below if you are ready to end your current
session.
</div>
<div class="modal-footer">
<button class="btn btn-secondary" type="button" data-dismiss="modal">Cancel</button>
<a class="btn btn-primary" href="/logout">Logout</a>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JavaScript-->
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="/vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Custom scripts for all pages-->
<script src="/assets/js/sb-admin-2.min.js"></script>
</body>
</html>