#1 Added Sauce Command

Merged
yannic merged 1 commits from paul into master 4 years ago
  1. +1
    -1
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioController.java
  2. +3
    -2
      app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioControllerManager.java
  3. +132
    -112
      app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandContext.java
  4. +57
    -47
      app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandDistributor.java
  5. +29
    -43
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/JokeCommand.java
  6. +5
    -3
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java
  7. +48
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/SauceCommand.java
  8. +2
    -2
      app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/StopCommand.java
  9. +1
    -1
      app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandLine.java
  10. +15
    -11
      app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandListener.java
  11. +59
    -21
      app/src/main/java/de/yannicpunktdee/yoshibot/main/Resources.java
  12. +147
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/main/SauceProvider.java
  13. +3
    -2
      app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java
  14. +38
    -0
      app/src/main/java/de/yannicpunktdee/yoshibot/utils/RestHelper.java
  15. +0
    -0
      gradlew

+ 1
- 1
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioController.java View File

@ -13,7 +13,7 @@ public class AudioController {
public AudioController(Guild guild) { public AudioController(Guild guild) {
this.guild = guild; this.guild = guild;
this.audioPlayer = YoshiBot.audioPlayerManager.createPlayer();
this.audioPlayer = YoshiBot.getInstance().audioPlayerManager.createPlayer();
audioPlayer.addListener(new AudioPlayerListener(guild.getAudioManager())); audioPlayer.addListener(new AudioPlayerListener(guild.getAudioManager()));
this.guild.getAudioManager().setSendingHandler(new AudioSendHandlerImpl(audioPlayer)); this.guild.getAudioManager().setSendingHandler(new AudioSendHandlerImpl(audioPlayer));


+ 3
- 2
app/src/main/java/de/yannicpunktdee/yoshibot/audio/AudioControllerManager.java View File

@ -1,6 +1,7 @@
package de.yannicpunktdee.yoshibot.audio; package de.yannicpunktdee.yoshibot.audio;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import de.yannicpunktdee.yoshibot.main.YoshiBot; import de.yannicpunktdee.yoshibot.main.YoshiBot;
@ -16,10 +17,10 @@ public class AudioControllerManager {
public AudioController getController(long guildId) { public AudioController getController(long guildId) {
AudioController ac = null; AudioController ac = null;
if(audioController.containsKey(guildId))
if (audioController.containsKey(guildId))
ac = audioController.get(guildId); ac = audioController.get(guildId);
else { else {
ac = new AudioController(YoshiBot.jda.getGuildById(guildId));
ac = new AudioController(Objects.requireNonNull(YoshiBot.getInstance().jda.getGuildById(guildId)));
audioController.put(guildId, ac); audioController.put(guildId, ac);
} }
return ac; return ac;


+ 132
- 112
app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandContext.java View File

@ -1,9 +1,10 @@
package de.yannicpunktdee.yoshibot.command; package de.yannicpunktdee.yoshibot.command;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import de.yannicpunktdee.yoshibot.command.YoshiCommandDistributor.Action; import de.yannicpunktdee.yoshibot.command.YoshiCommandDistributor.Action;
import de.yannicpunktdee.yoshibot.command.commands.SauceCommand;
import de.yannicpunktdee.yoshibot.main.SauceProvider;
import de.yannicpunktdee.yoshibot.main.YoshiBot; import de.yannicpunktdee.yoshibot.main.YoshiBot;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.entities.TextChannel;
@ -12,21 +13,22 @@ import net.dv8tion.jda.api.entities.VoiceChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;;
/** /**
* Parst einen Eingabestring, entscheidet ob er ein Kommando ist und zerlegt ihn in seine Bestandteile.
* Kommandos besitzen einen Status, der Auskunft gibt, ob Fehler beim Parsen des Eingabestrings aufgetreten
* sind oder der String gar kein Kommando war. Außerdem wird bei erfolgreich geparsten Kommandos eine Aktion
* festgelegt, die das Kommando ausführen soll, sowie die Argumente mit welcher das Kommando ausgeführt wird.
* Außerdem enthalten ist eine Referenz auf Ursprungs-User und -TextChannel.
* Parst einen Eingabestring, entscheidet ob er ein Kommando ist und zerlegt ihn in seine Bestandteile. Kommandos
* besitzen einen Status, der Auskunft gibt, ob Fehler beim Parsen des Eingabestrings aufgetreten sind oder der String
* gar kein Kommando war. Außerdem wird bei erfolgreich geparsten Kommandos eine Aktion festgelegt, die das Kommando
* ausführen soll, sowie die Argumente mit welcher das Kommando ausgeführt wird. Außerdem enthalten ist eine Referenz
* auf Ursprungs-User und -TextChannel.
*
* @author Yannic Link * @author Yannic Link
*/ */
public class YoshiCommandContext { public class YoshiCommandContext {
/** /**
* Repräsentiert einen Status, den eine YoshiCommand-Instanz hat, nachdem der Eingabestring eingelesen
* und geparst wurde. Sofern der Status nicht OK ist, ist diese Instanz entweder kein Kommando oder
* besitzt eine fehlerhafte Syntax.
* Repräsentiert einen Status, den eine YoshiCommand-Instanz hat, nachdem der Eingabestring eingelesen und geparst
* wurde. Sofern der Status nicht OK ist, ist diese Instanz entweder kein Kommando oder besitzt eine fehlerhafte
* Syntax.
*/ */
public static enum State {
public enum State {
/** /**
* Das Kommando wurde erfolgreich geparst und besitzt keine Syntaxfehler. * Das Kommando wurde erfolgreich geparst und besitzt keine Syntaxfehler.
*/ */
@ -48,10 +50,11 @@ public class YoshiCommandContext {
*/ */
BAD_SYNTAX BAD_SYNTAX
} }
/** /**
* Hilfskonstrukt. Beschreibt den Zustand vom Parser. * Hilfskonstrukt. Beschreibt den Zustand vom Parser.
*/ */
private static enum ReadingState{
private enum ReadingState {
/** /**
* Der Parser ist dabei festzustellen, ob es sich um ein Kommando handelt. * Der Parser ist dabei festzustellen, ob es sich um ein Kommando handelt.
*/ */
@ -84,7 +87,9 @@ public class YoshiCommandContext {
* Der Parser liest gerade einen zusammenhängenden Argumentenwert ein. * Der Parser liest gerade einen zusammenhängenden Argumentenwert ein.
*/ */
READING_STRING READING_STRING
};
}
;
/** /**
@ -105,133 +110,138 @@ public class YoshiCommandContext {
*/ */
private Map<String, String> arguments; private Map<String, String> arguments;
private List<String> argumentList;
private MessageReceivedEvent event; private MessageReceivedEvent event;
/** /**
* Erzeugt aus einem unbearbeiteten Eingabestring ein Kommando. Nach dem parsen enthält die state-Variable
* den Endzustand des Parsers.
* Erzeugt aus einem unbearbeiteten Eingabestring ein Kommando. Nach dem parsen enthält die state-Variable den
* Endzustand des Parsers.
*
* @param argumentsString Ein unbearbeiteter Eingabestring * @param argumentsString Ein unbearbeiteter Eingabestring
* @param user Der Benutzer, der das Kommando geschickt hat.
* @param channel Der Textchannel in den das Kommando geschickt wurde.
*/ */
public YoshiCommandContext(String argumentsString, MessageReceivedEvent event) { public YoshiCommandContext(String argumentsString, MessageReceivedEvent event) {
this.event = event; this.event = event;
argumentsString = argumentsString.trim(); argumentsString = argumentsString.trim();
arguments = new HashMap<String, String>();
argumentList = new ArrayList<>();
argumentList.addAll(Arrays.asList(argumentsString.split(" ")));
argumentList.remove(0);
arguments = new HashMap<>();
ReadingState readingState = ReadingState.VERIFYING; ReadingState readingState = ReadingState.VERIFYING;
String currentKey = null; String currentKey = null;
int startPos = 0; int startPos = 0;
int length = argumentsString.length(); int length = argumentsString.length();
for(int position = 0; position < length; position++) {
for (int position = 0; position < length; position++) {
char currentChar = argumentsString.charAt(position); char currentChar = argumentsString.charAt(position);
switch(readingState) {
switch (readingState) {
case VERIFYING:
if (!Character.isWhitespace(currentChar)) continue;
if (!argumentsString.substring(0, position).equals(PREFIX)) {
state = State.NO_COMMAND;
return;
}
readingState = ReadingState.AFTER_VERIFY;
continue;
case AFTER_VERIFY:
if (Character.isWhitespace(currentChar)) continue;
if (currentChar == '-') {
state = State.NO_ACTION;
return;
}
startPos = position;
readingState = ReadingState.READING_ACTION;
continue;
case READING_ACTION:
if (!Character.isWhitespace(currentChar)) continue;
try {
action = Action.valueOf(argumentsString.substring(startPos, position).toUpperCase());
readingState = ReadingState.INTERMEDIATE;
} catch (IllegalArgumentException e) {
state = State.UNKNOWN_ACTION;
return;
}
continue;
case INTERMEDIATE:
if (Character.isWhitespace(currentChar)) continue;
if ((currentChar != '-' || currentChar == '"') && action != Action.SAUCE) {
state = State.BAD_SYNTAX;
return;
}
startPos = position + 1;
readingState = ReadingState.READING_KEY;
continue;
case READING_KEY:
if (!Character.isWhitespace(currentChar)) continue;
currentKey = argumentsString.substring(startPos, position);
readingState = ReadingState.AFTER_KEY;
continue;
case AFTER_KEY:
if (Character.isWhitespace(currentChar)) continue;
if (currentChar == '-') {
arguments.put(currentKey, null);
startPos = position + 1;
readingState = ReadingState.READING_KEY;
} else if (currentChar == '"') {
startPos = position + 1;
readingState = ReadingState.READING_STRING;
} else {
startPos = position;
readingState = ReadingState.READING_VALUE;
}
continue;
case READING_VALUE:
if (!Character.isWhitespace(currentChar)) continue;
arguments.put(currentKey, argumentsString.substring(startPos, position));
readingState = ReadingState.INTERMEDIATE;
continue;
case READING_STRING:
if (currentChar != '"') continue;
if (argumentsString.charAt(position - 1) == '\\') continue;
arguments.put(currentKey, argumentsString.substring(startPos, position));
readingState = ReadingState.INTERMEDIATE;
continue;
}
}
switch (readingState) {
case INTERMEDIATE:
state = State.OK;
return;
case VERIFYING: case VERIFYING:
if(!Character.isWhitespace(currentChar)) continue;
if(!argumentsString.substring(0, position).equals(PREFIX)) {
if (argumentsString.equals(PREFIX)) {
action = Action.HELP;
state = State.OK;
} else {
state = State.NO_COMMAND; state = State.NO_COMMAND;
return;
} }
readingState = ReadingState.AFTER_VERIFY;
continue;
case AFTER_VERIFY:
if(Character.isWhitespace(currentChar)) continue;
if(currentChar == '-'){
state = State.NO_ACTION;
return;
}
startPos = position;
readingState = ReadingState.READING_ACTION;
continue;
return;
case READING_ACTION: case READING_ACTION:
if(!Character.isWhitespace(currentChar)) continue;
try{
action = Action.valueOf(argumentsString.substring(startPos, position).toUpperCase());
try {
action = Action.valueOf(argumentsString.substring(startPos).toUpperCase());
readingState = ReadingState.INTERMEDIATE; readingState = ReadingState.INTERMEDIATE;
} catch(IllegalArgumentException e) {
} catch (IllegalArgumentException e) {
state = State.UNKNOWN_ACTION; state = State.UNKNOWN_ACTION;
return; return;
} }
continue;
case INTERMEDIATE:
if(Character.isWhitespace(currentChar)) continue;
if(currentChar != '-' || currentChar == '"') {
state = State.BAD_SYNTAX;
return;
}
startPos = position + 1;
readingState = ReadingState.READING_KEY;
continue;
state = State.OK;
return;
case READING_KEY: case READING_KEY:
if(!Character.isWhitespace(currentChar)) continue;
currentKey = argumentsString.substring(startPos, position);
readingState = ReadingState.AFTER_KEY;
continue;
case AFTER_KEY:
if(Character.isWhitespace(currentChar)) continue;
if(currentChar == '-') {
arguments.put(currentKey, null);
startPos = position + 1;
readingState = ReadingState.READING_KEY;
} else if(currentChar == '"'){
startPos = position + 1;
readingState = ReadingState.READING_STRING;
} else {
startPos = position;
readingState = ReadingState.READING_VALUE;
}
continue;
arguments.put(argumentsString.substring(startPos), null);
state = State.OK;
return;
case READING_VALUE: case READING_VALUE:
if(!Character.isWhitespace(currentChar)) continue;
arguments.put(currentKey, argumentsString.substring(startPos, position));
readingState = ReadingState.INTERMEDIATE;
continue;
case READING_STRING:
if(currentChar != '"') continue;
if(argumentsString.charAt(position - 1) == '\\') continue;
arguments.put(currentKey, argumentsString.substring(startPos, position));
readingState = ReadingState.INTERMEDIATE;
continue;
}
}
switch(readingState) {
case INTERMEDIATE:
state = State.OK;
return;
case VERIFYING:
if(argumentsString.equals(PREFIX)) {
action = Action.HELP;
arguments.put(currentKey, argumentsString.substring(startPos));
state = State.OK; state = State.OK;
}else {
state = State.NO_COMMAND;
}
return;
case READING_ACTION:
try{
action = Action.valueOf(argumentsString.substring(startPos).toUpperCase());
readingState = ReadingState.INTERMEDIATE;
} catch(IllegalArgumentException e) {
state = State.UNKNOWN_ACTION;
return; return;
}
state = State.OK;
return;
case READING_KEY:
arguments.put(argumentsString.substring(startPos), null);
state = State.OK;
return;
case READING_VALUE:
arguments.put(currentKey, argumentsString.substring(startPos));
state = State.OK;
return;
default:
break;
default:
break;
} }
} }
@ -248,36 +258,42 @@ public class YoshiCommandContext {
public State getState() { public State getState() {
return state; return state;
} }
/** /**
* Gibt die im Kommando spezifizierte Aktion zurück. null, wenn status fehlerhaft oder kein Kommando. * Gibt die im Kommando spezifizierte Aktion zurück. null, wenn status fehlerhaft oder kein Kommando.
*/ */
public Action getAction() { public Action getAction() {
return action; return action;
} }
/** /**
* Prüft, ob das Kommando mit Argumenten aufgerufen wurde. * Prüft, ob das Kommando mit Argumenten aufgerufen wurde.
*/ */
public boolean hasArguments() { public boolean hasArguments() {
return !arguments.isEmpty(); return !arguments.isEmpty();
} }
/** /**
* Prüft, ob alle Key-Werte in der Argumentenliste vorhanden sind. * Prüft, ob alle Key-Werte in der Argumentenliste vorhanden sind.
*
* @param args Liste von den auf Existenz zu überprüfenden Argumenten. * @param args Liste von den auf Existenz zu überprüfenden Argumenten.
*/ */
public boolean containsArguments(String[] args) { public boolean containsArguments(String[] args) {
for(String arg : args) {
if(!arguments.containsKey(arg)) {
for (String arg : args) {
if (!arguments.containsKey(arg)) {
return false; return false;
} }
} }
return true; return true;
} }
/** /**
* Gibt den Wert eines Arguments zurück. * Gibt den Wert eines Arguments zurück.
*
* @param arg Name des Arguments. * @param arg Name des Arguments.
*/ */
public String getArgument(String arg) { public String getArgument(String arg) {
if(!arguments.containsKey(arg)) return null;
if (!arguments.containsKey(arg)) return null;
return arguments.get(arg); return arguments.get(arg);
} }
@ -285,4 +301,8 @@ public class YoshiCommandContext {
return event; return event;
} }
public List<String> getArguments() {
return this.argumentList;
}
} }

+ 57
- 47
app/src/main/java/de/yannicpunktdee/yoshibot/command/YoshiCommandDistributor.java View File

@ -3,64 +3,73 @@ package de.yannicpunktdee.yoshibot.command;
import de.yannicpunktdee.yoshibot.command.commands.*; import de.yannicpunktdee.yoshibot.command.commands.*;
/** /**
* Unterscheidet nach der spezifizierten Action welche YoshiCommand-Kindklasse zum Ausführen des Kommandos
* verwendet wird.
* Unterscheidet nach der spezifizierten Action welche YoshiCommand-Kindklasse zum Ausführen des Kommandos verwendet
* wird.
*
* @author Yannic Link * @author Yannic Link
*/ */
public class YoshiCommandDistributor { public class YoshiCommandDistributor {
/** /**
* Führt das jeweils zuständige Kommando aus. * Führt das jeweils zuständige Kommando aus.
*
* @param context * @param context
*/ */
public static void distribute(YoshiCommandContext context) { public static void distribute(YoshiCommandContext context) {
switch(context.getState()) {
case NO_ACTION:
context.getEvent().getTextChannel().sendMessage("Im letzten Befehl wurde keine Aktion spezifiziert. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
case UNKNOWN_ACTION:
context.getEvent().getTextChannel().sendMessage("Im letzten Befehl wurde eine unbekannte Aktion angegeben. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
case BAD_SYNTAX:
context.getEvent().getTextChannel().sendMessage("Der letzte Befehl hatte ein falsches Format. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
default:
break;
switch (context.getState()) {
case NO_ACTION:
context.getEvent().getTextChannel()
.sendMessage("Im letzten Befehl wurde keine Aktion spezifiziert. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
case UNKNOWN_ACTION:
context.getEvent().getTextChannel()
.sendMessage("Im letzten Befehl wurde eine unbekannte Aktion angegeben. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.").queue();
return;
case BAD_SYNTAX:
context.getEvent().getTextChannel().sendMessage("Der letzte Befehl hatte ein falsches Format. Führe \""
+ YoshiCommandContext.PREFIX + " help\" für Hilfe aus.")
.queue();
return;
default:
break;
} }
YoshiCommand command = null; YoshiCommand command = null;
switch(context.getAction()) {
case STOP:
command = new StopCommand(context);
break;
case HELP:
command = new HelpCommand(context);
break;
case JOKE:
command = new JokeCommand(context);
break;
case SAY:
command = new SayCommand(context);
break;
case LIST:
command = new ListCommand(context);
break;
case PLAY:
command = new PlayCommand(context);
break;
default:
context.getEvent().getTextChannel().sendMessage("Dieses Kommando existiert noch nicht.").queue();
break;
switch (context.getAction()) {
case STOP:
command = new StopCommand(context);
break;
case HELP:
command = new HelpCommand(context);
break;
case JOKE:
command = new JokeCommand(context);
break;
case SAY:
command = new SayCommand(context);
break;
case LIST:
command = new ListCommand(context);
break;
case PLAY:
command = new PlayCommand(context);
break;
case SAUCE:
command = new SauceCommand(context);
break;
default:
context.getEvent().getTextChannel().sendMessage("Dieses Kommando existiert noch nicht.").queue();
break;
} }
if(command != null) command.execute();
if (command != null) command.execute();
} }
/** /**
* Enthlt alle mglichen Aktionen, die der Yoshi-Bot ausfhren kann. * Enthlt alle mglichen Aktionen, die der Yoshi-Bot ausfhren kann.
*
* @author Yannic Link * @author Yannic Link
*/ */
public enum Action { public enum Action {
@ -77,9 +86,9 @@ public class YoshiCommandDistributor {
*/ */
JOKE, JOKE,
/** /**
* Gib die Nachricht -message aus. ber die Option -out [text|voice] wird angegeben, ob die Nachricht
* per Textnachricht oder als Text-To-Speech ausgegeben wird. Mit -channel lsst sich der Ausgabechannel
* bestimmen. Standardmig wird die Ausgabe in den Textchannel zurckgesendet, aus dem das Kommando kam.
* Gib die Nachricht -message aus. ber die Option -out [text|voice] wird angegeben, ob die Nachricht per
* Textnachricht oder als Text-To-Speech ausgegeben wird. Mit -channel lsst sich der Ausgabechannel bestimmen.
* Standardmig wird die Ausgabe in den Textchannel zurckgesendet, aus dem das Kommando kam.
*/ */
SAY, SAY,
/** /**
@ -90,15 +99,16 @@ public class YoshiCommandDistributor {
/** /**
* Gibt eine vorhandene Ressource -name aus. (Vorhandene Ressourcen lassen sich mit der Aktion LIST anzeigen). * Gibt eine vorhandene Ressource -name aus. (Vorhandene Ressourcen lassen sich mit der Aktion LIST anzeigen).
* ber den Parameter -type [link|audio|video] lsst sich der Typ der Ressource spezifizieren. Ein Link wird * ber den Parameter -type [link|audio|video] lsst sich der Typ der Ressource spezifizieren. Ein Link wird
* ber in den per -channel spezifizierten (default=Ursprungskanal) Textkanal geschickt. Eine Audiodatei
* wird ber den per -channel spezifizierten (default=Aktueller Kanal) Voice-Channel ausgegeben. Ein Video
* wird ber den per -channel spezifizierten (default=Aktueller Kanal) Voice-Channel abgespielt.
* ber in den per -channel spezifizierten (default=Ursprungskanal) Textkanal geschickt. Eine Audiodatei wird
* ber den per -channel spezifizierten (default=Aktueller Kanal) Voice-Channel ausgegeben. Ein Video wird ber
* den per -channel spezifizierten (default=Aktueller Kanal) Voice-Channel abgespielt.
*/ */
PLAY, PLAY,
/** /**
* Lscht die Ressource, die ber -name spezifiziert wurde. Mit -type wird der Ressourcentyp festgelegt. * Lscht die Ressource, die ber -name spezifiziert wurde. Mit -type wird der Ressourcentyp festgelegt.
*/ */
DELETE
DELETE,
SAUCE
} }


+ 29
- 43
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/JokeCommand.java View File

@ -8,6 +8,7 @@ import java.net.URL;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import de.yannicpunktdee.yoshibot.utils.RestHelper;
import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringEscapeUtils;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -19,9 +20,9 @@ import net.dv8tion.jda.api.entities.TextChannel;
/** /**
* Schickt einen zufälligen Jokus aus einer zufällig ausgewählten Quelle in den Textchannel. * Schickt einen zufälligen Jokus aus einer zufällig ausgewählten Quelle in den Textchannel.
*
* @author Yannic Link * @author Yannic Link
*/ */
@SuppressWarnings("deprecation")
public class JokeCommand extends YoshiCommand { public class JokeCommand extends YoshiCommand {
/** /**
@ -34,71 +35,56 @@ public class JokeCommand extends YoshiCommand {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override public synchronized boolean execute() {
@Override
public synchronized boolean execute() {
String message = "Jokus"; String message = "Jokus";
Random random = new Random(); Random random = new Random();
int number = random.nextInt(3); int number = random.nextInt(3);
switch(number) {
case 0: message = jokeApi(); break;
case 1: message = officialJokeApi(); break;
case 2: message = chuckNorris(); break;
default: message = "Jokus"; break;
switch (number) {
case 0:
message = jokeApi();
break;
case 1:
message = officialJokeApi();
break;
case 2:
message = chuckNorris();
break;
default:
message = "Jokus";
break;
} }
if(context.containsArguments(new String[] {"channel"})) {
if (context.containsArguments(new String[]{"channel"})) {
String arg = context.getArgument("channel"); String arg = context.getArgument("channel");
if(arg == null) {
if (arg == null) {
sendMessage("Es wurde kein channel angegeben."); sendMessage("Es wurde kein channel angegeben.");
return false; return false;
} }
List<TextChannel> channels = YoshiBot.jda.getTextChannelsByName(context.getArgument("channel"), true);
if(channels.isEmpty()) {
List<TextChannel> channels = YoshiBot.getInstance().jda
.getTextChannelsByName(context.getArgument("channel"), true);
if (channels.isEmpty()) {
sendMessage("Der Kanalname konnte nicht gefunden werden."); sendMessage("Der Kanalname konnte nicht gefunden werden.");
return false; return false;
} }
channels.get(0).sendMessage(message).queue(); channels.get(0).sendMessage(message).queue();
}else {
} else {
sendMessage(message); sendMessage(message);
} }
return true; return true;
} }
private String getFromURL(String url) throws IOException {
StringBuilder response = new StringBuilder("");
HttpURLConnection con = null;
try{
con = (HttpURLConnection)(new URL(url)).openConnection();
con.setRequestMethod("GET");
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while((line = br.readLine()) != null) {
response.append(StringEscapeUtils.unescapeHtml4(line));
}
br.close();
}catch(IOException e) {
return null;
}finally {
if(con != null) con.disconnect();
}
return response.toString();
}
private String chuckNorris() { private String chuckNorris() {
String url = "http://api.icndb.com/jokes/random"; String url = "http://api.icndb.com/jokes/random";
JSONObject json = null; JSONObject json = null;
try { try {
String raw = getFromURL(url);
String raw = RestHelper.getFromURL(url);
json = new JSONObject(raw); json = new JSONObject(raw);
return json.getJSONObject("value").getString("joke"); return json.getJSONObject("value").getString("joke");
}catch(JSONException | IOException e) {
} catch (JSONException | IOException e) {
return "Konnte keinen Jokus von \"" + url + "\" laden."; return "Konnte keinen Jokus von \"" + url + "\" laden.";
} }
} }
@ -109,13 +95,13 @@ public class JokeCommand extends YoshiCommand {
JSONObject json = null; JSONObject json = null;
try { try {
String raw = getFromURL(url);
String raw = RestHelper.getFromURL(url);
json = new JSONObject(raw); json = new JSONObject(raw);
String result = json.getString("setup"); String result = json.getString("setup");
result += " - "; result += " - ";
result += json.getString("punchline"); result += json.getString("punchline");
return result; return result;
}catch(JSONException | IOException e) {
} catch (JSONException | IOException e) {
return "Konnte keinen Jokus von \"" + url + "\" laden."; return "Konnte keinen Jokus von \"" + url + "\" laden.";
} }
} }
@ -126,13 +112,13 @@ public class JokeCommand extends YoshiCommand {
JSONObject json = null; JSONObject json = null;
try { try {
String raw = getFromURL(url);
String raw = RestHelper.getFromURL(url);
json = new JSONObject(raw); json = new JSONObject(raw);
String result = json.getString("setup"); String result = json.getString("setup");
result += " - "; result += " - ";
result += json.getString("delivery"); result += json.getString("delivery");
return result; return result;
}catch(JSONException | IOException e) {
} catch (JSONException | IOException e) {
return "Konnte keinen Jokus von \"" + url + "\" laden."; return "Konnte keinen Jokus von \"" + url + "\" laden.";
} }
} }


+ 5
- 3
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/PlayCommand.java View File

@ -23,7 +23,9 @@ public class PlayCommand extends YoshiCommand {
public boolean execute() { public boolean execute() {
if(!super.execute()) return false; if(!super.execute()) return false;
List<VoiceChannel> channels = YoshiBot.jda.getVoiceChannelsByName(context.getArgument("channel"), true);
YoshiBot yoshiBot = YoshiBot.getInstance();
List<VoiceChannel> channels = yoshiBot.jda.getVoiceChannelsByName(context.getArgument("channel"), true);
if(!(channels.size() > 0)) { if(!(channels.size() > 0)) {
context.getEvent().getTextChannel().sendMessage("Der Kanalname konnte nicht gefunden werden.").queue(); context.getEvent().getTextChannel().sendMessage("Der Kanalname konnte nicht gefunden werden.").queue();
return false; return false;
@ -36,9 +38,9 @@ public class PlayCommand extends YoshiCommand {
return false; return false;
} }
AudioController ac = YoshiBot.audioControllerManager.getController(vc.getGuild().getIdLong());
AudioController ac = yoshiBot.audioControllerManager.getController(vc.getGuild().getIdLong());
vc.getGuild().getAudioManager().openAudioConnection(vc); vc.getGuild().getAudioManager().openAudioConnection(vc);
YoshiBot.audioPlayerManager.loadItem(fileName, new AudioLoadResultHandlerImpl(ac));
yoshiBot.audioPlayerManager.loadItem(fileName, new AudioLoadResultHandlerImpl(ac));
return true; return true;
} }


+ 48
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/SauceCommand.java View File

@ -0,0 +1,48 @@
package de.yannicpunktdee.yoshibot.command.commands;
import de.yannicpunktdee.yoshibot.command.YoshiCommand;
import de.yannicpunktdee.yoshibot.command.YoshiCommandContext;
import de.yannicpunktdee.yoshibot.main.SauceProvider;
import net.dv8tion.jda.api.entities.MessageEmbed;
import java.util.List;
public class SauceCommand extends YoshiCommand {
/**
* Erzeugt ein neues Kommando, führt es aber noch nicht aus. Es wird ermittelt, ob die Argumentenkombination valide
* ist und das isOk-Flag gesetzt. Im Fehlerfall wird eine Fehleremeldung spezifiziert.
*
* @param context Der Kontext mit dem das Kommando aufgerufen wurde.
*/
public SauceCommand(YoshiCommandContext context) {
super(context);
}
/**
* {@inheritDoc}
*/
@Override
public boolean execute() {
if (!super.execute()) return false;
if (!context.getEvent().getTextChannel().isNSFW()) {
sendMessage("Dieser Kanal is nix gut, weil vong nsfw her. Geh woanders hin du kek");
return true;
}
List<String> arguments = context.getArguments();
arguments.remove(0);
try {
arguments.stream().map(Integer::parseInt).map(this::byIndex).forEach(this::sendMessage);
} catch (Exception e) {
sendMessage(byTags(arguments));
}
return true;
}
private MessageEmbed byIndex(int index) {
return SauceProvider.getSauce(index);
}
private MessageEmbed byTags(List<String> tags){
return SauceProvider.getRandomSauce(String.join(" ", tags));
}
}

+ 2
- 2
app/src/main/java/de/yannicpunktdee/yoshibot/command/commands/StopCommand.java View File

@ -15,8 +15,8 @@ public class StopCommand extends YoshiCommand {
@Override @Override
public boolean execute() { public boolean execute() {
if(!super.execute()) return false;
YoshiBot.stop();
if (!super.execute()) return false;
YoshiBot.getInstance().stop();
return true; return true;
} }


+ 1
- 1
app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandLine.java View File

@ -22,7 +22,7 @@ public class CommandLine extends Thread implements Runnable {
while((line = reader.readLine()) != null) { while((line = reader.readLine()) != null) {
line = line.trim(); line = line.trim();
if(line.equalsIgnoreCase("exit")) { if(line.equalsIgnoreCase("exit")) {
YoshiBot.stop();
YoshiBot.getInstance().stop();
return; return;
} }
System.out.print("> "); System.out.print("> ");


+ 15
- 11
app/src/main/java/de/yannicpunktdee/yoshibot/listeners/CommandListener.java View File

@ -7,9 +7,12 @@ import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import java.util.Arrays;
/** /**
* Lauscht auf eingehende Nachrichten und leitet diese an die YoshiBot.executeCommand-Methode weiter,
* falls es sich um ein Kommando handelt.
* Lauscht auf eingehende Nachrichten und leitet diese an die YoshiBot.executeCommand-Methode weiter, falls es sich um
* ein Kommando handelt.
*
* @author Yannic Link * @author Yannic Link
*/ */
public class CommandListener extends ListenerAdapter { public class CommandListener extends ListenerAdapter {
@ -17,23 +20,24 @@ public class CommandListener extends ListenerAdapter {
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override public void onMessageReceived(MessageReceivedEvent event) {
if(!event.isFromType(ChannelType.TEXT)) return;
@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (!event.isFromType(ChannelType.TEXT)) return;
if (event.getAuthor().isBot()) return;
if(event.getAuthor().isBot()) return;
boolean inErlaubtemKanal = Arrays.stream(Resources.getRestrictCommandsToChannel())
.anyMatch(channel -> channel.equalsIgnoreCase(event.getTextChannel().getName()));
if(Resources.getRestrictCommandsToChannel() != null
&& !Resources.getRestrictCommandsToChannel().equalsIgnoreCase(event.getTextChannel().getName()))
if (Resources.getRestrictCommandsToChannel() != null && !inErlaubtemKanal)
return; return;
String raw = event.getMessage().getContentRaw().trim(); String raw = event.getMessage().getContentRaw().trim();
if(!raw.startsWith(YoshiCommandContext.PREFIX)) return;
if (!raw.startsWith(YoshiCommandContext.PREFIX)) return;
YoshiCommandContext context = new YoshiCommandContext(raw, event); YoshiCommandContext context = new YoshiCommandContext(raw, event);
if(!context.getState().equals(YoshiCommandContext.State.NO_COMMAND)) YoshiBot.executeCommand(context);
return;
if (!context.getState().equals(YoshiCommandContext.State.NO_COMMAND)) YoshiBot.executeCommand(context);
} }
} }

+ 59
- 21
app/src/main/java/de/yannicpunktdee/yoshibot/main/Resources.java View File

@ -6,7 +6,11 @@ import de.yannicpunktdee.yoshibot.utils.Logger.Type;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.stream.Collectors;
public class Resources { public class Resources {
@ -19,21 +23,25 @@ public class Resources {
private static final String default_audio_source_directory = "rsc/audio/"; private static final String default_audio_source_directory = "rsc/audio/";
private static String audio_source_directory = default_audio_source_directory; private static String audio_source_directory = default_audio_source_directory;
private static final String default_restrict_commands_to_channel = null;
private static String restrict_commands_to_channel = default_restrict_commands_to_channel;
private static final String[] default_restrict_commands_to_channel = null;
private static String[] restrict_commands_to_channel = default_restrict_commands_to_channel;
private static String[] filtered_tags;
private static Map<String, List<String>> feedDetails;
public synchronized static boolean init(String pathToConfig) { public synchronized static boolean init(String pathToConfig) {
Logger.log("Lade Config.properties ...", Type.INFO); Logger.log("Lade Config.properties ...", Type.INFO);
if(pathToConfig != null){
if(!(new File(pathToConfig)).exists()){
if (pathToConfig != null) {
if (!(new File(pathToConfig)).exists()) {
Logger.log("Der in den Argumenten angegebene Pfad zur Config.properties existiert nicht.", Type.ERROR); Logger.log("Der in den Argumenten angegebene Pfad zur Config.properties existiert nicht.", Type.ERROR);
return false; return false;
} }
propertiesFilePath = pathToConfig; propertiesFilePath = pathToConfig;
}else if(!(new File(propertiesFilePath)).exists()){
Logger.log("Es wurde keine Config-Datei über den Pfad \"" + propertiesFilePath + "\" gefunden.", Type.ERROR);
} else if (!(new File(propertiesFilePath)).exists()) {
Logger.log("Es wurde keine Config-Datei über den Pfad \"" + propertiesFilePath + "\" gefunden.",
Type.ERROR);
return false; return false;
} }
@ -41,7 +49,7 @@ public class Resources {
try { try {
propertiesFile.load( propertiesFile.load(
new FileInputStream(propertiesFilePath) new FileInputStream(propertiesFilePath)
);
);
Logger.log("Config-Datei erfolgreich geladen.", Type.INFO); Logger.log("Config-Datei erfolgreich geladen.", Type.INFO);
} catch (IOException e) { } catch (IOException e) {
Logger.log("Es ist ein Fehler beim Öffnen der Config.propeties aufgetreten.", Type.ERROR); Logger.log("Es ist ein Fehler beim Öffnen der Config.propeties aufgetreten.", Type.ERROR);
@ -49,61 +57,91 @@ public class Resources {
} }
boolean isOk = initJdaBuilderString(); boolean isOk = initJdaBuilderString();
if(isOk) isOk = initAudio();
if(isOk) isOk = initChannelRestrict();
if (isOk) isOk = initChannelRestrict();
if (isOk) isOk = initAudio();
initTagFilter();
if(isOk) Logger.log("Die Konfigurationen wurden erfolgreich geladen.", Type.INFO);
if (isOk) Logger.log("Die Konfigurationen wurden erfolgreich geladen.", Type.INFO);
else Logger.log("Die Konfiguration konnte nicht geladen werden", Type.ERROR); else Logger.log("Die Konfiguration konnte nicht geladen werden", Type.ERROR);
return isOk; return isOk;
} }
private static boolean initJdaBuilderString() { private static boolean initJdaBuilderString() {
if(!propertiesFile.containsKey("jda_builder_string")) {
if (!propertiesFile.containsKey("jda_builder_string")) {
Logger.log("Die Config.properties benötigt das Attribut jda_builder_string.", Type.ERROR); Logger.log("Die Config.properties benötigt das Attribut jda_builder_string.", Type.ERROR);
return false; return false;
} }
jda_builder_string = propertiesFile.getProperty("jda_builder_string"); jda_builder_string = propertiesFile.getProperty("jda_builder_string");
return true; return true;
} }
public static String getJdaBuilderString() { public static String getJdaBuilderString() {
return jda_builder_string; return jda_builder_string;
} }
private static void initTagFilter() {
if (!propertiesFile.containsKey("tags_general_filter")) {
Logger.log("Kein Attribut 'tags_general_filter' gefunden", Type.WARNING);
} else {
filtered_tags = propertiesFile.getProperty("tags_general_filter").split(" ");
}
if (!propertiesFile.containsKey("feed_positive_tags")) {
Logger.log("Kein Attribut 'feed_positive_tags' gefunden", Type.WARNING);
} else {
String[] automatedFeeds = propertiesFile.getProperty("feed_positive_tags").split("//");
feedDetails = Arrays.stream(automatedFeeds).map(feedDetail -> feedDetail.split(" "))
.collect(Collectors.toMap(list -> list[0],
list -> Arrays.asList(list).subList(1, list.length)));
}
}
private static boolean initAudio() { private static boolean initAudio() {
if(propertiesFile.containsKey("audio_source_directory")) {
if (propertiesFile.containsKey("audio_source_directory")) {
audio_source_directory = propertiesFile.getProperty("audio_source_directory"); audio_source_directory = propertiesFile.getProperty("audio_source_directory");
}else{
} else {
Logger.log("Die Config.properties spezifiziert kein audio_source_directory. Lade default.", Type.WARNING); Logger.log("Die Config.properties spezifiziert kein audio_source_directory. Lade default.", Type.WARNING);
} }
File file = new File(audio_source_directory); File file = new File(audio_source_directory);
if(!file.exists() || !file.isDirectory()){
if (!file.exists() || !file.isDirectory()) {
Logger.log("Das Audio-Verzeichnis wurde nicht gefunden.", Type.ERROR); Logger.log("Das Audio-Verzeichnis wurde nicht gefunden.", Type.ERROR);
return false; return false;
} }
if(file.listFiles().length < 1)
if (file.listFiles().length < 1)
Logger.log("Das Audio-Verzeichnis ist leer.", Type.WARNING); Logger.log("Das Audio-Verzeichnis ist leer.", Type.WARNING);
return true; return true;
} }
public static String getAudioFilePath(String name) { public static String getAudioFilePath(String name) {
name = audio_source_directory + (audio_source_directory.endsWith("/")? "" : "/") + name + ".opus";
if((new File(name)).exists()) return name;
name = audio_source_directory + (audio_source_directory.endsWith("/") ? "" : "/") + name + ".opus";
if ((new File(name)).exists()) return name;
else return null; else return null;
} }
public static String getAudioSourceDirectory(){
public static String getAudioSourceDirectory() {
return audio_source_directory; return audio_source_directory;
} }
private static boolean initChannelRestrict() { private static boolean initChannelRestrict() {
if(propertiesFile.containsKey("restrict_commands_to_channel"))
restrict_commands_to_channel = propertiesFile.getProperty("restrict_commands_to_channel");
if (propertiesFile.containsKey("restrict_commands_to_channel"))
restrict_commands_to_channel = propertiesFile.getProperty("restrict_commands_to_channel").split(" ");
return true; return true;
} }
public static String getRestrictCommandsToChannel() {
public static String[] getRestrictCommandsToChannel() {
return restrict_commands_to_channel; return restrict_commands_to_channel;
} }
public static Map<String, List<String>> getFeedDetails() {
return feedDetails;
}
public static String[] getGeneralFilterTags() {
return filtered_tags;
}
} }

+ 147
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/main/SauceProvider.java View File

@ -0,0 +1,147 @@
package de.yannicpunktdee.yoshibot.main;
import de.yannicpunktdee.yoshibot.utils.Logger;
import de.yannicpunktdee.yoshibot.utils.RestHelper;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.TextChannel;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
public class SauceProvider {
private static final String BASE_URL = "https://r34-json.herokuapp.com/";
private int lastKnownSauce = -1;
private boolean isSauceInit = false;
public SauceProvider(int timer) {
this();
ScheduledExecutorService sauceScheduler = Executors.newScheduledThreadPool(1);
sauceScheduler.scheduleAtFixedRate(this::provideSauce, 0, timer, TimeUnit.SECONDS);
new Thread(this::initSauceProviding).start();
}
public SauceProvider() {
if (lastKnownSauce == -1) {
this.lastKnownSauce = this.getNewestIndex();
}
}
public static MessageEmbed getSauce(int index) {
String url = BASE_URL + "posts?id=" + index;
JSONObject post = getParsedSauceData(url).getJSONArray("posts").getJSONObject(0);
return makeStringFromJson(post);
}
public static MessageEmbed getRandomSauce(String tags) {
tags = tagsForRest(tags);
tags += String.join("+-", Resources.getGeneralFilterTags());
Random rand = new Random();
String url = BASE_URL + "posts?tags=" + String.join("+", tags);
JSONObject baseObj = getParsedSauceData(url);
int amount = baseObj.getInt("count");
int selectedIndex = rand.nextInt(amount);
int page = (selectedIndex / 100) % 100;
int pageIndex = selectedIndex % 100;
String pagedUrl = url + "&pid=" + page;
JSONObject post = Objects.requireNonNull(getParsedSauceData(pagedUrl)).getJSONArray("posts")
.getJSONObject(pageIndex);
return makeStringFromJson(post);
}
private static MessageEmbed makeStringFromJson(JSONObject post) {
EmbedBuilder eb = new EmbedBuilder();
eb.setTitle("Soße").setDescription("URL: " + post.getString("file_url"));
eb.addField("ID", post.getString("id"), false);
eb.addField("Tags", "`" + post.getJSONArray("tags").join("` `") + "`", false);
eb.setImage(post.getString("file_url"));
return eb.build();
}
private void provideSauce() {
if (!isSauceInit) return;
for (Map.Entry<String, List<String>> feed : Resources.getFeedDetails().entrySet()) {
String url = BASE_URL + "posts?tags=" + String.join("+", feed.getValue())
+ "+" + String.join("+", Resources.getGeneralFilterTags());
JSONArray posts = getParsedSauceData(url).getJSONArray("posts");
assert posts != null;
List<JSONObject> postsInternal =
StreamSupport.stream(posts.spliterator(), false)
.map(obj -> (JSONObject) obj)
.filter(obj -> obj.getInt("id") > lastKnownSauce)
.collect(Collectors.toList());
Collections.reverse(postsInternal);
YoshiBot yoshiBot = YoshiBot.getInstance();
for (JSONObject post : postsInternal) {
yoshiBot.jda.getTextChannelsByName(feed.getKey(), true).get(0)
.sendMessage(makeStringFromJson(post)).queue();
}
Logger.log(String.format("Found %d posts for feed '%s'", postsInternal.size(), feed.getKey()),
Logger.Type.INFO);
}
lastKnownSauce = this.getNewestIndex();
}
private void initSauceProviding() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
YoshiBot yoshiBot = YoshiBot.getInstance();
for (Map.Entry<String, List<String>> entry : Resources.getFeedDetails().entrySet()) {
List<TextChannel> channels = yoshiBot.jda.getTextChannelsByName(entry.getKey(), true);
if (channels.size() > 0) {
this.isSauceInit = true;
this.provideSauce();
} else {
Logger.log("Konnte keine Kanaäle finden für die Soße", Logger.Type.ERROR);
}
}
}
private int getNewestIndex() {
JSONObject result = getParsedSauceData("https://r34-json.herokuapp.com/posts?limit=1&q=index");
return result.getJSONArray("posts").getJSONObject(0).getInt("id");
}
private static JSONObject getParsedSauceData(String url) {
String raw = null;
try {
raw = RestHelper.getFromURL(url);
} catch (IOException e) {
e.printStackTrace();
}
assert raw != null;
return new JSONObject(raw);
}
private static String tagsForRest(String tags) {
char[] chars = tags.toCharArray();
for (int i = 1; i < chars.length - 1; i++) {
if (chars[i] == ' ') {
if (chars[i - 1] != '(' && chars[i + 1] != ')' && chars[i - 1] != '~' && chars[i + 1] != '~') {
chars[i] = '\t';
}
}
}
String result = new String(chars);
result = result.replace(" ", "%20").replace("\t", "+");
return result;
}
}

+ 3
- 2
app/src/main/java/de/yannicpunktdee/yoshibot/main/YoshiBot.java View File

@ -76,13 +76,14 @@ public class YoshiBot {
jda = jdaBuilder.build(); jda = jdaBuilder.build();
jdaBuilder.setActivity(Activity.playing("Haare waschen."));
jdaBuilder.setStatus(OnlineStatus.ONLINE);
jdaBuilder.setStatus(OnlineStatus.ONLINE).setActivity(Activity.playing("Haare waschen."));
System.out.println("YoshiBot online."); System.out.println("YoshiBot online.");
commandLineThread = new CommandLine(); commandLineThread = new CommandLine();
commandLineThread.start(); commandLineThread.start();
SauceProvider provider = new SauceProvider(300);
} }
public synchronized void stop() { public synchronized void stop() {


+ 38
- 0
app/src/main/java/de/yannicpunktdee/yoshibot/utils/RestHelper.java View File

@ -0,0 +1,38 @@
package de.yannicpunktdee.yoshibot.utils;
import org.apache.commons.lang3.StringEscapeUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public final class RestHelper {
public static String getFromURL(String url) throws IOException {
StringBuilder response = new StringBuilder("");
HttpURLConnection con = null;
try {
con = (HttpURLConnection) (new URL(url)).openConnection();
con.setRequestMethod("GET");
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
response.append(StringEscapeUtils.unescapeHtml4(line));
}
br.close();
} catch (IOException e) {
return null;
} finally {
if (con != null) con.disconnect();
}
return response.toString();
}
}

+ 0
- 0
gradlew View File


Loading…
Cancel
Save