Remove GSon, add ini4j

Refactor, simplify, change configuration files format
master
Dmitry Isaenko 2020-10-23 13:43:53 +03:00
parent 89fce149df
commit b3da839bcd
17 changed files with 688 additions and 478 deletions

13
pom.xml
View File

@ -19,18 +19,19 @@
<version>3.23.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver-sync</artifactId>
<version>3.9.1</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ini4j/ini4j -->
<dependency>
<groupId>org.ini4j</groupId>
<artifactId>ini4j</artifactId>
<version>0.5.4</version>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>

View File

@ -1,41 +1,36 @@
package InnaIrcBot.Commanders;
import InnaIrcBot.ProvidersConsumers.StreamProvider;
import InnaIrcBot.config.ConfigurationChannel;
import InnaIrcBot.config.ConfigurationManager;
import java.io.*;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.regex.Pattern;
//TODO: FLOOD, JOIN FLOOD
// TODO: @ configuration level: if in result we have empty string, no need to pass it to server
//TODO: FLOOD
public class ChanelCommander implements Runnable {
private final BlockingQueue<String> streamQueue;
private final String server;
private final String channel;
//TODO: add timers
private final HashMap<String, String[]> joinMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
private final HashMap<String, String[]> msgMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
private final HashMap<String, String[]> nickMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
private HashMap<String, String[]> joinMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
private HashMap<String, String[]> msgMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
private HashMap<String, String[]> nickMap; // Mask(Pattern) ->, Action | Where Action[0] could be: raw
private boolean joinFloodTrackNeed = false;
private boolean joinFloodTrackNeed = false;
private JoinFloodHandler jfh;
private boolean joinCloneTrackNeed = false; // todo:fix
private boolean joinCloneTrackNeed = false; // todo:fix
private JoinCloneHandler jch;
public ChanelCommander(BlockingQueue<String> stream, String serverName, String channel, String configFilePath){
public ChanelCommander(BlockingQueue<String> stream, String serverName, String channel) throws Exception{
this.streamQueue = stream;
this.server = serverName;
this.channel = channel;
this.joinMap = new HashMap<>();
this.msgMap = new HashMap<>();
this.nickMap = new HashMap<>();
readConfing(configFilePath);
readConfing();
}
@Override
@ -63,15 +58,10 @@ public class ChanelCommander implements Runnable {
break;
/*
case "PART": // todo: need to track join flood? Fuck that. Track using JOIN
break;
case "QUIT": // todo: need this?
break;
case "TOPIC": // todo: need this?
break;
case "MODE": // todo: need this?
break;
case "KICK": // todo: need this?
break; */
case "KICK": // todo: need this? */
default:
break;
}
@ -240,72 +230,23 @@ public class ChanelCommander implements Runnable {
executiveStr.append(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
}
StreamProvider.writeToStream(server, executiveStr.toString());
}
}
// TSV
private void parse(String[] directive){
if (directive.length >= 3 && directive[0] != null && !directive[0].startsWith("#") && directive[1] != null && directive[2] != null){
// System.out.println(Arrays.toString(directive)); // TODO:debug
switch (directive[0].toLowerCase()){
case "join":
joinMap.put(directive[1], Arrays.copyOfRange(directive, 2, directive.length));
break;
case "msg":
msgMap.put(directive[1], Arrays.copyOfRange(directive, 2, directive.length));
break;
case "nick":
nickMap.put(directive[1], Arrays.copyOfRange(directive, 2, directive.length));
break;
case "joinfloodcontrol":
if (!directive[1].isEmpty() && !directive[2].isEmpty() && Pattern.matches("^[0-9]+?$", directive[1].trim()) && Pattern.matches("^[0-9]+?$", directive[2].trim())) {
int events = Integer.parseInt(directive[1].trim());
int timeFrame = Integer.parseInt(directive[2].trim());
if (events > 0 && timeFrame > 0) {
jfh = new JoinFloodHandler(events, timeFrame, server, channel);
joinFloodTrackNeed = true;
}
else {
System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' and/or 'Time Frame in seconds' should be greater than 0");
}
}
else
System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' and/or 'Time Frame in seconds' should be numbers greater than 0");
break;
case "joinclonecontrol":
if (!directive[1].isEmpty() && !directive[2].isEmpty() && Pattern.matches("^[0-9]+?$", directive[1].trim())) {
int events = Integer.parseInt(directive[1].trim());
if (events > 0){
jch = new JoinCloneHandler(directive[2], events, server, channel); // TODO: REMOVE
joinCloneTrackNeed = true;
}
else {
System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' should be greater than 0");
}
} else {
System.out.println("Internal issue: thread ChanelCommander->parse(): 'Number of events' should be greater than 0 and pattern shouldn't be empty.");
}
}
}
}
private String simplifyNick(String nick){ return nick.replaceAll("!.*$",""); }
private void readConfing(String confFilesPath){
if (!confFilesPath.endsWith(File.separator))
confFilesPath += File.separator;
private void readConfing() throws Exception{
ConfigurationChannel configChannel = ConfigurationManager.getConfiguration(server).getChannelConfig(channel);
joinMap = configChannel.getJoinMap();
msgMap = configChannel.getMsgMap();
nickMap = configChannel.getNickMap();
File file = new File(confFilesPath+server+ channel +".csv"); // TODO: add/search for filename
if (!file.exists())
return;
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
parse(line.split("\t"));
}
if (configChannel.isJoinFloodControl()) {
jfh = new JoinFloodHandler(configChannel.getJoinFloodControlEvents(), configChannel.getJoinFloodControlTimeframe(), server, channel);
joinFloodTrackNeed = true;
}
catch (Exception e) {
System.out.println("Internal issue: thread ChanelCommander->readConfig():\t\n"+e.getMessage());
if (configChannel.isJoinCloneControl()) {
jch = new JoinCloneHandler(configChannel.getJoinCloneControlPattern(), configChannel.getJoinCloneControlTimeframe(), server, channel); // TODO: REMOVE
joinCloneTrackNeed = true;
}
}
}

View File

@ -1,14 +1,12 @@
package InnaIrcBot;
import InnaIrcBot.logging.LogDriver;
import java.util.ArrayList;
import java.util.List;
public class GlobalData {
private static final String version = "InnaIrcBot v0.8 \"Коммунарка\"";
public static synchronized String getAppVersion(){
return version;
return String.format("%s, %s %s %s", version,
System.getProperty("os.name"),
System.getProperty("os.version"),
System.getProperty("os.arch"));
}
public static final int CHANNEL_QUEUE_CAPACITY = 500;
}

View File

@ -6,6 +6,7 @@ import InnaIrcBot.IrcChannel;
import InnaIrcBot.logging.LogDriver;
import InnaIrcBot.logging.Worker;
import InnaIrcBot.config.ConfigurationManager;
import InnaIrcBot.logging.WorkerZero;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
@ -43,15 +44,12 @@ public class ChanConsumer implements Runnable {
this.nick = ownNick;
this.rejoin = ConfigurationManager.getConfiguration(serverName).getRejoinOnKick();
this.channels = channels;
// Create chanel commander thread, get pipe
getChanelCommander(
ConfigurationManager.getConfiguration(serverName).getChanelConfigurationsPath()
);
getChanelCommander();
}
// Create ChanelCommander
private void getChanelCommander(String chanelConfigurationsPath){
private void getChanelCommander() throws Exception{
this.queue = new ArrayBlockingQueue<>(GlobalData.CHANNEL_QUEUE_CAPACITY);
ChanelCommander commander = new ChanelCommander(queue, serverName, channelName, chanelConfigurationsPath);
ChanelCommander commander = new ChanelCommander(queue, serverName, channelName);
this.channelCommanderThread = new Thread(commander);
this.channelCommanderThread.start();
}
@ -147,7 +145,7 @@ public class ChanConsumer implements Runnable {
System.out.println("ChanConsumer (@"+serverName+"/"+channelName+")->fixLogDriverIssues(): Some issues detected. Trying to fix...");
this.writerWorker = LogDriver.getWorker(serverName, channelName); // Reset logDriver and try using the same one
if (! writerWorker.logAdd(a, b, c)){ // Write to it what was not written (most likely) and if it's still not consistent:
this.writerWorker = LogDriver.getZeroWorker();
this.writerWorker = new WorkerZero();
System.out.println("ChanConsumer (@"+serverName+"/"+channelName+")->fixLogDriverIssues(): failed to use defined LogDriver. Using ZeroWorker instead.");
}
}

View File

@ -42,9 +42,7 @@ public class DataProvider implements Runnable {
ReconnectControl.register(server);
LogDriver.setLogDriver(server,
configurationFile.getLogDriverConfiguration(),
configurationFile.getApplicationLogDir());
LogDriver.setLogDriver(server);
/* Used for sending data into consumers objects*/
Map<String, IrcChannel> ircChannels = Collections.synchronizedMap(new HashMap<>());
@ -77,8 +75,6 @@ public class DataProvider implements Runnable {
String chan = rawStrings[2].replaceAll("(\\s.?$)|(\\s.+?$)", "");
//System.out.println("\tChannel: "+chan+"\n\tAction: "+rawStrings[1]+"\n\tSender: "+rawStrings[0]+"\n\tMessage: "+rawStrings[2]+"\n");
if (rawStrings[1].equals("QUIT") || rawStrings[1].equals("NICK")) { // replace regex
for (IrcChannel ircChannel : ircChannels.values()) {
ircChannel.getChannelQueue().add(rawStrings[1] + " " + rawStrings[0] + " " + rawStrings[2]);

View File

@ -0,0 +1,102 @@
package InnaIrcBot.config;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public class ConfigurationChannel {
private HashMap<String, String[]> joinMap;
private HashMap<String, String[]> msgMap;
private HashMap<String, String[]> nickMap;
private boolean joinFloodControl;
private int joinFloodControlEvents;
private int joinFloodControlTimeframe;
private boolean joinCloneControl;
private int joinCloneControlTimeframe;
private String joinCloneControlPattern;
public ConfigurationChannel(
boolean joinFloodControl,
int joinFloodControlEvents,
int joinFloodControlSeconds,
boolean joinCloneControl,
int joinCloneControlTimeframe,
String joinCloneControlPattern,
List<String> rules){
parseRules(rules);
if (joinFloodControl)
validateJoinFloodControl(joinFloodControlEvents, joinFloodControlSeconds);
if (joinCloneControl)
validateJoinCloneControl(joinCloneControlTimeframe, joinCloneControlPattern);
}
private void parseRules(List<String> rules){
this.joinMap = new HashMap<>();
this.msgMap = new HashMap<>();
this.nickMap = new HashMap<>();
for (String rule : rules){
parseRule(rule);
}
}
private void parseRule(String rule){
String[] directive = rule.split("\t");
if (isNotValidDirective(directive))
return;
switch (directive[0].toLowerCase()){
case "join":
joinMap.put(directive[1], Arrays.copyOfRange(directive, 2, directive.length));
break;
case "msg":
msgMap.put(directive[1], Arrays.copyOfRange(directive, 2, directive.length));
break;
case "nick":
nickMap.put(directive[1], Arrays.copyOfRange(directive, 2, directive.length));
break;
}
}
private boolean isNotValidDirective(String[] directive){
return directive.length < 3 || directive[0] == null || directive[1] == null || directive[2] == null;
}
private void validateJoinFloodControl(int events, int timeFrame){
if (events <= 0 && timeFrame <= 0) {
System.out.println("Join Flood Control configuration issue: 'Join number' and 'time frame' should be greater than 0.");
return;
}
joinFloodControl = true;
joinFloodControlEvents = events;
joinFloodControlTimeframe = timeFrame;
}
private void validateJoinCloneControl(int timeFrame, String pattern){
if (timeFrame < 0) {
System.out.println("Join Clone Control configuration issue: 'time frame' should be greater than 0");
return;
}
joinCloneControl = true;
joinCloneControlTimeframe = timeFrame;
joinCloneControlPattern = pattern;
}
public HashMap<String, String[]> getJoinMap() { return joinMap; }
public HashMap<String, String[]> getMsgMap() { return msgMap; }
public HashMap<String, String[]> getNickMap() { return nickMap; }
public boolean isJoinFloodControl() { return joinFloodControl; }
public int getJoinFloodControlEvents() { return joinFloodControlEvents; }
public int getJoinFloodControlTimeframe() { return joinFloodControlTimeframe; }
public boolean isJoinCloneControl() { return joinCloneControl; }
public int getJoinCloneControlTimeframe() { return joinCloneControlTimeframe; }
public String getJoinCloneControlPattern() { return joinCloneControlPattern; }
}

View File

@ -1,10 +1,19 @@
package InnaIrcBot.config;
import org.ini4j.Config;
import org.ini4j.Ini;
import org.ini4j.Wini;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class ConfigurationFile {
private String serverName;
private int serverPort;
private String serverPass;
private String[] channels;
private String userNick;
private String userIdent;
private String userRealName;
@ -12,73 +21,143 @@ public class ConfigurationFile {
private String userNickAuthStyle;
private String userMode;
private boolean rejoinOnKick;
private String logDriver;
private String[] logDriverParameters;
private String botAdministratorPassword;
private String chanelConfigurationsPath;
private String applicationLogDir;
private LogDriverConfiguration logDriverConfiguration;
private List<String> channels;
private HashMap<String, ConfigurationChannel> channelConfigs;
public ConfigurationFile(String serverName,
int serverPort,
String serverPass,
String[] channels,
String userNick,
String userIdent,
String userRealName,
String userNickPass,
String userNickAuthStyle,
String userMode,
boolean rejoinOnKick,
String logDriver,
String[] logDriverParameters,
String botAdministratorPassword,
String chanelConfigurationsPath,
String applicationLogDir){
this.serverName = serverName;
this.serverPort = serverPort;
this.serverPass = serverPass;
this.channels = channels;
this.userIdent = userIdent;
this.userNick = userNick;
this.userRealName = userRealName;
this.userNickPass = userNickPass;
this.userNickAuthStyle = userNickAuthStyle;
this.userMode = userMode;
this.rejoinOnKick = rejoinOnKick;
this.logDriver = logDriver;
this.logDriverParameters = logDriverParameters;
this.botAdministratorPassword = botAdministratorPassword;
this.chanelConfigurationsPath = chanelConfigurationsPath;
this.applicationLogDir = applicationLogDir;
}
public String getServerName() { return nonNullString(serverName); }
public String getServerName() { return serverName; }
public int getServerPort() { return serverPort; }
public String getServerPass() { return nonNullString(serverPass); }
public String[] getChannels() { return channels; }
public String getUserNick() { return nonNullString(userNick); }
public String getUserIdent() { return nonNullString(userIdent); }
public String getUserRealName() { return nonNullString(userRealName); }
public String getUserNickPass() { return nonNullString(userNickPass); }
public String getUserNickAuthStyle() { return nonNullString(userNickAuthStyle); }
public String getUserMode() { return nonNullString(userMode); }
public String getServerPass() { return serverPass; }
public String getUserNick() { return userNick; }
public String getUserIdent() { return userIdent; }
public String getUserRealName() { return userRealName; }
public String getUserNickPass() { return userNickPass; }
public String getUserNickAuthStyle() { return userNickAuthStyle; }
public String getUserMode() { return userMode; }
public boolean getRejoinOnKick() { return rejoinOnKick; }
public String getBotAdministratorPassword() { return botAdministratorPassword; }
public String getApplicationLogDir() { return applicationLogDir; }
public LogDriverConfiguration getLogDriverConfiguration(){ return logDriverConfiguration; }
public List<String> getChannels() { return channels; }
public ConfigurationChannel getChannelConfig(String channel) { return channelConfigs.get(channel); }
public LogDriverConfiguration getLogDriverConfiguration(){
return new LogDriverConfiguration(nonNullString(logDriver).toLowerCase(), logDriverParameters);
public ConfigurationFile(String pathToConfigurationFile) throws Exception{
Wini ini = new Wini();
ini.setConfig(getConfig());
ini.load(new File(pathToConfigurationFile));
parseMain(ini);
parseLogging(ini);
parseChannels(ini);
validate();
}
public String getBotAdministratorPassword() { return nonNullString(botAdministratorPassword); }
public String getChanelConfigurationsPath() { return nonNullString(chanelConfigurationsPath); }
public String getApplicationLogDir() { return nonNullString(applicationLogDir); }
public void setUserNickAuthStyle(String userNickAuthStyle) {
this.userNickAuthStyle = userNickAuthStyle;
private Config getConfig(){
Config config = new Config();
config.setFileEncoding(StandardCharsets.UTF_8);
config.setMultiOption(true);
config.setEscape(true);
return config;
}
private String nonNullString(String value){
return value == null ? "" : value;
private void parseMain(Wini ini){
Ini.Section mainSection = ini.get("main");
this.serverName = mainSection.getOrDefault("server name", "");
this.serverPort = mainSection.get("server port", int.class);
this.serverPass = mainSection.getOrDefault("server password", "");
this.userNick = mainSection.getOrDefault("nickname", "");
this.userIdent = mainSection.getOrDefault("ident", "");
this.userRealName = mainSection.getOrDefault("real name", "");
this.userNickPass = mainSection.getOrDefault("nickname password", "");
this.userNickAuthStyle = mainSection.getOrDefault("nickserv auth method", "").toLowerCase();
this.userMode = mainSection.getOrDefault("user modes", "");
this.rejoinOnKick = mainSection.get("auto rejoin", boolean.class);
this.botAdministratorPassword = mainSection.getOrDefault("bot administrator password", "");
this.applicationLogDir = mainSection.getOrDefault("application logs", "");
}
private void parseChannels(Wini ini){
Ini.Section channelsSection = ini.get("channels");
this.channels = channelsSection.getAll("channel");
this.channelConfigs = new HashMap<>();
for (String channel: channels){
addNewChannelConfiguration(ini, channel);
}
}
private void addNewChannelConfiguration(Wini ini, String channelName){
Ini.Section channelSection = ini.get(channelName);
if (channelSection == null)
return;
Ini.Section rulesChannelSection = channelSection.getChild("rules");
List<String> channelRules = rulesChannelSection.getAll("rule"); //TODO: check not-null
if (channelRules == null)
channelRules = new ArrayList<>();
Ini.Section joinFloodControlSection = channelSection.getChild("rules");
boolean joinFloodControl = joinFloodControlSection.get("enable", boolean.class);
int joinFloodControlEventsNumber = -1;
int joinFloodControlTimeFrame = -1;
if (joinFloodControl){
joinFloodControlEventsNumber = joinFloodControlSection.get("join number", int.class);
joinFloodControlTimeFrame = joinFloodControlSection.get("time frame", int.class);
}
Ini.Section joinCloneControlSection = channelSection.getChild("rules");
boolean joinCloneControl = joinCloneControlSection.get("enable", boolean.class);;
int joinCloneControlTimeFrame = -1;
String joinCloneControlPattern = "";
if (joinCloneControl){
joinCloneControlTimeFrame = joinCloneControlSection.get("time frame", int.class);
joinCloneControlPattern = joinCloneControlSection.getOrDefault("pattern", "");
}
channelConfigs.put(channelName, new ConfigurationChannel(
joinFloodControl,
joinFloodControlEventsNumber,
joinFloodControlTimeFrame,
joinCloneControl,
joinCloneControlTimeFrame,
joinCloneControlPattern,
channelRules));
}
private void parseLogging(Wini ini){
Ini.Section channelsSection = ini.get("logging");
this.logDriverConfiguration = new LogDriverConfiguration(
channelsSection.getOrDefault("driver", ""),
channelsSection.getOrDefault("file(s) location", ""),
channelsSection.getOrDefault("MongoDB host:port", ""),
channelsSection.getOrDefault("MongoDB DB table", ""),
channelsSection.getOrDefault("MongoDB DB user", ""),
channelsSection.getOrDefault("MongoDB DB password", "")
);
}
//TODO: more validation
private void validate() throws Exception{
if (serverName.isEmpty())
throw new Exception("Server not defined in configuration file.");
if (serverPort <= 0 || serverPort > 65535)
throw new Exception("Server port number cannot be less/equal zero or greater then 65535");
if (userNick.isEmpty())
throw new Exception("Configuration issue: no nickname specified. ");
if (! userNickPass.isEmpty()) {
if (userNickAuthStyle.isEmpty())
throw new Exception("Configuration issue: password specified while auth method is not.");
if ( ! userNickAuthStyle.equals("rusnet") && ! userNickAuthStyle.equals("freenode"))
throw new Exception("Configuration issue: userNickAuthStyle could be freenode or rusnet.");
}
}
}

View File

@ -1,13 +1,15 @@
package InnaIrcBot.config;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.ini4j.*;
import org.ini4j.spi.EscapeTool;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class ConfigurationFileGenerator {
private String fileLocation;
@ -28,7 +30,6 @@ public class ConfigurationFileGenerator {
}
createConfigurationFile();
System.out.println("Configuration file created: " + this.fileLocation); // TODO: Move to l4j
} catch (IOException e){
System.out.println("Unable to write configuration file: \n\t"+e.getMessage());
@ -38,7 +39,7 @@ public class ConfigurationFileGenerator {
private void setLocationDefault(){
fileLocation = System.getProperty("user.dir")
+ File.separator
+ "myBotConfig.conf";
+ "innaircbot.conf";
}
private boolean locationNotDefined(){
@ -52,16 +53,17 @@ public class ConfigurationFileGenerator {
private void setLocationInsideFolder() throws IOException{
createFoldersIfNeeded();
if (fileLocation.endsWith(File.separator))
fileLocation = fileLocation + "myBotConfig.conf";
fileLocation = fileLocation + "innaircbot.conf";
else
fileLocation = fileLocation + File.separator + "myBotConfig.conf";
fileLocation = fileLocation + File.separator + "innaircbot.conf";
}
private void createFoldersIfNeeded() throws IOException{
Path folderPath = Paths.get(fileLocation);
if (! Files.exists(folderPath))
Files.createDirectories(folderPath);
}
private void createConfigurationFile() throws IOException{
/*
private void createConfigurationFileOld() throws IOException{
File configurationFile = new File(this.fileLocation);
Writer writerFile = new OutputStreamWriter(new FileOutputStream(configurationFile.getAbsolutePath()), StandardCharsets.UTF_8);
@ -78,7 +80,7 @@ public class ConfigurationFileGenerator {
"freenode",
"ix",
true,
"Files",
"files",
new String[] {System.getProperty("user.home")},
"pswd",
System.getProperty("user.home"),
@ -89,4 +91,91 @@ public class ConfigurationFileGenerator {
writingStorageObject.toJson(configurationFileObject, writerFile);
writerFile.close();
}
*/
private void createConfigurationFile() throws IOException{
final String mainSectionName = "main";
final String channelSectionName = "channels";
List<String> channels = new ArrayList<>();
channels.add("#main");
channels.add("#lpr");
List<String> logDriverPreferences = new ArrayList<>();
logDriverPreferences.add(System.getProperty("user.home"));
File configurationFile = new File(this.fileLocation);
Config myConfig = new Config();
myConfig.setFileEncoding(StandardCharsets.UTF_8);
myConfig.setMultiOption(true);
myConfig.setEscape(true);
//myConfig.setEmptyOption(true);
//myConfig.setComment(true);
Wini ini = new Wini();
ini.setConfig(myConfig);
Ini.Section mainSection = ini.add(mainSectionName);
mainSection.put( "server name", "srv");
mainSection.put( "server port", 6667);
mainSection.put( "server password", "");
mainSection.put( "nickname", "InnaIrcBot");
mainSection.put( "ident", "sweethome");
mainSection.put( "real name", "bot");
mainSection.put( "nickname password", "");
mainSection.put( "nickserv auth method", "freenode");
mainSection.put( "user modes", "i");
mainSection.put( "auto rejoin", true);
mainSection.put( "bot administrator password", "i_pswd");
mainSection.put( "application logs", "/tmp");
Ini.Section loggingSection = ini.add("logging");
loggingSection.put( "driver", "files");
loggingSection.put("file(s) location", "");
loggingSection.put("MongoDB host:port", "");
loggingSection.put("MongoDB DB table", "");
loggingSection.put("MongoDB DB user", "");
loggingSection.put("MongoDB DB password", "");
Ini.Section channelsSection = ini.add(channelSectionName);
channelsSection.putAll("channel", channels);
Ini.Section channelMainSection = ini.add( channels.get(0) );
Ini.Section channelMainRulesSection = channelMainSection.addChild("rules");
channelMainRulesSection.add("rule","join\t^cv.*\t\\cversion\t(^.+(\\s|\\t)+)");
channelMainRulesSection.add("rule","msg\t^cv.*\t\\cversion\t(^.+(\\s|\\t)+)");
channelMainRulesSection.add("rule", "join\t^BadGuy1(.+)?!.*\t\\kickban\trequested\\privmsg\tNever come back");
channelMainRulesSection.add("rule", "join\t^BadGuy2(.+)?!.*\t\\kick\tkick!");
channelMainRulesSection.add("rule", "join\t^BadGuy3(.+)?!.*\t\\ban\tban!");
channelMainRulesSection.add("rule", "nick\t^BadNickname.*\t\\chanmsg\tstop it!\n");
channelMainRulesSection.add("rule", "nick\t^Billilish.*\t\\voice");
channelMainRulesSection.add("rule", "msg\t^cci.*\t\\cclientinfo\t\t(^.+(\\s|\\t)+)\tThere are no ");
channelMainRulesSection.add("rule", "msg\t^cf.*\t\\cfinger\t(^.+(\\s|\\t)+)\tI \t D\t K");
channelMainRulesSection.add("rule", "msg\t^cp.*\t\\cping\t\t(^.+(\\s|\\t)+)\tlol");
channelMainRulesSection.add("rule", "msg\t^cs.*\t\\csource\t(^.+(\\s|\\t)+)\tpiu-\tpiu\t: ");
channelMainRulesSection.add("rule", "msg\t^ct.*\t\\ctime\t\t(^.+(\\s|\\t)+)\tOoops:");
channelMainRulesSection.add("rule", "msg\t^cui.*\t\\cuserinfo\t(^.+(\\s|\\t)+)\tNope: ");
channelMainRulesSection.add("rule", "msg\t^cv.*\t\\cversion\t(^.+(\\s|\\t)+)");
channelMainRulesSection.add("rule", "msg\t^pci.*\t\\pclientinfo\t(^.+(\\s|\\t)+)\tkek: ");
channelMainRulesSection.add("rule", "msg\t^pf.*\t\\pfinger\t(^.+(\\s|\\t)+)\t\tNobody like: ");
channelMainRulesSection.add("rule", "msg\t^pp.*\t\\pping\t\t(^.+(\\s|\\t)+)\tnope: ");
channelMainRulesSection.add("rule", "msg\t^ps.*\t\\psource\t(^.+(\\s|\\t)+)\t\tNooo ");
channelMainRulesSection.add("rule", "msg\t^pt.*\t\\ptime\t\t(^.+(\\s|\\t)+)\tHo-ho-ho: ");
channelMainRulesSection.add("rule", "msg\t^pu.*\t\\puserinfo\t(^.+(\\s|\\t)+)\tSome random text: ");
channelMainRulesSection.add("rule", "msg\t^pv.*\t\\pversion\t(^.+(\\s|\\t)+)\t\\chanmsg\tsent!");
Ini.Section channelMainJoinFloodControlSection = channelMainSection.addChild("JoinFloodControl");
channelMainJoinFloodControlSection.put("enable", true);
channelMainJoinFloodControlSection.put("join number", 3);
channelMainJoinFloodControlSection.put("time frame", 60);
Ini.Section channelMainJoinCloneControlSection = channelMainSection.addChild("JoinCloneControl");
channelMainJoinCloneControlSection.put("enable", false);
channelMainJoinCloneControlSection.put("pattern", "^.+[0-9]+?!.*$");
channelMainJoinFloodControlSection.put("time frame", 0);
ini.store(configurationFile);
}
}

View File

@ -1,50 +0,0 @@
package InnaIrcBot.config;
import com.google.gson.Gson;
import java.io.*;
public class ConfigurationFileReader {
private ConfigurationFileReader(){}
static ConfigurationFile read(String pathToFile) throws Exception{ // TODO: NULL or object
ConfigurationFile storageObject;
File configFile = new File(pathToFile);
try (Reader fileReader = new InputStreamReader(new FileInputStream(configFile))) {
storageObject = new Gson().fromJson(fileReader, ConfigurationFile.class);
}
validate(storageObject);
return storageObject;
}
private static void validate(ConfigurationFile configurationFile) throws Exception{ //TODO: more validation
if (configurationFile.getServerName().isEmpty())
throw new Exception("Server not defined in configuration file.");
if (configurationFile.getServerPort() <= 0)
throw new Exception("Server port set incorrectly in configuration file.");
String nick = configurationFile.getUserNick();
if (nick.isEmpty())
throw new Exception("Configuration issue: no nickname specified. ");
if (! configurationFile.getUserNickPass().isEmpty()) {
if (configurationFile.getUserNickAuthStyle().isEmpty())
throw new Exception("Configuration issue: password specified while auth method is not.");
configurationFile.setUserNickAuthStyle( configurationFile.getUserNickAuthStyle().toLowerCase() );
if ( ! configurationFile.getUserNickAuthStyle().equals("rusnet") && ! configurationFile.getUserNickAuthStyle().equals("freenode"))
throw new Exception("Configuration issue: userNickAuthStyle could be freenode or rusnet.");
}
if (configurationFile.getServerPort() <= 0 || configurationFile.getServerPort() > 65535)
throw new Exception("Server port number cannot be less/equal zero or greater then 65535");
}
}

View File

@ -8,7 +8,7 @@ public class ConfigurationManager {
private final static Map<String, ConfigurationFile> configurations = Collections.synchronizedMap(new HashMap<>());
public static ConfigurationFile readAndSetConfiguration(String pathToConfigurationFile) throws Exception{
ConfigurationFile configurationFile = ConfigurationFileReader.read(pathToConfigurationFile);
ConfigurationFile configurationFile = new ConfigurationFile(pathToConfigurationFile);
configurations.put(configurationFile.getServerName(), configurationFile);
return configurationFile;
}

View File

@ -4,37 +4,81 @@ import InnaIrcBot.logging.SupportedLogDrivers;
public class LogDriverConfiguration {
private String name;
private String[] params;
public LogDriverConfiguration(String name, String[] params){
private final String path;
private final String mongoURI;
private final String mongoTable;
private String mongoUser;
private String mongoPassword;
public LogDriverConfiguration(
String name,
String path,
String mongoURI,
String mongoTable,
String mongoUser,
String mongoPassword)
{
this.name = name.toLowerCase();
this.params = params;
this.path = path;
this.mongoURI = mongoURI;
this.mongoTable = mongoTable;
this.mongoUser = mongoUser;
this.mongoPassword = mongoPassword;
validateName();
validateParams();
validateConfiguration();
}
private void validateName(){
if (! SupportedLogDrivers.contains(name)) {
name = SupportedLogDrivers.zero;
}
}
private void validateParams(){
if (params == null) {
name = SupportedLogDrivers.zero;
return;
private void validateConfiguration(){
switch (this.name){
case SupportedLogDrivers.files:
case SupportedLogDrivers.sqlite:
validatePath();
break;
case SupportedLogDrivers.mongodb:
validateMongo();
break;
}
if (params.length == 0){
name = SupportedLogDrivers.zero;
return;
}
private void validatePath(){
try {
checkFieldNotEmpty(path);
}
if (params[0] == null){
name = SupportedLogDrivers.zero;
return;
}
if (params[0].isEmpty()){
catch (Exception e){
name = SupportedLogDrivers.zero;
}
}
private void validateMongo(){
try {
checkFieldNotEmpty(mongoURI);
checkFieldNotEmpty(mongoTable);
if (mongoUser == null)
mongoUser = "";
if (mongoPassword == null)
mongoPassword = "";
}
catch (Exception e){
name = SupportedLogDrivers.zero;
}
}
private void checkFieldNotEmpty(String field) throws Exception{
if (field == null || field.isEmpty()) {
throw new Exception();
}
}
public String getName() { return name; }
public String[] getParams() { return params; }
public String getPath() { return path; }
public String getMongoURI() { return mongoURI; }
public String getMongoTable() { return mongoTable; }
public String getMongoUser() { return mongoUser; }
public String getMongoPassword() { return mongoPassword; }
}

View File

@ -1,62 +1,52 @@
package InnaIrcBot.logging;
import InnaIrcBot.ProvidersConsumers.StreamProvider;
import InnaIrcBot.config.ConfigurationFile;
import InnaIrcBot.config.ConfigurationManager;
import InnaIrcBot.config.LogDriverConfiguration;
import java.util.HashMap;
public class LogDriver {
private final static HashMap<String, String[][]> serverDriver = new HashMap<>();
private final static HashMap<String, WorkerSystem> systemLogWorkerMap = new HashMap<>();
/**
* Define driver for desired server
* */
// TODO: add proxy worker for using with multiple drivers
public static synchronized void setLogDriver(String server,
LogDriverConfiguration logDriverConfiguration,
String applicationLogDir){
String[][] drvAndParams = {
{logDriverConfiguration.getName()},
logDriverConfiguration.getParams()
};
serverDriver.put(server, drvAndParams);
// TODO: add proxy multiple drivers support
public static synchronized void setLogDriver(String server){
String applicationLogDir;
try {
applicationLogDir = ConfigurationManager.getConfiguration(server).getApplicationLogDir();
}
catch (Exception e){
applicationLogDir = "";
}
systemLogWorkerMap.put(server, new WorkerSystem(server, applicationLogDir));
}
public static synchronized Worker getWorker(String server, String channel){
if (serverDriver.containsKey(server)) {
switch (serverDriver.get(server)[0][0]) {
try {
ConfigurationFile serverConfiguration = ConfigurationManager.getConfiguration(server);
LogDriverConfiguration logDriverConfiguration = serverConfiguration.getLogDriverConfiguration();
switch (logDriverConfiguration.getName()) {
case "files":
WorkerFiles workerFiles = new WorkerFiles(server, serverDriver.get(server)[1], channel);
return validateConsistancy(workerFiles, server, channel);
return new WorkerFiles(server, logDriverConfiguration, channel);
case "sqlite":
WorkerSQLite workerSQLite = new WorkerSQLite(server, serverDriver.get(server)[1], channel);
return validateConsistancy(workerSQLite, server, channel);
return new WorkerSQLite(server, logDriverConfiguration, channel);
case "mongodb":
WorkerMongoDB workerMongoDB = new WorkerMongoDB(server, serverDriver.get(server)[1], channel);
return validateConsistancy(workerMongoDB, server, channel);
return new WorkerMongoDB(server, logDriverConfiguration, channel);
case "zero":
default:
return new WorkerZero();
}
}
System.out.println("Issue on BotDriver->getWorker(): Channel requested for non-existing server?\n" +
"\tUsing ZeroWorker.");
return new WorkerZero();
catch (Exception e){
System.out.println("Issue on BotDriver->getWorker(): Channel requested for non-existing server? "
+ e.getMessage()
+ "\n\tUsing ZeroWorker.");
return new WorkerZero();
}
}
// If channel found that it's impossible to use defined worker from user settings and asking for use ZeroWorker
public static synchronized Worker getZeroWorker(){ return new WorkerZero(); }
public static synchronized WorkerSystem getSystemWorker(String serverName){
return systemLogWorkerMap.get(serverName);
}
private static Worker validateConsistancy(Worker worker, String server, String channel){ // synchronized?
if (worker.isConsistent()){
return worker;
}
System.out.println("BotDriver->validateConstancy(): Unable to use "
+worker.getClass().getSimpleName()+" for "+server+"/"+channel
+". Using ZeroWorker instead.");
return new WorkerZero();
}
}

View File

@ -1,5 +1,7 @@
package InnaIrcBot.logging;
import InnaIrcBot.config.LogDriverConfiguration;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@ -17,10 +19,10 @@ public class WorkerFiles implements Worker {
private boolean consistent;
public WorkerFiles(String server, String[] driverParameters, String channel){
public WorkerFiles(String server, LogDriverConfiguration logDriverConfiguration, String channel){
this.channel = channel.replaceAll(File.separator, ",");
formatFilePath(server, driverParameters);
formatFilePath(server, logDriverConfiguration.getPath());
try {
createServerFolder();
@ -31,9 +33,7 @@ public class WorkerFiles implements Worker {
}
}
private void formatFilePath(String server, String[] driverParameters){
String dirLocation = driverParameters[0].trim(); // TODO: MOVE trim() out of here
private void formatFilePath(String server, String dirLocation){
if (! dirLocation.endsWith(File.separator))
dirLocation += File.separator;

View File

@ -1,5 +1,6 @@
package InnaIrcBot.logging;
import InnaIrcBot.config.LogDriverConfiguration;
import com.mongodb.*;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
@ -24,27 +25,15 @@ public class WorkerMongoDB implements Worker { //TODO consider ski
private MongoCollection<Document> collection;
private boolean consistent;
public WorkerMongoDB(String server, String[] driverParameters, String channel){
public WorkerMongoDB(String server, LogDriverConfiguration logDriverConfiguration, String channel) throws Exception{
this.server = server;
if (driverParameters.length < 2)
return;
if (driverParameters[0].isEmpty())
return;
if (driverParameters[1].isEmpty())
return;
String mongoHostAddress = logDriverConfiguration.getMongoURI();
String mongoDBName = logDriverConfiguration.getMongoTable();
String mongoUser = logDriverConfiguration.getMongoUser();
String mongoPass = logDriverConfiguration.getMongoPassword();
String mongoHostAddress = driverParameters[0];
String mongoDBName = driverParameters[1];
String mongoUser;
String mongoPass;
if (driverParameters.length == 4 && !driverParameters[2].isEmpty() && !driverParameters[3].isEmpty()) {
mongoUser = driverParameters[2];
mongoPass = driverParameters[3];
}
else { // Consider that DB does not require auth, therefore any credentials are fine, since not null ;)
if (mongoUser.isEmpty()) {// Consider that DB does not require auth, therefore any credentials are fine, since not null ;)
mongoUser = "anon";
mongoPass = "anon";
}
@ -108,27 +97,12 @@ public class WorkerMongoDB implements Worker { //TODO consider ski
Document ping = new Document("ping", 1);
//
try {
Document answer = mongoDB.runCommand(ping); // reports to monitor thread if some fuckups happens
if (answer.get("ok") == null || (Double)answer.get("ok") != 1.0d){
close(server);
return;
}
consistent = true;
} catch (MongoCommandException mce){
System.out.println("BotMongoWorker (@"+this.server +"): Command exception. Check if username/password set correctly.");
close(server); // server received by constructor, not this.server
} catch (MongoTimeoutException mte) {
System.out.println("BotMongoWorker (@"+this.server +"): Timeout exception.");
close(server); // server received by constructor, not this.server
}catch (MongoException me){
System.out.println("BotMongoWorker (@"+this.server +"): MongoDB Exception.");
close(server); // server received by constructor, not this.server
} catch (IllegalStateException ise){
System.out.println("BotMongoWorker (@"+this.server +"): Illegal state exception: MongoDB server already closed (not an issue).");
consistent = false;
// no need to close() obviously
Document answer = mongoDB.runCommand(ping); // reports to monitor thread if some fuckups happens
if (answer.get("ok") == null || (Double)answer.get("ok") != 1.0d){
close(server);
return;
}
consistent = true;
setClosable();
}

View File

@ -1,5 +1,6 @@
package InnaIrcBot.logging;
import InnaIrcBot.config.LogDriverConfiguration;
import org.sqlite.SQLiteConfig;
import org.sqlite.SQLiteOpenMode;
@ -12,139 +13,129 @@ public class WorkerSQLite implements Worker {
private boolean consistent = false;
private PreparedStatement preparedStatement;
private String ircServer;
private final String server;
/**
* Don't even think of changing this balalaika.
* */
public WorkerSQLite(String server, String[] driverParameters, String channel){ // TODO: threads on SQLite level // remember: One file one DB
this.ircServer = server;
driverParameters[0] = driverParameters[0].trim();
File dir = new File(driverParameters[0]);
try {
dir.mkdirs(); // ignore result, because if it's already exists we're good. Otherwise, it will be created. Only issue that can occur is SecurityException thrown, so let's catch it.
} catch (Exception e){
System.out.println("BotSQLiteWorker (@"+server+")->constructor(): Failure:\n\tUnable to create directory to store DB file: \n\t" +e);
return; // consistent = false;
}
if (!dir.exists()) { // probably we might want to try-catch SecurityException, but if it appeared, it has been appeared already in previous block
System.out.println("BotSQLiteWorker (@"+server+")->constructor(): Failure:\n\tUnable to create directory to store DB file: " + driverParameters[0]);
return; // consistent = false;
public WorkerSQLite(String server, LogDriverConfiguration logDriverConfiguration, String channel) throws Exception{ // TODO: threads on SQLite level // remember: One file one DB
this.server = server;
String dbFileLocation = logDriverConfiguration.getPath();
File dir = new File(dbFileLocation);
dir.mkdirs(); // ignore result, because if it's already exists we're good. Otherwise, it will be created. Only issue that can occur is SecurityException thrown, so let's catch it.
if (!dir.exists()) {
throw new Exception("BotSQLiteWorker (@"+server+")->constructor(): Failure:\n\tUnable to create directory to store DB file: " + dbFileLocation);
}
String connectionURL;
if (driverParameters[0].endsWith(File.separator))
connectionURL = "jdbc:sqlite:"+driverParameters[0]+server+".db";
if (dbFileLocation.endsWith(File.separator))
connectionURL = "jdbc:sqlite:"+dbFileLocation+server+".db";
else
connectionURL = "jdbc:sqlite:"+driverParameters[0]+File.separator+server+".db";
connectionURL = "jdbc:sqlite:"+dbFileLocation+File.separator+server+".db";
channel = channel.trim().replaceAll("\"","\\\""); // TODO: use trim in every driver/worker?
try {
SQLiteConfig sqlConfig = new SQLiteConfig();
sqlConfig.setOpenMode(SQLiteOpenMode.NOMUTEX); //SQLITE_OPEN_NOMUTEX : multithreaded mode
this.connection = DriverManager.getConnection(connectionURL, sqlConfig.toProperties());
if (connection != null){
// Create table if not created
Statement statement = connection.createStatement();
String query = "CREATE TABLE IF NOT EXISTS \""+channel+"\" ("
+ " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ " unixtime INTEGER,"
+ " event TEXT,"
+ " subject TEXT,"
+ " message TEXT,"
+ " object TEXT"
+");";
statement.executeUpdate(query);
SQLiteConfig sqlConfig = new SQLiteConfig();
sqlConfig.setOpenMode(SQLiteOpenMode.NOMUTEX); //SQLITE_OPEN_NOMUTEX : multithreaded mode
// Check table representation
ResultSet rs = statement.executeQuery("PRAGMA table_info(\""+channel+"\");"); // executeQuery never null
boolean[] schemaResultCheck = {false, false, false, false, false, false};
this.connection = DriverManager.getConnection(connectionURL, sqlConfig.toProperties());
if (connection != null){
// Create table if not created
Statement statement = connection.createStatement();
String query = "CREATE TABLE IF NOT EXISTS \""+channel+"\" ("
+ " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+ " unixtime INTEGER,"
+ " event TEXT,"
+ " subject TEXT,"
+ " message TEXT,"
+ " object TEXT"
+");";
statement.executeUpdate(query);
while (rs.next()) {
switch (rs.getInt("cid")) {
case 0:
if (rs.getString("name").equals("id")
&& rs.getString("type").equals("INTEGER")
&& (rs.getInt("notnull") == 1)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 1))
schemaResultCheck[0] = true;
//System.out.println("Got 0");
break;
case 1:
if (rs.getString("name").equals("unixtime")
&& rs.getString("type").equals("INTEGER")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[1] = true;
//System.out.println("Got 1");
break;
case 2:
if (rs.getString("name").equals("event")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[2] = true;
//System.out.println("Got 2");
break;
case 3:
if (rs.getString("name").equals("subject")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[3] = true;
//System.out.println("Got 3");
break;
case 4:
if (rs.getString("name").equals("message")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[4] = true;
//System.out.println("Got 4");
break;
case 5:
if (rs.getString("name").equals("object")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[5] = true;
//System.out.println("Got 5");
break;
default:
for (int i = 0; i <= 5; i++) {
schemaResultCheck[i] = false; // If more then 5 elements, ruin results
}
}
}
// Validating result: it table in DB have expected schema. If not, removing and recreating table.
for (boolean element: schemaResultCheck) {
if (!element) {
System.out.println("BotSQLiteWorker (@"+server+")->Constructor(): Notice:\n\tFound already existing table for channel with incorrect syntax: removing table and re-creating.");
statement.executeUpdate("DROP TABLE \"" + channel + "\";");
statement.executeUpdate(query);
// Check table representation
ResultSet rs = statement.executeQuery("PRAGMA table_info(\""+channel+"\");"); // executeQuery never null
boolean[] schemaResultCheck = {false, false, false, false, false, false};
while (rs.next()) {
switch (rs.getInt("cid")) {
case 0:
if (rs.getString("name").equals("id")
&& rs.getString("type").equals("INTEGER")
&& (rs.getInt("notnull") == 1)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 1))
schemaResultCheck[0] = true;
//System.out.println("Got 0");
break;
}
case 1:
if (rs.getString("name").equals("unixtime")
&& rs.getString("type").equals("INTEGER")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[1] = true;
//System.out.println("Got 1");
break;
case 2:
if (rs.getString("name").equals("event")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[2] = true;
//System.out.println("Got 2");
break;
case 3:
if (rs.getString("name").equals("subject")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[3] = true;
//System.out.println("Got 3");
break;
case 4:
if (rs.getString("name").equals("message")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[4] = true;
//System.out.println("Got 4");
break;
case 5:
if (rs.getString("name").equals("object")
&& rs.getString("type").equals("TEXT")
&& (rs.getInt("notnull") == 0)
&& (rs.getString("dflt_value") == null)
&& (rs.getInt("pk") == 0))
schemaResultCheck[5] = true;
//System.out.println("Got 5");
break;
default:
for (int i = 0; i <= 5; i++) {
schemaResultCheck[i] = false; // If more then 5 elements, ruin results
}
}
this.consistent = true;
}
// Validating result: it table in DB have expected schema. If not, removing and recreating table.
for (boolean element: schemaResultCheck) {
if (!element) {
System.out.println("BotSQLiteWorker (@"+server+")->Constructor(): Notice:\n\tFound already existing table for channel with incorrect syntax: removing table and re-creating.");
statement.executeUpdate("DROP TABLE \"" + channel + "\";");
statement.executeUpdate(query);
break;
}
}
this.consistent = true;
this.preparedStatement = connection.prepareStatement(
"INSERT INTO \""+channel
+"\" (unixtime, event, subject, message, object) "
+"VALUES (?, ?, ?, ?, ?);");
}
else {
System.out.println("BotSQLiteWorker (@"+server+")->constructor() failed:\n\t Connection to SQLite not established.");
this.consistent = false;
}
this.preparedStatement = connection.prepareStatement(
"INSERT INTO \""+channel
+"\" (unixtime, event, subject, message, object) "
+"VALUES (?, ?, ?, ?, ?);");
}
catch (SQLException e){
System.out.println("BotSQLiteWorker (@"+server+")->constructor() failed:\n\t"+e);
this.consistent = false; // this.close();
else {
System.out.println("BotSQLiteWorker (@"+server+")->constructor() failed:\n\t Connection to SQLite not established.");
this.consistent = false;
}
}
@ -161,11 +152,6 @@ public class WorkerSQLite implements Worker {
preparedStatement.setString(2, event);
preparedStatement.setString(3, initiator);
switch (event) {
case "NICK":
case "JOIN":
preparedStatement.setString(4, message);
preparedStatement.setString(5, null);
break;
case "PART":
case "QUIT":
case "TOPIC":
@ -184,6 +170,8 @@ public class WorkerSQLite implements Worker {
preparedStatement.setString(4, message.replaceAll("^:", ""));
preparedStatement.setString(5,null);
break;
case "NICK":
case "JOIN":
default:
preparedStatement.setString(4, message);
preparedStatement.setString(5,null);
@ -191,12 +179,9 @@ public class WorkerSQLite implements Worker {
}
preparedStatement.executeUpdate();
}
catch (SQLException sqle){
System.out.println("BotSQLiteWorker (@"+ircServer+")->logAdd() failed:\n\t"+sqle);
this.close(); // consistent will become false. Don't touch this.
}catch (NullPointerException npe){
System.out.println("BotSQLiteWorker (@"+ircServer+")->logAdd() failed:\n\t"+npe);
this.consistent = false; // most likely closed/non-opened file
catch (Exception e) {
System.out.println("BotSQLiteWorker (@" + server + ")->logAdd() failed:\n\t" + e.getMessage());
this.close();
}
return consistent;
}
@ -208,7 +193,7 @@ public class WorkerSQLite implements Worker {
this.connection.close();
}
catch (SQLException | NullPointerException e){ //todo: consider redo
System.out.println("BotSQLiteWorker (@"+ircServer+")->close() failed:\n\t" + e); // nothing to do here
System.out.println("BotSQLiteWorker (@"+ server +")->close() failed:\n\t" + e); // nothing to do here
}
this.consistent = false;
}

View File

@ -1,38 +1,86 @@
package InnaIrcBot.config;
import InnaIrcBot.logging.SupportedLogDrivers;
import org.ini4j.Config;
import org.ini4j.Ini;
import org.ini4j.Wini;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class ConfigurationFileTest {
ConfigurationFile config;
ConfigurationFileTest(){
config = new ConfigurationFile(
null,
-100,
null,
null,
null,
null,
null,
null,
null,
null,
true,
null,
new String[]{null},
null,
null,
null
);
ConfigurationFileTest() throws Exception{
File file = File.createTempFile("temp", "Ini");
/*
List<String> logDriverPreferences = new ArrayList<>();
logDriverPreferences.add(System.getProperty("user.home"));
List<String> channels = new ArrayList<>();
channels.add("#main");
channels.add("#lpr");
Config myConfig = new Config();
myConfig.setFileEncoding(StandardCharsets.UTF_8);
Wini ini = new Wini();
ini.setConfig(myConfig);
Ini.Section mainSection = ini.add("main");
mainSection.put( "server name", "srv");
mainSection.put( "server port", 6667);
mainSection.put( "server password", "");
mainSection.put( "channels", channels); //mainSectionName,
mainSection.put( "nickname", "InnaIrcBot");
mainSection.put( "ident", "sweethome");
mainSection.put( "real name", "bot");
mainSection.put( "nickname password", "");
mainSection.put( "nickserv auth method", "freenode");
mainSection.put( "user modes", "i");
mainSection.put( "auto rejoin", true);
mainSection.put( "logging driver", "files");
mainSection.put( "logging driver prefs", logDriverPreferences);
mainSection.put( "bot administrator password", "i_pswd");
mainSection.put( "channels configuration path", "/tmp");
mainSection.put( "application logs", "/tmp");
ini.store(file);
*/
ConfigurationFileGenerator.generate(file.getAbsolutePath());
config = new ConfigurationFile(file.getAbsolutePath());
printAllConfigFields();
}
private String generateFile(){
return "";
}
private void printAllConfigFields(){
System.out.println();
System.out.println(config.getServerName());;
System.out.println(config.getServerPort());;
System.out.println(config.getServerPass());;
System.out.println(config.getUserNick());;
System.out.println(config.getUserIdent());;
System.out.println(config.getUserRealName());;
System.out.println(config.getUserNickPass());;
System.out.println(config.getUserNickAuthStyle());;
System.out.println(config.getUserMode());;
System.out.println(config.getRejoinOnKick());;
System.out.println(config.getBotAdministratorPassword());;
System.out.println(config.getApplicationLogDir());;
}
@Test
void getServerName() {
}
/*
@Test
void getServerPort() {
}
@ -93,4 +141,5 @@ class ConfigurationFileTest {
@Test
void setUserNickAuthStyle() {
}
*/
}

View File

@ -110,20 +110,34 @@ class LogDriverTest {
}
private void initializeFilesLogDriver(){
LogDriver.setLogDriver(serverNameFiles, new LogDriverConfiguration("FileS", new String[]{mainLogsDir.toString()}), "");
LogDriverConfiguration filesDrv = new LogDriverConfiguration("FileS",
mainLogsDir.toString(),
null,
null,
null,
null);
LogDriver.setLogDriver(serverNameFiles);
}
private void initializeSQLiteLogDriver(){
LogDriver.setLogDriver(serverNameSQLite, new LogDriverConfiguration("SQliTe", new String[]{mainSQLiteLogsDir.toString()}), "");
LogDriverConfiguration sqliteDrv = new LogDriverConfiguration("SQliTe",
mainLogsDir.toString(),
null,
null,
null,
null);
LogDriver.setLogDriver(serverNameSQLite);
}
private void initializeMongoDBLogDriver(){
String[] params = new String[]{"192.168.1.186:27017",
"irc",
"loper",
"password"};
LogDriver.setLogDriver("irc.tomsk.net",new LogDriverConfiguration("MongoDB", params),"");
LogDriverConfiguration mongoDrv = new LogDriverConfiguration("MongoDB",
null,
"192.168.1.186:27017",
"irc",
"loper",
"password");
LogDriver.setLogDriver("irc.tomsk.net");
}
private void close(){