From 594c71b37e64d099579642254be83783318407e6 Mon Sep 17 00:00:00 2001 From: thmsdy Date: Sat, 27 Jun 2026 01:26:31 -0500 Subject: [PATCH] Add timestamp checking to YouTube feeds --- pom.xml | 52 +++++++++---------- .../fpghoti/biscuit/guild/BiscuitGuild.java | 5 +- .../java/com/fpghoti/biscuit/rss/YTEntry.java | 7 ++- .../java/com/fpghoti/biscuit/rss/YTFeed.java | 50 ++++++++++++++++-- .../com/fpghoti/biscuit/rss/YTFeedConfig.java | 7 ++- 5 files changed, 88 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index b85327f..27a3bd9 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 com.fpghoti Biscuit - 2.0 Beta + 2.1 UTF-8 @@ -64,10 +64,10 @@ https://oss.sonatype.org/content/repositories/snapshots/ - arbjergDev-releases - Lavalink Repository - https://maven.lavalink.dev/releases - + arbjergDev-releases + Lavalink Repository + https://maven.lavalink.dev/releases + jitpack.io https://jitpack.io @@ -78,7 +78,7 @@ org.fusesource.jansi jansi - 2.4.1 + 2.4.3 com.github.GhotiMayo @@ -88,7 +88,7 @@ org.apache.commons commons-configuration2 - 2.11.0 + 2.15.1 org.spigotmc @@ -104,7 +104,7 @@ ch.qos.logback logback-classic - 1.5.17 + 1.5.37 com.jcabi @@ -114,12 +114,12 @@ joda-time joda-time - 2.13.1 + 2.14.2 net.dv8tion JDA - 6.4.1 + 6.4.2 com.github.cage @@ -127,34 +127,34 @@ 1.0 - javax.activation - activation - 1.1.1 + com.sun.activation + javax.activation + 1.2.0 - javax.mail - mail - 1.4.7 + com.sun.mail + javax.mail + 1.6.2 dev.arbjerg lavaplayer - 2.2.4 + 2.2.6 - dev.lavalink.youtube - v2 - 1.13.3 - + dev.lavalink.youtube + v2 + 1.18.1 + org.pf4j pf4j - 3.13.0 + 3.15.0 - - xom - xom - 1.3.9 + + xom + xom + 1.4.6 \ No newline at end of file diff --git a/src/main/java/com/fpghoti/biscuit/guild/BiscuitGuild.java b/src/main/java/com/fpghoti/biscuit/guild/BiscuitGuild.java index 223602f..b3def21 100644 --- a/src/main/java/com/fpghoti/biscuit/guild/BiscuitGuild.java +++ b/src/main/java/com/fpghoti/biscuit/guild/BiscuitGuild.java @@ -203,6 +203,7 @@ public class BiscuitGuild { String youTubeChannelURL = "null"; String message = "null"; String lastVideo = "null"; + String lastVideoTimestamp = "null"; Properties prop = new Properties(); InputStream input = null; @@ -221,6 +222,7 @@ public class BiscuitGuild { youTubeChannelURL = prop.getProperty("YouTubeChannelURL"); message = prop.getProperty("Message"); lastVideo = prop.getProperty("LastVideo"); + lastVideoTimestamp = prop.getProperty("LastVideoTimestamp"); } catch (IOException ex) { ex.printStackTrace(); } finally { @@ -240,6 +242,7 @@ public class BiscuitGuild { } YTFeed feed = new YTFeed(alias, textChannel, youTubeChannelURL, message); feed.setLastVideo(lastVideo); + feed.setLastVideoTimestamp(lastVideoTimestamp); return new YTFeedConfig(this, feed); } @@ -273,7 +276,7 @@ public class BiscuitGuild { YTFeedConfig config = ytfeeds.get(s); YTFeed feed = config.getFeed(); feed.post(); - config.setLastPosted(feed.getLastVideo()); + config.setLastPosted(feed.getLastVideo(), feed.getLastVideoTimestamp()); } } diff --git a/src/main/java/com/fpghoti/biscuit/rss/YTEntry.java b/src/main/java/com/fpghoti/biscuit/rss/YTEntry.java index acfabeb..add162f 100644 --- a/src/main/java/com/fpghoti/biscuit/rss/YTEntry.java +++ b/src/main/java/com/fpghoti/biscuit/rss/YTEntry.java @@ -13,10 +13,11 @@ public class YTEntry { private String id; private String title; private String author; + private String timestamp; private String description; private String thumbnail; - public YTEntry(String id, String title, String author, String description, String thumbnail) { + public YTEntry(String id, String title, String author, String timestamp, String description, String thumbnail) { this.id = id; this.title = title; this.author = author; @@ -36,6 +37,10 @@ public class YTEntry { return author; } + public String getTimestamp() { + return timestamp; + } + public String getDescription() { return description; } diff --git a/src/main/java/com/fpghoti/biscuit/rss/YTFeed.java b/src/main/java/com/fpghoti/biscuit/rss/YTFeed.java index aec8b34..2b791ee 100644 --- a/src/main/java/com/fpghoti/biscuit/rss/YTFeed.java +++ b/src/main/java/com/fpghoti/biscuit/rss/YTFeed.java @@ -2,6 +2,9 @@ package com.fpghoti.biscuit.rss; import java.awt.Color; import java.io.IOException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; @@ -23,6 +26,7 @@ public class YTFeed { private String channelURL; private String message; private String lastVideo; + private String lastVideoTimestamp; public YTFeed(String alias, TextChannel channel, String channelURL, String message) { this.guild = BiscuitGuild.getBiscuitGuild(channel.getGuild()); @@ -31,6 +35,7 @@ public class YTFeed { this.channelURL = channelURL; this.message = message; lastVideo = ""; + lastVideoTimestamp = ""; } public String getAlias() { @@ -52,11 +57,23 @@ public class YTFeed { public String getLastVideo() { return lastVideo; } - + + public String getLastVideoTimestamp() { + return lastVideoTimestamp; + } + + public Instant getLastInstant() { + return parseTimestamp(lastVideoTimestamp); + } + public void setLastVideo(String link) { lastVideo = link; } + public void setLastVideoTimestamp(String link) { + lastVideoTimestamp = link; + } + public void post(){ List ytentries = getEntries(); int index = 0; @@ -70,9 +87,20 @@ public class YTFeed { } index = 0; for(YTEntry entry : ytentries) { - if(index > lastVidIndex) { + String timestamp = entry.getTimestamp(); + Instant entryTimestamp = parseTimestamp(timestamp); + if(entryTimestamp == null) { + guild.error("Could not retrieve YouTube feed entry timestamp!"); + return; + } + if(getLastInstant() == null) { + guild.error("Could not retrieve YouTube feed last timestamp!"); + return; + } + if(index > lastVidIndex && entryTimestamp.isAfter(getLastInstant())) { String link = entry.getURL(); lastVideo = link; + lastVideoTimestamp = timestamp; MessageText.send(channel, message); MessageText.send(channel, entry.getEmbedMessage()); } @@ -100,6 +128,7 @@ public class YTFeed { String id = ""; String title = ""; String author = ""; + String timestamp = ""; String description = ""; String thumbnail = ""; @@ -119,6 +148,9 @@ public class YTFeed { } } } + if(value.getLocalName().equals("published")) { + timestamp = value.getValue(); + } if(value.getLocalName().equals("group")) { Elements subvalues = value.getChildElements(); for(Element subvalue : subvalues) { @@ -132,12 +164,24 @@ public class YTFeed { } } - ytentries.add(new YTEntry(id, title, author, description, thumbnail)); + ytentries.add(new YTEntry(id, title, author, timestamp, description, thumbnail)); } } return ytentries.reversed(); } + + private Instant parseTimestamp(String timestamp) { + if (timestamp == null || timestamp.trim().isEmpty()) { + return null; + } + + try { + return OffsetDateTime.parse(timestamp.trim()).toInstant(); + } catch (DateTimeParseException e) { + throw new IllegalArgumentException("Invalid YouTube timestamp: " + timestamp, e); + } + } } diff --git a/src/main/java/com/fpghoti/biscuit/rss/YTFeedConfig.java b/src/main/java/com/fpghoti/biscuit/rss/YTFeedConfig.java index 7c9f252..bb5c76c 100644 --- a/src/main/java/com/fpghoti/biscuit/rss/YTFeedConfig.java +++ b/src/main/java/com/fpghoti/biscuit/rss/YTFeedConfig.java @@ -54,15 +54,17 @@ public class YTFeedConfig { } - public void setLastPosted(String link) { + public void setLastPosted(String link, String timestamp) { PropertiesConfiguration prop = new PropertiesConfiguration(); PropertiesConfigurationLayout layout = new PropertiesConfigurationLayout(); prop.setLayout(layout); try { layout.load(prop, new FileReader(config)); FileWriter fw = new FileWriter(config); - prop.setProperty("LastVideo", link); + prop.setProperty("LastVideo", link); + prop.setProperty("LastVideoTimestamp", timestamp); feed.setLastVideo(link); + feed.setLastVideoTimestamp(timestamp); layout.save(prop, fw); } catch (ConfigurationException e) { e.printStackTrace(); @@ -105,6 +107,7 @@ public class YTFeedConfig { addProperty("YouTubeChannelURL", feed.getChannelURL(), prop); addProperty("Message", feed.getMesage(), prop); addProperty("LastVideo", "", prop); + addProperty("LastVideoTimestamp", "", prop); } private void addProperty(String key, String value, PropertiesConfiguration prop) {