Skip to content

Commit 424fd75

Browse files
authored
Merge pull request #1141 from derreisende77/develop
Verbessertes Zuschneiden der Beschreibungstexte
2 parents 1b58ad8 + 2822799 commit 424fd75

7 files changed

Lines changed: 125 additions & 22 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package de.mediathekview.mserver.base.utils;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.regex.Pattern;
6+
7+
public final class SentenceShortener {
8+
private static final Pattern WHITESPACE_REGEX = Pattern.compile("\\s+");
9+
private static final Pattern SENTENCE_BOUNDARY_REGEX = Pattern.compile("(?<=[.!?])\\s+");
10+
private static final String SHORTENING_SUFFIX = "...";
11+
12+
private SentenceShortener() {
13+
}
14+
15+
/**
16+
* Shortens text to a target length while preserving complete sentences.
17+
*
18+
* <p>Whitespace is normalized before shortening. If the text is already within the target
19+
* length, the normalized text is returned unchanged. If adding the next sentence would exceed
20+
* {@code targetLength + marginLength}, that sentence is omitted and {@code ...} is appended to
21+
* the returned text. If the first sentence alone is already longer than the limit, it is kept
22+
* whole.
23+
*
24+
* @param text the text to shorten; may be {@code null}
25+
* @param targetLength the preferred target length; must be positive
26+
* @param marginLength the allowed soft overflow beyond the target; must not be negative
27+
* @return the shortened text, or {@code null} if the input is {@code null} or blank
28+
* @throws IllegalArgumentException if {@code targetLength <= 0} or {@code marginLength < 0}
29+
*/
30+
public static String shorten(String text, int targetLength, int marginLength) {
31+
if (targetLength <= 0) {
32+
throw new IllegalArgumentException("targetLength must be positive");
33+
}
34+
if (marginLength < 0) {
35+
throw new IllegalArgumentException("marginLength must not be negative");
36+
}
37+
38+
String normalized = normalize(text);
39+
if (normalized == null || normalized.length() <= targetLength) {
40+
return normalized;
41+
}
42+
43+
int softLimit = targetLength + marginLength;
44+
String[] rawSentences = SENTENCE_BOUNDARY_REGEX.split(normalized);
45+
List<String> sentences = new ArrayList<>();
46+
for (String rawSentence : rawSentences) {
47+
String sentence = rawSentence.trim();
48+
if (!sentence.isEmpty()) {
49+
sentences.add(sentence);
50+
}
51+
}
52+
if (sentences.isEmpty()) {
53+
return normalized;
54+
}
55+
56+
List<String> selectedSentences = new ArrayList<>();
57+
int currentLength = 0;
58+
for (String sentence : sentences) {
59+
int candidateLength = selectedSentences.isEmpty()
60+
? sentence.length()
61+
: currentLength + 1 + sentence.length();
62+
if (candidateLength > softLimit) {
63+
break;
64+
}
65+
selectedSentences.add(sentence);
66+
currentLength = candidateLength;
67+
}
68+
69+
if (!selectedSentences.isEmpty()) {
70+
String shortened = String.join(" ", selectedSentences);
71+
return selectedSentences.size() < sentences.size()
72+
? shortened + SHORTENING_SUFFIX
73+
: shortened;
74+
}
75+
return sentences.size() > 1
76+
? sentences.getFirst() + SHORTENING_SUFFIX
77+
: sentences.getFirst();
78+
}
79+
80+
/**
81+
* Shortens text to a target length without any soft overflow margin.
82+
*
83+
* @param text the text to shorten; may be {@code null}
84+
* @param targetLength the preferred target length; must be positive
85+
* @return the shortened text, or {@code null} if the input is {@code null} or blank
86+
* @throws IllegalArgumentException if {@code targetLength <= 0}
87+
*/
88+
public static String shorten(String text, int targetLength) {
89+
return shorten(text, targetLength, 0);
90+
}
91+
92+
/**
93+
* Normalizes whitespace and trims a text value.
94+
*
95+
* @param text the text to normalize; may be {@code null}
96+
* @return the normalized text, or {@code null} if the input is {@code null} or blank
97+
*/
98+
public static String normalize(String text) {
99+
if (text == null) {
100+
return null;
101+
}
102+
String normalized = WHITESPACE_REGEX.matcher(text).replaceAll(" ").trim();
103+
return normalized.isEmpty() ? null : normalized;
104+
}
105+
}

src/main/java/de/mediathekview/mserver/base/utils/TextCleaner.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public class TextCleaner {
1111
private static final String CARRIAGE_RETURN = "\r";
1212
private static final String NO_BREAK_SPACE = "\u00a0";
1313
private static final int MAX_BESCHREIBUNG = 400;
14+
private static final int MAX_BESCHREIBUNG_MARGIN_LENGTH = 40;
1415
private static final String[] GERMAN_GEOBLOCKING_TEXTS = {
1516
"+++ Aus rechtlichen Gründen ist der Film nur innerhalb von Deutschland abrufbar. +++",
1617
"+++ Aus rechtlichen Gründen ist diese Sendung nur innerhalb von Deutschland abrufbar. +++",
@@ -64,10 +65,7 @@ private static String cleanGeoBlockingTexts(final String text) {
6465
}
6566

6667
private static String shortenBeschreibung(final String text) {
67-
if (text.length() > MAX_BESCHREIBUNG) {
68-
return text.substring(0, MAX_BESCHREIBUNG) + "\n.....";
69-
}
70-
return text;
68+
return SentenceShortener.shorten(text, MAX_BESCHREIBUNG, MAX_BESCHREIBUNG_MARGIN_LENGTH);
7169
}
7270

7371
private static String beschreibungCleanUp(

src/test/java/de/mediathekview/mserver/crawler/ard/json/ArdFilmDeserializerTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public static Collection<Object[]> data() {
112112
/*jsonFile*/ "/ard/ard_item_DGS_UT_AD.json",
113113
/*topic*/ "Tatort",
114114
/*title*/ "Der Fluch des Geldes",
115-
/*description*/ "Spielfilm Deutschland 2024 +++ \"Der Fluch des Geldes\" beginnt da, wo \"Die Kälte der Erde\" endete. Die Hauptkommissare streiten sich, denn Leo Hölzer musste entdecken, dass sein Partner Adam Schürk im Besitz der Beute aus einem Bankraub seines verstorbenen Vaters ist. +++ Mit Vladimir Burlakov, Daniel Sträßer, Susanne Bormann, Omar El-Saeidi, Jasmina Al Zihairi u.a. | Buch: Hendrik Hölzemann \n.....",
115+
/*description*/ "Spielfilm Deutschland 2024 +++ \"Der Fluch des Geldes\" beginnt da, wo \"Die Kälte der Erde\" endete. Die Hauptkommissare streiten sich, denn Leo Hölzer musste entdecken, dass sein Partner Adam Schürk im Besitz der Beute aus einem Bankraub seines verstorbenen Vaters ist. +++ Mit Vladimir Burlakov, Daniel Sträßer, Susanne Bormann, Omar El-Saeidi, Jasmina Al Zihairi u.a. | Buch: Hendrik Hölzemann | Regie: Christian Theede",
116116
/*date*/ LocalDateTime.parse("2024-01-28T20:15"),
117117
/*duration*/ Duration.parse("PT1H28M33S"),
118118
/*small*/ "https://pd-videos.daserste.de/int/2024/01/18/3322bac1-6935-4101-8e41-380d70eff67e/JOB_430813_sendeton_640x360-50p-1200kbit.mp4",
@@ -152,7 +152,7 @@ public static Collection<Object[]> data() {
152152
/*jsonFile*/ "/ard/ard_item_STD_DasErste.json",
153153
/*topic*/ "tagesschau",
154154
/*title*/ "tagesschau 11:10 Uhr, 01.05.2024",
155-
/*description*/ "Bundesweit Kundgebungen zum Tag der Arbeit für bessere Arbeitsbedingungen, Bereits erste Demonstrationen in Berlin und Hamburg, Polizei in Georgiens Hauptstadt Tiflis geht massiv gegen pro-europäische Demonstranten vor, US-Einsatzkräfte räumen mit Großaufgebot besetztes Gebäude der Columbia Universität in New York, US-Bestsellerautor Paul Auster stirbt im Alter von 77 Jahren, Walpurgisnacht im Har\n.....",
155+
/*description*/ "Bundesweit Kundgebungen zum Tag der Arbeit für bessere Arbeitsbedingungen, Bereits erste Demonstrationen in Berlin und Hamburg, Polizei in Georgiens Hauptstadt Tiflis geht massiv gegen pro-europäische Demonstranten vor, US-Einsatzkräfte räumen mit Großaufgebot besetztes Gebäude der Columbia Universität in New York, US-Bestsellerautor Paul Auster stirbt im Alter von 77 Jahren, Walpurgisnacht im Harz, Das Wetter",
156156
/*date*/ LocalDateTime.parse("2024-05-01T11:10"),
157157
/*duration*/ Duration.parse("PT5M6S"),
158158
/*small*/ "https://media.tagesschau.de/video/2024/0501/TV-20240501-1117-3700.webm.h264.mp4",
@@ -212,7 +212,7 @@ public static Collection<Object[]> data() {
212212
/*jsonFile*/ "/ard/ard_item_STD_ONE.json",
213213
/*topic*/ "Murdoch Mysteries",
214214
/*title*/ "Folge 4: Geisterstunde (S01/E04) (Originalversion)",
215-
/*description*/ "Murdoch schließt sich mit seinem Helden Arthur Conan Doyle zusammen, um einen Mord aufzuklären, der während einer Séance unter der Leitung des Mediums Sarah Pensall aufgedeckt wurde. Es scheint, dass das Opfer Ida Winston, Mitglied einer paranormalen Wächtergruppe, nicht von Sarahs Fähigkeiten überzeugt war. Murdoch fragt sich, ob Sarah Ida getötet hat, weil sie kurz davorstand, als Betrügerin ent\n.....",
215+
/*description*/ "Murdoch schließt sich mit seinem Helden Arthur Conan Doyle zusammen, um einen Mord aufzuklären, der während einer Séance unter der Leitung des Mediums Sarah Pensall aufgedeckt wurde. Es scheint, dass das Opfer Ida Winston, Mitglied einer paranormalen Wächtergruppe, nicht von Sarahs Fähigkeiten überzeugt war. Murdoch fragt sich, ob Sarah Ida getötet hat, weil sie kurz davorstand, als Betrügerin entlarvt zu werden.",
216216
/*date*/ LocalDateTime.parse("2024-05-01T04:15"),
217217
/*duration*/ Duration.parse("PT46M4S"),
218218
/*small*/ "https://wdrmedien-a.akamaihd.net/medp/ondemand/de/fsk12/310/3106351/3106351_57089636.mp4",
@@ -232,7 +232,7 @@ public static Collection<Object[]> data() {
232232
/*jsonFile*/ "/ard/ard_item_STD_RBB.json",
233233
/*topic*/ "Blue Moon",
234234
/*title*/ "Blue Moon vom 30.04.2024",
235-
/*description*/ "Den Rucksack auskippen, bloßstellende Fotos posten oder Beleidigungen nachrufen - fast jedes sechste Schulkind ist bei uns von Mobbing betroffen. Aber auch im Büro, an der Uni oder im Verein gibt es Mobbing! Diese Woche sprechen wir bei Fritz über das Thema Mobbing, alle Inhalte und Hilfsangebote findet ihr hier: fritz.de/mobbing. Claudia Kamieth will deshalb heute im Blue Moon von euch wissen: Wu\n.....",
235+
/*description*/ "Den Rucksack auskippen, bloßstellende Fotos posten oder Beleidigungen nachrufen - fast jedes sechste Schulkind ist bei uns von Mobbing betroffen. Aber auch im Büro, an der Uni oder im Verein gibt es Mobbing! Diese Woche sprechen wir bei Fritz über das Thema Mobbing, alle Inhalte und Hilfsangebote findet ihr hier: fritz.de/mobbing....",
236236
/*date*/ LocalDateTime.parse("2024-04-30T22:15"),
237237
/*duration*/ Duration.parse("PT1H43M15S"),
238238
/*small*/ "https://rbbmediapmdp-a.akamaihd.net/content/dd/f9/ddf9c4f0-2da1-45b9-812f-873f213ccbd5/eb2ed184-078d-11ef-b0da-02420a000df3_hd1080-avc360.mp4",
@@ -252,7 +252,7 @@ public static Collection<Object[]> data() {
252252
/*jsonFile*/ "/ard/ard_item_STD_AD_DasErste.json",
253253
/*topic*/ "Mord mit Aussicht",
254254
/*title*/ "Folge 3: Die Bestechlichen (S05/E03)",
255-
/*description*/ "Marie zögert noch bei Gisberts Angebot, zu ihm auf den Schweine-Hof zu ziehen. Willkommene Ablenkung bietet Marie eine Leiche im Heuballen auf Müller Schlichtings Wiese. Der Tote ist Albert Appel, der mit seinem Bruder Kai einen Bauernhof betreibt und außerdem Schiedsrichter der Regionalliga ist. Die Ermittlungen führen in die Welt des Fußballs und zweier rivalisierender Clubs. Das Auftauchen ein\n.....",
255+
/*description*/ "Marie zögert noch bei Gisberts Angebot, zu ihm auf den Schweine-Hof zu ziehen. Willkommene Ablenkung bietet Marie eine Leiche im Heuballen auf Müller Schlichtings Wiese. Der Tote ist Albert Appel, der mit seinem Bruder Kai einen Bauernhof betreibt und außerdem Schiedsrichter der Regionalliga ist. Die Ermittlungen führen in die Welt des Fußballs und zweier rivalisierender Clubs....",
256256
/*date*/ LocalDateTime.parse("2024-04-30T20:15"),
257257
/*duration*/ Duration.parse("PT47M20S"),
258258
/*small*/ "https://wdrmedien-a.akamaihd.net/medp/ondemand/weltweit/fsk12/310/3101569/3101569_56955169.mp4",
@@ -272,7 +272,7 @@ public static Collection<Object[]> data() {
272272
/*jsonFile*/ "/ard/ard_item_STD_AD_MDR.json",
273273
/*topic*/ "Auf schmaler Spur",
274274
/*title*/ "Reichsbahn-Oldies im Trend",
275-
/*description*/ "Mit gerade mal 27 Jahren ist Tobias Sambill Geschäftsführer des „Salzland Railservice“ in Bernburg. Seine Geschäftsidee: Er betreibt Güterverkehr mit alten Reichsbahnloks und ist ganz verrückt nach „Ludmilla“, Baujahr 1974, 3.000 PS Leistung. Ludmilla ist der Spitzname für Dieselloks der Baureihe 130, die ab 1970 aus der Sowjetunion zur Reichsbahn kamen. Auch in Löbau ist der Nachwuchs schon in d\n.....",
275+
/*description*/ "Mit gerade mal 27 Jahren ist Tobias Sambill Geschäftsführer des „Salzland Railservice“ in Bernburg. Seine Geschäftsidee: Er betreibt Güterverkehr mit alten Reichsbahnloks und ist ganz verrückt nach „Ludmilla“, Baujahr 1974, 3.000 PS Leistung. Ludmilla ist der Spitzname für Dieselloks der Baureihe 130, die ab 1970 aus der Sowjetunion zur Reichsbahn kamen. Auch in Löbau ist der Nachwuchs schon in der Verantwortung....",
276276
/*date*/ LocalDateTime.parse("2024-05-01T13:20"),
277277
/*duration*/ Duration.parse("PT29M31S"),
278278
/*small*/ "https://odgeomdr-a.akamaihd.net/mp4dyn2/a/FCMS-a66d00f7-05d6-4280-8dbe-9c81a47c8667-41dd60577440_a6.mp4",
@@ -312,7 +312,7 @@ public static Collection<Object[]> data() {
312312
/*jsonFile*/ "/ard/ard_item_ignore_OV.json",
313313
/*topic*/ "You shall not lie - Tödliche Geheimnisse",
314314
/*title*/ "Folge 4: Der Verrat (S01/E04)",
315-
/*description*/ "Zwischen Macarena und Iván, der jetzt von ihrer Schwangerschaft weiß, kommt es zu einer dramatischen Auseinandersetzung auf See. Erschöpft schwimmt der 18-Jährige an Land und beschuldigt sie, ihn vom Boot gestoßen zu haben. Die Lehrerin muss nun nicht nur die Folgen ihres Seitensprungs fürchten, sondern auch eine Anzeige wegen versuchten Totschlags. +++ Sechsteilige Thrillerserie, Spanien 2021\n.....",
315+
/*description*/ "Zwischen Macarena und Iván, der jetzt von ihrer Schwangerschaft weiß, kommt es zu einer dramatischen Auseinandersetzung auf See. Erschöpft schwimmt der 18-Jährige an Land und beschuldigt sie, ihn vom Boot gestoßen zu haben. Die Lehrerin muss nun nicht nur die Folgen ihres Seitensprungs fürchten, sondern auch eine Anzeige wegen versuchten Totschlags....",
316316
/*date*/ LocalDateTime.parse("2022-10-15T02:50"),
317317
/*duration*/ Duration.parse("PT42M18S"),
318318
/*small*/ "https://pd-videos.daserste.de/de/2022/10/11/1cb6c5d8-c0f4-4868-ac42-2a06b7a3381f/JOB_461836_sendeton_640x360-50p-1200kbit.mp4",

src/test/java/de/mediathekview/mserver/crawler/ard/tasks/ArdFilmDetailTaskTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public static Collection<Object[]> data() {
9797
),
9898
/*topic*/ "Fickt euch!",
9999
/*title*/ "Keine Chance für Smegma! Intimhygiene für Jungs I Fickt euch - Ist doch nur Sex",
100-
/*description*/ "Den Penis richtig waschen ist ganz einfach! Was ihr beachten müsst, um Infektionen und unangenehme Gerüche zu vermeiden, erfahrt ihr im Video. Du willst mehr? Dann abonniere meinen Kanal: https://www.youtube.com/channel/UC3ZkjIfabQzVypsQBd9-AIQ?sub_confirmation=1Fickt euch! bei Facebook: http://www.facebook.com/istdochnursexFickt euch! bei Instagram: http://www.instagram.com/istdochnursexFickt euc\n.....",
100+
/*description*/ "Den Penis richtig waschen ist ganz einfach! Was ihr beachten müsst, um Infektionen und unangenehme Gerüche zu vermeiden, erfahrt ihr im Video. Du willst mehr? Dann abonniere meinen Kanal: https://www.youtube.com/channel/UC3ZkjIfabQzVypsQBd9-AIQ?sub_confirmation=1Fickt euch! bei Facebook: http://www.facebook.com/istdochnursexFickt euch! bei Instagram: http://www.instagram.com/istdochnursexFickt euch! bei Snapchat: @istdochnursex",
101101
/*date*/ LocalDateTime.parse("2016-12-13T15:00"),
102102
/*duration*/ Duration.parse("PT3M5S"),
103103
/*small*/ "http://localhost:50998/22679/files/21/01/30/2678992/22679-jqh9gFKRm8YDnC2.ism/22679-jqh9gFKRm8YDnC2-audio=152016-video=771000.m3u8",

0 commit comments

Comments
 (0)