net.jmhertlein.alphonseirc.MSTDeskEngRunner.java Source code

Java tutorial

Introduction

Here is the source code for net.jmhertlein.alphonseirc.MSTDeskEngRunner.java

Source

/*
 * Copyright (C) 2013 Joshua Michael Hertlein <jmhertlein@gmail.com>
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.jmhertlein.alphonseirc;

import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermissions;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.jmhertlein.core.io.Files;
import org.jibble.pircbot.IrcException;
import org.json.JSONObject;
import org.yaml.snakeyaml.Yaml;

/**
 *
 * @author Joshua Michael Hertlein <jmhertlein@gmail.com>
 */
public class MSTDeskEngRunner {
    private static final String XKCD_URL = "https://xkcd.com/info.0.json";
    private static final File CONFIG_FILE = Files.join(System.getProperty("user.home"), ".config", "alphonseirc",
            "config.yml");
    private static String nick, pass, server;
    private static List<String> channels;
    private static Set<String> noVoiceNicks, masters;
    private static Map<LocalDate, LocalTime> dadLeaveTimes;
    private static int maxXKCD;
    private static long cachedUTC;

    public static int getMaxXKCD() {
        return maxXKCD;
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);

        loadConfig();

        AlphonseBot bot = new AlphonseBot(nick, pass, server, channels, maxXKCD, noVoiceNicks, masters,
                dadLeaveTimes);
        bot.setMessageDelay(500);
        try {
            bot.startConnection();
        } catch (IOException | IrcException ex) {
            Logger.getLogger(MSTDeskEngRunner.class.getName()).log(Level.SEVERE, null, ex);
        }

        boolean quit = false;
        while (!quit) {
            String curLine = scan.nextLine();

            switch (curLine) {
            case "exit":
                System.out.println("Quitting.");
                bot.onPreQuit();
                bot.disconnect();
                bot.dispose();
                writeConfig();
                quit = true;
                System.out.println("Quit'd.");
                break;
            case "msg":
                Scanner lineScan = new Scanner(scan.nextLine());
                try {
                    bot.sendMessage(lineScan.next(), lineScan.nextLine());
                } catch (Exception e) {
                    System.err.println(e.getClass().toString());
                    System.err.println("Not enough args");
                }
                break;
            default:
                System.out.println("Invalid command.");
            }
        }
    }

    private static void loadConfig() {
        boolean read = false;
        File f = CONFIG_FILE;
        if (!f.exists()) {
            read = true;
            try {
                f.getParentFile().mkdirs();
                f.createNewFile();
                java.nio.file.Files.setPosixFilePermissions(Paths.get(f.toURI()),
                        PosixFilePermissions.fromString("rw-------"));
            } catch (IOException ex) {
                Logger.getLogger(MSTDeskEngRunner.class.getName()).log(Level.SEVERE, null, ex);
                System.err.println("Error writing empty config.yml!");
            }
        }

        Map<String, Object> config;

        if (read) {
            Console console = System.console();
            console.printf("Nick: \n->");
            nick = console.readLine();
            console.printf("\nPassword: \n-|");
            pass = new String(console.readPassword());
            console.printf("\nServer: \n->");
            server = console.readLine();
            console.printf("\nChannels: (ex: #java,#linux,#gnome)\n->");
            channels = Arrays.asList(console.readLine().split(","));
            System.out.println("Fetching max XKCD...");
            maxXKCD = fetchMaxXKCD();
            System.out.println("Fetched.");
            cachedUTC = System.currentTimeMillis();

            dadLeaveTimes = new HashMap<>();
            noVoiceNicks = new HashSet<>();

            writeConfig();
            System.out.println("Wrote config to file: " + CONFIG_FILE.getAbsolutePath());

        } else {
            try (FileInputStream fis = new FileInputStream(f)) {
                Yaml y = new Yaml();
                config = y.loadAs(fis, Map.class);
            } catch (IOException ex) {
                Logger.getLogger(MSTDeskEngRunner.class.getName()).log(Level.SEVERE, null, ex);
                System.err.println("Error parsing config!");
                return;
            }

            nick = (String) config.get("nick");
            pass = (String) config.get("password");
            server = (String) config.get("server");
            channels = (List<String>) config.get("channels");
            maxXKCD = (Integer) config.get("cachedMaxXKCD");
            cachedUTC = (Long) config.get("cachedUTC");
            noVoiceNicks = (Set<String>) config.get("noVoiceNicks");
            masters = (Set<String>) config.get("masters");
            if (masters == null) {
                masters = new HashSet<>();
                masters.add("Everdras");
            }

            if (noVoiceNicks == null)
                noVoiceNicks = new HashSet<>();

            noVoiceNicks.stream().forEach((s) -> System.out.println("Loaded novoice nick: " + s));
            masters.stream().forEach((s) -> System.out.println("Loaded master nick: " + s));

            if (checkXKCDUpdate())
                writeConfig();
            else
                System.out.println("Loaded cached XKCD.");

            Map<String, Object> serialDadLeaveTimes = (Map<String, Object>) config.get("dadLeaveTimes");
            dadLeaveTimes = new HashMap<>();
            if (serialDadLeaveTimes != null)
                serialDadLeaveTimes.keySet().stream().forEach((time) -> {
                    dadLeaveTimes.put(LocalDate.parse(time),
                            LocalTime.parse((String) serialDadLeaveTimes.get(time)));
                });

        }
    }

    public static boolean checkXKCDUpdate() {
        if ((System.currentTimeMillis() - cachedUTC * 1000) > (2 * 24 * 60 * 60 * 1000)) { // 2 days
            maxXKCD = fetchMaxXKCD();
            cachedUTC = System.currentTimeMillis();
            return true;
        }
        return false;
    }

    public static void writeConfig() {
        Map<String, Object> m = new HashMap<>();
        m.put("nick", nick);
        m.put("password", pass);
        m.put("server", server);
        m.put("channels", channels);
        m.put("cachedMaxXKCD", maxXKCD);
        m.put("cachedUTC", cachedUTC);
        m.put("noVoiceNicks", noVoiceNicks);
        m.put("masters", masters);

        Map<String, Object> serialDadTimes = new HashMap<>();

        dadLeaveTimes.keySet().stream()
                .forEach(d -> serialDadTimes.put(d.toString(), dadLeaveTimes.get(d).toString()));

        m.put("dadLeaveTimes", serialDadTimes);

        Yaml yaml = new Yaml();
        String yamlOutput = yaml.dump(m);
        try (PrintWriter pw = new PrintWriter(CONFIG_FILE)) {
            pw.print(yamlOutput);
        } catch (IOException ex) {
            Logger.getLogger(MSTDeskEngRunner.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static int fetchMaxXKCD() {
        URL xkcdURL;
        try {
            xkcdURL = new URL(XKCD_URL);
        } catch (MalformedURLException ex) {
            Logger.getLogger(AlphonseBot.class.getName()).log(Level.SEVERE, null, ex);
            return 0;
        }

        JSONObject json;
        try (Scanner scan = new Scanner(xkcdURL.openStream())) {
            scan.useDelimiter("\\A");
            json = new JSONObject(scan.next());
        } catch (IOException ex) {
            Logger.getLogger(AlphonseBot.class.getName()).log(Level.SEVERE, null, ex);
            return 0;
        }

        return json.getInt("num");
    }
}