46 lines
1.9 KiB
Java
46 lines
1.9 KiB
Java
package com.hlab.yanalyst.domain.channel;
|
|
|
|
import com.hlab.yanalyst.web.dto.YoutubeSearchResultDto;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Comparator;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
|
|
/** 검색된 Shorts 목록 → 채널별 최고 배율 후보 집계·필터·정렬(순수 로직). */
|
|
public final class DiscoveryRanker {
|
|
|
|
private DiscoveryRanker() {}
|
|
|
|
public record Candidate(String channelId, String channelTitle, String thumbnailUrl, Long subscriberCount,
|
|
String topVideoId, String topVideoTitle, Long topVideoViewCount,
|
|
double ratio, String region) {}
|
|
|
|
public static List<Candidate> rank(List<YoutubeSearchResultDto> items, long maxSubscribers,
|
|
double minRatio, Set<String> excludeChannelIds) {
|
|
Map<String, Candidate> best = new LinkedHashMap<>();
|
|
for (YoutubeSearchResultDto it : items) {
|
|
String ch = it.getChannelId();
|
|
Long subs = it.getSubscriberCount();
|
|
Long views = it.getViewCount();
|
|
if (ch == null || subs == null || subs <= 0 || views == null) continue;
|
|
if (excludeChannelIds.contains(ch)) continue;
|
|
if (subs > maxSubscribers) continue;
|
|
|
|
double ratio = (double) views / subs;
|
|
if (ratio < minRatio) continue;
|
|
|
|
Candidate prev = best.get(ch);
|
|
if (prev == null || ratio > prev.ratio()) {
|
|
best.put(ch, new Candidate(ch, it.getChannelTitle(), it.getThumbnailUrl(), subs,
|
|
it.getVideoId(), it.getTitle(), views, ratio, it.getChannelCountry()));
|
|
}
|
|
}
|
|
List<Candidate> out = new ArrayList<>(best.values());
|
|
out.sort(Comparator.comparingDouble(Candidate::ratio).reversed());
|
|
return out;
|
|
}
|
|
}
|