2019-05-06 06:28:30 -04:00
|
|
|
package net.filebot.web;
|
|
|
|
|
|
|
|
import static java.util.Arrays.*;
|
2019-06-01 06:43:18 -04:00
|
|
|
import static java.util.Collections.*;
|
2019-05-06 06:28:30 -04:00
|
|
|
import static java.util.stream.Collectors.*;
|
2019-06-07 10:21:49 -04:00
|
|
|
import static net.filebot.Logging.*;
|
2019-05-06 06:28:30 -04:00
|
|
|
import static net.filebot.util.JsonUtilities.*;
|
2019-06-01 06:43:18 -04:00
|
|
|
import static net.filebot.util.StringUtilities.*;
|
2019-05-06 06:28:30 -04:00
|
|
|
import static net.filebot.web.WebRequest.*;
|
|
|
|
|
|
|
|
import java.net.URL;
|
|
|
|
import java.util.ArrayList;
|
2019-06-01 06:43:18 -04:00
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.HashMap;
|
2019-05-06 06:28:30 -04:00
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Objects;
|
2019-06-01 06:43:18 -04:00
|
|
|
import java.util.Optional;
|
2019-05-30 15:25:54 -04:00
|
|
|
import java.util.Set;
|
2019-05-06 06:28:30 -04:00
|
|
|
|
|
|
|
import net.filebot.Cache;
|
|
|
|
import net.filebot.CacheType;
|
2019-06-01 11:56:51 -04:00
|
|
|
import net.filebot.Resource;
|
2019-05-06 06:28:30 -04:00
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
public enum XEM {
|
2019-05-06 06:28:30 -04:00
|
|
|
|
2019-06-07 10:21:49 -04:00
|
|
|
AniDB, TheTVDB, Scene, Tract;
|
2019-06-01 06:43:18 -04:00
|
|
|
|
|
|
|
public String getOriginName() {
|
|
|
|
switch (this) {
|
|
|
|
case TheTVDB:
|
|
|
|
return "tvdb";
|
2019-06-07 10:21:49 -04:00
|
|
|
default:
|
|
|
|
return name().toLowerCase();
|
2019-06-01 06:43:18 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Integer getSeason(Integer s) {
|
|
|
|
return this == AniDB ? 1 : s;
|
|
|
|
}
|
|
|
|
|
2019-06-01 11:56:51 -04:00
|
|
|
protected final Resource<Set<Integer>> haveMap = Resource.lazy(this::getHaveMap);
|
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
public Optional<Episode> map(Episode episode, XEM destination) throws Exception {
|
2019-06-01 11:56:51 -04:00
|
|
|
Integer seriesId = episode.getSeriesInfo().getId();
|
2019-06-01 06:43:18 -04:00
|
|
|
|
2019-06-01 11:56:51 -04:00
|
|
|
if (!haveMap.get().contains(seriesId)) {
|
2019-06-01 06:43:18 -04:00
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
|
|
|
String seriesName = episode.getSeriesName();
|
|
|
|
Integer season = getSeason(episode.getSeason());
|
|
|
|
|
|
|
|
Map<String, List<String>> names = getNames(seriesId);
|
|
|
|
|
|
|
|
Integer mappedSeason = names.entrySet().stream().filter(it -> {
|
|
|
|
return it.getValue().contains(seriesName);
|
|
|
|
}).map(it -> {
|
|
|
|
return matchInteger(it.getKey());
|
|
|
|
}).filter(Objects::nonNull).findFirst().orElse(season);
|
|
|
|
|
|
|
|
String mappedSeriesName = names.get("all").get(0);
|
|
|
|
|
2019-06-01 11:56:51 -04:00
|
|
|
Map<String, Map<String, Number>> mapping = episode.getEpisode() != null ? getSingle(seriesId, mappedSeason, episode.getEpisode()) : getSingle(seriesId, 0, episode.getSpecial());
|
2019-06-01 06:43:18 -04:00
|
|
|
|
|
|
|
List<Episode> mappedEpisode = mapping.entrySet().stream().filter(it -> {
|
|
|
|
return it.getKey().startsWith(destination.getOriginName());
|
|
|
|
}).map(it -> {
|
2019-06-07 10:21:49 -04:00
|
|
|
debug.finest(format("[XEM] %s | %s | %s", mappedSeriesName, mappedSeason, it));
|
2019-06-01 11:56:51 -04:00
|
|
|
|
2019-06-07 10:21:49 -04:00
|
|
|
Map<String, Number> mappedNumbers = it.getValue();
|
2019-06-01 11:56:51 -04:00
|
|
|
Integer e = getInteger(mappedNumbers, "episode");
|
|
|
|
Integer a = getInteger(mappedNumbers, "absolute");
|
2019-06-03 23:02:26 -04:00
|
|
|
Integer special = null;
|
2019-06-01 06:43:18 -04:00
|
|
|
|
2019-06-03 23:02:26 -04:00
|
|
|
return episode.derive(mappedSeriesName, mappedSeason, e, a, special);
|
2019-06-01 06:43:18 -04:00
|
|
|
}).collect(toList());
|
|
|
|
|
|
|
|
if (mappedEpisode.size() == 1) {
|
|
|
|
return Optional.of(mappedEpisode.get(0));
|
|
|
|
} else if (mappedEpisode.size() > 1) {
|
|
|
|
return Optional.of(new MultiEpisode(mappedEpisode));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Optional.empty();
|
|
|
|
}
|
|
|
|
|
2019-06-01 11:56:51 -04:00
|
|
|
public List<Map<String, Map<String, Integer>>> getAll(Integer id) throws Exception {
|
2019-05-06 08:54:12 -04:00
|
|
|
Map<String, Object> parameters = new LinkedHashMap<>(2);
|
2019-06-01 06:43:18 -04:00
|
|
|
parameters.put("origin", getOriginName());
|
2019-05-30 15:25:54 -04:00
|
|
|
parameters.put("id", id);
|
2019-05-06 08:54:12 -04:00
|
|
|
|
2019-05-30 15:25:54 -04:00
|
|
|
Object response = request("all", parameters);
|
|
|
|
return (List) asList(getArray(response, "data"));
|
|
|
|
}
|
2019-05-06 08:54:12 -04:00
|
|
|
|
2019-06-01 11:56:51 -04:00
|
|
|
public Map<String, Map<String, Number>> getSingle(Integer id, Integer season, Integer episode) throws Exception {
|
2019-05-30 15:25:54 -04:00
|
|
|
Map<String, Object> parameters = new LinkedHashMap<>(4);
|
2019-06-01 06:43:18 -04:00
|
|
|
parameters.put("origin", getOriginName());
|
2019-05-30 15:25:54 -04:00
|
|
|
parameters.put("id", id);
|
|
|
|
parameters.put("season", season);
|
|
|
|
parameters.put("episode", episode);
|
|
|
|
|
|
|
|
Object response = request("single", parameters);
|
|
|
|
return (Map) getMap(response, "data");
|
2019-05-06 08:54:12 -04:00
|
|
|
}
|
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
public List<SearchResult> getAllNames() throws Exception {
|
|
|
|
return getAllNames(null, null, true);
|
2019-05-06 06:28:30 -04:00
|
|
|
}
|
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
public List<SearchResult> getAllNames(Integer season, String language, boolean defaultNames) throws Exception {
|
2019-05-30 15:25:54 -04:00
|
|
|
List<SearchResult> result = new ArrayList<>();
|
|
|
|
|
2019-05-06 08:54:12 -04:00
|
|
|
Map<String, Object> parameters = new LinkedHashMap<>(4);
|
2019-06-01 06:43:18 -04:00
|
|
|
parameters.put("origin", getOriginName());
|
2019-05-06 06:28:30 -04:00
|
|
|
parameters.put("season", season);
|
|
|
|
parameters.put("language", language);
|
|
|
|
parameters.put("defaultNames", defaultNames ? "1" : "0");
|
|
|
|
|
2019-05-30 15:25:54 -04:00
|
|
|
Object response = request("allNames", parameters);
|
2019-05-06 06:28:30 -04:00
|
|
|
|
|
|
|
getMap(response, "data").forEach((k, v) -> {
|
|
|
|
int id = Integer.parseInt(k.toString());
|
|
|
|
List<String> names = stream(asArray(v)).filter(Objects::nonNull).map(Objects::toString).filter(s -> s.length() > 0).collect(toList());
|
|
|
|
|
|
|
|
if (names.size() > 0) {
|
|
|
|
result.add(new SearchResult(id, names.get(0), names.subList(1, names.size())));
|
|
|
|
}
|
|
|
|
});
|
2019-05-30 15:25:54 -04:00
|
|
|
|
2019-05-06 06:28:30 -04:00
|
|
|
return result;
|
2019-05-30 15:25:54 -04:00
|
|
|
}
|
2019-05-06 06:28:30 -04:00
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
public Set<Integer> getHaveMap() throws Exception {
|
2019-05-30 15:25:54 -04:00
|
|
|
Map<String, Object> parameters = new LinkedHashMap<>(1);
|
2019-06-01 06:43:18 -04:00
|
|
|
parameters.put("origin", getOriginName());
|
2019-05-30 15:25:54 -04:00
|
|
|
|
|
|
|
Object response = request("havemap", parameters);
|
|
|
|
return stream(getArray(response, "data")).map(Object::toString).map(Integer::parseInt).collect(toSet());
|
|
|
|
}
|
|
|
|
|
2019-06-01 11:56:51 -04:00
|
|
|
public Map<String, List<String>> getNames(Integer id) throws Exception {
|
2019-05-30 15:25:54 -04:00
|
|
|
Map<String, Object> parameters = new LinkedHashMap<>(3);
|
2019-06-01 06:43:18 -04:00
|
|
|
parameters.put("origin", getOriginName());
|
2019-05-30 15:25:54 -04:00
|
|
|
parameters.put("id", id);
|
|
|
|
parameters.put("defaultNames", "1");
|
|
|
|
|
|
|
|
Object response = request("names", parameters);
|
2019-06-01 06:43:18 -04:00
|
|
|
Map<String, List<String>> names = new HashMap<>();
|
|
|
|
|
|
|
|
getMap(response, "data").forEach((k, v) -> {
|
|
|
|
names.put(k.toString(), asNamesList(v));
|
|
|
|
});
|
|
|
|
|
|
|
|
return names;
|
2019-05-30 15:25:54 -04:00
|
|
|
}
|
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
private List<String> asNamesList(Object value) {
|
|
|
|
if (value instanceof Map) {
|
|
|
|
Map<Object, Object[]> names = (Map) value;
|
|
|
|
return names.values().stream().flatMap(a -> stream(a)).map(Object::toString).collect(toList());
|
|
|
|
} else if (value instanceof Collection) {
|
|
|
|
Collection<Object> names = (Collection) value;
|
|
|
|
return names.stream().map(Object::toString).collect(toList());
|
|
|
|
}
|
|
|
|
return singletonList(value.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Object request(String path, Map<String, Object> parameters) throws Exception {
|
2019-05-30 15:25:54 -04:00
|
|
|
return request(path + '?' + encodeParameters(parameters, true));
|
2019-05-06 06:28:30 -04:00
|
|
|
}
|
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
protected Object request(String path) throws Exception {
|
2019-05-30 15:25:54 -04:00
|
|
|
return getCache().json(path, this::getResource).expire(Cache.ONE_WEEK).get();
|
2019-05-06 06:28:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
protected URL getResource(String path) throws Exception {
|
|
|
|
return new URL("http://thexem.de/map/" + path);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected Cache getCache() {
|
|
|
|
return Cache.getCache("xem", CacheType.Monthly);
|
|
|
|
}
|
|
|
|
|
2019-06-01 06:43:18 -04:00
|
|
|
public static List<String> names() {
|
|
|
|
return stream(values()).map(Enum::name).collect(toList());
|
|
|
|
}
|
|
|
|
|
|
|
|
public static XEM forName(String name) {
|
|
|
|
for (XEM db : values()) {
|
|
|
|
if (db.name().equalsIgnoreCase(name) || db.getOriginName().equalsIgnoreCase(name)) {
|
|
|
|
return db;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-07 10:21:49 -04:00
|
|
|
throw new IllegalArgumentException(String.format("%s not in %s", name, asList(values())));
|
2019-06-01 06:43:18 -04:00
|
|
|
}
|
|
|
|
|
2019-05-06 06:28:30 -04:00
|
|
|
}
|