überarbeitung Code und hinzufügen Auto Favo für neue Storys

This commit is contained in:
Ocame
2024-09-09 21:25:02 +02:00
parent 418efd2f47
commit c7a9a84dac
16 changed files with 579 additions and 515 deletions

View File

@ -5,7 +5,7 @@ plugins {
application.mainClass = "de.ocame.ffdiscordbot.Main"
group 'de.ocame'
version '1.1-SNAPSHOT'
version '1.2-SNAPSHOT'
repositories {

View File

@ -29,4 +29,12 @@ public class ConfigLoader {
return properties.getProperty("ff.password");
}
public String getFfFavList() {
return properties.getProperty("ff.favList");
}
public Long getDebugChannel() {
return Long.parseLong(properties.getProperty("debug.Channel"));
}
}

View File

@ -0,0 +1,5 @@
package de.ocame.ffdiscordbot;
public record DataChapter(String name, String link, String storyId, long date, long number) {
}

View File

@ -0,0 +1,5 @@
package de.ocame.ffdiscordbot;
public record DataStory(String name, String link, String ffid, long date, String author, Integer tagId) {
}

View File

@ -1,242 +0,0 @@
package de.ocame.ffdiscordbot;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import java.awt.*;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
public class DiscordOutput {
private final List<StoryOutputText> chapterText;
public DiscordOutput() {
chapterText = new ArrayList<>();
chapterText.add(new StoryOutputText(
"Oh, wie mein Herz singt! **%autor%** hat ein neues Kapitel unserer Geschichte \"**%storyName%**\" geschrieben, " +
"und es heißt \"**%chapterName%**\". \n\nIch spüre die Aufregung in der Luft, als ob jeder Flügelschlag mich höher trägt. " +
"Die Welt leuchtet in neuen Farben, und jeder Sonnenstrahl erzählt von Abenteuern, die uns erwarten. Dieses Kapitel " +
"verspricht so viel ich kann es kaum erwarten, in die Worte zu tauchen und die Geschichten, die sie verbergen, " +
"zu entdecken!"
, "https://media.discordapp.net/stickers/1219043798101786624.webp?size=160"));
chapterText.add(new StoryOutputText(
"Aye, Text in Sicht, ihr Seeratten! **%autor%** hat ein neues Kapitel in der Geschichte \"**%storyName%**\" aufgetan, und " +
"es trägt den Namen \"**%chapterName%**\". Macht die Fässer klar, holt die besten Getränke, und besetzt die Bildschirme! \n" +
"Keiner rührt sich, bis wir jedes Wort gelesen haben, verstanden? Und hört gut hin: Wer es wagt, auch nur ein Wort " +
"zu spoilern, wird schneller gekielholt, als er \"Piratenkodex\" sagen kann! Jetzt aber volle Fahrt voraus das " +
"Abenteuer ruft!", "https://cdn.discordapp.com/attachments/542202034330271759/1272999183673987133/image.png?ex=66bd0460&is=66bbb2e0&hm=708f10708d0616ed212d0c288cfde503fb27785ddd68c1ba30bb4d3f7698acee&"));
chapterText.add(new StoryOutputText(
"Mesdames et Messieurs, heute habe ich die Ehre, Ihnen ein exquisites Gericht zu präsentieren: " +
"das \"**%chapterName%**\" à la \"**%storyName%**\", nach der feinen Art unseres geschätzten Chef-Autors \"**%autor%**\". \n" +
"Es ist ein Meisterwerk der literarischen Küche, perfekt gewürzt mit Spannung und serviert mit einer Prise Abenteuer. " +
"Lassen Sie sich von den Aromen dieser neuen Geschichte verführen und genießen Sie jeden Bissen bon appétit!",
"https://cdn.discordapp.com/attachments/542202034330271759/1272999507587629188/image.png?ex=66bd04ad&is=66bbb32d&hm=d4d7325f233c27a75305ee9622c9f87b03e1aa507acb534c2fd6c3de62d435d1&",
new Color(255, 0, 229)));
chapterText.add(new StoryOutputText(
"........................\n " +
"........................\n " +
"........................\n " +
"........................\n " +
"Na los, Grünschnabel, hör auf zu trödeln und lies endlich das neue Kapitel \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" " +
"vom \"**%autor%**\" vor! Meine Zeit ist nicht unendlich, und ich hab keine Lust, hier ewig zu warten. Also mach schon, bevor ich " +
"noch selbst anfangen muss, die Seiten zu ertasten!"
));
chapterText.add(new StoryOutputText(
"Das neue Kapitel \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" vom \"**%autor%**\" ist erschienen, und ich werde es als Erster lesen. " +
"Während die Piraten noch ihren Rum genießen, verschaffe ich mir den Wissensvorsprung. Mit jedem Satz, den ich lese, " +
"wird meine Strategie schärfer, und bald werde ich ihnen einen Schritt voraus sein. Ein kluger Kopf gewinnt schließlich immer " +
"das Spiel.",
"https://cdn.discordapp.com/attachments/542202034330271759/1273002039923965952/image.png?ex=66bd0709&is=66bbb589&hm=77130cbe420a9e941e58e68010c12cc2e53c54c288b8563fd6a1a856ffebd0df&"
));
chapterText.add(new StoryOutputText(
"hcilrütan ebah hci sad etseuen Letipak nohcs neseleg \n\n" +
"Erika Rückwerts die Worte auszuprechen ist kein Reptiloidisch!\n\n" +
"Menschen! Natürlich habe ich das neueste Kapitel schon gelesen. Kein Zweifel, es ist genauso grandios, " +
"wie ich es erwartet habe. Jede Wendung, jeder Dialog einfach meisterhaft. Und falls du es wissen willst: Es handelt sich " +
"um \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" vom Autor \"**%autor%**\". Wenn du wirklich etwas Gutes lesen willst, dann ist das genau das " +
"Richtige für dich. Aber hey, das hab ich ja gleich gewusst.",
"https://cdn.discordapp.com/attachments/542202034330271759/1273005878974349313/image.png?ex=66bd0a9c&is=66bbb91c&hm=8e7701f259b7bd84ea3b91b5c8fb63c4b8807dd297a05fc9289aead8c1978fac&",
new Color(40, 145, 6)
));
chapterText.add(new StoryOutputText(
"Ah, wie wunderbar! Endlich halte ich das neue Kapitel \"**%chapterName%**\" aus der Geschichte \"**%storyName%**\" " +
"vom \"**%autor%**\" in den Händen. Ein wahres Vergnügen für den Geist! Und bitte, meine Lieben, lasst den Kronleuchter in Ruhe. " +
"Er spendet gerade das perfekte Licht zum Lesen eine solch erhabene Lektüre verdient schließlich die besten Bedingungen."
));
chapterText.add(new StoryOutputText("Ich habe die Zukunft gesehen, und glaub mir, das neue Kapitel von \"**%chapterName%**\" aus der Geschichte " +
"\"**%storyName%**\" vom \"**%autor%**\" ist etwas ganz Besonderes. Es ist, als ob die Worte selbst eine Melodie singen, die so sanft und " +
"doch so kraftvoll ist, dass sie dich mitreißt, egal wohin sie dich führt. Jedes Wort, jede Zeile sie fließen wie ein ruhiger " +
"Fluss, der dich in eine Welt entführt, die so fesselnd und lebendig ist, dass du alles um dich herum vergisst.\n" +
"\n" +
"Es ist wie der erste Schluck eines perfekt gebrühten Tees, dieser Moment, in dem sich die Wärme in deinem Körper ausbreitet " +
"und du spürst, wie jeder Tropfen dich beruhigt und gleichzeitig belebt. Ach, Tee... Was für ein wunderbares Getränk, nicht wahr? " +
"So viel Sorgfalt und Liebe steckt in jeder Tasse, genau wie in diesen Worten, die ich gerade gelesen habe. Die Teeblätter, " +
"die mit so viel Bedacht und Geduld gepflückt werden, erinnern mich an die frischen Pflanzen im Frühling, wenn alles grünt und blüht. " +
"Sie sind voller Leben, voller Möglichkeiten, genau wie die Geschichten, die uns erzählen, wohin unser Weg führen könnte.\n" +
"\n" +
"Wie wunderschön es doch ist, in solchen einfachen Freuden Trost zu finden sei es in einem guten Buch, einer heißen Tasse Tee oder dem " +
"Anblick von Pflanzen, die in ihrer vollen Pracht stehen. Manchmal sind es gerade diese kleinen, stillen Momente, die das Leben wirklich " +
"lebenswert machen."));
}
public void newChapter(JDA jda, DataChapter chapter, DataStory story) {
newChapter(jda, chapter, story, null, null);
}
public void newChapter(JDA jda, DataChapter chapter, DataStory story, Integer version, Long tagetChannel) {
try {
String message;
EmbedBuilder outputBox = new EmbedBuilder();
outputBox.setTitle("Neues Kapitel:", chapter.link());
List<StoryOutputText> chapterTexte;
if(version != null) {
chapterTexte = SQLiteStorage.getChapterTexte(version);
}
else {
chapterTexte = SQLiteStorage.getChapterTexte(story);
}
StoryOutputText versionText = null;
if(chapterTexte.size() == 0)
return;
Random random = new Random();
versionText = chapterTexte.get(random.nextInt(chapterTexte.size()));
message = versionText.getMessage();
message = message.replace("%chapterName%", "**" + chapter.name() + "**")
.replace("%storyName%", "**" + story.name() + "**")
.replace("%autor%", "**" + story.author() + "**");
outputBox.setDescription(message);
outputBox.setColor(versionText.getColor());
Instant instant = Instant.ofEpochSecond(chapter.date());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy HH:mm 'Uhr'");
outputBox.setFooter("Veröffentlicht am " + dateTime.format(formatter));
if(versionText.getImage() != null && !Objects.equals(versionText.getImage(), ""))
outputBox.setThumbnail(versionText.getImage());
Long[] channelIds = SQLiteStorage.getChannelIds();
if(tagetChannel != null) {
Objects.requireNonNull(jda.getTextChannelById(tagetChannel))
.sendMessage("Hier ist ein Text vor dem Embed <@&423156046115242005> :")
.setEmbeds(outputBox.build())
.queue();
}
else if(Objects.requireNonNull(channelIds).length == 0) {
Objects.requireNonNull(jda.getTextChannelById(542202034330271759L)).sendMessageEmbeds(outputBox.build()).queue();
}
else {
for (Long channelId : channelIds ) {
try {
if (Objects.requireNonNull(jda.getTextChannelById(channelId)).canTalk())
Objects.requireNonNull(jda.getTextChannelById(channelId)).sendMessageEmbeds(outputBox.build()).queue();
}
catch (NullPointerException e) {
//
}
}
}
}
catch (NumberFormatException e) {
//jda.getTextChannelById(channelId).sendMessage("Nope").queue();
System.out.println("problem: " + e.getMessage());
}
catch (Exception e) {
System.out.println("problem: " + e.getMessage());
}
}
public void newStory(JDA jda, DataStory story) {
newStory(jda, story, null);
}
public void newStory(JDA jda, DataStory story, Integer version) {
try {
String message;
EmbedBuilder outputBox = new EmbedBuilder();
outputBox.setTitle("Neue Gesichte:", story.link());
List<StoryOutputText> storyTexte = SQLiteStorage.getStoryTexte();
StoryOutputText versionText = null;
if(storyTexte.size() == 0)
return;
if(version != null) {
versionText = storyTexte.get(version);
}
if(version == null || versionText == null) {
Random random = new Random();
versionText = storyTexte.get(random.nextInt(storyTexte.size()));
}
message = versionText.getMessage();
message = message.replace("%storyName%", "**" + story.name() + "**")
.replace("%autor%", "**" + story.author() + "**");
outputBox.setDescription(message);
outputBox.setColor(versionText.getColor());
Instant instant = Instant.ofEpochSecond(story.date());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy HH:mm 'Uhr'");
outputBox.setFooter("Veröffentlicht am " + dateTime.format(formatter));
if(versionText.getImage() != null && !Objects.equals(versionText.getImage(), ""))
outputBox.setThumbnail(versionText.getImage());
Long[] channelIds = SQLiteStorage.getChannelIds();
if(channelIds.length == 0) {
jda.getTextChannelById(542202034330271759L).sendMessageEmbeds(outputBox.build()).queue();
}
else {
for (Long channelId : channelIds ) {
try {
if (jda.getTextChannelById(channelId).canTalk())
jda.getTextChannelById(channelId).sendMessageEmbeds(outputBox.build())
.queue();
}
catch (NullPointerException e) {
//
}
}
}
}
catch (NumberFormatException e) {
//jda.getTextChannelById(channelId).sendMessage("Nope").queue();
}
catch (NullPointerException e ) {
//
}
catch (Exception e) {
System.out.println("problem: " + e.getMessage());
}
}
}

View File

@ -1,69 +1,60 @@
package de.ocame.ffdiscordbot;
import de.ocame.ffdiscordbot.fetcher.DefaultHtmlFetcher;
import de.ocame.ffdiscordbot.output.ChapterNotifier;
import de.ocame.ffdiscordbot.output.InfoNotifier;
import de.ocame.ffdiscordbot.output.StoryNotifier;
import net.dv8tion.jda.api.JDA;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.Instant;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FanFiktionReader {
private final HtmlFetcher fetcher;
private final DiscordOutput dco;
private final DefaultHtmlFetcher fetcher; // Use the HtmlFetcher interface
private final JDA jda;
private long time = 30*60;
private long time = 30 * 60;
private final String URL = "https://www.fanfiktion.de";
public FanFiktionReader(JDA jda) {
fetcher = new HtmlFetcher();
this.fetcher = new DefaultHtmlFetcher();
SQLiteStorage.createTable();
dco = new DiscordOutput();
this.jda = jda;
}
/**
* Liest neue Ereignse von der Alert Seite aus
* Liest neue Ereignse von der Alert-Seite aus
*/
public void checkAlerts() {
try {
String alertURL = "https://www.fanfiktion.de/?a=i";
Document alertPage = fetcher.fetchURL(alertURL);
// Login Check
Elements title = alertPage.getElementsByTag("title");
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
login();
alertPage = fetcher.fetchURL(alertURL);
title = alertPage.getElementsByTag("title");
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
// Fehler
return;
}
}
Document alertPage = fetchHTMLWithAuthentication(URL + "/?a=i");
if (alertPage == null)
return;
// Story Check
Element authorBox = alertPage.getElementById("ffcbox-alerts_author-box");
if(authorBox != null) {
if (authorBox != null) {
Elements rows = authorBox.select("table tbody tr");
for (Element row : rows) {
checkNewStoryFromAlert(row);
@ -72,7 +63,7 @@ public class FanFiktionReader {
// Kapitel Check
Element StoryBox = alertPage.getElementById("ffcbox-alerts_story-box");
if(StoryBox != null) {
if (StoryBox != null) {
Elements rows = StoryBox.select("table tbody tr");
for (Element row : rows) {
@ -80,20 +71,19 @@ public class FanFiktionReader {
if (cols.size() >= 2) {
Element link = cols.get(1).selectFirst("a");
String linkHref = (link != null) ? link.attr("href") : "No link";
String chaptertime = cols.get(6).text();
String chaptertime = cols.get(5).text();
long chapterUnixtime = DateToTimestamp(chaptertime);
Element delLink = cols.last().selectFirst("a");
String delLinkHref = (delLink != null) ? delLink.attr("href") : "No link";
checkNewChapter("https://www.fanfiktion.de" + linkHref, chapterUnixtime);
checkNewChapter(URL + linkHref, chapterUnixtime);
// Ausführung des Links, um Inhalt aus Alert zu entfernen
try {
if(!delLinkHref.equals("No link"))
fetcher.fetchURL("https://www.fanfiktion.de" + delLinkHref);
}
catch (IOException | InterruptedException | URISyntaxException e) {
if (!delLinkHref.equals("No link"))
fetcher.fetchHtml(URL + delLinkHref);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
@ -101,16 +91,15 @@ public class FanFiktionReader {
}
}
}
catch (IOException | InterruptedException | URISyntaxException e) {
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Random random = new Random();
this.time = random.nextLong(24*60,34*60);
this.time = random.nextLong(24 * 60, 34 * 60);
}
/**
* Liest neue Storys von der Alarm Seite aus
* Liest neue Storys von der Alarm-Seite aus
*
* @param row
*/
@ -125,24 +114,22 @@ public class FanFiktionReader {
Element link = cols.get(1).selectFirst("a");
String linkHref = (link != null) ? link.attr("href") : "No link";
String[] hrefElements = linkHref.split("/s/",2);
String[] hrefElements = linkHref.split("/s/", 2);
String storyId = hrefElements[1];
if(!SQLiteStorage.checkStory(storyId)) {
/* todo: neue Story gefunden Ausgabe */
DataStory newStory = new DataStory(storyName, "https://www.fanfiktion.de/s/" + storyId, storyId,storyUnixtime,storyAutor, 0);
if (SQLiteStorage.isStoryInvalid(storyId)) {
DataStory newStory = new DataStory(storyName, URL + "/s/" + storyId, storyId, storyUnixtime, storyAutor, 0);
SQLiteStorage.insertStorys(newStory);
dco.newStory(jda, newStory);
new StoryNotifier(jda, newStory).sendOutput();
addStoryToFavorit(storyId);
}
Element delLink = cols.last().selectFirst("a");
String delLinkHref = (delLink != null) ? delLink.attr("href") : "No link";
// Ausführung des Links, um Inhalt aus Alert zu entfernen
try {
if(!delLinkHref.equals("No link"))
fetcher.fetchURL("https://www.fanfiktion.de" + delLinkHref);
}
catch (IOException | InterruptedException | URISyntaxException e) {
if (!delLinkHref.equals("No link"))
fetcher.fetchHtml(URL + delLinkHref);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
@ -157,29 +144,21 @@ public class FanFiktionReader {
public void checkNewChapter(String url, long chapterDate) {
try {
// Login Check
Document storyPage = fetcher.fetchURL(url);
Elements title = storyPage.getElementsByTag("title");
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
login();
storyPage = fetcher.fetchURL(url);
title = storyPage.getElementsByTag("title");
if(title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
// Fehler
return;
}
}
Document storyPage = fetchHTMLWithAuthentication(url);
if (storyPage == null)
return;
// Auswahl Select für Kapitel Auswahl
Element chapterSelect = storyPage.getElementById("kA");
if(chapterSelect != null) {
if (chapterSelect != null) {
Elements options = storyPage.select("option");
String chapterName = options.last().text();
String chapterNumer = options.last().attr("value");
String onChange = chapterSelect.attributes().get("onchange")
.replace("location.href = '" , "")
.replace("' + this.value + '" , chapterNumer)
.replace("'" , "");
.replace("location.href = '", "")
.replace("' + this.value + '", chapterNumer)
.replace("'", "");
// Regulärer Ausdruck für die ffid nach /s/
String regex = "/s/([a-zA-Z0-9]+)/";
@ -193,26 +172,26 @@ public class FanFiktionReader {
// todo: fehler behandlung
}
if(SQLiteStorage.checkChapter(ffid, Long.parseLong(chapterNumer))) {
if (!SQLiteStorage.checkChapter(ffid, Long.parseLong(chapterNumer))) {
/* todo: neue Chapter gefunden Ausgabe */
if(!SQLiteStorage.checkStory(ffid)) {
readandSaveStory(storyPage);
if (SQLiteStorage.isStoryInvalid(ffid)) {
readandSaveStory(storyPage);
}
DataStory ds = SQLiteStorage.getStory(ffid);
DataChapter newChapter = new DataChapter(chapterName, "https://www.fanfiktion.de" + onChange, ffid, chapterDate, Long.parseLong(chapterNumer));
DataChapter newChapter = new DataChapter(chapterName, URL + onChange, ffid, chapterDate, Long.parseLong(chapterNumer));
SQLiteStorage.insertChapter(newChapter);
//clearChapter();
dco.newChapter(jda, newChapter, ds);
new ChapterNotifier(jda, newChapter, ds).sendOutput();
}
}
}
catch (IOException | InterruptedException | URISyntaxException e) {
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
/**
* List alle Infos aus einer Story Seite aus, um das relevante zu speichern
*
* @param storyPage
*/
public void readandSaveStory(Document storyPage) {
@ -231,22 +210,24 @@ public class FanFiktionReader {
if (matcher.find()) {
// Die gefundene Nummernfolge ausgeben
ffid = matcher.group(1);
} else {
}
else {
// todo: fehler behandlung
return;
}
if(!SQLiteStorage.checkStory(ffid)) {
DataStory newStory = new DataStory(storyName, "https://www.fanfiktion.de/s/" + ffid, ffid, storyUnixtime, storyAutor, 0);
if (SQLiteStorage.isStoryInvalid(ffid)) {
DataStory newStory = new DataStory(storyName, URL + "/s/" + ffid, ffid, storyUnixtime, storyAutor, 0);
SQLiteStorage.insertStorys(newStory);
addStoryToFavorit(ffid);
}
}
public void outputCheapterTester(int chapterId, String chapterTextTitle, String storyTitle, String autor, Long tagetChannel) {
DataStory ds = new DataStory(storyTitle, "https://www.fanfiktion.de", "", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC), autor, 0);
DataChapter dc = new DataChapter(chapterTextTitle, "https://www.fanfiktion.de", "", LocalDateTime.now().toEpochSecond(ZoneOffset.UTC), 1);
dco.newChapter(jda, dc, ds, chapterId, tagetChannel);
DataStory ds = new DataStory(storyTitle, URL, "", Instant.now().getEpochSecond(), autor, 0);
DataChapter dc = new DataChapter(chapterTextTitle, URL, "", Instant.now().getEpochSecond(), 1);
new ChapterNotifier(jda, dc, ds).setVersion(chapterId).sendOutput(tagetChannel);
}
/**
@ -257,19 +238,23 @@ public class FanFiktionReader {
*/
public long DateToTimestamp(String dateString) {
//dateString = "02.08.2024 | 21:21 Uhr";
//dateString = "02.08.2024 | 21:21 Uhr";
// Definiere das Datumsformat
//DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy | HH:mm 'Uhr'").withResolverStyle(ResolverStyle.STRICT);
//DateTimeFormatter formatteralternativ = DateTimeFormatter.ofPattern("dd.MM.yyyy'");
// Definiere das Datumsformat
//DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy | HH:mm 'Uhr'").withResolverStyle(ResolverStyle.STRICT);
//DateTimeFormatter formatteralternativ = DateTimeFormatter.ofPattern("dd.MM.yyyy'");
String[] patterns = {"dd.MM.yyyy | HH:mm 'Uhr'" , "dd.MM.yyyy'", "dd.MM.yyyy HH:mm'"};
LocalDateTime dateTime = parseDateTimeWithMultiplePatterns(dateString, patterns);
if(dateTime == null || dateTime.toEpochSecond(ZoneOffset.UTC) == 0) {
return 0;
}
else
return dateTime.toEpochSecond(ZoneOffset.UTC);
String[] patterns = {"dd.MM.yyyy | HH:mm 'Uhr'", "dd.MM.yyyy'", "dd.MM.yyyy HH:mm'"};
LocalDateTime dateTime = parseDateTimeWithMultiplePatterns(dateString, patterns);
if (dateTime == null || dateTime.toEpochSecond(ZoneOffset.UTC) == 0) {
return 0;
} else {
ZoneId zoneId = ZoneId.of("Europe/Berlin");
ZonedDateTime zonedDateTime = dateTime.atZone(zoneId);
Instant instant = zonedDateTime.toInstant();
return instant.getEpochSecond();
}
}
@ -290,24 +275,25 @@ public class FanFiktionReader {
* Führt den Login aus
*/
public void login() {
System.out.print("Login muss ausgeführt werden");
try {
ConfigLoader configLoader = new ConfigLoader();
String loginURL = "https://www.fanfiktion.de/?a=l";
Document logintPage = fetcher.fetchURL(loginURL);
String loginURL = URL + "/?a=l";
Document logintPage = fetcher.fetchHtml(loginURL);
Elements nameBox = logintPage.select ("input[name='nickname']");
Elements pwBox = logintPage.select ("input[name='passwd']");
Elements nameBox = logintPage.select("input[name='nickname']");
Elements pwBox = logintPage.select("input[name='passwd']");
if(nameBox.isEmpty()) {
// todo: Fehler wenn Login nicht geht
if (nameBox.isEmpty()) {
time += 2 * 60 * 60; // Zeit um 2h erhöhen
new InfoNotifier(jda).setMessagetext("Login Fehlgeschlagen").sendOutput();
}
Elements aBox = logintPage.select ("input[name='a']");
Elements uBox = logintPage.select ("input[name='u']");
Elements aBox = logintPage.select("input[name='a']");
Elements uBox = logintPage.select("input[name='u']");
String uValue = fetcher.getCookieValue("https://www.fanfiktion.de/", "u");
String uValue = fetcher.getCookieValue(URL, "u");
uValue = java.net.URLDecoder.decode(uValue, StandardCharsets.UTF_8);
String ffNickname = configLoader.getUsername();
@ -319,16 +305,15 @@ public class FanFiktionReader {
+ "&savelogindata=" + java.net.URLEncoder.encode("1", StandardCharsets.UTF_8);
Document loginRequest = fetcher.fetchHtml(URL, postData);
nameBox = loginRequest.select("input[name='nickname']");
Document loginRequest = fetcher.fetchURL("https://www.fanfiktion.de/", postData);
nameBox = loginRequest.select ("input[name='nickname']");
if(!nameBox.isEmpty()) {
// todo: Fehler wenn Login nicht geht
if (!nameBox.isEmpty()) {
time += 2 * 60 * 60; // Zeit um 2h erhöhen
new InfoNotifier(jda).setMessagetext("Login Fehlgeschlagen").sendOutput();
}
}
catch (IOException | InterruptedException | URISyntaxException e) {
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
@ -339,23 +324,45 @@ public class FanFiktionReader {
return time;
}
public void clearChapter(String url) {
try {
Document storyPage = fetcher.fetchURL(url);
Elements title = storyPage.getElementsByTag("title");
if (title.first().text().contains("keine Berechtigung!")) {
login();
storyPage = fetcher.fetchURL(url);
title = storyPage.getElementsByTag("title");
if (title.first().text().contains("keine Berechtigung!")) {
// Fehler
return;
}
public Document fetchHTMLWithAuthentication(String alertURL) throws IOException, InterruptedException {
Document alertPage = fetcher.fetchHtml(alertURL);
// Login Check
Elements title = alertPage.getElementsByTag("title");
if (title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
login();
alertPage = fetcher.fetchHtml(alertURL);
title = alertPage.getElementsByTag("title");
if (title.first().text().contains("keine Berechtigung!") || title.first().text().contains("Session-Error") || title.first().text().contains("Login")) {
// Fehler
return null;
}
}
catch (IOException | InterruptedException | URISyntaxException e) {
e.printStackTrace();
return alertPage;
}
public void addStoryToFavorit(String ffid) {
ConfigLoader configLoader = new ConfigLoader();
String ffFavList = configLoader.getFfFavList();
String postData = "storyid=" + java.net.URLEncoder.encode(ffid, StandardCharsets.UTF_8)
+ "&favlist=" + java.net.URLEncoder.encode(ffFavList, StandardCharsets.UTF_8)
+ "&alert=1";
try {
Document sendToFav = fetcher.fetchHtml(URL + "/?a=q&a1=v&t=addstory&lbi=popup-addtofav-body&ar=1&action=i", postData);
if(sendToFav.getElementsByClass("successbox").isEmpty()) {
System.out.print("Story konnte nicht hinzugefügt werden");
new InfoNotifier(jda).setMessagetext("Story " + ffid + "konnte nicht hinzugefügt werden. \n" + sendToFav.toString()).sendOutput();
}
}
catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@ -5,7 +5,6 @@ import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.requests.GatewayIntent;
import org.jsoup.nodes.Document;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@ -19,9 +18,6 @@ public class Main {
ConfigLoader configLoader = new ConfigLoader();
// Insert your bot's token here
//String token = "MTI3NzcxNTQ1NTI1MDkyMzU4MA.GUuRyh.07mjVRcI7MhLHo-Wdnytvxlb3Pts-hfRaNMaPA";
// iro
String token = configLoader.getToken();
/**/
JDA jda = JDABuilder.createDefault(token)
@ -33,7 +29,8 @@ public class Main {
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
}
catch (InterruptedException e) {
}
FanFiktionReader ffr = new FanFiktionReader(jda);
@ -43,7 +40,7 @@ public class Main {
socketThread.start();
//ffr.checkAlerts();
ffr.checkAlerts();
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final long[] delay = {30 * 60};
@ -52,7 +49,7 @@ public class Main {
Runnable task = new Runnable() {
@Override
public void run() {
//ffr.checkAlerts();
ffr.checkAlerts();
// Berechne das neue Intervall basierend auf ffr.getTime()
delay[0] = ffr.getTime();
@ -64,8 +61,6 @@ public class Main {
// Plane die erste Ausführung der Aufgabe
scheduledFuture.set(scheduler.schedule(task, delay[0], TimeUnit.SECONDS));
}
}

View File

@ -2,23 +2,23 @@ package de.ocame.ffdiscordbot;
import java.awt.*;
public class StoryOutputText {
public class OutputContentElement {
private final String message;
private final String image;
private final Color color;
public StoryOutputText(String message) {
public OutputContentElement(String message) {
this.message = message;
this.image = null;
this.color = new Color(36, 153, 245);
}
public StoryOutputText(String message, String image) {
public OutputContentElement(String message, String image) {
this.message = message;
this.image = image;
this.color = new Color(36, 153, 245);
}
public StoryOutputText(String message, String image, Color color) {
public OutputContentElement(String message, String image, Color color) {
this.message = message;
this.image = image;
this.color = color;

View File

@ -123,7 +123,7 @@ public class SQLiteStorage {
}
public static boolean checkStory(String ffid) {
public static boolean isStoryInvalid(String ffid) {
String sql = "SELECT COUNT(*) FROM Storys WHERE ffid = ?";
@ -132,13 +132,13 @@ public class SQLiteStorage {
if (rs.next()) {
int count = rs.getInt(1);
return count > 0; // Gibt true zurück, wenn die ID existiert, sonst false
return count <= 0; // Gibt true zurück, wenn die ID existiert, sonst false
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return false;
return true;
}
public static boolean checkChapter(String ffid, long number) {
@ -215,25 +215,6 @@ public class SQLiteStorage {
}
}
public static void main(String[] args) {
createTable();
/* DataStory record1 = new DataStory("Text 1", "https://link1.com", "Text 2");
DataStory record2 = new DataStory("Text 3", "https://link2.com", "Text 4");
// Insert data into SQLite
insertData(record1);
insertData(record2);
// Load data from SQLite
List<DataStory> loadedData = loadData();
for (DataStory record : loadedData) {
System.out.println(record);
}
}*/
}
private static int executeUpdateWithRetry(Connection conn, String sql, Object... params) throws SQLException {
int attempt = 0;
boolean success = false;
@ -291,11 +272,13 @@ public class SQLiteStorage {
System.out.println("Datenbank gesperrt, versuche erneut... (Versuch " + attempt + " von " + MAX_RETRIES + ")");
try {
Thread.sleep(RETRY_WAIT_TIME_MS);
} catch (InterruptedException ie) {
}
catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new SQLException("Der Thread wurde unterbrochen.", ie);
}
} else {
}
else {
throw e; // Andere SQL-Fehler weiterwerfen
}
}
@ -328,13 +311,14 @@ public class SQLiteStorage {
}
return null;
}
} catch (SQLException e) {
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
return null;
}
public static List<StoryOutputText> getChapterTexte(DataStory ds) {
public static List<OutputContentElement> getChapterTexte(DataStory ds) {
String sql = """
SELECT\s
CT.id,
@ -359,10 +343,10 @@ public class SQLiteStorage {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
ResultSet rs = executeQueryWithRetry(conn, sql, ds.tagId());
List<StoryOutputText> outputList = new ArrayList<>();
List<OutputContentElement> outputList = new ArrayList<>();
if (rs.next()) {
outputList.add(new StoryOutputText(
while (rs.next()) {
outputList.add(new OutputContentElement(
rs.getString("chapterText"),
rs.getString("imageUrl"),
Color.decode(rs.getString("color")))
@ -370,14 +354,15 @@ public class SQLiteStorage {
}
return outputList;
} catch (SQLException e) {
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
return null;
}
public static List<StoryOutputText> getChapterTexte(int ctId) {
public static List<OutputContentElement> getChapterTexte(int ctId) {
String sql = """
SELECT\s
CT.id,
@ -394,10 +379,10 @@ public class SQLiteStorage {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
ResultSet rs = executeQueryWithRetry(conn, sql, ctId);
List<StoryOutputText> outputList = new ArrayList<>();
List<OutputContentElement> outputList = new ArrayList<>();
if (rs.next()) {
outputList.add(new StoryOutputText(
while (rs.next()) {
outputList.add(new OutputContentElement(
rs.getString("chapterText"),
rs.getString("imageUrl"),
Color.decode(rs.getString("color")))
@ -405,14 +390,15 @@ public class SQLiteStorage {
}
return outputList;
} catch (SQLException e) {
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
return null;
}
public static List<StoryOutputText> getStoryTexte() {
public static List<OutputContentElement> getStoryTexte() {
String sql = """
SELECT\s
CT.id,
@ -428,10 +414,10 @@ public class SQLiteStorage {
try (Connection conn = DriverManager.getConnection(DB_URL)) {
ResultSet rs = executeQueryWithRetry(conn, sql);
List<StoryOutputText> outputList = new ArrayList<>();
List<OutputContentElement> outputList = new ArrayList<>();
if (rs.next()) {
outputList.add(new StoryOutputText(
while (rs.next()) {
outputList.add(new OutputContentElement(
rs.getString("storyText"),
rs.getString("imageUrl"),
Color.decode(rs.getString("color")))
@ -439,7 +425,8 @@ public class SQLiteStorage {
}
return outputList;
} catch (SQLException e) {
}
catch (SQLException e) {
System.out.println(e.getMessage());
}
@ -447,11 +434,4 @@ public class SQLiteStorage {
}
}
record DataStory(String name, String link, String ffid, long date, String author, Integer tagId) {
}
record DataChapter(String name, String link, String storyId, long date, long number) {
}

View File

@ -37,68 +37,85 @@ class SocketServerRunnable implements Runnable {
JSONObject jsonData = new JSONObject(jsonMessageFromClient);
String action = jsonData.getString("action");
JSONObject jsonResponse= new JSONObject();
Long channelId = null;
if(action.equals("channelCheck")) {
Object channelIdObj = jsonData.get("channelId");
if(channelIdObj.equals("")) {
jsonResponse.put("status", "fail");
continue;
switch (action) {
case "channelCheck" -> {
if (channelCheckAction(jsonData, out))
continue;
}
if (channelIdObj instanceof Number) {
channelId = ((Number) channelIdObj).longValue();
} else if (channelIdObj instanceof String) {
String channelIdStr = (String) channelIdObj;
channelId = Long.parseLong(channelIdStr);
} else {
jsonResponse.put("status", "fail");
continue;
}
String response = "";
try {
TextChannel textchannel = jda.getTextChannelById(channelId);
if (textchannel.canTalk()) {
jsonResponse.put("status", "success")
.put("name", textchannel.getName())
.put("serverName", textchannel.getGuild().getName());
}
else {
jsonResponse.put("status", "fail");
}
} catch (NullPointerException e) {
jsonResponse.put("status", "error");
}
out.println(jsonResponse);
}
else if(action.equals("check")) {
ffr.checkAlerts();
jsonResponse.put("status", "success");
out.println(jsonResponse);
}
else if(action.equals("chapterTest")) {
String storyName = jsonData.getString("storyName");
String chapterName = jsonData.getString("chapterName");
String author = jsonData.getString("author");
Integer id = jsonData.getInt("id");
Long target = jsonData.getLong("target");
ffr.outputCheapterTester(id, chapterName, storyName, author, target);
jsonResponse.put("status", "success");
out.println(jsonResponse);
case "check" -> checkAction(out);
case "chapterTest" -> chapterTest(jsonData, out);
case "addFavo" -> addFavo(jsonData);
}
} catch (IOException | NullPointerException e) {
}
catch (IOException | NullPointerException e) {
System.out.println("Fehler bei der Kommunikation mit dem Client: " + e.getMessage());
e.printStackTrace();
}
}
} catch (IOException e) {
}
catch (IOException e) {
System.out.println("Server konnte nicht gestartet werden: " + e.getMessage());
}
}
private Boolean channelCheckAction(JSONObject jsonData, PrintWriter out) {
JSONObject jsonResponse= new JSONObject();
Long channelId = null;
Object channelIdObj = jsonData.get("channelId");
if(channelIdObj.equals("")) {
jsonResponse.put("status", "fail");
return true;
}
if (channelIdObj instanceof Number) {
channelId = ((Number) channelIdObj).longValue();
}
else if (channelIdObj instanceof String) {
String channelIdStr = (String) channelIdObj;
channelId = Long.parseLong(channelIdStr);
}
else {
jsonResponse.put("status", "fail");
return true;
}
String response = "";
try {
TextChannel textchannel = jda.getTextChannelById(channelId);
if (textchannel.canTalk()) {
jsonResponse.put("status", "success")
.put("name", textchannel.getName())
.put("serverName", textchannel.getGuild().getName());
}
else {
jsonResponse.put("status", "fail");
}
}
catch (NullPointerException e) {
jsonResponse.put("status", "error");
}
out.println(jsonResponse);
return false;
}
private void checkAction(PrintWriter out) {
ffr.checkAlerts();
out.println( new JSONObject().put("status", "success"));
}
private void chapterTest(JSONObject jsonData, PrintWriter out) {
String storyName = jsonData.getString("storyName");
String chapterName = jsonData.getString("chapterName");
String author = jsonData.getString("author");
int id = jsonData.getInt("id");
Long target = jsonData.getLong("target");
ffr.outputCheapterTester(id, chapterName, storyName, author, target);
out.println( new JSONObject().put("status", "success"));
}
private void addFavo(JSONObject jsonData) {
String ffId = jsonData.getString("ffId");
ffr.addStoryToFavorit(ffId);
}
}

View File

@ -1,17 +1,12 @@
package de.ocame.ffdiscordbot;
package de.ocame.ffdiscordbot.fetcher;
import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
import java.net.URI;
import java.net.*;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.HttpCookie;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.CookieStore;
import java.net.URISyntaxException;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
@ -21,16 +16,13 @@ import com.google.gson.reflect.TypeToken;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.net.http.HttpRequest.BodyPublishers;
public class HtmlFetcher {
public class DefaultHtmlFetcher implements HtmlFetcher {
private final HttpClient client;
private final CookieManager cookieManager;
private static final String COOKIE_FILE = "cookies.json";
public HtmlFetcher() {
public DefaultHtmlFetcher() {
cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
client = HttpClient.newBuilder()
@ -42,10 +34,12 @@ public class HtmlFetcher {
loadCookies();
}
public Document fetchURL(String url) throws IOException, InterruptedException, URISyntaxException {
return fetchURL(url, "");
@Override
public Document fetchHtml(String url) throws IOException, InterruptedException {
return fetchHtml(url, null);
}
public Document fetchURL(String url, String postData) throws IOException, InterruptedException, URISyntaxException {
public Document fetchHtml(String url, String postData) throws IOException, InterruptedException {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0")
@ -60,19 +54,12 @@ public class HtmlFetcher {
// Wenn postData nicht leer ist, füge die POST-Daten hinzu
requestBuilder
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(BodyPublishers.ofString(postData));
.POST(HttpRequest.BodyPublishers.ofString(postData));
}
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// Print cookies if any
CookieStore cookieStore = cookieManager.getCookieStore();
List<HttpCookie> cookies = cookieStore.getCookies();
/*for (HttpCookie cookie : cookies) {
System.out.println("Cookie: " + cookie);
}*/
// Save cookies
saveCookies();
@ -108,6 +95,17 @@ public class HtmlFetcher {
}
}
public String getCookieValue(String uri, String cookieName) {
CookieStore cookieStore = cookieManager.getCookieStore();
List<HttpCookie> cookies = cookieStore.get(URI.create(uri));
for (HttpCookie cookie : cookies) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
return null; // Cookie wurde nicht gefunden
}
private static class SerializableCookie {
private String uri;
private String name;
@ -139,19 +137,4 @@ public class HtmlFetcher {
return cookie;
}
}
public CookieManager getCookieManager() {
return cookieManager;
}
public String getCookieValue(String uri, String cookieName) {
CookieStore cookieStore = cookieManager.getCookieStore();
List<HttpCookie> cookies = cookieStore.get(URI.create(uri));
for (HttpCookie cookie : cookies) {
if (cookie.getName().equals(cookieName)) {
return cookie.getValue();
}
}
return null; // Cookie wurde nicht gefunden
}
}

View File

@ -0,0 +1,9 @@
package de.ocame.ffdiscordbot.fetcher;
import org.jsoup.nodes.Document;
import java.io.IOException;
public interface HtmlFetcher {
Document fetchHtml(String url) throws IOException, InterruptedException;
}

View File

@ -0,0 +1,132 @@
package de.ocame.ffdiscordbot.output;
import de.ocame.ffdiscordbot.DataStory;
import de.ocame.ffdiscordbot.OutputContentElement;
import de.ocame.ffdiscordbot.SQLiteStorage;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
// Basisklasse für Benachrichtigungen
public abstract class BaseNotifier <T extends BaseNotifier<T>> {
protected final JDA jda;
private Integer version;
public void setStory(DataStory story) {
this.story = story;
}
private DataStory story;
private Long targetChannel;
public BaseNotifier(JDA jda) {
this.jda = jda;
}
// Allgemeine Benachrichtigungsmethode
public void sendOutput(Long targetChannel) {
this.targetChannel = targetChannel;
sendOutput();
}
public void sendOutput() {
EmbedBuilder outputBox = createEmbed();
Long[] channelIds = SQLiteStorage.getChannelIds();
if(targetChannel != null) {
Objects.requireNonNull(jda.getTextChannelById(targetChannel))
// .sendMessage("Hier ist ein Text vor dem Embed <@&423156046115242005> :")
// .setEmbeds(outputBox.build())
.sendMessageEmbeds(outputBox.build())
.queue();
}
else if(Objects.requireNonNull(channelIds).length == 0) {
Objects.requireNonNull(jda.getTextChannelById(542202034330271759L)).sendMessageEmbeds(outputBox.build()).queue();
}
else {
for (Long channelId : channelIds ) {
try {
if (Objects.requireNonNull(jda.getTextChannelById(channelId)).canTalk())
Objects.requireNonNull(jda.getTextChannelById(channelId)).sendMessageEmbeds(outputBox.build()).queue();
}
catch (NullPointerException e) {
//
}
}
}
}
// Abstrakte Methode, um den spezifischen Titel zu liefern
protected abstract String getEmbedTitle();
// Abstrakte Methode zur Lieferung der Platzhalter und deren Ersetzungen
protected abstract Map<String, String> getMessagePlaceholders();
// Abstrakte Methode zur Lieferung des Links (falls erforderlich)
protected abstract String getLink();
// Methode zum Erstellen des Embeds, die Platzhalter verwendet
protected EmbedBuilder createEmbed() {
EmbedBuilder outputBox = new EmbedBuilder();
OutputContentElement outputContentElement = getOCE();
// Titel und Link von der spezifischen Implementierung holen
outputBox.setTitle(getEmbedTitle(), getLink())
.setColor(outputContentElement.getColor());
// Nachricht holen und Platzhalter ersetzen
String message = outputContentElement.getMessage();
for (Map.Entry<String, String> entry : getMessagePlaceholders().entrySet()) {
message = message.replace(entry.getKey(), entry.getValue());
}
outputBox.setDescription(message);
// Zeitformatierung und Footer
Instant instant = Instant.ofEpochSecond(getDate());
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneId.of("Europe/Berlin"));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yy HH:mm 'Uhr'");
outputBox.setFooter("Veröffentlicht am " + dateTime.format(formatter));
// Thumbnail setzen, falls vorhanden
if (outputContentElement.getImage() != null && !Objects.equals(outputContentElement.getImage(), "")) {
outputBox.setThumbnail(outputContentElement.getImage());
}
return outputBox;
}
// Methode zur Auswahl eines OutputContentElement, kann auch einheitlich gehalten werden
protected OutputContentElement getOCE() {
List<OutputContentElement> chapterTexte;
if(version != null) {
chapterTexte = SQLiteStorage.getChapterTexte(version);
}
else {
chapterTexte = SQLiteStorage.getChapterTexte(story);
}
assert chapterTexte != null;
if(chapterTexte.isEmpty())
return null;
Random random = new Random();
return chapterTexte.get(random.nextInt(chapterTexte.size()));
}
// Abstrakte Methode zur Rückgabe des Zeitstempels
protected abstract long getDate();
@SuppressWarnings("unchecked")
public T setVersion(Integer version) {
this.version = version;
return (T) this;
}
}

View File

@ -0,0 +1,49 @@
package de.ocame.ffdiscordbot.output;
import net.dv8tion.jda.api.JDA;
import de.ocame.ffdiscordbot.DataChapter;
import de.ocame.ffdiscordbot.DataStory;
import java.util.Map;
// Handles notifications about new chapters
public class ChapterNotifier extends BaseNotifier<ChapterNotifier> {
private DataChapter chapter;
private DataStory story;
public ChapterNotifier(JDA jda, DataChapter chapter, DataStory story) {
super(jda);
this.chapter = chapter;
this.story = story;
super.setStory(story);
}
@Override
protected String getEmbedTitle() {
return "Neues Kapitel:";
}
@Override
protected Map<String, String> getMessagePlaceholders() {
return Map.of(
"%chapterName%", "**" + chapter.name() + "**",
"%storyName%", "**" + story.name() + "**",
"%autor%", "**" + story.author() + "**"
);
}
@Override
protected String getLink() {
return chapter.link();
}
@Override
protected long getDate() {
return chapter.date();
}
}

View File

@ -0,0 +1,54 @@
package de.ocame.ffdiscordbot.output;
import de.ocame.ffdiscordbot.ConfigLoader;
import de.ocame.ffdiscordbot.OutputContentElement;
import net.dv8tion.jda.api.JDA;
import java.time.Instant;
import java.util.Map;
import java.util.Properties;
public class InfoNotifier extends BaseNotifier<InfoNotifier> {
private String messagetext;
public InfoNotifier(JDA jda) {
super(jda);
this.sendOutput(new ConfigLoader().getDebugChannel() );
}
@Override
protected String getEmbedTitle() {
return "Problem:";
}
@Override
protected Map<String, String> getMessagePlaceholders() {
return Map.of(
"%storyName%", ""
);
}
@Override
protected String getLink() {
return "";
}
@Override
protected long getDate() {
return Instant.now().getEpochSecond();
}
@Override
protected OutputContentElement getOCE() {
return new OutputContentElement("Fehler " + messagetext);
}
public InfoNotifier setMessagetext(String messagetext) {
this.messagetext = messagetext;
return this;
}
}

View File

@ -0,0 +1,62 @@
package de.ocame.ffdiscordbot.output;
import de.ocame.ffdiscordbot.OutputContentElement;
import de.ocame.ffdiscordbot.SQLiteStorage;
import net.dv8tion.jda.api.JDA;
import de.ocame.ffdiscordbot.DataStory;
import java.util.List;
import java.util.Map;
import java.util.Random;
// Handles notifications about new stories
public class StoryNotifier extends BaseNotifier<StoryNotifier> {
private final DataStory story;
public StoryNotifier(JDA jda, DataStory story) {
super(jda);
this.story = story;
}
@Override
protected String getEmbedTitle() {
return "Neue Geschichte:";
}
@Override
protected Map<String, String> getMessagePlaceholders() {
return Map.of(
"%storyName%", "**" + story.name() + "**",
"%autor%", "**" + story.author() + "**"
);
}
@Override
protected String getLink() {
return story.link();
}
@Override
protected long getDate() {
return story.date();
}
// Methode zur Auswahl eines OutputContentElement, kann auch einheitlich gehalten werden
@Override
protected OutputContentElement getOCE() {
List<OutputContentElement> storyTexte;
storyTexte = SQLiteStorage.getStoryTexte();
assert storyTexte != null;
if(storyTexte.isEmpty())
return null;
Random random = new Random();
return storyTexte.get(random.nextInt(storyTexte.size()));
}
}