Skip to content

Instantly share code, notes, and snippets.

@Shengaero
Last active February 11, 2018 17:55
Show Gist options
  • Save Shengaero/f424b396a685d4eac74e909d77815590 to your computer and use it in GitHub Desktop.
Save Shengaero/f424b396a685d4eac74e909d77815590 to your computer and use it in GitHub Desktop.
GuildSettingsManager and GuildSettingsProvider example implemenations using JSON
/*
* Copyright 2016-2018 John Grosh (jagrosh) & Kaidan Gustave (TheMonitorLizard)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jagrosh.jdautilities.examples.command;
import com.jagrosh.jdautilities.command.GuildSettingsProvider;
import org.json.JSONArray;
import org.json.JSONObject;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* @author Kaidan Gustave
*/
public class JSONGuildSettings implements GuildSettingsProvider
{
private static final String PREFIXES_KEY = "prefixes";
private final JSONObject guildJson;
private final JSONSettingsManager manager;
public JSONGuildSettings(JSONObject guildJson, JSONSettingsManager manager)
{
this.guildJson = guildJson;
this.manager = manager;
}
@Nullable
@Override
public Collection<String> getPrefixes()
{
JSONArray prefixes = guildJson.optJSONArray(PREFIXES_KEY);
if(prefixes == null)
return null;
Set<String> set = new HashSet<>();
for(Object prefix : prefixes)
{
set.add(Objects.toString(prefix));
}
return set;
}
public boolean hasPrefix(String prefix)
{
JSONArray prefixes = guildJson.optJSONArray(PREFIXES_KEY);
if(prefixes == null || prefixes.length() == 0)
return false;
for(Object p : prefixes)
{
String pre = Objects.toString(p);
if(pre.equals(prefix.toLowerCase()))
return true;
}
return false;
}
public void addPrefix(String prefix)
{
// Do not allow double insertion
if(hasPrefix(prefix))
return;
JSONArray prefixes = guildJson.optJSONArray(PREFIXES_KEY);
if(prefixes == null)
{
prefixes = new JSONArray();
guildJson.put(PREFIXES_KEY, prefixes);
}
// Make sure to only insert lowercase
prefixes.put(prefix.toLowerCase());
manager.setToSave();
}
public void removePrefix(String prefix)
{
if(!hasPrefix(prefix)) // This also checks if prefixes is null or empty
return;
JSONArray prefixes = guildJson.optJSONArray(PREFIXES_KEY);
for(int i = 0; i < prefixes.length(); i++)
{
String pre = Objects.toString(prefixes.get(i));
if(pre.equals(prefix.toLowerCase()))
{
prefixes.remove(i);
manager.setToSave();
break;
}
}
}
public JSONSettingsManager getManager()
{
return manager;
}
public JSONObject getGuildJson()
{
return guildJson;
}
}
/*
* Copyright 2016-2018 John Grosh (jagrosh) & Kaidan Gustave (TheMonitorLizard)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jagrosh.jdautilities.examples.command;
import com.jagrosh.jdautilities.command.GuildSettingsManager;
import net.dv8tion.jda.core.entities.Guild;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static java.nio.file.StandardOpenOption.*;
/**
* @author Kaidan Gustave
*/
public class JSONSettingsManager implements GuildSettingsManager<JSONGuildSettings>
{
public static final Logger LOG = LoggerFactory.getLogger(JSONSettingsManager.class);
private final File file;
private final Map<Long, JSONGuildSettings> map;
private final ScheduledExecutorService executor;
private boolean requiresSave = false;
public JSONSettingsManager(File file) throws IOException, JSONException
{
this.file = file;
this.map = new HashMap<>();
this.executor = Executors.newSingleThreadScheduledExecutor();
// Create a new file if one does not exist
if(!file.exists())
Files.write(file.toPath(), "{}".getBytes(), CREATE_NEW, WRITE);
JSONObject mainMap = new JSONObject(new String(Files.readAllBytes(file.toPath())));
for(String key : mainMap.keySet())
{
JSONObject guildJSON = mainMap.getJSONObject(key);
final long keyAsLong;
try {
keyAsLong = Long.parseLong(key);
} catch(NumberFormatException e) {
throw new JSONException("Could not convert " + key + " to a long!", e);
}
map.put(keyAsLong, new JSONGuildSettings(guildJSON, this));
}
}
@Nullable
@Override
public JSONGuildSettings getSettings(Guild guild)
{
synchronized(map)
{
return map.get(guild.getIdLong());
}
}
public JSONGuildSettings createSettings(Guild guild)
{
synchronized(map)
{
return map.computeIfAbsent(guild.getIdLong(), id -> {
JSONGuildSettings settings = new JSONGuildSettings(new JSONObject(), this);
setToSave();
return settings;
});
}
}
public void removeSettings(Guild guild)
{
synchronized(map)
{
JSONGuildSettings removed = map.remove(guild.getIdLong());
if(removed != null)
setToSave();
}
}
@Override
public void shutdown()
{
LOG.info("Shutting down save executor");
executor.shutdown();
// save if we need to
if(requiresSave)
{
save();
}
}
public void setToSave()
{
if(!requiresSave)
{
this.requiresSave = true;
executor.schedule(this::save, 30, TimeUnit.SECONDS);
}
}
private void save()
{
if(!requiresSave)
return;
LOG.debug("Saving JSONGuildSettings...");
JSONObject json = new JSONObject();
synchronized(map)
{
map.forEach((id, settings) -> json.put(Long.toUnsignedString(id), settings.getGuildJson()));
}
try {
Files.write(file.toPath(), json.toString().getBytes(), TRUNCATE_EXISTING, WRITE);
} catch(IOException e) {
LOG.warn("Failed to save GuildSettings", e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment