mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
fix youtube favicon fetching
This commit is contained in:
@@ -13,6 +13,9 @@ app:
|
|||||||
# put your google analytics tracking code here
|
# put your google analytics tracking code here
|
||||||
googleAnalyticsTrackingCode:
|
googleAnalyticsTrackingCode:
|
||||||
|
|
||||||
|
# put your google server key (used for youtube favicon fetching)
|
||||||
|
googleAuthKey:
|
||||||
|
|
||||||
# number of http threads
|
# number of http threads
|
||||||
backgroundThreads: 3
|
backgroundThreads: 3
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ app:
|
|||||||
# put your google analytics tracking code here
|
# put your google analytics tracking code here
|
||||||
googleAnalyticsTrackingCode:
|
googleAnalyticsTrackingCode:
|
||||||
|
|
||||||
|
# put your google server key (used for youtube favicon fetching)
|
||||||
|
googleAuthKey:
|
||||||
|
|
||||||
# number of http threads
|
# number of http threads
|
||||||
backgroundThreads: 3
|
backgroundThreads: 3
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ app:
|
|||||||
# put your google analytics tracking code here
|
# put your google analytics tracking code here
|
||||||
googleAnalyticsTrackingCode:
|
googleAnalyticsTrackingCode:
|
||||||
|
|
||||||
|
# put your google server key (used for youtube favicon fetching)
|
||||||
|
googleAuthKey:
|
||||||
|
|
||||||
# number of http threads
|
# number of http threads
|
||||||
backgroundThreads: 3
|
backgroundThreads: 3
|
||||||
|
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@@ -353,6 +353,12 @@
|
|||||||
<version>0.9.15</version>
|
<version>0.9.15</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.apis</groupId>
|
||||||
|
<artifactId>google-api-services-youtube</artifactId>
|
||||||
|
<version>v3-rev138-1.20.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.h2database</groupId>
|
<groupId>com.h2database</groupId>
|
||||||
<artifactId>h2</artifactId>
|
<artifactId>h2</artifactId>
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ public class CommaFeedConfiguration extends Configuration {
|
|||||||
|
|
||||||
private String googleAnalyticsTrackingCode;
|
private String googleAnalyticsTrackingCode;
|
||||||
|
|
||||||
|
private String googleAuthKey;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Min(1)
|
@Min(1)
|
||||||
@Valid
|
@Valid
|
||||||
|
|||||||
@@ -1,18 +1,31 @@
|
|||||||
package com.commafeed.backend.favicon;
|
package com.commafeed.backend.favicon;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.jsoup.Jsoup;
|
import org.apache.http.NameValuePair;
|
||||||
import org.jsoup.nodes.Document;
|
import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
import org.jsoup.select.Elements;
|
|
||||||
|
|
||||||
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
import com.commafeed.backend.HttpGetter;
|
import com.commafeed.backend.HttpGetter;
|
||||||
import com.commafeed.backend.HttpGetter.HttpResult;
|
import com.commafeed.backend.HttpGetter.HttpResult;
|
||||||
import com.commafeed.backend.model.Feed;
|
import com.commafeed.backend.model.Feed;
|
||||||
|
import com.google.api.client.http.HttpRequest;
|
||||||
|
import com.google.api.client.http.HttpRequestInitializer;
|
||||||
|
import com.google.api.client.http.javanet.NetHttpTransport;
|
||||||
|
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||||
|
import com.google.api.services.youtube.YouTube;
|
||||||
|
import com.google.api.services.youtube.model.Channel;
|
||||||
|
import com.google.api.services.youtube.model.ChannelListResponse;
|
||||||
|
import com.google.api.services.youtube.model.Thumbnail;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
|
||||||
@@ -20,40 +33,60 @@ import com.commafeed.backend.model.Feed;
|
|||||||
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
||||||
|
|
||||||
private final HttpGetter getter;
|
private final HttpGetter getter;
|
||||||
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] fetch(Feed feed) {
|
public byte[] fetch(Feed feed) {
|
||||||
String url = feed.getUrl();
|
String url = feed.getUrl();
|
||||||
|
|
||||||
if (!url.toLowerCase().contains("://gdata.youtube.com/")) {
|
if (!url.toLowerCase().contains("youtube.com/feeds/videos.xml")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String userName = extractUserName(url);
|
String googleAuthKey = config.getApplicationSettings().getGoogleAuthKey();
|
||||||
if (userName == null) {
|
if (googleAuthKey == null) {
|
||||||
|
log.debug("no google auth key configured");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String profileUrl = "https://gdata.youtube.com/feeds/users/" + userName;
|
|
||||||
|
|
||||||
byte[] bytes = null;
|
byte[] bytes = null;
|
||||||
String contentType = null;
|
String contentType = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log.debug("Getting YouTube user's icon, {}", url);
|
List<NameValuePair> params = URLEncodedUtils.parse(url.substring(url.indexOf("?") + 1), StandardCharsets.UTF_8);
|
||||||
|
Optional<NameValuePair> userId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("user")).findFirst();
|
||||||
// initial get to translate username to obscure user thumbnail URL
|
Optional<NameValuePair> channelId = params.stream().filter(nvp -> nvp.getName().equalsIgnoreCase("channel")).findFirst();
|
||||||
HttpResult profileResult = getter.getBinary(profileUrl, TIMEOUT);
|
System.out.println(userId.isPresent());
|
||||||
Document doc = Jsoup.parse(new String(profileResult.getContent()), profileUrl);
|
if (!userId.isPresent() && !channelId.isPresent()) {
|
||||||
|
|
||||||
Elements thumbnails = doc.select("media|thumbnail");
|
|
||||||
if (thumbnails.isEmpty()) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String thumbnailUrl = thumbnails.get(0).attr("abs:url");
|
|
||||||
|
|
||||||
// final get to actually retrieve the thumbnail
|
YouTube youtube = new YouTube.Builder(new NetHttpTransport(), JacksonFactory.getDefaultInstance(),
|
||||||
HttpResult iconResult = getter.getBinary(thumbnailUrl, TIMEOUT);
|
new HttpRequestInitializer() {
|
||||||
|
@Override
|
||||||
|
public void initialize(HttpRequest request) throws IOException {
|
||||||
|
}
|
||||||
|
}).setApplicationName("CommaFeed").build();
|
||||||
|
|
||||||
|
YouTube.Channels.List list = youtube.channels().list("snippet");
|
||||||
|
list.setKey(googleAuthKey);
|
||||||
|
if (userId.isPresent()) {
|
||||||
|
list.setForUsername(userId.get().getValue());
|
||||||
|
} else {
|
||||||
|
list.setId(channelId.get().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug("contacting youtube api");
|
||||||
|
ChannelListResponse response = list.execute();
|
||||||
|
if (response.getItems().isEmpty()) {
|
||||||
|
log.debug("youtube api returned no items");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel channel = response.getItems().get(0);
|
||||||
|
Thumbnail thumbnail = channel.getSnippet().getThumbnails().getDefault();
|
||||||
|
|
||||||
|
log.debug("fetching favicon");
|
||||||
|
HttpResult iconResult = getter.getBinary(thumbnail.getUrl(), TIMEOUT);
|
||||||
bytes = iconResult.getContent();
|
bytes = iconResult.getContent();
|
||||||
contentType = iconResult.getContentType();
|
contentType = iconResult.getContentType();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -65,19 +98,4 @@ public class YoutubeFaviconFetcher extends AbstractFaviconFetcher {
|
|||||||
}
|
}
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String extractUserName(String url) {
|
|
||||||
int apiOrBase = url.indexOf("/users/");
|
|
||||||
if (apiOrBase == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int userEndSlash = url.indexOf('/', apiOrBase + "/users/".length());
|
|
||||||
if (userEndSlash == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return url.substring(apiOrBase + "/users/".length(), userEndSlash);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user