This commit is contained in:
Erik C. Thauvin 2021-05-16 08:17:16 -07:00
parent 8681dea66f
commit 082b430ee2
25 changed files with 68 additions and 560 deletions

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="checkstyle-version" value="8.29" />
<entry key="copy-libs" value="true" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnly" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
</project>

View file

@ -1,18 +1,5 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<JavaCodeStyleSettings>
<option name="ANNOTATION_PARAMETER_WRAP" value="2" />
<option name="ALIGN_MULTILINE_ANNOTATION_PARAMETERS" value="true" />
<option name="ALIGN_MULTILINE_TEXT_BLOCKS" value="true" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value>
<package name="java.awt" withSubpackages="false" static="false" />
</value>
</option>
<option name="JD_INDENT_ON_CONTINUATION" value="true" />
</JavaCodeStyleSettings>
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS"> <option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value /> <value />
@ -21,335 +8,7 @@
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" /> <option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="ALIGN_MULTILINE_METHOD_BRACKETS" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="5" />
<option name="METHOD_PARAMETERS_WRAP" value="5" />
<option name="RESOURCE_LIST_WRAP" value="1" />
<option name="EXTENDS_LIST_WRAP" value="1" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="BINARY_OPERATION_WRAP" value="1" />
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="1" />
<option name="FOR_STATEMENT_WRAP" value="1" />
<option name="ARRAY_INITIALIZER_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" />
<option name="ASSERT_STATEMENT_WRAP" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="WHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="WRAP_LONG_LINES" value="true" />
<option name="VARIABLE_ANNOTATION_WRAP" value="2" />
<option name="ENUM_CONSTANTS_WRAP" value="1" />
<indentOptions>
<option name="USE_RELATIVE_INDENTS" value="true" />
</indentOptions>
<arrangement>
<groups>
<group>
<type>OVERRIDDEN_METHODS</type>
<order>BY_NAME</order>
</group>
</groups>
<rules>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
<visibility />
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PROTECTED>true</PROTECTED>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PRIVATE>true</PRIVATE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PROTECTED>true</PROTECTED>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PRIVATE>true</PRIVATE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<FIELD>true</FIELD>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CONSTRUCTOR>true</CONSTRUCTOR>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD>true</METHOD>
<STATIC>true</STATIC>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<METHOD>true</METHOD>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<ENUM>true</ENUM>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INTERFACE>true</INTERFACE>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<CLASS>true</CLASS>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CLASS>true</CLASS>
</match>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin"> <codeStyleSettings language="kotlin">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_EXTENDS_LIST" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="5" /> <option name="CALL_PARAMETERS_WRAP" value="5" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" /> <option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" /> <option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
@ -359,9 +18,6 @@
<option name="EXTENDS_LIST_WRAP" value="1" /> <option name="EXTENDS_LIST_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="1" /> <option name="METHOD_CALL_CHAIN_WRAP" value="1" />
<option name="ASSIGNMENT_WRAP" value="1" /> <option name="ASSIGNMENT_WRAP" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
</codeStyleSettings> </codeStyleSettings>
</code_scheme> </code_scheme>
</component> </component>

View file

@ -1,36 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="created" />
</inspection_tool>
</profile>
</component>

View file

@ -1,7 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" value="Erik's Default" />
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

View file

@ -11,30 +11,15 @@
<option name="name" value="JBoss Community repository" /> <option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository> </remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$MAVEN_REPOSITORY$/" />
</remote-repository>
<remote-repository>
<option name="id" value="BintrayJCenter" />
<option name="name" value="BintrayJCenter" />
<option name="url" value="https://jcenter.bintray.com/" />
</remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="MavenLocal" /> <option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" /> <option name="name" value="MavenLocal" />
<option name="url" value="file:$MAVEN_REPOSITORY$" /> <option name="url" value="file:$MAVEN_REPOSITORY$" />
</remote-repository> </remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="MavenLocal" /> <option name="id" value="MavenRepo" />
<option name="name" value="MavenLocal" /> <option name="name" value="MavenRepo" />
<option name="url" value="file:$MAVEN_REPOSITORY$/" /> <option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository> </remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="maven" /> <option name="id" value="maven" />

6
.idea/misc.xml generated
View file

@ -1,11 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="15" project-jdk-type="JavaSDK" /> <component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="15" project-jdk-type="JavaSDK" />
</project> </project>

View file

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="mobibot" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.version="0.7.3-beta+547" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/../../out/production/classes" />
<output-test url="file://$MODULE_DIR$/../../out/test/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../..">
<sourceFolder url="file://$MODULE_DIR$/../../src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../src/generated/java" isTestSource="false" generated="true" />
<excludeFolder url="file://$MODULE_DIR$/../../.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../build" />
<excludeFolder url="file://$MODULE_DIR$/../../kobaltBuild" />
<excludeFolder url="file://$MODULE_DIR$/../../out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: pircbot:pircbot:1.5.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: pircbot:pircbot:1.5.0:sources" level="project" />
<orderEntry type="library" name="Gradle: org.apache.logging.log4j:log4j-core:2.12.1" level="project" />
<orderEntry type="library" name="Gradle: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />
<orderEntry type="library" name="Gradle: org.apache.logging.log4j:log4j-api:2.12.1" level="project" />
<orderEntry type="library" name="Gradle: org.apache.commons:commons-lang3:3.9" level="project" />
<orderEntry type="library" name="Gradle: commons-cli:commons-cli:1.4" level="project" />
<orderEntry type="library" name="Gradle: commons-net:commons-net:3.6" level="project" />
<orderEntry type="library" name="Gradle: net.thauvin.erik:pinboard-poster:1.0.1" level="project" />
<orderEntry type="library" name="Gradle: net.aksingh:owm-japis:2.5.3.0" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.retrofit2:converter-gson:2.5.0" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.retrofit2:retrofit:2.5.0" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:4.2.0" level="project" />
<orderEntry type="library" name="Gradle: com.rometools:rome:1.12.2" level="project" />
<orderEntry type="library" name="Gradle: org.json:json:20190722" level="project" />
<orderEntry type="library" name="Gradle: org.jsoup:jsoup:1.12.1" level="project" />
<orderEntry type="library" name="Gradle: net.objecthunter:exp4j:0.4.8" level="project" />
<orderEntry type="library" name="Gradle: org.twitter4j:twitter4j-core:4.0.7" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.50" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.50" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: net.thauvin.erik:semver:1.2.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.github.spotbugs:spotbugs-annotations:4.0.0-beta4" level="project" />
<orderEntry type="library" name="Gradle: com.rometools:rome-utils:1.12.2" level="project" />
<orderEntry type="library" name="Gradle: org.slf4j:slf4j-api:1.7.25" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:2.2.2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.3.50" level="project" />
<orderEntry type="library" name="Gradle: org.jdom:jdom2:2.0.6" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.gson:gson:2.8.5" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.3.50" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.github.spullara.mustache.java:compiler:0.9.6" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.testng:testng:7.0.0" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.assertj:assertj-core:3.13.2" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: com.beust:jcommander:1.72" level="project" />
</component>
</module>

2
.idea/vcs.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>

View file

@ -53,9 +53,9 @@ public final class War extends AbstractModule {
private static final String WAR_CMD = "war"; private static final String WAR_CMD = "war";
// Deck of card // Deck of card
private static final String[] WAR_DECK = private static final String[] WAR_DECK =
new String[]{ "Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2" }; new String[]{"Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"};
// Suits for the deck of card // Suits for the deck of card
private static final String[] WAR_SUITS = new String[]{ "Hearts", "Spades", "Diamonds", "Clubs" }; private static final String[] WAR_SUITS = new String[]{"Hearts", "Spades", "Diamonds", "Clubs"};
/** /**
* The default constructor. * The default constructor.
@ -85,9 +85,9 @@ public final class War extends AbstractModule {
y = RANDOM.nextInt(WAR_DECK.length); y = RANDOM.nextInt(WAR_DECK.length);
getBot().send(sender + " drew the " + bold(WAR_DECK[i]) + " of " getBot().send(sender + " drew the " + bold(WAR_DECK[i]) + " of "
+ bold(WAR_SUITS[RANDOM.nextInt(WAR_SUITS.length)])); + bold(WAR_SUITS[RANDOM.nextInt(WAR_SUITS.length)]));
getBot().action("drew the " + bold(WAR_DECK[y]) + " of " getBot().action("drew the " + bold(WAR_DECK[y]) + " of "
+ bold(WAR_SUITS[RANDOM.nextInt(WAR_SUITS.length)])); + bold(WAR_SUITS[RANDOM.nextInt(WAR_SUITS.length)]));
if (i != y) { if (i != y) {
break; break;

View file

@ -33,6 +33,8 @@ package net.thauvin.erik.mobibot
import com.rometools.rome.io.SyndFeedInput import com.rometools.rome.io.SyndFeedInput
import com.rometools.rome.io.XmlReader import com.rometools.rome.io.XmlReader
import net.thauvin.erik.mobibot.Utils.green
import net.thauvin.erik.mobibot.Utils.helpFormat
import java.net.MalformedURLException import java.net.MalformedURLException
import java.net.URL import java.net.URL
@ -67,7 +69,7 @@ class FeedReader(
var i = 0 var i = 0
while (i < items.size && i < maxItems) { while (i < items.size && i < maxItems) {
send(sender, items[i].title, false) send(sender, items[i].title, false)
send(sender, Utils.helpFormat(Utils.green(items[i].link), false), false) send(sender, helpFormat(green(items[i].link), false), false)
i++ i++
} }
} }

View file

@ -32,8 +32,9 @@
package net.thauvin.erik.mobibot package net.thauvin.erik.mobibot
import kotlinx.coroutines.async import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import net.thauvin.erik.mobibot.entries.EntryLink import net.thauvin.erik.mobibot.entries.EntryLink
import net.thauvin.erik.pinboard.PinboardPoster import net.thauvin.erik.pinboard.PinboardPoster
import java.time.ZoneId import java.time.ZoneId
@ -51,15 +52,15 @@ object PinboardUtils {
*/ */
@JvmStatic @JvmStatic
fun addPin(poster: PinboardPoster, ircServer: String, entry: EntryLink) = runBlocking { fun addPin(poster: PinboardPoster, ircServer: String, entry: EntryLink) = runBlocking {
async { withContext(Dispatchers.Default) {
poster.addPin( poster.addPin(
entry.link, entry.link,
entry.title, entry.title,
postedBy(entry, ircServer), entry.postedBy(ircServer),
entry.pinboardTags, entry.pinboardTags,
entry.date.toTimestamp() entry.date.toTimestamp()
) )
}.await() }
} }
/** /**
@ -67,9 +68,9 @@ object PinboardUtils {
*/ */
@JvmStatic @JvmStatic
fun deletePin(poster: PinboardPoster, entry: EntryLink) = runBlocking { fun deletePin(poster: PinboardPoster, entry: EntryLink) = runBlocking {
async { withContext(Dispatchers.Default) {
poster.deletePin(entry.link) poster.deletePin(entry.link)
}.await() }
} }
/** /**
@ -77,14 +78,14 @@ object PinboardUtils {
*/ */
@JvmStatic @JvmStatic
fun updatePin(poster: PinboardPoster, ircServer: String, oldUrl: String, entry: EntryLink) = runBlocking { fun updatePin(poster: PinboardPoster, ircServer: String, oldUrl: String, entry: EntryLink) = runBlocking {
async { withContext(Dispatchers.Default) {
with(entry) { with(entry) {
if (oldUrl != link) { if (oldUrl != link) {
poster.deletePin(oldUrl) poster.deletePin(oldUrl)
poster.addPin( poster.addPin(
link, link,
title, title,
postedBy(entry, ircServer), entry.postedBy(ircServer),
pinboardTags, pinboardTags,
date.toTimestamp() date.toTimestamp()
) )
@ -92,7 +93,7 @@ object PinboardUtils {
poster.addPin( poster.addPin(
link, link,
title, title,
postedBy(entry, ircServer), entry.postedBy(ircServer),
pinboardTags, pinboardTags,
date.toTimestamp(), date.toTimestamp(),
replace = true, replace = true,
@ -100,7 +101,7 @@ object PinboardUtils {
) )
} }
} }
}.await() }
} }
/** /**
@ -109,15 +110,16 @@ object PinboardUtils {
@JvmStatic @JvmStatic
fun Date.toTimestamp(): String { fun Date.toTimestamp(): String {
return ZonedDateTime.ofInstant( return ZonedDateTime.ofInstant(
this.toInstant().truncatedTo(ChronoUnit.SECONDS), this.toInstant().truncatedTo(ChronoUnit.SECONDS),
ZoneId.systemDefault()).format(DateTimeFormatter.ISO_INSTANT) ZoneId.systemDefault()
).format(DateTimeFormatter.ISO_INSTANT)
} }
/** /**
* Returns the pinboard.in extended attribution line. * Returns the pinboard.in extended attribution line.
*/ */
private fun postedBy(entry: EntryLink, ircServer: String): String { private fun EntryLink.postedBy(ircServer: String): String {
return "Posted by ${entry.nick} on ${entry.channel} ( $ircServer )" return "Posted by ${this.nick} on ${this.channel} ( $ircServer )"
} }
} }

View file

@ -59,11 +59,11 @@ class Recap(bot: Mobibot) : AbstractCommand(bot) {
fun storeRecap(sender: String, message: String, isAction: Boolean) { fun storeRecap(sender: String, message: String, isAction: Boolean) {
recaps.add( recaps.add(
LocalDateTime.now(Clock.systemUTC()).toUtcDateTime() LocalDateTime.now(Clock.systemUTC()).toUtcDateTime()
+ " - $sender" + (if (isAction) " " else ": ") + message + " - $sender" + (if (isAction) " " else ": ") + message
) )
@Suppress("MagicNumber") @Suppress("MagicNumber")
if (recaps.size > 10) { if (recaps.size > 10) {
recaps.removeAt(0) recaps.removeFirst()
} }
} }
} }

View file

@ -40,7 +40,7 @@ class Versions(bot: Mobibot) : AbstractCommand(bot) {
private val allVersions = listOf( private val allVersions = listOf(
"Version: ${ReleaseInfo.VERSION} (${ReleaseInfo.BUILDDATE.toIsoLocalDate()})", "Version: ${ReleaseInfo.VERSION} (${ReleaseInfo.BUILDDATE.toIsoLocalDate()})",
"Platform: " + System.getProperty("os.name") + ' ' + System.getProperty("os.version") "Platform: " + System.getProperty("os.name") + ' ' + System.getProperty("os.version")
+ " (" + System.getProperty("os.arch") + ')', + " (" + System.getProperty("os.arch") + ')',
"Runtime: " + System.getProperty("java.runtime.name") + ' ' + System.getProperty("java.runtime.version") "Runtime: " + System.getProperty("java.runtime.name") + ' ' + System.getProperty("java.runtime.version")
) )
override val name = "versions" override val name = "versions"

View file

@ -80,7 +80,7 @@ object EntriesMgr {
if (!history.contains(bot.today)) { if (!history.contains(bot.today)) {
history.add(bot.today) history.add(bot.today)
while (history.size > maxBacklogs) { while (history.size > maxBacklogs) {
history.removeAt(0) history.removeFirst()
} }
} }
OutputStreamWriter( OutputStreamWriter(
@ -201,7 +201,6 @@ object EntriesMgr {
language = "en" language = "en"
} }
val buff: StringBuilder = StringBuilder() val buff: StringBuilder = StringBuilder()
var comment: EntryComment
for (i in entries.size - 1 downTo 0) { for (i in entries.size - 1 downTo 0) {
with(entries[i]) { with(entries[i]) {
buff.setLength(0) buff.setLength(0)
@ -215,13 +214,11 @@ object EntriesMgr {
.append("</b></a>") .append("</b></a>")
if (comments.size > 0) { if (comments.size > 0) {
buff.append(" <br/><br/>") buff.append(" <br/><br/>")
val comments = comments
for (j in comments.indices) { for (j in comments.indices) {
comment = comments[j]
if (j > 0) { if (j > 0) {
buff.append(" <br/>") buff.append(" <br/>")
} }
buff.append(comment.nick).append(": ").append(comment.comment) buff.append(comments[j].nick).append(": ").append(comments[j].comment)
} }
} }
item = SyndEntryImpl() item = SyndEntryImpl()

View file

@ -43,9 +43,7 @@ data class EntryComment(var comment: String, var nick: String) : Serializable {
*/ */
val date: LocalDateTime = LocalDateTime.now() val date: LocalDateTime = LocalDateTime.now()
override fun toString(): String { override fun toString(): String = "EntryComment{comment='$comment', date=$date, nick='$nick'}"
return ("EntryComment{comment='$comment', date=$date, nick='$nick'}")
}
companion object { companion object {
// Serial version UID // Serial version UID

View file

@ -145,8 +145,8 @@ class EntryLink : Serializable {
*/ */
fun matches(match: String?): Boolean { fun matches(match: String?): Boolean {
return (StringUtils.containsIgnoreCase(link, match) return (StringUtils.containsIgnoreCase(link, match)
|| StringUtils.containsIgnoreCase(title, match) || StringUtils.containsIgnoreCase(title, match)
|| StringUtils.containsIgnoreCase(nick, match)) || StringUtils.containsIgnoreCase(nick, match))
} }
/** /**
@ -203,7 +203,7 @@ class EntryLink : Serializable {
*/ */
override fun toString(): String { override fun toString(): String {
return ("EntryLink{channel='$channel', comments=$comments, date=$date, link='$link', login='$login'," + return ("EntryLink{channel='$channel', comments=$comments, date=$date, link='$link', login='$login'," +
"nick='$nick', tags=$tags, title='$title'}") "nick='$nick', tags=$tags, title='$title'}")
} }
companion object { companion object {

View file

@ -152,6 +152,9 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
// Last exchange rates table publication date // Last exchange rates table publication date
private var pubDate = "" private var pubDate = ""
private fun Double.formatCurrency(): String =
NumberFormat.getCurrencyInstance(Constants.LOCALE).format(this).substring(1)
/** /**
* Converts from a currency to another. * Converts from a currency to another.
*/ */
@ -171,11 +174,8 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
val doubleFrom = EXCHANGE_RATES[to]!!.toDouble() val doubleFrom = EXCHANGE_RATES[to]!!.toDouble()
val doubleTo = EXCHANGE_RATES[from]!!.toDouble() val doubleTo = EXCHANGE_RATES[from]!!.toDouble()
PublicMessage( PublicMessage(
NumberFormat.getCurrencyInstance(Constants.LOCALE).format(amt).substring(1) amt.formatCurrency() + " ${cmds[1].uppercase()} = "
+ " ${cmds[1].uppercase()} = " + (amt * doubleTo / doubleFrom).formatCurrency() + " ${cmds[3].uppercase()}"
+ NumberFormat.getCurrencyInstance(Constants.LOCALE)
.format(amt * doubleTo / doubleFrom).substring(1)
+ " ${cmds[3].uppercase()}"
) )
} catch (e: NumberFormatException) { } catch (e: NumberFormatException) {
ErrorMessage("Let's try with some real numbers next time, okay?") ErrorMessage("Let's try with some real numbers next time, okay?")
@ -187,6 +187,7 @@ class CurrencyConverter(bot: Mobibot) : ThreadedModule(bot) {
} else ErrorMessage("Invalid query. Let's try again.") } else ErrorMessage("Invalid query. Let's try again.")
} }
@JvmStatic @JvmStatic
fun currencyRates(): List<String> { fun currencyRates(): List<String> {
val rates = mutableListOf<String>() val rates = mutableListOf<String>()

View file

@ -54,12 +54,12 @@ class Dice(bot: Mobibot) : AbstractModule(bot) {
send( send(
channel, channel,
"$sender rolled two dice: ${bold(playerRoll.first)} and ${bold(playerRoll.second)}" "$sender rolled two dice: ${bold(playerRoll.first)} and ${bold(playerRoll.second)}"
+ " for a total of ${bold(playerTotal)}", + " for a total of ${bold(playerTotal)}",
isPrivate isPrivate
) )
action( action(
"rolled two dice: ${bold(roll.first)} and ${bold(roll.second)}" + "rolled two dice: ${bold(roll.first)} and ${bold(roll.second)}" +
" for a total of ${bold(total)}" " for a total of ${bold(total)}"
) )
when (winLoseOrTie(total, playerTotal)) { when (winLoseOrTie(total, playerTotal)) {
Result.WIN -> action("wins.") Result.WIN -> action("wins.")

View file

@ -97,7 +97,7 @@ class GoogleSearch(bot: Mobibot) : ThreadedModule(bot) {
try { try {
val url = URL( val url = URL(
"https://www.googleapis.com/customsearch/v1?key=$apiKey&cx=$cseKey" + "https://www.googleapis.com/customsearch/v1?key=$apiKey&cx=$cseKey" +
"&q=${encodeUrl(query)}&filter=1&num=5&alt=json" "&q=${encodeUrl(query)}&filter=1&num=5&alt=json"
) )
val json = JSONObject(urlReader(url)) val json = JSONObject(urlReader(url))
val ja = json.getJSONArray("items") val ja = json.getJSONArray("items")

View file

@ -58,8 +58,8 @@ class Lookup(bot: Mobibot) : AbstractModule(bot) {
} catch (ignore: UnknownHostException) { } catch (ignore: UnknownHostException) {
if (args.matches( if (args.matches(
("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." + ("(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)").toRegex() "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)").toRegex()
) )
) { ) {
try { try {

View file

@ -56,7 +56,7 @@ class RockPaperScissors(bot: Mobibot) : AbstractModule(bot) {
add( add(
helpFormat( helpFormat(
"%c ${Hands.ROCK.name.lowercase()} | ${Hands.PAPER.name.lowercase()}" "%c ${Hands.ROCK.name.lowercase()} | ${Hands.PAPER.name.lowercase()}"
+ " | ${Hands.SCISSORS.name.lowercase()}" + " | ${Hands.SCISSORS.name.lowercase()}"
) )
) )
} }

View file

@ -139,7 +139,7 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
response = urlReader( response = urlReader(
URL( URL(
"${ALPHAVANTAGE_URL}SYMBOL_SEARCH&keywords=" + encodeUrl(symbol) "${ALPHAVANTAGE_URL}SYMBOL_SEARCH&keywords=" + encodeUrl(symbol)
+ "&apikey=" + encodeUrl(apiKey) + "&apikey=" + encodeUrl(apiKey)
) )
) )
var json = getJsonResponse(response, debugMessage) var json = getJsonResponse(response, debugMessage)
@ -153,8 +153,8 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
response = urlReader( response = urlReader(
URL( URL(
"${ALPHAVANTAGE_URL}GLOBAL_QUOTE&symbol=" "${ALPHAVANTAGE_URL}GLOBAL_QUOTE&symbol="
+ encodeUrl(symbolInfo.getString("1. symbol")) + encodeUrl(symbolInfo.getString("1. symbol"))
+ "&apikey=" + encodeUrl(apiKey) + "&apikey=" + encodeUrl(apiKey)
) )
) )
json = getJsonResponse(response, debugMessage) json = getJsonResponse(response, debugMessage)
@ -166,28 +166,23 @@ class StockQuote(bot: Mobibot) : ThreadedModule(bot) {
add( add(
PublicMessage( PublicMessage(
"Symbol: " + unescapeXml(quote.getString("01. symbol")) "Symbol: " + unescapeXml(quote.getString("01. symbol"))
+ " [" + unescapeXml(symbolInfo.getString("2. name")) + ']' + " [" + unescapeXml(symbolInfo.getString("2. name")) + ']'
) )
) )
add(PublicMessage(" Price: " + unescapeXml(quote.getString("05. price")))) add(PublicMessage(" Price: " + unescapeXml(quote.getString("05. price"))))
add( add(PublicMessage(" Previous: " + unescapeXml(quote.getString("08. previous close"))))
PublicMessage(
" Previous: " + unescapeXml(quote.getString("08. previous close"))
)
)
add(NoticeMessage(" Open: " + unescapeXml(quote.getString("02. open")))) add(NoticeMessage(" Open: " + unescapeXml(quote.getString("02. open"))))
add(NoticeMessage(" High: " + unescapeXml(quote.getString("03. high")))) add(NoticeMessage(" High: " + unescapeXml(quote.getString("03. high"))))
add(NoticeMessage(" Low: " + unescapeXml(quote.getString("04. low")))) add(NoticeMessage(" Low: " + unescapeXml(quote.getString("04. low"))))
add(NoticeMessage(" Volume: " + unescapeXml(quote.getString("06. volume")))) add(NoticeMessage(" Volume: " + unescapeXml(quote.getString("06. volume"))))
add( add(NoticeMessage(
NoticeMessage(
" Latest: " + unescapeXml(quote.getString("07. latest trading day")) " Latest: " + unescapeXml(quote.getString("07. latest trading day"))
) )
) )
add( add(
NoticeMessage( NoticeMessage(
" Change: " + unescapeXml(quote.getString("09. change")) + " [" " Change: " + unescapeXml(quote.getString("09. change")) + " ["
+ unescapeXml(quote.getString("10. change percent")) + ']' + unescapeXml(quote.getString("10. change percent")) + ']'
) )
) )
} }

View file

@ -104,9 +104,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
@Throws(ModuleException::class) @Throws(ModuleException::class)
fun getWeather(query: String, apiKey: String?): List<Message> { fun getWeather(query: String, apiKey: String?): List<Message> {
if (apiKey.isNullOrBlank()) { if (apiKey.isNullOrBlank()) {
throw ModuleException( throw ModuleException("${WEATHER_CMD.capitalise()} is disabled. The API key is missing.")
"${WEATHER_CMD.capitalise()} is disabled. The API key is missing."
)
} }
val owm = OWM(apiKey) val owm = OWM(apiKey)
val messages = mutableListOf<Message>() val messages = mutableListOf<Message>()
@ -127,9 +125,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
owm.currentWeatherByCityName(city, getCountry(country)) owm.currentWeatherByCityName(city, getCountry(country))
} }
if (cwd.hasCityName()) { if (cwd.hasCityName()) {
messages.add( messages.add(PublicMessage("City: ${cwd.cityName} [${country.uppercase()}]"))
PublicMessage("City: ${cwd.cityName} [${country.uppercase()}]")
)
with(cwd.mainData) { with(cwd.mainData) {
if (this != null) { if (this != null) {
if (hasTemp()) { if (hasTemp()) {
@ -170,7 +166,7 @@ class Weather2(bot: Mobibot) : ThreadedModule(bot) {
messages.add( messages.add(
NoticeMessage( NoticeMessage(
"https://openweathermap.org/find?q=" "https://openweathermap.org/find?q="
+ encodeUrl("$city,${country.uppercase()}"), + encodeUrl("$city,${country.uppercase()}"),
Colors.GREEN Colors.GREEN
) )
) )

View file

@ -58,6 +58,10 @@ class WorldTime(bot: Mobibot) : AbstractModule(bot) {
// The Time command // The Time command
private const val TIME_CMD = "time" private const val TIME_CMD = "time"
// Date/Time Format
private var dtf =
DateTimeFormatter.ofPattern("'The time is ${bold("'HH:mm'")} on ${bold("'EEEE, d MMMM yyyy'")} in '")
/** /**
* Returns the current Internet (beat) Time. * Returns the current Internet (beat) Time.
*/ */
@ -65,7 +69,7 @@ class WorldTime(bot: Mobibot) : AbstractModule(bot) {
private fun internetTime(): String { private fun internetTime(): String {
val zdt = ZonedDateTime.now(ZoneId.of("UTC+01:00")) val zdt = ZonedDateTime.now(ZoneId.of("UTC+01:00"))
val beats = ((zdt[ChronoField.SECOND_OF_MINUTE] + zdt[ChronoField.MINUTE_OF_HOUR] * 60 val beats = ((zdt[ChronoField.SECOND_OF_MINUTE] + zdt[ChronoField.MINUTE_OF_HOUR] * 60
+ zdt[ChronoField.HOUR_OF_DAY] * 3600) / 86.4).toInt() + zdt[ChronoField.HOUR_OF_DAY] * 3600) / 86.4).toInt()
return String.format(Locale.getDefault(), "%c%03d", '@', beats) return String.format(Locale.getDefault(), "%c%03d", '@', beats)
} }
@ -79,15 +83,8 @@ class WorldTime(bot: Mobibot) : AbstractModule(bot) {
if (BEATS_KEYWORD == tz) { if (BEATS_KEYWORD == tz) {
"The current Internet Time is: ${bold(internetTime())} $BEATS_KEYWORD" "The current Internet Time is: ${bold(internetTime())} $BEATS_KEYWORD"
} else { } else {
(ZonedDateTime.now() (ZonedDateTime.now().withZoneSameInstant(ZoneId.of(tz)).format(dtf)
.withZoneSameInstant(ZoneId.of(tz)) + bold(tz.substring(tz.indexOf('/') + 1).replace('_', ' ')))
.format(
DateTimeFormatter.ofPattern(
"'The time is ${bold("'HH:mm'")} on ${bold("'EEEE, d MMMM yyyy'")} in '"
)
)
+ bold(tz.substring(tz.indexOf('/') + 1).replace('_', ' '))
)
} }
} else { } else {
return ErrorMessage("Unsupported country/zone. Please try again.") return ErrorMessage("Unsupported country/zone. Please try again.")

View file

@ -32,14 +32,14 @@
package net.thauvin.erik.mobibot package net.thauvin.erik.mobibot
import net.thauvin.erik.mobibot.entries.EntryLink
import net.thauvin.erik.mobibot.PinboardUtils.toTimestamp import net.thauvin.erik.mobibot.PinboardUtils.toTimestamp
import net.thauvin.erik.mobibot.entries.EntryLink
import net.thauvin.erik.pinboard.PinboardPoster import net.thauvin.erik.pinboard.PinboardPoster
import org.testng.Assert.assertFalse import org.testng.Assert.assertFalse
import org.testng.Assert.assertTrue import org.testng.Assert.assertTrue
import org.testng.annotations.Test import org.testng.annotations.Test
import java.util.Date
import java.net.URL import java.net.URL
import java.util.Date
class PinboardUtilsTest : LocalProperties() { class PinboardUtilsTest : LocalProperties() {
@Test @Test
@ -71,7 +71,7 @@ class PinboardUtilsTest : LocalProperties() {
val response = Utils.urlReader( val response = Utils.urlReader(
URL( URL(
"https://api.pinboard.in/v1/posts/get?auth_token=${apiToken}&tag=test&" "https://api.pinboard.in/v1/posts/get?auth_token=${apiToken}&tag=test&"
+ Utils.encodeUrl(url) + Utils.encodeUrl(url)
) )
) )