mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
return the correct media type for favicons (fix #736)
This commit is contained in:
@@ -3,6 +3,8 @@ package com.commafeed.backend.favicon;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -18,7 +20,7 @@ public abstract class AbstractFaviconFetcher {
|
|||||||
|
|
||||||
protected static int TIMEOUT = 4000;
|
protected static int TIMEOUT = 4000;
|
||||||
|
|
||||||
public abstract byte[] fetch(Feed feed);
|
public abstract Favicon fetch(Feed feed);
|
||||||
|
|
||||||
protected boolean isValidIconResponse(byte[] content, String contentType) {
|
protected boolean isValidIconResponse(byte[] content, String contentType) {
|
||||||
if (content == null) {
|
if (content == null) {
|
||||||
@@ -48,4 +50,11 @@ public abstract class AbstractFaviconFetcher {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public static class Favicon {
|
||||||
|
private final byte[] icon;
|
||||||
|
private final String mediaType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ public class DefaultFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
private final HttpGetter getter;
|
private final HttpGetter getter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] fetch(Feed feed) {
|
public Favicon fetch(Feed feed) {
|
||||||
byte[] icon = fetch(feed.getLink());
|
Favicon icon = fetch(feed.getLink());
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
icon = fetch(feed.getUrl());
|
icon = fetch(feed.getUrl());
|
||||||
}
|
}
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] fetch(String url) {
|
private Favicon fetch(String url) {
|
||||||
if (url == null) {
|
if (url == null) {
|
||||||
log.debug("url is null");
|
log.debug("url is null");
|
||||||
return null;
|
return null;
|
||||||
@@ -53,7 +53,7 @@ public class DefaultFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
url = url.substring(0, firstSlash);
|
url = url.substring(0, firstSlash);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] icon = getIconAtRoot(url);
|
Favicon icon = getIconAtRoot(url);
|
||||||
|
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
icon = getIconInPage(url);
|
icon = getIconInPage(url);
|
||||||
@@ -62,7 +62,7 @@ public class DefaultFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getIconAtRoot(String url) {
|
private Favicon getIconAtRoot(String url) {
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
String contentType = null;
|
String contentType = null;
|
||||||
|
|
||||||
@@ -78,12 +78,12 @@ public class DefaultFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
if (!isValidIconResponse(bytes, contentType)) {
|
||||||
bytes = null;
|
return null;
|
||||||
}
|
}
|
||||||
return bytes;
|
return new Favicon(bytes, contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getIconInPage(String url) {
|
private Favicon getIconInPage(String url) {
|
||||||
|
|
||||||
Document doc = null;
|
Document doc = null;
|
||||||
try {
|
try {
|
||||||
@@ -127,6 +127,6 @@ public class DefaultFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes;
|
return new Favicon(bytes, contentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class FacebookFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
private final HttpGetter getter;
|
private final HttpGetter getter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] fetch(Feed feed) {
|
public Favicon fetch(Feed feed) {
|
||||||
String url = feed.getUrl();
|
String url = feed.getUrl();
|
||||||
|
|
||||||
if (!url.toLowerCase().contains("www.facebook.com")) {
|
if (!url.toLowerCase().contains("www.facebook.com")) {
|
||||||
@@ -54,9 +54,9 @@ public class FacebookFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
if (!isValidIconResponse(bytes, contentType)) {
|
||||||
bytes = null;
|
return null;
|
||||||
}
|
}
|
||||||
return bytes;
|
return new Favicon(bytes, contentType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractUserName(String url) {
|
private String extractUserName(String url) {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] fetch(Feed feed) {
|
public Favicon fetch(Feed feed) {
|
||||||
String url = feed.getUrl();
|
String url = feed.getUrl();
|
||||||
|
|
||||||
if (!url.toLowerCase().contains("youtube.com/feeds/videos.xml")) {
|
if (!url.toLowerCase().contains("youtube.com/feeds/videos.xml")) {
|
||||||
@@ -94,8 +94,8 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isValidIconResponse(bytes, contentType)) {
|
if (!isValidIconResponse(bytes, contentType)) {
|
||||||
bytes = null;
|
return null;
|
||||||
}
|
}
|
||||||
return bytes;
|
return new Favicon(bytes, contentType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.apache.commons.io.IOUtils;
|
|||||||
|
|
||||||
import com.commafeed.backend.dao.FeedDAO;
|
import com.commafeed.backend.dao.FeedDAO;
|
||||||
import com.commafeed.backend.favicon.AbstractFaviconFetcher;
|
import com.commafeed.backend.favicon.AbstractFaviconFetcher;
|
||||||
|
import com.commafeed.backend.favicon.AbstractFaviconFetcher.Favicon;
|
||||||
import com.commafeed.backend.feed.FeedUtils;
|
import com.commafeed.backend.feed.FeedUtils;
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
|
|
||||||
@@ -21,7 +22,7 @@ public class FeedService {
|
|||||||
private final FeedDAO feedDAO;
|
private final FeedDAO feedDAO;
|
||||||
private final Set<AbstractFaviconFetcher> faviconFetchers;
|
private final Set<AbstractFaviconFetcher> faviconFetchers;
|
||||||
|
|
||||||
private byte[] defaultFavicon;
|
private Favicon defaultFavicon;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public FeedService(FeedDAO feedDAO, Set<AbstractFaviconFetcher> faviconFetchers) {
|
public FeedService(FeedDAO feedDAO, Set<AbstractFaviconFetcher> faviconFetchers) {
|
||||||
@@ -29,7 +30,7 @@ public class FeedService {
|
|||||||
this.faviconFetchers = faviconFetchers;
|
this.faviconFetchers = faviconFetchers;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
defaultFavicon = IOUtils.toByteArray(getClass().getResource("/images/default_favicon.gif"));
|
defaultFavicon = new Favicon(IOUtils.toByteArray(getClass().getResource("/images/default_favicon.gif")), "image/gif");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("could not load default favicon", e);
|
throw new RuntimeException("could not load default favicon", e);
|
||||||
}
|
}
|
||||||
@@ -49,9 +50,9 @@ public class FeedService {
|
|||||||
return feed;
|
return feed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] fetchFavicon(Feed feed) {
|
public Favicon fetchFavicon(Feed feed) {
|
||||||
|
|
||||||
byte[] icon = null;
|
Favicon icon = null;
|
||||||
for (AbstractFaviconFetcher faviconFetcher : faviconFetchers) {
|
for (AbstractFaviconFetcher faviconFetcher : faviconFetchers) {
|
||||||
icon = faviconFetcher.fetch(feed);
|
icon = faviconFetcher.fetch(feed);
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.Comparator;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -45,6 +46,7 @@ import com.commafeed.backend.cache.CacheService;
|
|||||||
import com.commafeed.backend.dao.FeedCategoryDAO;
|
import com.commafeed.backend.dao.FeedCategoryDAO;
|
||||||
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
import com.commafeed.backend.dao.FeedEntryStatusDAO;
|
||||||
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
import com.commafeed.backend.dao.FeedSubscriptionDAO;
|
||||||
|
import com.commafeed.backend.favicon.AbstractFaviconFetcher.Favicon;
|
||||||
import com.commafeed.backend.feed.FeedEntryKeyword;
|
import com.commafeed.backend.feed.FeedEntryKeyword;
|
||||||
import com.commafeed.backend.feed.FeedFetcher;
|
import com.commafeed.backend.feed.FeedFetcher;
|
||||||
import com.commafeed.backend.feed.FeedQueues;
|
import com.commafeed.backend.feed.FeedQueues;
|
||||||
@@ -339,9 +341,9 @@ public class FeedREST {
|
|||||||
return Response.status(Status.NOT_FOUND).build();
|
return Response.status(Status.NOT_FOUND).build();
|
||||||
}
|
}
|
||||||
Feed feed = subscription.getFeed();
|
Feed feed = subscription.getFeed();
|
||||||
byte[] icon = feedService.fetchFavicon(feed);
|
Favicon icon = feedService.fetchFavicon(feed);
|
||||||
|
|
||||||
ResponseBuilder builder = Response.ok(icon, "image/x-icon");
|
ResponseBuilder builder = Response.ok(icon.getIcon(), Optional.ofNullable(icon.getMediaType()).orElse("image/x-icon"));
|
||||||
|
|
||||||
CacheControl cacheControl = new CacheControl();
|
CacheControl cacheControl = new CacheControl();
|
||||||
cacheControl.setMaxAge(2592000);
|
cacheControl.setMaxAge(2592000);
|
||||||
|
|||||||
Reference in New Issue
Block a user