mirror of
https://github.com/Athou/commafeed.git
synced 2026-09-26 14:04:41 +00:00
migrate from java.util.Date to java.time
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.codec.binary.StringUtils;
|
||||
@@ -32,8 +32,8 @@ public class FeedFetcher {
|
||||
private final HttpGetter getter;
|
||||
private final Set<FeedURLProvider> urlProviders;
|
||||
|
||||
public FeedFetcherResult fetch(String feedUrl, boolean extractFeedUrlFromHtml, String lastModified, String eTag, Date lastPublishedDate,
|
||||
String lastContentHash) throws FeedException, IOException, NotModifiedException {
|
||||
public FeedFetcherResult fetch(String feedUrl, boolean extractFeedUrlFromHtml, String lastModified, String eTag,
|
||||
Instant lastPublishedDate, String lastContentHash) throws FeedException, IOException, NotModifiedException {
|
||||
log.debug("Fetching feed {}", feedUrl);
|
||||
|
||||
int timeout = 20000;
|
||||
@@ -76,8 +76,7 @@ public class FeedFetcher {
|
||||
etagHeaderValueChanged ? result.getETag() : null);
|
||||
}
|
||||
|
||||
if (lastPublishedDate != null && parserResult.lastPublishedDate() != null
|
||||
&& lastPublishedDate.getTime() == parserResult.lastPublishedDate().getTime()) {
|
||||
if (lastPublishedDate != null && lastPublishedDate.equals(parserResult.lastPublishedDate())) {
|
||||
log.debug("publishedDate not modified: {}", feedUrl);
|
||||
throw new NotModifiedException("publishedDate not modified",
|
||||
lastModifiedHeaderValueChanged ? result.getLastModifiedSince() : null,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -11,8 +12,6 @@ import java.util.concurrent.SynchronousQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import com.codahale.metrics.Gauge;
|
||||
import com.codahale.metrics.Meter;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
@@ -166,12 +165,12 @@ public class FeedRefreshEngine implements Managed {
|
||||
|
||||
private List<Feed> getNextUpdatableFeeds(int max) {
|
||||
return unitOfWork.call(() -> {
|
||||
Date lastLoginThreshold = Boolean.TRUE.equals(config.getApplicationSettings().getHeavyLoad())
|
||||
? DateUtils.addDays(new Date(), -30)
|
||||
Instant lastLoginThreshold = Boolean.TRUE.equals(config.getApplicationSettings().getHeavyLoad())
|
||||
? Instant.now().minus(Duration.ofDays(30))
|
||||
: null;
|
||||
List<Feed> feeds = feedDAO.findNextUpdatable(max, lastLoginThreshold);
|
||||
// update disabledUntil to prevent feeds from being returned again by feedDAO.findNextUpdatable()
|
||||
Date nextUpdateDate = DateUtils.addMinutes(new Date(), config.getApplicationSettings().getRefreshIntervalMinutes());
|
||||
Instant nextUpdateDate = Instant.now().plus(Duration.ofMinutes(config.getApplicationSettings().getRefreshIntervalMinutes()));
|
||||
feedDAO.setDisabledUntil(feeds.stream().map(AbstractModel::getId).toList(), nextUpdateDate);
|
||||
return feeds;
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
|
||||
import com.commafeed.CommaFeedConfiguration;
|
||||
|
||||
@@ -21,61 +21,59 @@ public class FeedRefreshIntervalCalculator {
|
||||
this.refreshIntervalMinutes = config.getApplicationSettings().getRefreshIntervalMinutes();
|
||||
}
|
||||
|
||||
public Date onFetchSuccess(Date publishedDate, Long averageEntryInterval) {
|
||||
Date defaultRefreshInterval = getDefaultRefreshInterval();
|
||||
public Instant onFetchSuccess(Instant publishedDate, Long averageEntryInterval) {
|
||||
Instant defaultRefreshInterval = getDefaultRefreshInterval();
|
||||
return heavyLoad ? computeRefreshIntervalForHeavyLoad(publishedDate, averageEntryInterval, defaultRefreshInterval)
|
||||
: defaultRefreshInterval;
|
||||
}
|
||||
|
||||
public Date onFeedNotModified(Date publishedDate, Long averageEntryInterval) {
|
||||
Date defaultRefreshInterval = getDefaultRefreshInterval();
|
||||
return heavyLoad ? computeRefreshIntervalForHeavyLoad(publishedDate, averageEntryInterval, defaultRefreshInterval)
|
||||
: defaultRefreshInterval;
|
||||
public Instant onFeedNotModified(Instant publishedDate, Long averageEntryInterval) {
|
||||
return onFetchSuccess(publishedDate, averageEntryInterval);
|
||||
}
|
||||
|
||||
public Date onFetchError(int errorCount) {
|
||||
public Instant onFetchError(int errorCount) {
|
||||
int retriesBeforeDisable = 3;
|
||||
if (errorCount < retriesBeforeDisable || !heavyLoad) {
|
||||
return getDefaultRefreshInterval();
|
||||
}
|
||||
|
||||
int disabledHours = Math.min(24 * 7, errorCount - retriesBeforeDisable + 1);
|
||||
return DateUtils.addHours(new Date(), disabledHours);
|
||||
return Instant.now().plus(Duration.ofHours(disabledHours));
|
||||
}
|
||||
|
||||
private Date getDefaultRefreshInterval() {
|
||||
return DateUtils.addMinutes(new Date(), refreshIntervalMinutes);
|
||||
private Instant getDefaultRefreshInterval() {
|
||||
return Instant.now().plus(Duration.ofMinutes(refreshIntervalMinutes));
|
||||
}
|
||||
|
||||
private Date computeRefreshIntervalForHeavyLoad(Date publishedDate, Long averageEntryInterval, Date defaultRefreshInterval) {
|
||||
Date now = new Date();
|
||||
private Instant computeRefreshIntervalForHeavyLoad(Instant publishedDate, Long averageEntryInterval, Instant defaultRefreshInterval) {
|
||||
Instant now = Instant.now();
|
||||
|
||||
if (publishedDate == null) {
|
||||
// feed with no entries, recheck in 24 hours
|
||||
return DateUtils.addHours(now, 24);
|
||||
} else if (publishedDate.before(DateUtils.addMonths(now, -1))) {
|
||||
return now.plus(Duration.ofHours(24));
|
||||
} else if (ChronoUnit.DAYS.between(publishedDate, now) >= 30) {
|
||||
// older than a month, recheck in 24 hours
|
||||
return DateUtils.addHours(now, 24);
|
||||
} else if (publishedDate.before(DateUtils.addDays(now, -14))) {
|
||||
return now.plus(Duration.ofHours(24));
|
||||
} else if (ChronoUnit.DAYS.between(publishedDate, now) >= 14) {
|
||||
// older than two weeks, recheck in 12 hours
|
||||
return DateUtils.addHours(now, 12);
|
||||
} else if (publishedDate.before(DateUtils.addDays(now, -7))) {
|
||||
return now.plus(Duration.ofHours(12));
|
||||
} else if (ChronoUnit.DAYS.between(publishedDate, now) >= 7) {
|
||||
// older than a week, recheck in 6 hours
|
||||
return DateUtils.addHours(now, 6);
|
||||
return now.plus(Duration.ofHours(6));
|
||||
} else if (averageEntryInterval != null) {
|
||||
// use average time between entries to decide when to refresh next, divided by factor
|
||||
int factor = 2;
|
||||
|
||||
// not more than 6 hours
|
||||
long date = Math.min(DateUtils.addHours(now, 6).getTime(), now.getTime() + averageEntryInterval / factor);
|
||||
long date = Math.min(now.plus(Duration.ofHours(6)).toEpochMilli(), now.toEpochMilli() + averageEntryInterval / factor);
|
||||
|
||||
// not less than default refresh interval
|
||||
date = Math.max(defaultRefreshInterval.getTime(), date);
|
||||
date = Math.max(defaultRefreshInterval.toEpochMilli(), date);
|
||||
|
||||
return new Date(date);
|
||||
return Instant.ofEpochMilli(date);
|
||||
} else {
|
||||
// unknown case, recheck in 24 hours
|
||||
return DateUtils.addHours(now, 24);
|
||||
return now.plus(Duration.ofHours(24));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -161,7 +161,7 @@ public class FeedRefreshUpdater implements Managed {
|
||||
|
||||
if (!processed) {
|
||||
// requeue asap
|
||||
feed.setDisabledUntil(new Date(0));
|
||||
feed.setDisabledUntil(Instant.EPOCH);
|
||||
}
|
||||
|
||||
if (insertedAtLeastOneEntry) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.commafeed.backend.feed;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
|
||||
import com.codahale.metrics.Meter;
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
@@ -58,8 +58,8 @@ public class FeedRefreshWorker {
|
||||
|
||||
Integer maxEntriesAgeDays = config.getApplicationSettings().getMaxEntriesAgeDays();
|
||||
if (maxEntriesAgeDays > 0) {
|
||||
Date threshold = DateUtils.addDays(new Date(), -1 * maxEntriesAgeDays);
|
||||
entries = entries.stream().filter(entry -> entry.updated().after(threshold)).toList();
|
||||
Instant threshold = Instant.now().minus(Duration.ofDays(maxEntriesAgeDays));
|
||||
entries = entries.stream().filter(entry -> entry.updated().isAfter(threshold)).toList();
|
||||
}
|
||||
|
||||
String urlAfterRedirect = result.urlAfterRedirect();
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.commafeed.backend.feed.parser;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.DateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
@@ -50,8 +51,8 @@ public class FeedParser {
|
||||
|
||||
private static final Namespace ATOM_10_NS = Namespace.getNamespace("http://www.w3.org/2005/Atom");
|
||||
|
||||
private static final Date START = new Date(86400000);
|
||||
private static final Date END = new Date(1000L * Integer.MAX_VALUE - 86400000);
|
||||
private static final Instant START = Instant.ofEpochMilli(86400000);
|
||||
private static final Instant END = Instant.ofEpochMilli(1000L * Integer.MAX_VALUE - 86400000);
|
||||
|
||||
private final EncodingDetector encodingDetector;
|
||||
private final FeedCleaner feedCleaner;
|
||||
@@ -72,9 +73,9 @@ public class FeedParser {
|
||||
String title = feed.getTitle();
|
||||
String link = feed.getLink();
|
||||
List<Entry> entries = buildEntries(feed, feedUrl);
|
||||
Date lastEntryDate = entries.stream().findFirst().map(Entry::updated).orElse(null);
|
||||
Date lastPublishedDate = validateDate(feed.getPublishedDate(), false);
|
||||
if (lastPublishedDate == null || lastEntryDate != null && lastPublishedDate.before(lastEntryDate)) {
|
||||
Instant lastEntryDate = entries.stream().findFirst().map(Entry::updated).orElse(null);
|
||||
Instant lastPublishedDate = toValidInstant(feed.getPublishedDate(), false);
|
||||
if (lastPublishedDate == null || lastEntryDate != null && lastPublishedDate.isBefore(lastEntryDate)) {
|
||||
lastPublishedDate = lastEntryDate;
|
||||
}
|
||||
Long averageEntryInterval = averageTimeBetweenEntries(entries);
|
||||
@@ -122,7 +123,7 @@ public class FeedParser {
|
||||
url = guid;
|
||||
}
|
||||
|
||||
Date updated = buildEntryUpdateDate(item);
|
||||
Instant updated = buildEntryUpdateDate(item);
|
||||
Content content = buildContent(item);
|
||||
|
||||
entries.add(new Entry(guid, url, updated, content));
|
||||
@@ -153,15 +154,12 @@ public class FeedParser {
|
||||
return new Enclosure(enclosure.getUrl(), enclosure.getType());
|
||||
}
|
||||
|
||||
private Date buildEntryUpdateDate(SyndEntry item) {
|
||||
private Instant buildEntryUpdateDate(SyndEntry item) {
|
||||
Date date = item.getUpdatedDate();
|
||||
if (date == null) {
|
||||
date = item.getPublishedDate();
|
||||
}
|
||||
if (date == null) {
|
||||
date = new Date();
|
||||
}
|
||||
return validateDate(date, true);
|
||||
return toValidInstant(date, true);
|
||||
}
|
||||
|
||||
private String buildEntryUrl(SyndFeed feed, String feedUrl, SyndEntry item) {
|
||||
@@ -176,19 +174,21 @@ public class FeedParser {
|
||||
return FeedUtils.toAbsoluteUrl(url, feedLink, feedUrl);
|
||||
}
|
||||
|
||||
private Date validateDate(Date date, boolean nullToNow) {
|
||||
Date now = new Date();
|
||||
private Instant toValidInstant(Date date, boolean nullToNow) {
|
||||
Instant now = Instant.now();
|
||||
if (date == null) {
|
||||
return nullToNow ? now : null;
|
||||
}
|
||||
if (date.before(START) || date.after(END)) {
|
||||
|
||||
Instant instant = date.toInstant();
|
||||
if (instant.isBefore(START) || instant.isAfter(END)) {
|
||||
return now;
|
||||
}
|
||||
|
||||
if (date.after(now)) {
|
||||
if (instant.isAfter(now)) {
|
||||
return now;
|
||||
}
|
||||
return date;
|
||||
return instant;
|
||||
}
|
||||
|
||||
private String getContent(SyndEntry item) {
|
||||
@@ -262,7 +262,7 @@ public class FeedParser {
|
||||
|
||||
SummaryStatistics stats = new SummaryStatistics();
|
||||
for (int i = 0; i < entries.size() - 1; i++) {
|
||||
long diff = Math.abs(entries.get(i).updated().getTime() - entries.get(i + 1).updated().getTime());
|
||||
long diff = Math.abs(entries.get(i).updated().toEpochMilli() - entries.get(i + 1).updated().toEpochMilli());
|
||||
stats.addValue(diff);
|
||||
}
|
||||
return (long) stats.getMean();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.commafeed.backend.feed.parser;
|
||||
|
||||
import java.util.Date;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
public record FeedParserResult(String title, String link, Date lastPublishedDate, Long averageEntryInterval, Date lastEntryDate,
|
||||
public record FeedParserResult(String title, String link, Instant lastPublishedDate, Long averageEntryInterval, Instant lastEntryDate,
|
||||
List<Entry> entries) {
|
||||
public record Entry(String guid, String url, Date updated, Content content) {
|
||||
public record Entry(String guid, String url, Instant updated, Content content) {
|
||||
}
|
||||
|
||||
public record Content(String title, String content, String author, String categories, Enclosure enclosure, Media media) {
|
||||
|
||||
Reference in New Issue
Block a user