Skip to content

Commit 50deda4

Browse files
committed
correct handling of dgs videotype (#1067)
1 parent e740cd7 commit 50deda4

File tree

3 files changed

+380
-77
lines changed

3 files changed

+380
-77
lines changed

src/main/java/de/mediathekview/mserver/crawler/zdf/tasks/ZdfFilmTask.java

Lines changed: 88 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,105 @@
1313
import de.mediathekview.mserver.crawler.zdf.json.DownloadDto;
1414
import de.mediathekview.mserver.crawler.zdf.json.ZdfDownloadDtoDeserializer;
1515
import jakarta.ws.rs.client.WebTarget;
16-
import org.apache.logging.log4j.LogManager;
17-
import org.apache.logging.log4j.Logger;
18-
1916
import java.lang.reflect.Type;
2017
import java.net.MalformedURLException;
2118
import java.net.URI;
2219
import java.time.Duration;
2320
import java.util.*;
21+
import org.apache.logging.log4j.LogManager;
22+
import org.apache.logging.log4j.Logger;
2423

2524
public class ZdfFilmTask extends ZdfTaskBase<Film, ZdfFilmDto> {
2625

2726
private static final Logger LOG = LogManager.getLogger(ZdfFilmTask.class);
2827

2928
private static final Type OPTIONAL_DOWNLOAD_DTO_TYPE_TOKEN =
30-
new TypeToken<Optional<DownloadDto>>() {}.getType();
29+
new TypeToken<Optional<DownloadDto>>() {}.getType();
3130

3231
private final transient ZdfVideoUrlOptimizer optimizer = new ZdfVideoUrlOptimizer(crawler);
3332

34-
public ZdfFilmTask(
35-
AbstractCrawler aCrawler, Queue<ZdfFilmDto> aUrlToCrawlDtos, String authKey) {
33+
public ZdfFilmTask(AbstractCrawler aCrawler, Queue<ZdfFilmDto> aUrlToCrawlDtos, String authKey) {
3634
super(aCrawler, aUrlToCrawlDtos, authKey);
3735
registerJsonDeserializer(OPTIONAL_DOWNLOAD_DTO_TYPE_TOKEN, new ZdfDownloadDtoDeserializer());
3836
}
3937

40-
private static Film createFilm(final ZdfFilmDto aFilm, final DownloadDto downloadDto) throws MalformedURLException {
38+
private static Film createFilm(final ZdfFilmDto aFilm, final DownloadDto downloadDto)
39+
throws MalformedURLException {
4140
final Film film =
42-
new Film(
43-
UUID.randomUUID(),
44-
aFilm.getSender(),
45-
aFilm.getTitle(),
46-
aFilm.getTopic(),
47-
aFilm.getTime(),
48-
downloadDto.getDuration().orElse(Duration.ZERO));
41+
new Film(
42+
UUID.randomUUID(),
43+
aFilm.getSender(),
44+
aFilm.getTitle(),
45+
aFilm.getTopic(),
46+
aFilm.getTime(),
47+
downloadDto.getDuration().orElse(Duration.ZERO));
4948

5049
film.setBeschreibung(aFilm.getDescription());
5150
film.setWebsite(URI.create(aFilm.getWebsite()).toURL());
5251

5352
return film;
5453
}
5554

55+
private static void setSubtitle(DownloadDto downloadDto, Film filmWithLanguage, String language)
56+
throws MalformedURLException {
57+
final Optional<String> subtitleUrl = downloadDto.getSubTitleUrl(language);
58+
if (subtitleUrl.isPresent()) {
59+
filmWithLanguage.addSubtitle(URI.create(subtitleUrl.get()).toURL());
60+
}
61+
}
62+
63+
private static void setGeoLocation(DownloadDto downloadDto, Film filmWithLanguage) {
64+
final Optional<GeoLocations> geoLocation = downloadDto.getGeoLocation();
65+
if (geoLocation.isPresent()) {
66+
final Collection<GeoLocations> geo = new ArrayList<>();
67+
geo.add(geoLocation.get());
68+
filmWithLanguage.setGeoLocations(geo);
69+
}
70+
}
71+
72+
private static Film clone(final Film aFilm, final String aLanguage) {
73+
final Film film =
74+
new Film(
75+
UUID.randomUUID(),
76+
aFilm.getSender(),
77+
aFilm.getTitel(),
78+
aFilm.getThema(),
79+
aFilm.getTime(),
80+
aFilm.getDuration());
81+
82+
film.setBeschreibung(aFilm.getBeschreibung());
83+
film.setWebsite(aFilm.getWebsite().orElse(null));
84+
85+
updateTitle(aLanguage, film);
86+
87+
return film;
88+
}
89+
90+
private static void updateTitle(final String aLanguage, final Film aFilm) {
91+
String title = aFilm.getTitel();
92+
switch (aLanguage) {
93+
case ZdfConstants.LANGUAGE_GERMAN:
94+
return;
95+
case ZdfConstants.LANGUAGE_ENGLISH:
96+
title += " (Englisch)";
97+
break;
98+
case ZdfConstants.LANGUAGE_FRENCH:
99+
title += " (Französisch)";
100+
break;
101+
default:
102+
title += "(" + aLanguage + ")";
103+
}
104+
105+
aFilm.setTitel(title);
106+
}
107+
56108
@Override
57109
protected void processRestTarget(ZdfFilmDto aDTO, WebTarget aTarget) {
58-
final Optional<DownloadDto> downloadDto = deserialize(aTarget, OPTIONAL_DOWNLOAD_DTO_TYPE_TOKEN);
110+
final Optional<DownloadDto> downloadDto =
111+
deserialize(aTarget, OPTIONAL_DOWNLOAD_DTO_TYPE_TOKEN);
59112
if (downloadDto.isPresent()) {
60113
try {
61-
addFilm(downloadDto.get(), createFilm(aDTO, downloadDto.get()));
114+
addFilm(downloadDto.get(), createFilm(aDTO, downloadDto.get()), aDTO.getVideoType());
62115
crawler.incrementAndGetActualCount();
63116
crawler.updateProgress();
64117
} catch (final MalformedURLException e) {
@@ -67,7 +120,12 @@ protected void processRestTarget(ZdfFilmDto aDTO, WebTarget aTarget) {
67120
crawler.updateProgress();
68121
}
69122
} else {
70-
LOG.error("ZdfFilmDetailTask: no video {} {} {} in {}",aDTO.getSender(), aDTO.getTitle(), aDTO.getTopic() , aDTO);
123+
LOG.error(
124+
"ZdfFilmDetailTask: no video {} {} {} in {}",
125+
aDTO.getSender(),
126+
aDTO.getTitle(),
127+
aDTO.getTopic(),
128+
aDTO);
71129
crawler.incrementAndGetErrorCount();
72130
crawler.updateProgress();
73131
}
@@ -79,8 +137,8 @@ protected AbstractRecursiveConverterTask<Film, ZdfFilmDto> createNewOwnInstance(
79137
return new ZdfFilmTask(crawler, aElementsToProcess, getAuthKey().orElse(null));
80138
}
81139

82-
private void addFilm(final DownloadDto downloadDto, final Film result)
83-
throws MalformedURLException {
140+
private void addFilm(final DownloadDto downloadDto, final Film result, String videoType)
141+
throws MalformedURLException {
84142

85143
String previousLanguage = null;
86144
Film previousMainFilm = null;
@@ -91,11 +149,12 @@ private void addFilm(final DownloadDto downloadDto, final Film result)
91149

92150
if (language.endsWith(ZdfConstants.LANGUAGE_SUFFIX_AD)) {
93151
final Map<Resolution, FilmUrl> urls =
94-
getOptimizedUrls(downloadDto.getDownloadUrls(language));
152+
getOptimizedUrls(downloadDto.getDownloadUrls(language));
95153
urls.forEach(currentFilm::addAudioDescription);
96-
} else if (language.endsWith(ZdfConstants.LANGUAGE_SUFFIX_DGS)) {
154+
} else if (language.endsWith(ZdfConstants.LANGUAGE_SUFFIX_DGS)
155+
|| "DGS".equalsIgnoreCase(videoType)) {
97156
final Map<Resolution, FilmUrl> urls =
98-
getOptimizedUrls(downloadDto.getDownloadUrls(language));
157+
getOptimizedUrls(downloadDto.getDownloadUrls(language));
99158
urls.forEach(currentFilm::addSignLanguage);
100159
} else {
101160
LOG.debug("unknown language suffix: {}", language);
@@ -106,8 +165,12 @@ private void addFilm(final DownloadDto downloadDto, final Film result)
106165
setGeoLocation(downloadDto, filmWithLanguage);
107166

108167
final Map<Resolution, FilmUrl> urls =
109-
getOptimizedUrls(downloadDto.getDownloadUrls(language));
110-
urls.forEach(filmWithLanguage::addUrl);
168+
getOptimizedUrls(downloadDto.getDownloadUrls(language));
169+
if ("DGS".equalsIgnoreCase(videoType)) {
170+
urls.forEach(filmWithLanguage::addSignLanguage);
171+
} else {
172+
urls.forEach(filmWithLanguage::addUrl);
173+
}
111174

112175
if (!taskResults.add(filmWithLanguage)) {
113176
LOG.error("Rejected duplicate {}", filmWithLanguage);
@@ -119,7 +182,7 @@ private void addFilm(final DownloadDto downloadDto, final Film result)
119182
}
120183

121184
private Map<Resolution, FilmUrl> getOptimizedUrls(Map<Resolution, String> urls)
122-
throws MalformedURLException {
185+
throws MalformedURLException {
123186
Map<Resolution, FilmUrl> result = new EnumMap<>(Resolution.class);
124187

125188
for (final Map.Entry<Resolution, String> qualitiesEntry : urls.entrySet()) {
@@ -143,56 +206,4 @@ private Map<Resolution, FilmUrl> getOptimizedUrls(Map<Resolution, String> urls)
143206
}
144207
return result;
145208
}
146-
147-
private static void setSubtitle(DownloadDto downloadDto, Film filmWithLanguage, String language) throws MalformedURLException {
148-
final Optional<String> subtitleUrl = downloadDto.getSubTitleUrl(language);
149-
if (subtitleUrl.isPresent()) {
150-
filmWithLanguage.addSubtitle(URI.create(subtitleUrl.get()).toURL());
151-
}
152-
}
153-
154-
private static void setGeoLocation(DownloadDto downloadDto, Film filmWithLanguage) {
155-
final Optional<GeoLocations> geoLocation = downloadDto.getGeoLocation();
156-
if (geoLocation.isPresent()) {
157-
final Collection<GeoLocations> geo = new ArrayList<>();
158-
geo.add(geoLocation.get());
159-
filmWithLanguage.setGeoLocations(geo);
160-
}
161-
}
162-
163-
private static Film clone(final Film aFilm, final String aLanguage) {
164-
final Film film =
165-
new Film(
166-
UUID.randomUUID(),
167-
aFilm.getSender(),
168-
aFilm.getTitel(),
169-
aFilm.getThema(),
170-
aFilm.getTime(),
171-
aFilm.getDuration());
172-
173-
film.setBeschreibung(aFilm.getBeschreibung());
174-
film.setWebsite(aFilm.getWebsite().orElse(null));
175-
176-
updateTitle(aLanguage, film);
177-
178-
return film;
179-
}
180-
181-
private static void updateTitle(final String aLanguage, final Film aFilm) {
182-
String title = aFilm.getTitel();
183-
switch (aLanguage) {
184-
case ZdfConstants.LANGUAGE_GERMAN:
185-
return;
186-
case ZdfConstants.LANGUAGE_ENGLISH:
187-
title += " (Englisch)";
188-
break;
189-
case ZdfConstants.LANGUAGE_FRENCH:
190-
title += " (Französisch)";
191-
break;
192-
default:
193-
title += "(" + aLanguage + ")";
194-
}
195-
196-
aFilm.setTitel(title);
197-
}
198209
}

src/test/java/de/mediathekview/mserver/crawler/zdf/json/ZdfTopicSeasonDeserializerTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,36 @@ void deserializeValidJson() {
4545
"default",
4646
"https://api.zdf.de/tmd/2/android_native_5/vod/ptmd/mediathek/240101_2015_sendung_trs/8")));
4747
}
48+
49+
@Test
50+
void deserializeJsonWithDgs() {
51+
final JsonObject json = JsonFileReader.readJson("/zdf/zdf_topic_page_with_dgs.json");
52+
final PagedElementListDTO<ZdfFilmDto> actual = target.deserialize(json, null, null);
53+
54+
assertEquals(Optional.empty(), actual.getNextPage());
55+
assertEquals(2, actual.getElements().size());
56+
assertThat(
57+
actual.getElements(),
58+
Matchers.containsInAnyOrder(
59+
new ZdfFilmDto(
60+
Sender.ZDF,
61+
"Die Insel der Giganten (S01/E04)",
62+
"Die Knochen des Lusotitan Old Grande erzählen die Geschichte eines alten, aber ehrgeizigen Bullen, der sich aufmacht, eine Partnerin zu finden, und bereit ist, dafür alles zu riskieren.",
63+
"https://www.zdf.de/video/dokus/terra-x-unter-dinos-geheimnisse-der-urzeit-dokureihe-100/terra-x-unter-dinos-lusotitan-old-grande-die-insel-der-giganten-doku-100",
64+
LocalDateTime.of(2025, 8, 20, 4, 0, 0),
65+
"dgs",
66+
"https://api.zdf.de/tmd/2/android_native_5/vod/ptmd/mediathek/250914_dk_dinos_insel_giganten_tex_dgs/2?caption_source=250914_dk_dinos_insel_giganten_tex%2F5"),
67+
new ZdfFilmDto(
68+
Sender.ZDF,
69+
"Die Insel der Giganten (S01/E04)",
70+
"Die Knochen des Lusotitan Old Grande erzählen die Geschichte eines alten, aber ehrgeizigen Bullen, der sich aufmacht, eine Partnerin zu finden, und bereit ist, dafür alles zu riskieren.",
71+
"https://www.zdf.de/video/dokus/terra-x-unter-dinos-geheimnisse-der-urzeit-dokureihe-100/terra-x-unter-dinos-lusotitan-old-grande-die-insel-der-giganten-doku-100",
72+
LocalDateTime.of(2025, 8, 20, 4, 0, 0),
73+
"default",
74+
"https://api.zdf.de/tmd/2/android_native_5/vod/ptmd/mediathek/250914_dk_dinos_insel_giganten_tex/5")));
75+
}
76+
77+
4878
@Test
4979
void deserializeZdfNeo() {
5080
final JsonObject json = JsonFileReader.readJson("/zdf/zdf_topic_page_neo.json");

0 commit comments

Comments
 (0)