/*
* Copyright 2012-2016 Jon VanAlten
*
* This file is part of Botula.
*
* Botula is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Botula is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Botula. If not, see <http://www.gnu.org/licenses/>.
*/
package com.vanaltj.botula.config;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
import org.pircbotx.Configuration;
import org.pircbotx.hooks.managers.SequentialListenerManager;
import com.vanaltj.botula.listeners.commands.AdminCommandListener;
import com.vanaltj.botula.listeners.commands.ChannelCommandListener;
import com.vanaltj.botula.listeners.reactions.ButtBotListener;
public class Configurations {
// TODO support more than one server.
private static final String ENV_BOTULA_HOME = "BOTULA_HOME";
private static final String BOTULA_HOME = ".botula";
private static final String CONFIG_FILE = "conf.properties";
private static final String PROPERTY_NETWORKS = "networks";
private static final String PROPERTY_NAME = ".name";
private static final String PROPERTY_FINGER = ".finger";
private static final String PROPERTY_ADMIN = ".admin";
private static final String PROPERTY_SERVER = ".server";
private static final String PROPERTY_CHANNELS = ".channels";
private static final String DEFAULT_NETWORK = "example";
private static final String DEFAULT_NAME = "CountBotula";
private static final String DEFAULT_FINGER = "I'm Henry the Eighth I Am!";
private static final String DEFAULT_ADMIN = "root";
private static final String DEFAULT_SERVER = "irc.example.com";
private static final String DEFAULT_CHANNELS = "#chat,#help";
private static final String DEFAULT_COMMENT =
"This is an example configuration.\n" +
"Botula created it because you didn't have one.\n" +
"Note that symbols in channel names may need to be escaped.";
private Configurations() {} // Not to be instantiated.
public static Collection<Configuration> getBotConfigs() throws IOException {
HashSet<Configuration> configs = new HashSet<Configuration>();
Properties properties = getConfigProperties();
String networksProperty = properties.getProperty(PROPERTY_NETWORKS);
for (String network : splitByComma(networksProperty)) {
configs.add(getConfigFromProperties(network, properties));
}
return configs;
}
private static Properties getConfigProperties() throws IOException {
Properties properties = new Properties();
String home = System.getenv(ENV_BOTULA_HOME);
if (home == null) {
home = getUserBotulaHome();
}
File botHome = new File(home);
if (!botHome.exists()) {
botHome.mkdirs();
}
File propsFile = new File(botHome, CONFIG_FILE);
try {
properties.load(new FileReader(propsFile));
} catch (FileNotFoundException fnf) {
createPropertiesFromDefault(properties, propsFile);
}
return properties;
}
private static String getUserBotulaHome() {
String userHome = System.getProperty("user.home");
File userHomeFile = new File(userHome);
File botHomeFile = new File(userHomeFile, BOTULA_HOME);
return botHomeFile.getAbsolutePath();
}
private static void createPropertiesFromDefault(Properties properties, File propsFile) throws IOException {
System.out.println("No configuration file present!");
System.out.println("Creating configuration file from default values.");
System.out.println("These values are almost certainly not what you want.");
populateDefaultProperties(properties);
storeProperties(properties, propsFile);
System.out.println("Please edit the configuration file:");
System.out.println(" " + propsFile.getAbsolutePath());
}
private static void populateDefaultProperties(Properties properties) {
properties.put(DEFAULT_NETWORK + PROPERTY_FINGER, DEFAULT_FINGER);
properties.put(DEFAULT_NETWORK + PROPERTY_NAME, DEFAULT_NAME);
properties.put(DEFAULT_NETWORK + PROPERTY_CHANNELS, DEFAULT_CHANNELS);
properties.put(DEFAULT_NETWORK + PROPERTY_ADMIN, DEFAULT_ADMIN);
properties.put(DEFAULT_NETWORK + PROPERTY_SERVER, DEFAULT_SERVER);
properties.put(PROPERTY_NETWORKS, DEFAULT_NETWORK);
}
private static void storeProperties(Properties properties, File propsFile) throws IOException {
try (FileWriter writer = new FileWriter(propsFile)) {
properties.store(new FileWriter(propsFile), DEFAULT_COMMENT);
}
}
private static Configuration getConfigFromProperties(String network, Properties properties) {
Configuration.Builder builder = new Configuration.Builder();
String name = properties.getProperty(network + PROPERTY_NAME);
builder.setName(name);
builder.setAutoNickChange(true); // Add number to end if nick taken.
String finger = properties.getProperty(network + PROPERTY_FINGER);
if (finger != null && finger.length() < 0) {
builder.setFinger(finger);
}
String server = properties.getProperty(network + PROPERTY_SERVER);
builder.addServer(server);
String channelsProperty = properties.getProperty(network + PROPERTY_CHANNELS);
Collection<String> channels = splitByComma(channelsProperty);
for (String channel : channels) {
builder.addAutoJoinChannel(channel);
}
SequentialListenerManager.SequentialListenerManagerBuilder lmBuilder =
SequentialListenerManager.builder();
SequentialListenerManager lm = lmBuilder.build();
String adminNick = properties.getProperty(network + PROPERTY_ADMIN);
if (adminNick != null && adminNick.length() > 0) {
lm.addListenerSequential(new AdminCommandListener(adminNick));
}
lm.addListenerPooled(new ChannelCommandListener());
lm.addListenerPooled(new ButtBotListener(name));
builder.setListenerManager(lm);
return builder.buildConfiguration();
}
private static Collection<String> splitByComma(String input) {
HashSet<String> toReturn = new HashSet<String>();
String[] inputSplit = input.split(",");
for (String item : inputSplit) {
toReturn.add(item.trim());
}
return toReturn;
}
}