Added uptime().

This commit is contained in:
Erik C. Thauvin 2020-02-10 22:57:13 -08:00
parent e74b87d371
commit 0c32333c75
3 changed files with 164 additions and 208 deletions

View file

@ -62,6 +62,7 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option; import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options; import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException; import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -78,6 +79,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.time.Clock; import java.time.Clock;
@ -109,10 +111,9 @@ public class Mobibot extends PircBot {
private static final String DEFAULT_SERVER = "irc.freenode.net"; private static final String DEFAULT_SERVER = "irc.freenode.net";
// The info strings. // The info strings.
private static final String[] INFO_STRS = { private static final String[] INFO_STRS =
ReleaseInfo.PROJECT + " v" + ReleaseInfo.VERSION + " by Erik C. Thauvin (erik@thauvin.net)", {ReleaseInfo.PROJECT + " v" + ReleaseInfo.VERSION + " by Erik C. Thauvin (erik@thauvin.net)",
"https://www.mobitopia.org/mobibot/" "https://www.mobitopia.org/mobibot/"};
};
// The link match string. // The link match string.
private static final String LINK_MATCH = "^[hH][tT][tT][pP](|[sS])://.*"; private static final String LINK_MATCH = "^[hH][tT][tT][pP](|[sS])://.*";
@ -132,39 +133,18 @@ public class Mobibot extends PircBot {
// The modules. // The modules.
private static final List<AbstractModule> MODULES = new ArrayList<>(0); private static final List<AbstractModule> MODULES = new ArrayList<>(0);
// The start time.
private static final long START_TIME = System.currentTimeMillis();
// The tags/categories marker. // The tags/categories marker.
private static final String TAGS_MARKER = "tags:"; private static final String TAGS_MARKER = "tags:";
// The version strings. // The version strings.
private static final String[] VERSION_STRS = { private static final String[] VERSION_STRS = {"Version: " + ReleaseInfo.VERSION + " (" + Utils.isoLocalDate(
"Version: " ReleaseInfo.BUILDDATE) + ')', "Platform: " + System.getProperty("os.name") + " (" + System.getProperty(
+ ReleaseInfo.VERSION "os.version") + ", " + System.getProperty("os.arch") + ", " + System.getProperty("user.country") + ')',
+ " (" "Runtime: " + System.getProperty("java.runtime.name") + " (build "
+ Utils.isoLocalDate(ReleaseInfo.BUILDDATE) + ')', + System.getProperty("java.runtime.version") + ')',
"Platform: " "VM: " + System.getProperty("java.vm.name") + " (build " + System
+ System.getProperty("os.name") .getProperty("java.vm.version") + ", " + System.getProperty(
+ " (" "java.vm.info") + ')'};
+ System.getProperty("os.version")
+ ", "
+ System.getProperty("os.arch")
+ ", "
+ System.getProperty("user.country") + ')',
"Runtime: "
+ System.getProperty("java.runtime.name")
+ " (build "
+ System.getProperty("java.runtime.version")
+ ')',
"VM: "
+ System.getProperty("java.vm.name")
+ " (build "
+ System.getProperty("java.vm.version")
+ ", "
+ System.getProperty("java.vm.info")
+ ')'
};
// The logger. // The logger.
private static final Logger logger = LogManager.getLogger(Mobibot.class); private static final Logger logger = LogManager.getLogger(Mobibot.class);
// The commands list. // The commands list.
@ -223,9 +203,9 @@ public class Mobibot extends PircBot {
public Mobibot(final String nickname, final String channel, final String logsDirPath, final Properties p) { public Mobibot(final String nickname, final String channel, final String logsDirPath, final Properties p) {
super(); super();
System.getProperties().setProperty("sun.net.client.defaultConnectTimeout", System.getProperties().setProperty("sun.net.client.defaultConnectTimeout",
String.valueOf(Constants.CONNECT_TIMEOUT)); String.valueOf(Constants.CONNECT_TIMEOUT));
System.getProperties().setProperty("sun.net.client.defaultReadTimeout", System.getProperties().setProperty("sun.net.client.defaultReadTimeout",
String.valueOf(Constants.CONNECT_TIMEOUT)); String.valueOf(Constants.CONNECT_TIMEOUT));
setName(nickname); setName(nickname);
@ -274,8 +254,7 @@ public class Mobibot extends PircBot {
setLogin(p.getProperty("login", getName())); setLogin(p.getProperty("login", getName()));
setVersion(p.getProperty("weblog", "")); setVersion(p.getProperty("weblog", ""));
setMessageDelay(MESSAGE_DELAY); setMessageDelay(MESSAGE_DELAY);
setIdentity(p.getProperty("ident", ""), p.getProperty("ident-nick", ""), setIdentity(p.getProperty("ident", ""), p.getProperty("ident-nick", ""), p.getProperty("ident-msg", ""));
p.getProperty("ident-msg", ""));
// Set the URLs // Set the URLs
setWeblogUrl(getVersion()); setWeblogUrl(getVersion());
@ -304,12 +283,11 @@ public class Mobibot extends PircBot {
MODULES.add(new WorldTime()); MODULES.add(new WorldTime());
// Load the modules properties // Load the modules properties
MODULES.stream().filter(AbstractModule::hasProperties).forEach( MODULES.stream().filter(AbstractModule::hasProperties).forEach(module -> {
module -> { for (final String s : module.getPropertyKeys()) {
for (final String s : module.getPropertyKeys()) { module.setProperty(s, p.getProperty(s, ""));
module.setProperty(s, p.getProperty(s, "")); }
} });
});
// Get the tell command settings // Get the tell command settings
tell = new Tell(this, p.getProperty("tell-max-days"), p.getProperty("tell-max-size")); tell = new Tell(this, p.getProperty("tell-max-days"), p.getProperty("tell-max-size"));
@ -340,7 +318,7 @@ public class Mobibot extends PircBot {
* @param action The action. * @param action The action.
*/ */
private void action(final String channel, final String action) { private void action(final String channel, final String action) {
if (Utils.isValidString(channel) && Utils.isValidString(action)) { if (StringUtils.isNotBlank(channel) && StringUtils.isNotBlank(action)) {
sendAction(channel, action); sendAction(channel, action);
} }
} }
@ -364,8 +342,7 @@ public class Mobibot extends PircBot {
if (retries == MAX_RECONNECT) { if (retries == MAX_RECONNECT) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug( logger.debug(
"Unable to reconnect to " + ircServer + " after " + MAX_RECONNECT + " retries.", "Unable to reconnect to " + ircServer + " after " + MAX_RECONNECT + " retries.", ex);
ex);
} }
e.printStackTrace(System.err); e.printStackTrace(System.err);
@ -388,7 +365,7 @@ public class Mobibot extends PircBot {
* @param sender The nick of the person who sent the private message. * @param sender The nick of the person who sent the private message.
*/ */
private void feedResponse(final String sender) { private void feedResponse(final String sender) {
if (Utils.isValidString(feedUrl)) { if (StringUtils.isNotBlank(feedUrl)) {
new Thread(new FeedReader(this, sender, feedUrl)).start(); new Thread(new FeedReader(this, sender, feedUrl)).start();
} else { } else {
send(sender, "There is no weblog setup for this channel."); send(sender, "There is no weblog setup for this channel.");
@ -478,10 +455,8 @@ public class Mobibot extends PircBot {
for (final char c : getNick().toCharArray()) { for (final char c : getNick().toCharArray()) {
if (Character.isLetter(c)) { if (Character.isLetter(c)) {
buff.append('[') buff.append('[').append(String.valueOf(c).toLowerCase(Constants.LOCALE)).append(
.append(String.valueOf(c).toLowerCase(Constants.LOCALE)) String.valueOf(c).toUpperCase(Constants.LOCALE)).append(']');
.append(String.valueOf(c).toUpperCase(Constants.LOCALE))
.append(']');
} else { } else {
buff.append(c); buff.append(c);
} }
@ -651,11 +626,8 @@ public class Mobibot extends PircBot {
if (isOp(sender)) { if (isOp(sender)) {
send(sender, "The op commands are:"); send(sender, "The op commands are:");
send(sender, helpIndent( send(sender, helpIndent(
Commands.CYCLE_CMD + " " Commands.CYCLE_CMD + " " + Commands.ME_CMD + " " + Commands.MSG_CMD + " " + Commands.SAY_CMD
+ Commands.ME_CMD + " " + " " + Commands.VERSION_CMD));
+ Commands.MSG_CMD + " "
+ Commands.SAY_CMD + " "
+ Commands.VERSION_CMD));
} }
} }
} }
@ -666,12 +638,12 @@ public class Mobibot extends PircBot {
*/ */
private void identify() { private void identify() {
// Identify with NickServ // Identify with NickServ
if (Utils.isValidString(identPwd)) { if (StringUtils.isNotBlank(identPwd)) {
identify(identPwd); identify(identPwd);
} }
// Identify with a specified nick // Identify with a specified nick
if (Utils.isValidString(identNick) && Utils.isValidString(identMsg)) { if (StringUtils.isNotBlank(identNick) && StringUtils.isNotBlank(identMsg)) {
sendMessage(identNick, identMsg); sendMessage(identNick, identMsg);
} }
} }
@ -740,40 +712,9 @@ public class Mobibot extends PircBot {
final StringBuilder info = new StringBuilder(28).append("Uptime: "); final StringBuilder info = new StringBuilder(28).append("Uptime: ");
long timeInSeconds = (System.currentTimeMillis() - START_TIME) / 1000L; info.append(Utils.uptime(ManagementFactory.getRuntimeMXBean().getUptime()));
final long years = timeInSeconds / 31540000L; info.append("[Entries: ").append(entries.size());
if (years > 0) {
info.append(years).append(Utils.plural(years, " year ", " years "));
timeInSeconds -= (years * 31540000L);
}
final long weeks = timeInSeconds / 604800L;
if (weeks > 0) {
info.append(weeks).append(Utils.plural(weeks, " week ", " weeks "));
timeInSeconds -= (weeks * 604800L);
}
final long days = timeInSeconds / 86400L;
if (days > 0) {
info.append(days).append(Utils.plural(days, " day ", " days "));
timeInSeconds -= (days * 86400L);
}
final long hours = timeInSeconds / 3600L;
if (hours > 0) {
info.append(hours).append(Utils.plural(hours, " hour ", " hours "));
timeInSeconds -= (hours * 3600L);
}
final long minutes = timeInSeconds / 60L;
info.append(minutes).append(Utils.plural(minutes, " minute ", " minutes "))
.append("[Entries: ").append(entries.size());
if (tell.isEnabled() && isOp(sender)) { if (tell.isEnabled() && isOp(sender)) {
info.append(", Messages: ").append(tell.size()); info.append(", Messages: ").append(tell.size());
@ -791,7 +732,7 @@ public class Mobibot extends PircBot {
* @return <code>true</code> if the nick should be ignored, <code>false</code> otherwise. * @return <code>true</code> if the nick should be ignored, <code>false</code> otherwise.
*/ */
private boolean isIgnoredNick(final String nick) { private boolean isIgnoredNick(final String nick) {
return Utils.isValidString(nick) && ignoredNicks.contains(nick.toLowerCase(Constants.LOCALE)); return StringUtils.isNotBlank(nick) && ignoredNicks.contains(nick.toLowerCase(Constants.LOCALE));
} }
/** /**
@ -826,18 +767,17 @@ public class Mobibot extends PircBot {
* *
* @param args The command line arguments. * @param args The command line arguments.
*/ */
@SuppressFBWarnings({"INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE", "DM_DEFAULT_ENCODING", @SuppressFBWarnings(
"IOI_USE_OF_FILE_STREAM_CONSTRUCTORS"}) {"INFORMATION_EXPOSURE_THROUGH_AN_ERROR_MESSAGE", "DM_DEFAULT_ENCODING", "IOI_USE_OF_FILE_STREAM_CONSTRUCTORS"})
@SuppressWarnings({"PMD.SystemPrintln", "PMD.AvoidFileStream"}) @SuppressWarnings({"PMD.SystemPrintln", "PMD.AvoidFileStream"})
public static void main(final String[] args) { public static void main(final String[] args) {
// Setup the command line options // Setup the command line options
final Options options = new Options(); final Options options = new Options();
options.addOption(Commands.HELP_ARG.substring(0, 1), Commands.HELP_ARG, false, "print this help message"); options.addOption(Commands.HELP_ARG.substring(0, 1), Commands.HELP_ARG, false, "print this help message");
options.addOption(Commands.DEBUG_ARG.substring(0, 1), Commands.DEBUG_ARG, false, options.addOption(Commands.DEBUG_ARG.substring(0, 1), Commands.DEBUG_ARG, false,
"print debug & logging data directly to the console"); "print debug & logging data directly to the console");
options.addOption(Option.builder( options.addOption(Option.builder(Commands.PROPS_ARG.substring(0, 1)).hasArg().argName("file").desc(
Commands.PROPS_ARG.substring(0, 1)).hasArg().argName("file").desc("use " + "alternate properties file") "use " + "alternate properties file").longOpt(Commands.PROPS_ARG).build());
.longOpt(Commands.PROPS_ARG).build());
options.addOption(Commands.VERSION_ARG.substring(0, 1), Commands.VERSION_ARG, false, "print version info"); options.addOption(Commands.VERSION_ARG.substring(0, 1), Commands.VERSION_ARG, false, "print version info");
// Parse the command line // Parse the command line
@ -862,8 +802,8 @@ public class Mobibot extends PircBot {
} else { } else {
final Properties p = new Properties(); final Properties p = new Properties();
try (final InputStream fis = Files.newInputStream(Paths.get( try (final InputStream fis = Files.newInputStream(
line.getOptionValue(Commands.PROPS_ARG.charAt(0), "./mobibot.properties")))) { Paths.get(line.getOptionValue(Commands.PROPS_ARG.charAt(0), "./mobibot.properties")))) {
// Load the properties files // Load the properties files
p.load(fis); p.load(fis);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
@ -883,8 +823,8 @@ public class Mobibot extends PircBot {
// Redirect the stdout and stderr // Redirect the stdout and stderr
if (!line.hasOption(Commands.DEBUG_ARG.charAt(0))) { if (!line.hasOption(Commands.DEBUG_ARG.charAt(0))) {
try { try {
final PrintStream stdout = new PrintStream(new FileOutputStream( final PrintStream stdout = new PrintStream(
logsDir + channel.substring(1) + '.' + Utils.today() + ".log", true)); new FileOutputStream(logsDir + channel.substring(1) + '.' + Utils.today() + ".log", true));
System.setOut(stdout); System.setOut(stdout);
} catch (IOException e) { } catch (IOException e) {
System.err.println("Unable to open output (stdout) log file."); System.err.println("Unable to open output (stdout) log file.");
@ -893,8 +833,7 @@ public class Mobibot extends PircBot {
} }
try { try {
final PrintStream stderr = new PrintStream( final PrintStream stderr = new PrintStream(new FileOutputStream(logsDir + nickname + ".err", true));
new FileOutputStream(logsDir + nickname + ".err", true));
System.setErr(stderr); System.setErr(stderr);
} catch (IOException e) { } catch (IOException e) {
System.err.println("Unable to open error (stderr) log file."); System.err.println("Unable to open error (stderr) log file.");
@ -916,7 +855,7 @@ public class Mobibot extends PircBot {
*/ */
@Override @Override
protected final void onDisconnect() { protected final void onDisconnect() {
if (Utils.isValidString(weblogUrl)) { if (StringUtils.isNotBlank(weblogUrl)) {
setVersion(weblogUrl); setVersion(weblogUrl);
} }
@ -930,10 +869,7 @@ public class Mobibot extends PircBot {
*/ */
@SuppressFBWarnings(value = "CC_CYCLOMATIC_COMPLEXITY", justification = "Working on it.") @SuppressFBWarnings(value = "CC_CYCLOMATIC_COMPLEXITY", justification = "Working on it.")
@Override @Override
protected final void onMessage(final String channel, protected final void onMessage(final String channel, final String sender, final String login, final String hostname,
final String sender,
final String login,
final String hostname,
final String message) { final String message) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(">>> {} : {}", sender, message); logger.debug(">>> {} : {}", sender, message);
@ -971,7 +907,7 @@ public class Mobibot extends PircBot {
if (data.length == 1) { if (data.length == 1) {
title = data[0].trim(); title = data[0].trim();
} else { } else {
if (Utils.isValidString(data[0])) { if (StringUtils.isNotBlank(data[0])) {
title = data[0].trim(); title = data[0].trim();
} }
@ -984,7 +920,7 @@ public class Mobibot extends PircBot {
final Document html = Jsoup.connect(link).userAgent("Mozilla").get(); final Document html = Jsoup.connect(link).userAgent("Mozilla").get();
final String htmlTitle = html.title(); final String htmlTitle = html.title();
if (Utils.isValidString(htmlTitle)) { if (StringUtils.isNotBlank(htmlTitle)) {
title = htmlTitle; title = htmlTitle;
} }
} catch (IOException ignore) { } catch (IOException ignore) {
@ -1010,8 +946,7 @@ public class Mobibot extends PircBot {
} }
} else { } else {
final EntryLink entry = entries.get(dupIndex); final EntryLink entry = entries.get(dupIndex);
send(sender, Utils.bold("Duplicate") + " >> " send(sender, Utils.bold("Duplicate") + " >> " + EntriesUtils.buildLink(dupIndex, entry));
+ EntriesUtils.buildLink(dupIndex, entry));
} }
} }
} else if (message.matches(getNickPattern() + ":.*")) { // mobibot: <command> } else if (message.matches(getNickPattern() + ":.*")) { // mobibot: <command>
@ -1236,9 +1171,7 @@ public class Mobibot extends PircBot {
*/ */
@SuppressFBWarnings(value = {"DM_EXIT", "CC_CYCLOMATIC_COMPLEXITY"}, justification = "Yes, we want to bail out.") @SuppressFBWarnings(value = {"DM_EXIT", "CC_CYCLOMATIC_COMPLEXITY"}, justification = "Yes, we want to bail out.")
@Override @Override
protected final void onPrivateMessage(final String sender, protected final void onPrivateMessage(final String sender, final String login, final String hostname,
final String login,
final String hostname,
final String message) { final String message) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug(">>> {} : {}", sender, message); logger.debug(">>> {} : {}", sender, message);
@ -1346,12 +1279,9 @@ public class Mobibot extends PircBot {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
protected final void onAction(final String sender, protected final void onAction(final String sender, final String login, final String hostname, final String target,
final String login,
final String hostname,
final String target,
final String action) { final String action) {
if (target.equals(ircChannel)) { if (target != null && target.equals(ircChannel)) {
storeRecap(sender, action, true); storeRecap(sender, action, true);
} }
} }
@ -1406,7 +1336,7 @@ public class Mobibot extends PircBot {
* sent. * sent.
*/ */
public final void send(final String sender, final String message, final boolean isPrivate) { public final void send(final String sender, final String message, final boolean isPrivate) {
if (Utils.isValidString(message) && Utils.isValidString(sender)) { if (StringUtils.isNotBlank(message) && StringUtils.isNotBlank(sender)) {
if (isPrivate) { if (isPrivate) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Sending message to {} : {}", sender, message); logger.debug("Sending message to {} : {}", sender, message);
@ -1472,6 +1402,7 @@ public class Mobibot extends PircBot {
* @param message The actual message. * @param message The actual message.
* @param color The message's color. * @param color The message's color.
*/ */
@SuppressWarnings("unused")
public final void send(final String who, final String message, final String color) { public final void send(final String who, final String message, final String color) {
send(who, Utils.colorize(message, color), false); send(who, Utils.colorize(message, color), false);
} }
@ -1513,7 +1444,7 @@ public class Mobibot extends PircBot {
* @param nicks The nicks to ignore * @param nicks The nicks to ignore
*/ */
final void setIgnoredNicks(final String nicks) { final void setIgnoredNicks(final String nicks) {
if (Utils.isValidString(nicks)) { if (StringUtils.isNotBlank(nicks)) {
final StringTokenizer st = new StringTokenizer(nicks, ","); final StringTokenizer st = new StringTokenizer(nicks, ",");
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
@ -1528,7 +1459,7 @@ public class Mobibot extends PircBot {
* @param apiToken The API token * @param apiToken The API token
*/ */
final void setPinboardAuth(final String apiToken) { final void setPinboardAuth(final String apiToken) {
if (Utils.isValidString(apiToken)) { if (StringUtils.isNotBlank(apiToken)) {
pinboard = new Pinboard(this, apiToken, ircServer); pinboard = new Pinboard(this, apiToken, ircServer);
} }
} }
@ -1558,7 +1489,7 @@ public class Mobibot extends PircBot {
*/ */
private static void sleep(final int secs) { private static void sleep(final int secs) {
try { try {
Thread.sleep((long) (secs * 1000)); Thread.sleep(secs * 1000L);
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
// Do nothing. // Do nothing.
} }
@ -1573,7 +1504,7 @@ public class Mobibot extends PircBot {
*/ */
private void storeRecap(final String sender, final String message, final boolean isAction) { private void storeRecap(final String sender, final String message, final boolean isAction) {
recap.add(Utils.utcDateTime(LocalDateTime.now(Clock.systemUTC())) + " -> " + sender + (isAction ? " " : ": ") recap.add(Utils.utcDateTime(LocalDateTime.now(Clock.systemUTC())) + " -> " + sender + (isAction ? " " : ": ")
+ message); + message);
if (recap.size() > MAX_RECAP) { if (recap.size() > MAX_RECAP) {
recap.remove(0); recap.remove(0);
@ -1586,16 +1517,13 @@ public class Mobibot extends PircBot {
* @param msg The twitter message. * @param msg The twitter message.
*/ */
final void twitterNotification(final String msg) { final void twitterNotification(final String msg) {
if (twitterModule.isEnabled() && Utils.isValidString(twitterHandle)) { if (twitterModule.isEnabled() && StringUtils.isNotBlank(twitterHandle)) {
new Thread(() -> { new Thread(() -> {
try { try {
twitterModule.post( twitterModule.post(twitterHandle, getName() + ' ' + ReleaseInfo.VERSION + " " + msg, true);
twitterHandle,
getName() + ' ' + ReleaseInfo.VERSION + " " + msg, true);
} catch (ModuleException e) { } catch (ModuleException e) {
if (logger.isWarnEnabled()) { if (logger.isWarnEnabled()) {
logger.warn( logger.warn("Failed to notify @" + twitterHandle + ": " + msg, e);
"Failed to notify @" + twitterHandle + ": " + msg, e);
} }
} }
}).start(); }).start();
@ -1693,14 +1621,14 @@ public class Mobibot extends PircBot {
entry = entries.get(i); entry = entries.get(i);
if (lcArgs.length() > 0) { if (lcArgs.length() > 0) {
if ((entry.getLink().toLowerCase(Constants.LOCALE).contains(lcArgs)) if ((entry.getLink().toLowerCase(Constants.LOCALE).contains(lcArgs)) || (entry.getTitle()
|| (entry.getTitle().toLowerCase(Constants.LOCALE).contains(lcArgs)) .toLowerCase(
Constants.LOCALE)
.contains(lcArgs))
|| (entry.getNick().toLowerCase(Constants.LOCALE).contains(lcArgs))) { || (entry.getNick().toLowerCase(Constants.LOCALE).contains(lcArgs))) {
if (sent > MAX_ENTRIES) { if (sent > MAX_ENTRIES) {
send(sender, send(sender, "To view more, try: " + Utils
"To view more, try: " + Utils .bold(getNick() + ": " + Commands.VIEW_CMD + ' ' + (i + 1) + ' ' + lcArgs), isPrivate);
.bold(getNick() + ": " + Commands.VIEW_CMD + ' ' + (i + 1) + ' ' + lcArgs),
isPrivate);
break; break;
} }
@ -1711,9 +1639,8 @@ public class Mobibot extends PircBot {
} else { } else {
if (sent > MAX_ENTRIES) { if (sent > MAX_ENTRIES) {
send(sender, send(sender,
"To view more, try: " + Utils "To view more, try: " + Utils.bold(getNick() + ": " + Commands.VIEW_CMD + ' ' + (i + 1)),
.bold(getNick() + ": " + Commands.VIEW_CMD + ' ' + (i + 1)), isPrivate);
isPrivate);
break; break;
} }

View file

@ -32,6 +32,7 @@
package net.thauvin.erik.mobibot; package net.thauvin.erik.mobibot;
import org.apache.commons.lang3.StringUtils;
import org.jibble.pircbot.Colors; import org.jibble.pircbot.Colors;
import java.io.File; import java.io.File;
@ -39,6 +40,7 @@ import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit;
/** /**
* Miscellaneous utilities class. * Miscellaneous utilities class.
@ -77,16 +79,6 @@ public final class Utils {
return colorize(s, Colors.BOLD); return colorize(s, Colors.BOLD);
} }
/**
* Capitalize a string.
*
* @param s The string.
* @return The capitalized string.
*/
public static String capitalize(final String s) {
return s.substring(0, 1).toUpperCase(Constants.LOCALE) + s.substring(1);
}
/** /**
* Colorize a string. * Colorize a string.
* *
@ -95,8 +87,8 @@ public final class Utils {
* @return The colorized string. * @return The colorized string.
*/ */
static String colorize(final String s, final String color) { static String colorize(final String s, final String color) {
if (!Utils.isValidString(color) || Colors.NORMAL.equals(color)) { if (s == null) {
return s; return Colors.NORMAL;
} else if (Colors.BOLD.equals(color) || Colors.REVERSE.equals(color)) { } else if (Colors.BOLD.equals(color) || Colors.REVERSE.equals(color)) {
return color + s + color; return color + s + color;
} }
@ -105,7 +97,7 @@ public final class Utils {
} }
/** /**
* Meks the given string cyan. * Makes the given string cyan.
* *
* @param s The string. * @param s The string.
* @return The cyan string. * @return The cyan string.
@ -166,25 +158,6 @@ public final class Utils {
return colorize(s, Colors.DARK_GREEN); return colorize(s, Colors.DARK_GREEN);
} }
/**
* Returns <code>true</code> if the given string is <em>not</em> blank or null.
*
* @param s The string to check.
* @return <code>true</code> if the string is valid, <code>false</code> otherwise.
*/
public static boolean isValidString(final CharSequence s) {
if (s == null || s.length() == 0) {
return false;
}
final int len = s.length();
for (int i = 0; i < len; i++) {
if (!Character.isWhitespace(s.charAt(i))) {
return true;
}
}
return false;
}
/** /**
* Returns the specified date as an ISO local date string. * Returns the specified date as an ISO local date string.
* *
@ -205,6 +178,19 @@ public final class Utils {
return date.format(DateTimeFormatter.ISO_LOCAL_DATE); return date.format(DateTimeFormatter.ISO_LOCAL_DATE);
} }
/**
* Obfuscates the given string.
*
* @param s The string.
* @return The obfuscated string.
*/
public static String obfuscate(final String s) {
if (StringUtils.isNotBlank(s)) {
return StringUtils.repeat('x', s.length());
}
return s;
}
/** /**
* Returns the plural form of a word, if count &gt; 1. * Returns the plural form of a word, if count &gt; 1.
* *
@ -247,19 +233,66 @@ public final class Utils {
* @return The unescaped string. * @return The unescaped string.
*/ */
public static String unescapeXml(final String str) { public static String unescapeXml(final String str) {
return str.replace("&amp;", "&") return str.replace("&amp;", "&").replace("&lt;", "<").replace("&gt;", ">").replace("&quot;", "\"").replace(
.replace("&lt;", "<") "&apos;", "'").replace("&#39;", "'");
.replace("&gt;", ">") }
.replace("&quot;", "\"")
.replace("&apos;", "'") /**
.replace("&#39;", "'"); * Converts milliseconds to year month week day hour and minutes.
*
* @param uptime The uptime in milliseconds.
* @return The uptime in year month week day hours and minutes.
*/
public static String uptime(final long uptime) {
final StringBuilder info = new StringBuilder();
long days = TimeUnit.MILLISECONDS.toDays(uptime);
final long years = days / 365;
days %= 365;
final long months = days / 30;
days %= 30;
final long weeks = days / 7;
days %= 7;
final long hours = TimeUnit.MILLISECONDS.toHours(uptime) - TimeUnit.DAYS.toHours(
TimeUnit.MILLISECONDS.toDays(uptime));
final long minutes = TimeUnit.MILLISECONDS.toMinutes(uptime) - TimeUnit.HOURS.toMinutes(
TimeUnit.MILLISECONDS.toHours(uptime));
if (years > 0) {
info.append(years).append(plural(years, " year ", " years "));
}
if (months > 0) {
info.append(weeks).append(plural(months, " month ", " months "));
}
if (weeks > 0) {
info.append(weeks).append(plural(weeks, " week ", " weeks "));
}
if (days > 0) {
info.append(days).append(plural(days, " day ", " days "));
}
if (hours > 0) {
info.append(hours).append(plural(hours, " hour ", " hours "));
}
if (minutes > 0) {
info.append(minutes).append(plural(minutes, " minute", " minutes"));
}
return info.toString();
} }
/** /**
* Returns the specified date formatted as <code>yyyy-MM-dd HH:mm</code>. * Returns the specified date formatted as <code>yyyy-MM-dd HH:mm</code>.
* *
* @param date The date. * @param date The date.
* @return The fromatted date. * @return The formatted date.
*/ */
public static String utcDateTime(final Date date) { public static String utcDateTime(final Date date) {
return utcDateTime(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())); return utcDateTime(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));

View file

@ -32,6 +32,7 @@
package net.thauvin.erik.mobibot; package net.thauvin.erik.mobibot;
import org.apache.commons.lang3.StringUtils;
import org.jibble.pircbot.Colors; import org.jibble.pircbot.Colors;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -54,8 +55,7 @@ public class UtilsTest {
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
private final Calendar cal = Calendar.getInstance(); private final Calendar cal = Calendar.getInstance();
private final LocalDateTime localDateTime = private final LocalDateTime localDateTime = LocalDateTime.of(1952, 2, 17, 12, 30, 0);
LocalDateTime.of(1952, 2, 17, 12, 30, 0);
@BeforeClass @BeforeClass
public void setUp() { public void setUp() {
@ -68,17 +68,12 @@ public class UtilsTest {
assertThat(Utils.bold(ASCII)).as("bold(ascii").isEqualTo(Colors.BOLD + ASCII + Colors.BOLD); assertThat(Utils.bold(ASCII)).as("bold(ascii").isEqualTo(Colors.BOLD + ASCII + Colors.BOLD);
} }
@Test
public void testCapitalize() {
assertThat(Utils.capitalize("this is a test.")).isEqualTo("This is a test.");
}
@Test @Test
public void testColorize() { public void testColorize() {
assertThat(Utils.colorize(ASCII, Colors.REVERSE)).as("reverse") assertThat(Utils.colorize(ASCII, Colors.REVERSE)).as("colorize(reverse)").isEqualTo(
.isEqualTo(Colors.REVERSE + ASCII + Colors.REVERSE); Colors.REVERSE + ASCII + Colors.REVERSE);
assertThat(Utils.colorize(ASCII, Colors.RED)).as("red") assertThat(Utils.colorize(ASCII, Colors.RED)).as("colorize(red)").isEqualTo(Colors.RED + ASCII + Colors.NORMAL);
.isEqualTo(Colors.RED + ASCII + Colors.NORMAL); assertThat(Utils.colorize(null, Colors.RED)).as("colorize(null)").isEqualTo(Colors.NORMAL);
} }
@Test @Test
@ -88,10 +83,9 @@ public class UtilsTest {
@Test @Test
public void testEnsureDir() { public void testEnsureDir() {
assertThat(Utils.ensureDir("dir", false)).as("ensureDir(dir, false)") assertThat(Utils.ensureDir("dir", false)).as("ensureDir(dir, false)").isEqualTo("dir" + File.separatorChar);
.isEqualTo("dir" + File.separatorChar); assertThat(Utils.ensureDir("https://erik.thauvin.net", true)).as("ensureDir(erik.thauvin.net, true)").isEqualTo(
assertThat(Utils.ensureDir("https://erik.thauvin.net", true)) "https://erik.thauvin.net/");
.as("ensureDir(erik.thauvin.net, true)").isEqualTo("https://erik.thauvin.net/");
} }
@Test @Test
@ -105,21 +99,19 @@ public class UtilsTest {
assertThat(Utils.green(ASCII)).isEqualTo(Colors.DARK_GREEN + ASCII + Colors.NORMAL); assertThat(Utils.green(ASCII)).isEqualTo(Colors.DARK_GREEN + ASCII + Colors.NORMAL);
} }
@Test
public void testIsValidString() {
assertThat(Utils.isValidString(ASCII)).as("isValidString(ascii)").isTrue();
assertThat(Utils.isValidString("")).as("isValidString(empty)").isFalse();
assertThat(Utils.isValidString(" ")).as("isValidString( )").isFalse();
assertThat(Utils.isValidString(" \t ")).as("isValidString(tab)").isFalse();
assertThat(Utils.isValidString(null)).as("isValidString(null)").isFalse();
}
@Test @Test
public void testIsoLocalDate() { public void testIsoLocalDate() {
assertThat(Utils.isoLocalDate(cal.getTime())).as("isoLocalDate(date)").isEqualTo("1952-02-17"); assertThat(Utils.isoLocalDate(cal.getTime())).as("isoLocalDate(date)").isEqualTo("1952-02-17");
assertThat(Utils.isoLocalDate(localDateTime)).as("isoLocalDate(localDate)").isEqualTo("1952-02-17"); assertThat(Utils.isoLocalDate(localDateTime)).as("isoLocalDate(localDate)").isEqualTo("1952-02-17");
} }
@Test
public void testObfuscate() {
assertThat(Utils.obfuscate(ASCII).length()).as("obfuscate is right length").isEqualTo(ASCII.length());
assertThat(Utils.obfuscate(ASCII)).as("obfuscate()").isEqualTo(StringUtils.repeat("x", ASCII.length()));
assertThat(Utils.obfuscate(" ")).as("obfuscate(blank)").isEqualTo(" ");
}
@Test @Test
public void testPlural() { public void testPlural() {
final String week = "week"; final String week = "week";
@ -143,14 +135,18 @@ public class UtilsTest {
@Test @Test
public void testUnescapeXml() { public void testUnescapeXml() {
assertThat(Utils.unescapeXml("&lt;a name=&quot;test &amp; &apos;&#39;&quot;&gt;")) assertThat(Utils.unescapeXml("&lt;a name=&quot;test &amp; &apos;&#39;&quot;&gt;")).isEqualTo(
.isEqualTo("<a name=\"test & ''\">"); "<a name=\"test & ''\">");
}
@Test
public void testUptime() {
assertThat("17 years 2 months 2 weeks 1 day 6 hours 45 minutes").isEqualTo(Utils.uptime(547800300076L));
} }
@Test @Test
public void testUtcDateTime() { public void testUtcDateTime() {
assertThat(Utils.utcDateTime(cal.getTime())).as("utcDateTime(date)").isEqualTo("1952-02-17 12:30"); assertThat(Utils.utcDateTime(cal.getTime())).as("utcDateTime(date)").isEqualTo("1952-02-17 12:30");
assertThat(Utils.utcDateTime(localDateTime)).as("utcDateTime(localDate)") assertThat(Utils.utcDateTime(localDateTime)).as("utcDateTime(localDate)").isEqualTo("1952-02-17 12:30");
.isEqualTo("1952-02-17 12:30");
} }
} }