From f10b990e13cc49137f7d4e4cac7b4fe09aa7682a Mon Sep 17 00:00:00 2001 From: CodingPF Date: Fri, 27 Oct 2023 10:36:41 +0200 Subject: [PATCH 1/7] order filmlist by time (reverse order) --- .../de/mediathekview/mlib/daten/MediaResourceComperators.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/mediathekview/mlib/daten/MediaResourceComperators.java b/src/main/java/de/mediathekview/mlib/daten/MediaResourceComperators.java index 78f8c396..e14af6ba 100644 --- a/src/main/java/de/mediathekview/mlib/daten/MediaResourceComperators.java +++ b/src/main/java/de/mediathekview/mlib/daten/MediaResourceComperators.java @@ -14,7 +14,7 @@ public enum MediaResourceComperators { AbstractMediaResource::getThema, Comparator.nullsFirst(Comparator.naturalOrder()))), DATE_COMPERATOR( Comparator.comparing( - AbstractMediaResource::getTime, Comparator.nullsFirst(Comparator.naturalOrder()))), + AbstractMediaResource::getTime, Comparator.nullsFirst(Comparator.reverseOrder()))), DEFAULT_COMPERATOR(createDefaultComperator()); private final Comparator> comparator; From 23fb8635a304bd1a1e7a880a9647391677ef7481 Mon Sep 17 00:00:00 2001 From: CodingPF Date: Fri, 27 Oct 2023 10:37:07 +0200 Subject: [PATCH 2/7] add response type, response path --- .../mlib/tool/FileSizeDeterminer.java | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/mediathekview/mlib/tool/FileSizeDeterminer.java b/src/main/java/de/mediathekview/mlib/tool/FileSizeDeterminer.java index ce863063..50ebbdbf 100644 --- a/src/main/java/de/mediathekview/mlib/tool/FileSizeDeterminer.java +++ b/src/main/java/de/mediathekview/mlib/tool/FileSizeDeterminer.java @@ -8,8 +8,10 @@ import org.jetbrains.annotations.NotNull; import java.io.IOException; +import java.util.Optional; import static jakarta.ws.rs.core.HttpHeaders.CONTENT_LENGTH; +import static jakarta.ws.rs.core.HttpHeaders.CONTENT_TYPE; public class FileSizeDeterminer { private static final Logger LOG = LogManager.getLogger(FileSizeDeterminer.class); @@ -19,7 +21,45 @@ public class FileSizeDeterminer { private static final String FILE_TYPE_M3U8 = "m3u8"; private final String url; private final OkHttpClient client; - + // + private Optional fileSizeInByte = Optional.empty(); + private Optional responsePath = Optional.empty(); + private Optional responseContentType = Optional.empty(); + + + /* + * get the file size of the url in byte + */ + public long getFileSizeInByte() { + if (fileSizeInByte.isEmpty()) { + getFileSizeForBuilder(); + } + return fileSizeInByte.orElse(-1L); + } + + /* + * get the path of the response which may differ to request url for redirects + */ + public String getResponsePath() { + if (responsePath.isEmpty()) { + getFileSizeInByte(); + } + return responsePath.orElse(""); + } + + /* + * get the content type of the reponse message + */ + + public String getResponseContentType() { + if (responseContentType.isEmpty()) { + getFileSizeInByte(); + } + return responseContentType.orElse(""); + } + + + /** * Builds the determiner with the default read- and connect timeout of 30 seconds. * @@ -55,7 +95,10 @@ private Long getFileSizeByRequest(final RequestType requestType) { try (final Response response = client.newCall(createRequestBuilderForRequestType(requestType).build()).execute()) { final String contentLengthHeader = response.header(CONTENT_LENGTH); - return parseContentLength(contentLengthHeader); + responseContentType = Optional.of(response.header(CONTENT_TYPE, "")); + responsePath = Optional.of(response.request().url().encodedPath()); + fileSizeInByte = Optional.of(parseContentLength(contentLengthHeader)); + return fileSizeInByte.get(); } catch (final IOException ioException) { LOG.error( "Something went wrong determining the file size of \"{}\" with {} request.", From b2e986766ac1ebec263451dcc08f75978b601c91 Mon Sep 17 00:00:00 2001 From: CodingPF Date: Fri, 27 Oct 2023 10:37:34 +0200 Subject: [PATCH 3/7] new Filmlist writter and reader --- TestConfig.yaml | 2 + .../mlib/daten/AbstractMediaResource.java | 12 + .../filmlisten/FilmToFakeJsonConverter.java | 372 ------------- .../reader/FilmlistOldFormatReader.java | 502 +++++++++++++----- .../writer/AbstractFilmlistWriter.java | 3 + .../writer/FilmlistOldFormatWriter.java | 325 +++++++++++- .../filmlisten/writer/FilmlistWriter.java | 11 + .../FilmlistOldFormatReaderTest.java | 275 ++++++++++ .../FilmlistOldFormatWriterTest.java | 49 ++ .../TestFilmlistOldFormatReader.json | 22 + .../TestFilmlistOldFormatWriter.json | 1 + 11 files changed, 1059 insertions(+), 515 deletions(-) create mode 100644 TestConfig.yaml delete mode 100644 src/main/java/de/mediathekview/mlib/filmlisten/FilmToFakeJsonConverter.java create mode 100644 src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java create mode 100644 src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java create mode 100644 src/test/resources/TestFilmlistOldFormatReader.json create mode 100644 src/test/resources/TestFilmlistOldFormatWriter.json diff --git a/TestConfig.yaml b/TestConfig.yaml new file mode 100644 index 00000000..9b389a4c --- /dev/null +++ b/TestConfig.yaml @@ -0,0 +1,2 @@ +valueWithDefault: TestValue +valueWithoutDefault: Some other test value diff --git a/src/main/java/de/mediathekview/mlib/daten/AbstractMediaResource.java b/src/main/java/de/mediathekview/mlib/daten/AbstractMediaResource.java index d705d31a..f2f31a0b 100644 --- a/src/main/java/de/mediathekview/mlib/daten/AbstractMediaResource.java +++ b/src/main/java/de/mediathekview/mlib/daten/AbstractMediaResource.java @@ -136,6 +136,10 @@ public void setBeschreibung(final String aBeschreibung) { beschreibung = TextCleaner.shortAndCleanBeschreibung(aBeschreibung, titel, thema); } + public void setBeschreibungRaw(final String aBeschreibung) { + beschreibung = aBeschreibung; + } + public Optional getDefaultUrl() { if (urls.containsKey(Resolution.NORMAL)) { return Optional.of(getUrl(Resolution.NORMAL)); @@ -174,6 +178,10 @@ public String getThema() { public void setThema(final String aThema) { thema = TextCleaner.clean(aThema); } + + public void setThemaRaw(final String aThema) { + thema = aThema; + } public LocalDateTime getTime() { return time; @@ -190,6 +198,10 @@ public String getTitel() { public void setTitel(final String aTitel) { titel = TextCleaner.clean(aTitel); } + + public void setTitelRaw(final String aTitel) { + titel = aTitel; + } public T getUrl(final Resolution aQuality) { return urls.get(aQuality); diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/FilmToFakeJsonConverter.java b/src/main/java/de/mediathekview/mlib/filmlisten/FilmToFakeJsonConverter.java deleted file mode 100644 index 104285cb..00000000 --- a/src/main/java/de/mediathekview/mlib/filmlisten/FilmToFakeJsonConverter.java +++ /dev/null @@ -1,372 +0,0 @@ -package de.mediathekview.mlib.filmlisten; - -import com.google.gson.Gson; -import de.mediathekview.mlib.daten.*; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Serializable; -import java.net.URL; -import java.time.*; -import java.time.format.DateTimeFormatter; -import java.util.Collection; -import java.util.List; -import java.util.Locale; -import java.util.Objects; - -import static java.time.format.FormatStyle.MEDIUM; - -/** - * A helper class to generate the old fake json format for a {@link - * de.mediathekview.mlib.daten.Film}. - */ -public class FilmToFakeJsonConverter { - private static final Logger LOG = LogManager.getLogger(FilmToFakeJsonConverter.class); - private static final Object[] COLUMNNAMES = - new String[] { - "Sender", - "Thema", - "Titel", - "Datum", - "Zeit", - "Dauer", - "Größe [MB]", - "Beschreibung", - "Url", - "Website", - "Url Untertitel", - "Url RTMP", - "Url Klein", - "Url RTMP Klein", - "Url HD", - "Url RTMP HD", - "DatumL", - "Url History", - "Geo", - "neu" - }; - private static final String OUTPUT_PATTERN = - "\"X\":[\"%s\",%s,%s,\"%s\",\"%s\",\"%s\",\"%s\",%s,\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]"; - private static final String META_INFORMATION_PATTERN = - "\"Filmliste\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]"; - private static final String COLUMNNAMES_PATTERN = - "\"Filmliste\":[\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"]"; - private static final char SPLITTERATOR = ','; - private static final char FAKE_JSON_BEGIN = '{'; - private static final char FAKE_JSON_END = '}'; - private static final DateTimeFormatter DATE_FORMATTER = - DateTimeFormatter.ofLocalizedDate(MEDIUM).withLocale(Locale.GERMANY); - private static final DateTimeFormatter TIME_FORMATTER = - DateTimeFormatter.ofLocalizedTime(MEDIUM).withLocale(Locale.GERMANY); - private static final ZoneId ZONE_ID = ZoneId.of("Europe/Berlin"); - private static final char GEO_SPLITTERATOR = '-'; - private static final String URL_INTERSECTION_REDUCE_PATTERN = "%d|"; - private static final String DURATION_FORMAT = "HH:mm:ss"; - private String lastSender; - private String lastThema; - - public void toFakeJson( - final List> aResources, - final OutputStreamWriter outputstream, - final String aFilmlisteDatum, - final String aFilmlisteDatumGmt, - final String aFilmlisteVersion, - final String aFilmlisteProgramm, - final String aFilmlisteId) throws IOException { - outputstream.write(FAKE_JSON_BEGIN); - outputstream.write( - String.format( - META_INFORMATION_PATTERN, - aFilmlisteDatum, - aFilmlisteDatumGmt, - aFilmlisteVersion, - aFilmlisteProgramm, - aFilmlisteId)); - appendEnd(outputstream, false); - - outputstream.write(String.format(COLUMNNAMES_PATTERN, COLUMNNAMES)); - appendEnd(outputstream, false); - - lastSender = ""; - lastThema = ""; - for (final AbstractMediaResource mediaResource : - aResources.stream().filter(Objects::nonNull).toList()) { - try { - resourceToFakeJson( - outputstream, - mediaResource, - mediaResource.equals(aResources.get(aResources.size() - 1))); - } catch (final Exception exception) { - LOG.error("A film can't be converted to old json format.", exception); - LOG.debug(String.format("The film which can't be converted: %s", mediaResource.toString())); - } - } - - outputstream.write(FAKE_JSON_END); - - } - - private void appendEnd(final OutputStreamWriter outputstream, final boolean aIsLastFilm) throws IOException { - if (!aIsLastFilm) { - outputstream.write(SPLITTERATOR); - } - } - - private String durationToString(final Duration aDuration) { - // there is no duration for a few films => use duration of 0 instead - if (aDuration == null) { - return "00:00:00"; - } - return LocalTime.MIDNIGHT.plus(aDuration).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); - } - - private String geolocationsToStirng(final Collection aGeoLocations) { - final StringBuilder geolocationsStringBuilder = new StringBuilder(); - if (!aGeoLocations.isEmpty()) { - for (final GeoLocations geoLocation : aGeoLocations) { - geolocationsStringBuilder.append(geoLocation.getDescription()); - geolocationsStringBuilder.append(GEO_SPLITTERATOR); - } - geolocationsStringBuilder.deleteCharAt( - geolocationsStringBuilder.lastIndexOf(String.valueOf(GEO_SPLITTERATOR))); - } - return geolocationsStringBuilder.toString(); - } - - private Resolution getDefaultResolution(final AbstractMediaResource aMediaResource) { - if (aMediaResource.getUrls().containsKey(Resolution.NORMAL)) { - return Resolution.NORMAL; - } - - for (final Resolution quality : Resolution.getFromBestToLowest()) { - if (aMediaResource.getUrls().containsKey(quality)) { - return quality; - } - } - return Resolution.VERY_SMALL; - } - - private String getSubtitles(final AbstractMediaResource aMediaResource) { - if (aMediaResource instanceof Film film) { - if (film.getSubtitles().isEmpty()) { - return ""; - } - - // prefer ttml-files - String url = ""; - for (final URL subtitleUrl : film.getSubtitles()) { - if (url.isEmpty() || subtitleUrl.getFile().endsWith(".ttml")) { - url = subtitleUrl.toString(); - } - } - return url; - } - - return ""; - } - - private String reduceUrl(final String aBaseUrl, final String aUrlToReduce) { - final StringBuilder urlIntersectionBuilder = new StringBuilder(); - for (int i = 0; - i < aBaseUrl.length() - && i < aUrlToReduce.length() - && aBaseUrl.charAt(i) == aUrlToReduce.charAt(i); - i++) { - urlIntersectionBuilder.append(aBaseUrl.charAt(i)); - } - - final String urlIntersection = urlIntersectionBuilder.toString(); - final String result; - if (urlIntersection.isEmpty()) { - result = aUrlToReduce; - } else { - result = - aUrlToReduce.replace( - urlIntersection, - String.format(URL_INTERSECTION_REDUCE_PATTERN, urlIntersection.length())); - } - return result; - } - - private long convertDateTimeToLong(final LocalDateTime dateTime) { - if (dateTime == null) { - return 0; - } - - final ZonedDateTime zonedDateTime = dateTime.atZone(ZONE_ID); - return zonedDateTime.toEpochSecond(); - } - - private void resourceToFakeJson( - final OutputStreamWriter outputstream, - final AbstractMediaResource aMediaResource, - final boolean aIsLastFilm) throws IOException { - - final String title = aMediaResource.getTitel(); - appendDefaultEntry(aMediaResource, title, outputstream, aIsLastFilm); - appendAudioDescriptionEntry(aMediaResource, title, outputstream, aIsLastFilm); - appendSignLanguageEntry(aMediaResource, title, outputstream, aIsLastFilm); - } - - private void appendDefaultEntry(AbstractMediaResource aMediaResource, String title, OutputStreamWriter outputstream, boolean aIsLastFilm) throws IOException { - final String url; - String urlKlein = ""; - String urlHd = ""; - - final Serializable mediaUrl = aMediaResource.getUrl(getDefaultResolution(aMediaResource)); - if (mediaUrl != null) { - // create film entry - url = mediaUrl.toString(); - if (aMediaResource.getUrls().containsKey(Resolution.SMALL)) { - urlKlein = aMediaResource.getUrl(Resolution.SMALL).toString(); - } - if (aMediaResource.getUrls().containsKey(Resolution.HD)) { - urlHd = aMediaResource.getUrl(Resolution.HD).toString(); - } - - appendMediaResource( - outputstream, aMediaResource, title, urlKlein, url, urlHd, aIsLastFilm); - } - } - - private void appendAudioDescriptionEntry( - final AbstractMediaResource aMediaResource, - final String aTitle, - final OutputStreamWriter outputstream, - final boolean aIsLastFilm) throws IOException { - final String url; - String urlSmall = ""; - String urlHd = ""; - - if (aMediaResource instanceof Film film) { - FilmUrl filmUrl = film.getAudioDescription(Resolution.NORMAL); - if (filmUrl != null) { - url = filmUrl.toString(); - - filmUrl = film.getAudioDescription(Resolution.SMALL); - if (filmUrl != null) { - urlSmall = filmUrl.toString(); - } - - filmUrl = film.getAudioDescription(Resolution.HD); - if (filmUrl != null) { - urlHd = filmUrl.toString(); - } - - final String titleAudioDescription = aTitle + " (Audiodeskription)"; - appendMediaResource( - outputstream, - aMediaResource, - titleAudioDescription, - urlSmall, - url, - urlHd, - aIsLastFilm); - } - } - } - - private void appendSignLanguageEntry( - final AbstractMediaResource aMediaResource, - final String aTitle, - final OutputStreamWriter outputstream, - final boolean aIsLastFilm) throws IOException { - final String url; - String urlSmall = ""; - String urlHd = ""; - - if (aMediaResource instanceof Film film) { - FilmUrl filmUrl = film.getSignLanguage(Resolution.NORMAL); - if (filmUrl != null) { - url = filmUrl.toString(); - - filmUrl = film.getSignLanguage(Resolution.SMALL); - if (filmUrl != null) { - urlSmall = filmUrl.toString(); - } - - filmUrl = film.getSignLanguage(Resolution.HD); - if (filmUrl != null) { - urlHd = filmUrl.toString(); - } - - final String titleSignLanguage = aTitle + " (Gebärdensprache)"; - appendMediaResource( - outputstream, aMediaResource, titleSignLanguage, urlSmall, url, urlHd, aIsLastFilm); - } - } - } - - private void appendMediaResource( - final OutputStreamWriter outputstream, - final AbstractMediaResource aMediaResource, - final String aTitle, - String aUrlSmall, - final String aUrlNormal, - String aUrlHd, - final boolean aIsLastFilm) throws IOException { - final Gson gson = new Gson(); - - final String thema = setThema(aMediaResource); - final String sender = setSender(aMediaResource); - - aUrlSmall = reduceUrl(aUrlNormal, aUrlSmall); - aUrlHd = reduceUrl(aUrlNormal, aUrlHd); - - final String website = aMediaResource.getWebsite().map(URL::toString).orElse(""); - - outputstream.write( - String.format( - OUTPUT_PATTERN, - sender, - gson.toJson(thema), - gson.toJson(aTitle), - aMediaResource.getTime() == null - ? "" - : DATE_FORMATTER.format(aMediaResource.getTime().toLocalDate()), - aMediaResource.getTime() == null - ? "" - : TIME_FORMATTER.format(aMediaResource.getTime().toLocalTime()), - aMediaResource instanceof Podcast podcast - ? durationToString(podcast.getDuration()) : "", - aMediaResource instanceof Podcast podcast - ? (podcast.getFileSizeKB(getDefaultResolution(aMediaResource))/1024) : "", - gson.toJson(aMediaResource.getBeschreibung()), - aUrlNormal, - website, - getSubtitles(aMediaResource), - "", - aUrlSmall, - "", - aUrlHd, - "", - convertDateTimeToLong(aMediaResource.getTime()), - "", // History - geolocationsToStirng(aMediaResource.getGeoLocations()), - aMediaResource instanceof Podcast podcast && podcast.isNeu())); - - appendEnd(outputstream, aIsLastFilm); - } - - private String setSender(final AbstractMediaResource aMediaResource) { - String sender = aMediaResource.getSenderName(); - if (lastSender.equals(sender)) { - sender = ""; - } else { - lastSender = sender; - } - return sender; - } - - private String setThema(final AbstractMediaResource aMediaResource) { - String thema = aMediaResource.getThema(); - if (lastThema.equals(thema)) { - thema = ""; - } else { - lastThema = thema; - } - return thema; - } -} diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java b/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java index 45abf56d..042765e1 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java @@ -1,177 +1,421 @@ package de.mediathekview.mlib.filmlisten.reader; import de.mediathekview.mlib.daten.Film; +import de.mediathekview.mlib.daten.FilmUrl; import de.mediathekview.mlib.daten.Filmlist; -import de.mediathekview.mlib.tool.TextCleaner; +import de.mediathekview.mlib.daten.GeoLocations; +import de.mediathekview.mlib.daten.Resolution; +import de.mediathekview.mlib.daten.Sender; + +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; import java.nio.charset.StandardCharsets; +import java.time.DateTimeException; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import static java.lang.String.format; import static java.time.format.FormatStyle.MEDIUM; -import static java.time.format.FormatStyle.SHORT; public class FilmlistOldFormatReader extends AbstractFilmlistReader { - private static final String ENTRY_DELIMETER = "\\],"; private static final Logger LOG = LogManager.getLogger(FilmlistOldFormatReader.class); private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDate(MEDIUM).withLocale(Locale.GERMANY); - private static final DateTimeFormatter TIME_FORMATTER = - DateTimeFormatter.ofLocalizedTime(SHORT).withLocale(Locale.GERMANY); - private static final String ENTRY_PATTERN = "\"\\w*\"\\s?:\\s*\\[\\s?(\"([^\"]|\\\")*\",?\\s?)*"; - private static final String ENTRY_SPLIT_PATTERN = "\"(\\\\\"|[^\"])*\""; - private static final String FILM_ENTRY_ID = "X"; - private static final String DATE_TIME_SPLITTERATOR = ",?\\s+"; - private static final String QUOTATION_MARK = "\""; - + private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm[:ss]", Locale.GERMANY); + + private static final LocalDate DEFAULT_DATE = LocalDate.parse("01.01.1970", DATE_FORMATTER); + private static final DateTimeFormatter FILMLIST_CREATIONDATE_PATTERN = DateTimeFormatter.ofPattern("dd.MM.yyyy, HH:mm", Locale.GERMANY); + private static final char GEO_SPLITTERATOR = '-'; + private static final String URL_SPLITTERATOR = "\\|"; + private String sender = ""; + private String thema = ""; + private String debug = ""; + int cnt = 0; + + public static void main(String[] args) throws FileNotFoundException { + new FilmlistOldFormatReader().read(new FileInputStream("C:/Users/steph/Desktop/Mediathek/oldFormat/Filmliste-akt-oldformat.json")); + } + @Override - public Optional read(final InputStream aInputStream) { - try (final Scanner scanner = new Scanner(aInputStream, StandardCharsets.UTF_8.name()); - final Scanner entryScanner = scanner.useDelimiter(ENTRY_DELIMETER)) { - return convertEntriesToFilms(findEntries(entryScanner)); - } finally { - try { - aInputStream.close(); - } catch (final IOException exception) { - LOG.debug("Can't close the ioStream", exception); + public Optional read(InputStream aInputStream) { + long start = System.currentTimeMillis(); + /* + String bigFile = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmliste-akt-oldformat.json"; + String medium = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmlist - Kopie.json"; + String smallFile = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmlist.json"; + String broken = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmlist-broken.json"; + */ + Filmlist filmlist = new Filmlist(); + int cnt = 0; + debug = "LINE " + cnt; + // + + try (JsonReader jsonReader = new JsonReader(new InputStreamReader(aInputStream, StandardCharsets.UTF_8))) + { + headerMeta(jsonReader, filmlist); + headerColumns(jsonReader); + while (jsonReader.peek() != JsonToken.END_OBJECT) + { + try { + readRecrod(jsonReader).ifPresent(aFilm -> {filmlist.add(aFilm);}); + } catch (Exception e) { + if (!recoverParser(jsonReader)) { + System.out.println("error after " + ((System.currentTimeMillis()-start)/1000) + " on " + cnt + " elements (" + filmlist.getFilms().size()+")"); + throw(e); + } + } + cnt++; } + } catch (IOException e) { + LOG.error(e); + return Optional.of(filmlist); } - } - - @NotNull - private Optional convertEntriesToFilms(final List entries) { - final Filmlist filmlist = new Filmlist(); - final List> futureFilms = asyncConvertEntriesToFilms(entries, filmlist); - futureFilms.stream() - .map( - filmFuture -> { - try { - return filmFuture.get(); - } catch (final InterruptedException interruptedException) { - LOG.debug( - "Some error occured during converting a old film list entry to an film.", - interruptedException); - Thread.currentThread().interrupt(); - } catch (final Exception exception) { - LOG.debug( - "Some error occured during converting a old film list entry to an film.", - exception); - } - return null; - }) - .filter(Objects::nonNull) - .filter(film -> !film.getUrls().isEmpty()) - .forEach(filmlist::add); + LOG.debug("done reading in " + ((System.currentTimeMillis()-start)/1000) + "sec for " + cnt + " elements (" + filmlist.getFilms().size()+")"); return Optional.of(filmlist); + } - - @NotNull - private List> asyncConvertEntriesToFilms( - final List entries, final Filmlist filmlist) { - final ExecutorService executorService = Executors.newWorkStealingPool(); - boolean isFirst = true; - Future filmEntryBefore = null; - final List> futureFilms = new ArrayList<>(); - - final List> splittedEntries = - entries.stream() - .map(this::splittEntry) - .filter(splittEntry -> !splittEntry.isEmpty()) - .toList(); - - for (final List splittedEntry : splittedEntries) { - if (isFirst) { - setMetaInfo(filmlist, splittedEntry); - isFirst = false; - } else if (splittedEntry.size() == 21 && FILM_ENTRY_ID.equals(splittedEntry.get(0))) { - filmEntryBefore = - convertEntryToFilm(filmEntryBefore, executorService, futureFilms, splittedEntry); - } else { - // TODO do something useful here - LOG.debug(String.format("unkown entry %s",splittedEntry)); + + private boolean recoverParser(JsonReader jsonReader) { + int maxTry = 25; + try { + while (maxTry > 0 && !JsonToken.END_ARRAY.equals(jsonReader.peek())) { + jsonReader.nextString(); + maxTry--; } + jsonReader.endArray(); + return true; + } catch (Exception e) { + // TODO: handle exception } - return futureFilms; + return false; } - - private Future convertEntryToFilm( - Future filmEntryBefore, - final ExecutorService executorService, - final List> futureFilms, - final List splittedEntry) { + + + private void headerMeta(JsonReader jsonReader, Filmlist filmlist) throws IOException { + jsonReader.beginObject(); + jsonReader.nextName(); + jsonReader.beginArray(); + filmlist.setCreationDate(readHeader01CreationDate(jsonReader.nextString())); // localdatetime + jsonReader.nextString(); // localdatetime UTC + readHeader03Version(jsonReader.nextString()); // Version + jsonReader.nextString(); // Version + filmlist.setListId(readHeader05Hash(jsonReader.nextString())); // hash + jsonReader.endArray(); + + } + + private LocalDateTime readHeader01CreationDate(String in) { + if (StringUtils.isNotBlank(in)) { + try { + return LocalDateTime.parse(in, FILMLIST_CREATIONDATE_PATTERN); + } catch (DateTimeParseException e) { + LOG.warn(format("Error readHeader01CreationDate format string %s on line %s throws %s", in, debug, e )); + } + } + return LocalDateTime.now(); + } + private String readHeader03Version(String in) { + return in; + } + private UUID readHeader05Hash(String in) { try { - final Future newEntry = - executorService.submit(new OldFilmlistEntryToFilmTask(splittedEntry, filmEntryBefore)); - futureFilms.add(newEntry); - filmEntryBefore = newEntry; - } catch (final Exception exception) { - LOG.debug( - String.format("Error on converting the following text to a film:%n %s ", splittedEntry)); + return UUID.fromString(in); + } catch (Exception e) { + LOG.warn("Error readHeader05Hash format string " + in); } - return filmEntryBefore; + return UUID.randomUUID(); } - - private List findEntries(final Scanner entryScanner) { - final List entries = new ArrayList<>(); - - while (entryScanner.hasNext()) { - final String entry = entryScanner.next(); - final Matcher entryMatcher = Pattern.compile(ENTRY_PATTERN).matcher(entry); - if (entryMatcher.find()) { - entries.add(entryMatcher.group()); + + private void headerColumns(JsonReader jsonReader) throws IOException { + jsonReader.nextName(); + jsonReader.beginArray(); + jsonReader.nextString(); // Sender + jsonReader.nextString(); // Thema + jsonReader.nextString(); // Titel + jsonReader.nextString(); // Datum + jsonReader.nextString(); // Zeit + jsonReader.nextString(); // Dauer + jsonReader.nextString(); // Größe [MB] + jsonReader.nextString(); // Beschreibung + jsonReader.nextString(); // Url + jsonReader.nextString(); // Website + jsonReader.nextString(); // Url Untertitel + jsonReader.nextString(); // Url RTMP + jsonReader.nextString(); // Url Klein + jsonReader.nextString(); // Url RTMP Klein + jsonReader.nextString(); // Url HD + jsonReader.nextString(); // Url RTMP HD + jsonReader.nextString(); // DatumL + jsonReader.nextString(); // Url History + jsonReader.nextString(); // Geo + jsonReader.nextString(); // neu + jsonReader.endArray(); + }; + + private Optional readRecrod(JsonReader jsonReader) throws IOException { + cnt++; + // + Film f = new Film(); + f.setUuid(UUID.randomUUID()); + // + jsonReader.nextName(); + jsonReader.beginArray(); + sender = readRecord01Sender(jsonReader.nextString(), sender); + f.setSender(Sender.getSenderByName(sender).get()); + // + thema = readRecord02Thema(jsonReader.nextString(), thema); + f.setThemaRaw(thema); + // + String titel = readRecord03Titel(jsonReader.nextString()); + f.setTitelRaw(titel); + debug = sender + thema + titel; + // + f.setTime(readRecord04Datum(jsonReader.nextString()).atTime(readRecord05Zeit(jsonReader.nextString()))); + // + f.setDuration(readRecord06Dauer(jsonReader.nextString())); + // + long size = readRecord07Groesse(jsonReader.nextString()); + // + f.setBeschreibungRaw(readRecord08Beschreibung(jsonReader.nextString())); + // + URL urlNormal = readRecord09Url(jsonReader.nextString()); + // + f.setWebsite(readRecord10Website(jsonReader.nextString())); + // + f.addSubtitle(readRecord11Untertitel(jsonReader.nextString())); + // + readRecord12UrlRTMP(jsonReader.nextString()); + // + String urlKlein = readRecord13UrlKlein(jsonReader.nextString()); + // + readRecord14UrlRTMPKlein(jsonReader.nextString()); + // + String urlHd = readRecord15UrlHD(jsonReader.nextString()); + // + readRecord16UrlRTMPHD(jsonReader.nextString()); + // + readRecord17DatumL(jsonReader.nextString()); + // + readRecord18UrlHistory(jsonReader.nextString()); + // + f.setGeoLocations(readRecord19Geo(jsonReader.nextString())); + // + f.setNeu(readRecord20Neu(jsonReader.nextString())); + // + jsonReader.endArray(); + // + f.setUrls(generateUrls(urlNormal, urlKlein, urlHd, size)); + // + if (f.getUrls().size() > 0) { + return Optional.of(f); + } else { + LOG.warn(format("Error no urls for film %s", debug)); + return Optional.empty(); + } + } + + + private Map generateUrls(URL urlNormal, String urlSmall, String urlHd, long size) { + Map urls = new HashMap<>(); + if (urlNormal != null) { + urls.put(Resolution.NORMAL, new FilmUrl(urlNormal, size)); + rebuildUrl(urlNormal, urlSmall).ifPresent( u -> { + urls.put(Resolution.SMALL, new FilmUrl(u, 0L)); + }); + rebuildUrl(urlNormal, urlHd).ifPresent( u -> { + urls.put(Resolution.HD, new FilmUrl(u, 0L)); + }); + } + return urls; + } + + private Optional rebuildUrl(URL urlNromal, String targetUrl) { + if (!targetUrl.isBlank()) { + try { + final String[] splittedUrlText = targetUrl.split(URL_SPLITTERATOR); + if (splittedUrlText.length == 2) { + final int lengthOfOld = Integer.parseInt(splittedUrlText[0]); + return Optional.of(new URL(urlNromal.toString().substring(0, lengthOfOld) + splittedUrlText[1])); + } + return Optional.of(new URL(targetUrl)); + } catch (Exception e) { + LOG.warn(format("Error rebuildUrl format string %s on line %s throws %s", targetUrl, debug, e )); } } - return entries; + return Optional.empty(); } + + + + //////////////////////////////////////////////////////////// - private void setMetaInfo(final Filmlist aFilmlist, final List aSplittedEntry) { - try { - setCreationTime(aFilmlist, aSplittedEntry); - setListId(aFilmlist, aSplittedEntry); - } catch (final Exception exception) { - LOG.debug("Somethin went wrong on setting the meta data of filmlist.", exception); + protected String readRecord01Sender(String in, String sender) { + if (!in.isBlank()) { + sender = in; } + return sender; } - - private void setListId(final Filmlist aFilmlist, final List aSplittedEntry) { - try { - aFilmlist.setListId(UUID.fromString(aSplittedEntry.get(5))); - } catch (final IllegalArgumentException illegalArgumentException) { - LOG.debug(String.format("Can't parse the film list id. Setting a random uuid. %s", aSplittedEntry), illegalArgumentException); - aFilmlist.setListId(UUID.randomUUID()); + + protected String readRecord02Thema(String in, String thema) { + if (!in.isBlank()) { + thema = in; + } + return thema; + } + + protected String readRecord03Titel(String in) { + return in; + } + + protected LocalDate readRecord04Datum(String in) { + if (StringUtils.isNotBlank(in)) { + try { + return LocalDate.parse(in, DATE_FORMATTER); + } catch (DateTimeParseException e) { + LOG.warn(format("Error readRecord04Datum format string %s on line %s throws %s", in, debug, e )); + } } + return DEFAULT_DATE; + } + + protected LocalTime readRecord05Zeit(String in) { + if (StringUtils.isNotBlank(in)) { + try { + return LocalTime.parse(in, TIME_FORMATTER); + } catch (DateTimeParseException e) { + LOG.warn(format("Error readRecord05Zeit format string %s on line %s throws %s", in, debug, e )); + } + } + return LocalTime.MIDNIGHT; + } + + protected Duration readRecord06Dauer(String in) { + if (StringUtils.isNotBlank(in)) { + try { + return Duration.between(LocalTime.MIDNIGHT, LocalTime.parse(in)); + } catch (DateTimeException | ArithmeticException e) { + LOG.info(format("Error readRecord06Dauer format string %s on line %s throws %s", in, debug, e )); + } + } + return Duration.ZERO; + } + + protected long readRecord07Groesse(String in) { + if (StringUtils.isNotBlank(in)) { + try { + return Long.parseLong(in)*1024; // oldFilmlist format is MB - new DM is KB + } catch (NumberFormatException e) { + LOG.warn(format("Error readRecord07Groesse format string %s on line %s throws %s", in, debug, e )); + } + } + return 0L; } - private void setCreationTime(final Filmlist aFilmlist, final List aSplittedEntry) { - final String[] dateTimeSplitted = aSplittedEntry.get(1).split(DATE_TIME_SPLITTERATOR); - aFilmlist.setCreationDate( - LocalDateTime.of( - LocalDate.parse(dateTimeSplitted[0], DATE_FORMATTER), - LocalTime.parse(dateTimeSplitted[1], TIME_FORMATTER))); + protected String readRecord08Beschreibung(String in) { + return in; + } + + protected URL readRecord09Url(String in) { + if (!in.isBlank()) { + try { + return new URL(in); + } catch (final MalformedURLException e) { + LOG.warn(format("Error readRecord09Url format string %s on line %s throws %s", in, debug, e )); + } + } + return null; + } + + protected URL readRecord10Website(String in) { + if (!in.isBlank() && in.startsWith("http")) { + try { + return new URL(in); + } catch (final MalformedURLException e) { + LOG.warn(format("Error readRecord10Website format string %s on line %s throws %s", in, debug, e )); + } + } + return null; } + + protected URL readRecord11Untertitel(String in) { + if (!in.isBlank() && in.startsWith("http")) { + try { + return new URL(in); + } catch (final MalformedURLException e) { + LOG.warn(format("Error readRecord11Untertitel format string %s on line %s throws %s", in, debug, e )); + } + } + return null; + } + + protected String readRecord12UrlRTMP(String in) { + return in; + } + + protected String readRecord13UrlKlein(String in) { + return in; + } + + protected String readRecord14UrlRTMPKlein(String in) { + return in; + } + + protected String readRecord15UrlHD(String in) { + return in; + } + + protected String readRecord16UrlRTMPHD(String in) { + return in; + } + + protected String readRecord17DatumL(String in) { + return in; + } + + protected String readRecord18UrlHistory(String in) { + return in; + } + + protected Collection readRecord19Geo(String in) { + final Collection geoLocations = new ArrayList<>(); - private List splittEntry(final String aEntry) { - final List entrySplits = new ArrayList<>(); - final Matcher entrySplitMatcher = Pattern.compile(ENTRY_SPLIT_PATTERN).matcher(aEntry); - while (entrySplitMatcher.find()) { - entrySplits.add( - TextCleaner.clean( - entrySplitMatcher.group().replaceFirst(QUOTATION_MARK, "").replaceAll("\"$", ""))); + final GeoLocations singleGeoLocation = GeoLocations.getFromDescription(in); + if (singleGeoLocation == GeoLocations.GEO_NONE) { + for (final String geoText : in.split(String.valueOf(GEO_SPLITTERATOR))) { + final GeoLocations geoLocation = GeoLocations.getFromDescription(geoText); + if (geoLocation != GeoLocations.GEO_NONE) { + geoLocations.add(geoLocation); + } + } + } else { + geoLocations.add(singleGeoLocation); } - return entrySplits; + return geoLocations; } + + protected Boolean readRecord20Neu(String in) { + return Boolean.parseBoolean(in); + } + + + + } diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java index 9a9a79fd..6d1221bf 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java @@ -1,5 +1,6 @@ package de.mediathekview.mlib.filmlisten.writer; +import de.mediathekview.mlib.daten.Film; import de.mediathekview.mlib.daten.Filmlist; import de.mediathekview.mlib.messages.LibMessages; import de.mediathekview.mlib.messages.MessageCreator; @@ -12,6 +13,7 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.file.Path; +import java.util.stream.Stream; public abstract class AbstractFilmlistWriter extends MessageCreator { private static final Logger LOG = LogManager.getLogger(AbstractFilmlistWriter.class); @@ -25,6 +27,7 @@ protected AbstractFilmlistWriter(final MessageListener... aListeners) { } public abstract boolean write(Filmlist filmlist, OutputStream outputStream) throws IOException; + public abstract boolean write(Stream filmlist, OutputStream outputStream) throws IOException; public boolean write(Filmlist filmlist, Path savePath) { try (final OutputStream os = new FileOutputStream(savePath.toFile()); diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java index 9f8115a8..cbc3113f 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java @@ -1,40 +1,337 @@ package de.mediathekview.mlib.filmlisten.writer; +import de.mediathekview.mlib.daten.AbstractMediaResource; +import de.mediathekview.mlib.daten.Film; import de.mediathekview.mlib.daten.Filmlist; +import de.mediathekview.mlib.daten.GeoLocations; import de.mediathekview.mlib.daten.MediaResourceComperators; -import de.mediathekview.mlib.filmlisten.FilmToFakeJsonConverter; -import de.mediathekview.mlib.tool.Version; -import de.mediathekview.mlib.tool.VersionReader; +import de.mediathekview.mlib.daten.Podcast; +import de.mediathekview.mlib.daten.Resolution; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import java.time.LocalTime; +import java.time.ZoneId; import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.util.Collection; import java.util.Locale; +import java.util.stream.Stream; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.google.gson.stream.JsonWriter; import static java.time.format.FormatStyle.MEDIUM; import static java.time.format.FormatStyle.SHORT; public class FilmlistOldFormatWriter extends AbstractFilmlistWriter { + private static final Logger LOG = LogManager.getLogger(FilmlistOldFormatWriter.class); + private static final DateTimeFormatter DATE_FORMATTER = + DateTimeFormatter.ofLocalizedDate(MEDIUM).withLocale(Locale.GERMANY); + private static final DateTimeFormatter TIME_FORMATTER = + DateTimeFormatter.ofLocalizedTime(MEDIUM).withLocale(Locale.GERMANY); + private static final String DURATION_FORMAT = "HH:mm:ss"; + private static final String URL_INTERSECTION_REDUCE_PATTERN = "%d|"; + private static final ZoneId ZONE_ID = ZoneId.of("Europe/Berlin"); + private static final char GEO_SPLITTERATOR = '-'; private static final DateTimeFormatter DATE_TIME_FORMAT = DateTimeFormatter.ofLocalizedDateTime(MEDIUM, SHORT).withLocale(Locale.GERMANY); + protected String sender = ""; + protected String thema = ""; + protected int cnt; + + + @Override + public boolean write(Stream filmlist, OutputStream outputStream) throws IOException { + long start = System.currentTimeMillis(); + try { + LOG.info("start writting data"); + JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8)); + jsonWriter.beginObject(); + writeMetaHeader(new Filmlist(), jsonWriter); + writeColumnHeader(jsonWriter); + filmlist.forEach(aFilm -> { + try { + writeRecord(aFilm, jsonWriter); + cnt++; + if (cnt % 1000 == 0) { + jsonWriter.flush(); + } + } catch (IOException e) { + LOG.error(e); + } + }); + jsonWriter.endObject(); + jsonWriter.flush(); + LOG.info("done writting in " + ((System.currentTimeMillis()-start)/1000) + "sec for " + cnt + " elements"); + } catch (IOException e) { + LOG.error(e); + return false; + } + return true; + } + @Override public boolean write(Filmlist filmlist, OutputStream outputStream) throws IOException { - final FilmToFakeJsonConverter filmToFakeJsonConverter = new FilmToFakeJsonConverter(); - final Version progVersion = new VersionReader().readVersion(); - try (final OutputStreamWriter osw = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) { - filmToFakeJsonConverter.toFakeJson( - filmlist.getSorted(MediaResourceComperators.DEFAULT_COMPERATOR.getComparator()), - osw, - DATE_TIME_FORMAT.format(filmlist.getCreationDate()), - DATE_TIME_FORMAT.format(filmlist.getCreationDate().atZone(ZoneOffset.UTC)), - progVersion.toString(), - String.format(" [Vers.: %s ]", progVersion), - filmlist.getListId().toString()); + long start = System.currentTimeMillis(); + try { + LOG.info("start writting data"); + JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8)); + jsonWriter.beginObject(); + writeMetaHeader(filmlist, jsonWriter); + writeColumnHeader(jsonWriter); + filmlist.getSorted(MediaResourceComperators.DEFAULT_COMPERATOR.getComparator()).forEach(aFilm -> { + try { + writeRecord(aFilm, jsonWriter); + cnt++; + } catch (IOException e) { + LOG.error(e); + } + }); + jsonWriter.endObject(); + jsonWriter.flush(); + LOG.info("done writting in " + ((System.currentTimeMillis()-start)/1000) + "sec for " + cnt + " elements (" + filmlist.getFilms().size()+")"); + } catch (IOException e) { + LOG.error(e); + return false; } return true; } + + protected void writeMetaHeader(Filmlist list, JsonWriter jsonWriter ) throws IOException { + jsonWriter.name("Filmliste").beginArray(); + jsonWriter.value(writeMetaHeader01CreationDate(list)); + jsonWriter.value(writeMetaHeader02CreationDateUTC(list)); + jsonWriter.value(writeMetaHeader03Version(list)); + jsonWriter.value(writeMetaHeader04VErsionLong(list)); + jsonWriter.value(writeMetaHeader05Id(list)); + jsonWriter.endArray(); + + } + + protected String writeMetaHeader01CreationDate(Filmlist in) { + return DATE_TIME_FORMAT.format(in.getCreationDate()); + } + + protected String writeMetaHeader02CreationDateUTC(Filmlist in) { + return DATE_TIME_FORMAT.format(in.getCreationDate().atZone(ZoneOffset.UTC)); + } + + protected String writeMetaHeader03Version(Filmlist in) { + return "4"; + } + + protected String writeMetaHeader04VErsionLong(Filmlist in) { + return "MSearch [Vers.: 4.0.1]"; + } + + protected String writeMetaHeader05Id(Filmlist in) { + return in.getListId().toString(); + } + + + protected void writeColumnHeader(JsonWriter jsonWriter) throws IOException { + jsonWriter.name("Filmliste").beginArray(); + jsonWriter.value("Sender"); + jsonWriter.value("Thema"); + jsonWriter.value("Titel"); + jsonWriter.value("Datum"); + jsonWriter.value("Zeit"); + jsonWriter.value("Dauer"); + jsonWriter.value("Größe [MB]"); + jsonWriter.value("Beschreibung"); + jsonWriter.value("Url"); + jsonWriter.value("Website"); + jsonWriter.value("Url Untertitel"); + jsonWriter.value("Url RTMP"); + jsonWriter.value("Url Klein"); + jsonWriter.value("Url RTMP Klein"); + jsonWriter.value("Url HD"); + jsonWriter.value("Url RTMP HD"); + jsonWriter.value("DatumL"); + jsonWriter.value("Url History"); + jsonWriter.value("Geo"); + jsonWriter.value("neu"); + jsonWriter.endArray(); + } + + protected void writeRecord(AbstractMediaResource film, JsonWriter jsonWriter) throws IOException { + jsonWriter.name("X").beginArray(); + jsonWriter.value(writeRecord01Sender(film, this.sender)); + jsonWriter.value(writeRecord02Thema(film, this.thema)); + jsonWriter.value(writeRecord03Titel(film)); + jsonWriter.value(writeRecord04Datum(film)); + jsonWriter.value(writeRecord05Zeit(film)); + jsonWriter.value(writeRecord06Dauer(film)); + jsonWriter.value(writeRecord07Groesse(film)); + jsonWriter.value(writeRecord08Beschreibung(film)); + jsonWriter.value(writeRecord09UrlNormal(film)); + jsonWriter.value(writeRecord10Website(film)); + jsonWriter.value(writeRecord11Untertitel(film)); + jsonWriter.value(writeRecord12UrlRTMP(film)); + jsonWriter.value(writeRecord13UrlKlein(film)); + jsonWriter.value(writeRecord14UrlKleinRTMP(film)); + jsonWriter.value(writeRecord15UrlHD(film)); + jsonWriter.value(writeRecord16UrlHdRTMP(film)); + jsonWriter.value(writeRecord17DatumL(film)); + jsonWriter.value(writeRecord18UrlHistory(film)); + jsonWriter.value(writeRecord19Geo(film)); + jsonWriter.value(writeRecord20Neu(film)); + jsonWriter.endArray(); + } + + protected String writeRecord01Sender(AbstractMediaResource in, String aSender) { + if (!aSender.equalsIgnoreCase(in.getSenderName())) { + this.sender = in.getSenderName(); + return in.getSenderName(); + } else { + return ""; + } + } + + protected String writeRecord02Thema(AbstractMediaResource in, String aThema) { + if(!aThema.equalsIgnoreCase(in.getThema()) ) { + this.thema = in.getThema(); + return in.getThema(); + } else { + return ""; + } + } + + protected String writeRecord03Titel(AbstractMediaResource in) { + return in.getTitel(); + } + + protected String writeRecord04Datum(AbstractMediaResource in) { + return in.getTime().format(DATE_FORMATTER); + } + + protected String writeRecord05Zeit(AbstractMediaResource in) { + return in.getTime().format(TIME_FORMATTER); + } + + protected String writeRecord06Dauer(AbstractMediaResource in) { + if (!(in instanceof Podcast pIn) || pIn.getDuration().isZero()) { + return ""; + } + return LocalTime.MIDNIGHT.plus(pIn.getDuration()).format(DateTimeFormatter.ofPattern(DURATION_FORMAT)); + } + + protected String writeRecord07Groesse(AbstractMediaResource in) { + if ((in instanceof Podcast pIn) && pIn.getUrl(Resolution.NORMAL) != null) + return (pIn.getUrl(Resolution.NORMAL).getFileSize()/1024) + ""; + return ""; + } + + protected String writeRecord08Beschreibung(AbstractMediaResource in) { + return in.getBeschreibung(); + } + + protected String writeRecord09UrlNormal(AbstractMediaResource in) { + if ((in instanceof Podcast pIn) && pIn.getUrl(Resolution.NORMAL) != null) + return pIn.getUrl(Resolution.NORMAL).getUrl().toString(); + return ""; + } + + protected String writeRecord10Website(AbstractMediaResource in) { + if (in.getWebsite().isPresent()) { + return in.getWebsite().get().toString(); + } + return ""; + } + + protected String writeRecord11Untertitel(AbstractMediaResource in) { + if ((in instanceof Film fIn) && !fIn.getSubtitles().isEmpty()) { + return fIn.getSubtitles().toArray()[0].toString(); + } + return ""; + } + + protected String writeRecord12UrlRTMP(AbstractMediaResource in) { + return ""; + } + + protected String writeRecord13UrlKlein(AbstractMediaResource in) { + if ((in instanceof Podcast pIn) && in.getUrl(Resolution.SMALL) != null && pIn.getUrl(Resolution.NORMAL) != null) { + return reduceUrl(pIn.getUrl(Resolution.NORMAL).getUrl().toString(), pIn.getUrl(Resolution.SMALL).getUrl().toString()); + } + return ""; + } + + protected String writeRecord14UrlKleinRTMP(AbstractMediaResource in) { + return ""; + } + + protected String writeRecord15UrlHD(AbstractMediaResource in) { + if ((in instanceof Podcast pIn) && in.getUrl(Resolution.HD) != null && in.getUrl(Resolution.NORMAL) != null) { + return reduceUrl(pIn.getUrl(Resolution.NORMAL).getUrl().toString(), pIn.getUrl(Resolution.HD).getUrl().toString()); + } + return ""; + } + + protected String writeRecord16UrlHdRTMP(AbstractMediaResource in) { + return ""; + } + + protected String writeRecord17DatumL(AbstractMediaResource in) { + final ZonedDateTime zonedDateTime = in.getTime().atZone(ZONE_ID); + return zonedDateTime.toEpochSecond()+""; + } + + protected String writeRecord18UrlHistory(AbstractMediaResource in) { + return ""; + } + + protected String writeRecord19Geo(AbstractMediaResource in) { + return geolocationsToStirng(in.getGeoLocations()); + } + + protected String writeRecord20Neu(AbstractMediaResource in) { + if ((in instanceof Podcast pIn)) { + return Boolean.toString(pIn.isNeu()); + } + return Boolean.toString(false); + } + + protected String reduceUrl(final String aBaseUrl, final String aUrlToReduce) { + final StringBuilder urlIntersectionBuilder = new StringBuilder(); + for (int i = 0; + i < aBaseUrl.length() + && i < aUrlToReduce.length() + && aBaseUrl.charAt(i) == aUrlToReduce.charAt(i); + i++) { + urlIntersectionBuilder.append(aBaseUrl.charAt(i)); + } + + final String urlIntersection = urlIntersectionBuilder.toString(); + final String result; + if (urlIntersection.isEmpty()) { + result = aUrlToReduce; + } else { + result = + aUrlToReduce.replace( + urlIntersection, + String.format(URL_INTERSECTION_REDUCE_PATTERN, urlIntersection.length())); + } + return result; + } + + private String geolocationsToStirng(final Collection aGeoLocations) { + final StringBuilder geolocationsStringBuilder = new StringBuilder(); + if (!aGeoLocations.isEmpty()) { + for (final GeoLocations geoLocation : aGeoLocations) { + geolocationsStringBuilder.append(geoLocation.getDescription()); + geolocationsStringBuilder.append(GEO_SPLITTERATOR); + } + geolocationsStringBuilder.deleteCharAt( + geolocationsStringBuilder.lastIndexOf(String.valueOf(GEO_SPLITTERATOR))); + } + return geolocationsStringBuilder.toString(); + } } diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java index e3c8b5f4..73b3a47d 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java @@ -2,6 +2,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; + +import de.mediathekview.mlib.daten.Film; import de.mediathekview.mlib.daten.Filmlist; import de.mediathekview.mlib.daten.GsonDurationAdapter; import de.mediathekview.mlib.daten.GsonLocalDateTimeAdapter; @@ -14,6 +16,8 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.LocalDateTime; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class FilmlistWriter extends AbstractFilmlistWriter { @@ -39,4 +43,11 @@ public boolean write(Filmlist filmlist, OutputStream outputStream) throws IOExce return true; } + + @Override + public boolean write(Stream filmlist, OutputStream outputStream) throws IOException { + Filmlist fl = new Filmlist(); + fl.addAllFilms(filmlist.collect(Collectors.toList())); + return write(fl, outputStream); + } } diff --git a/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java new file mode 100644 index 00000000..9ada0f36 --- /dev/null +++ b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java @@ -0,0 +1,275 @@ +package de.mediathekview.mlib.filmlisten; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import de.mediathekview.mlib.daten.Film; +import de.mediathekview.mlib.daten.FilmUrl; +import de.mediathekview.mlib.daten.Filmlist; +import de.mediathekview.mlib.daten.GeoLocations; +import de.mediathekview.mlib.daten.Resolution; +import de.mediathekview.mlib.daten.Sender; +import de.mediathekview.mlib.filmlisten.reader.FilmlistOldFormatReader; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Path; +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +public class FilmlistOldFormatReaderTest { + + @Test + void readFilmlistOldFormatIncludingBrokenRecords() + throws IOException { + ClassLoader classLoader = getClass().getClassLoader(); + final Path testFilePath = new File(classLoader.getResource("TestFilmlistOldFormatReader.json").getFile()).toPath(); + Optional resultingList = new FilmlistOldFormatReader().read(new FileInputStream(testFilePath.toString())); + assertTrue(resultingList.isPresent()); + // + ArrayList expectedFilms = expectedFilmlist(); + resultingList.get().getFilms().values().forEach( f -> { + assertTrue(expectedFilms.contains(f)); + Film expectedFilm = expectedFilms.get(expectedFilms.indexOf(f)); + assertEquals(f.getSender(), expectedFilm.getSender()); + assertEquals(f.getTitel(), expectedFilm.getTitel()); + assertEquals(f.getThema(), expectedFilm.getThema()); + assertEquals(f.getTime(), expectedFilm.getTime()); + assertEquals(f.getDuration(), expectedFilm.getDuration()); + assertEquals(f.getBeschreibung(), expectedFilm.getBeschreibung()); + assertEquals(f.getWebsite(), expectedFilm.getWebsite()); + assertEquals(f.getTime(), expectedFilm.getTime()); + assertEquals(f.getTime(), expectedFilm.getTime()); + assertIterableEquals(f.getSubtitles(), expectedFilm.getSubtitles()); + if (expectedFilm.getUrl(Resolution.SMALL) != null) + assertEquals(f.getUrl(Resolution.SMALL).toString(), expectedFilm.getUrl(Resolution.SMALL).toString()); + if (expectedFilm.getUrl(Resolution.NORMAL) != null) + assertEquals(f.getUrl(Resolution.NORMAL).toString(), expectedFilm.getUrl(Resolution.NORMAL).toString()); + if (expectedFilm.getUrl(Resolution.HD) != null) + assertEquals(f.getUrl(Resolution.HD).toString(), expectedFilm.getUrl(Resolution.HD).toString()); + + + + }); + + //assertThat(testFilms, Matchers.containsInAnyOrder(expectedFilms)); + + } + + private ArrayList expectedFilmlist() { + ArrayList expected = new ArrayList(); + try { + // 1 element + Film completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37° Totgerast (Audiodeskription)"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(45)); + completeMatchExpected.setTime(LocalDateTime.of(2023, 5, 30, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 405L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 2 element + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Ein Gen verändert unser Leben (Audiodeskription)"); + completeMatchExpected.setBeschreibung("description \"37°\" with quotes"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(41)); + completeMatchExpected.setTime(LocalDateTime.of(2023, 5, 16, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 405L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 3,4,5 element > broken + // + // 6 element + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 1"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 416L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 6 element DATE + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 2"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(1970, 1, 1, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 416L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 7 element TIME + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 3"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 0, 0, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 416L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 8 element DURATIN + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 4"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ZERO); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 416L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 9 element SIZE + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 5"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 10 element broken normal url + // 11 element website + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 7"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + //completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 12 element subtitel + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 8"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + //completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 13 element small + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 9"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + //completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 14 element hd + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 10"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + //completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 15 element geo + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 11"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + //completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // 16 element neu + completeMatchExpected = new Film(); + completeMatchExpected.setSender(Sender.DREISAT); + completeMatchExpected.setThema("37 Grad"); + completeMatchExpected.setTitelRaw("37°: Mein Tanz, mein Battle 12"); + completeMatchExpected.setBeschreibung("description"); + completeMatchExpected.setDuration(Duration.ofMinutes(28).plusSeconds(42)); + completeMatchExpected.setTime(LocalDateTime.of(2022, 10, 11, 22, 15, 0)); + completeMatchExpected.setWebsite(new URL("https://host.de/something/website.html")); + completeMatchExpected.addUrl(Resolution.NORMAL, new FilmUrl(new URL("https://some.host.de/normal.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.SMALL, new FilmUrl(new URL("https://some.host.de/small.mp4"), 0L)); + completeMatchExpected.addUrl(Resolution.HD, new FilmUrl(new URL("https://some.host.de/hd.mp4"), 0L)); + completeMatchExpected.addGeolocation(GeoLocations.GEO_DE_AT_CH); + completeMatchExpected.addSubtitle(new URL("https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml")); + expected.add(completeMatchExpected); + // + } catch (Exception e) { + // no exception + } + return expected; + + } + +} diff --git a/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java new file mode 100644 index 00000000..0f01bf54 --- /dev/null +++ b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java @@ -0,0 +1,49 @@ +package de.mediathekview.mlib.filmlisten; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import de.mediathekview.mlib.daten.Filmlist; +import de.mediathekview.mlib.filmlisten.reader.FilmlistOldFormatReader; +import de.mediathekview.mlib.filmlisten.writer.FilmlistOldFormatWriter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Optional; + + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +public class FilmlistOldFormatWriterTest { + @TempDir + Path tempDir; + + @Test + void readFilmlistOldFormatIncludingBrokenRecords() + throws IOException { + ClassLoader classLoader = getClass().getClassLoader(); + final Path testFilePath = new File(classLoader.getResource("TestFilmlistOldFormatWriter.json").getFile()).toPath(); + Optional testFilmlist = new FilmlistOldFormatReader().read(new FileInputStream(testFilePath.toString())); + assertTrue( testFilmlist.isPresent()); + // + Path tempFile = Files.createTempFile(tempDir, "TestFilmlistOldFormatWriter", ".out"); + new FilmlistOldFormatWriter().write(testFilmlist.get(), tempFile); + + assertTrue( Files.exists(tempFile)); + // + String actualData = Files.readString(tempFile, StandardCharsets.UTF_16).substring(100); + String expectedData = Files.readString(testFilePath, StandardCharsets.UTF_16).substring(100); + assertEquals(expectedData, actualData, "Filmlisten stimmen überein."); + // + Files.deleteIfExists(tempFile); + + } + + + +} diff --git a/src/test/resources/TestFilmlistOldFormatReader.json b/src/test/resources/TestFilmlistOldFormatReader.json new file mode 100644 index 00000000..8b6366f7 --- /dev/null +++ b/src/test/resources/TestFilmlistOldFormatReader.json @@ -0,0 +1,22 @@ +{ + "Filmliste": ["30.05.2023, 19:21", "30.05.2023, 17:21", "3", "MSearch [Vers.: 3.1.212]", "6fe29b8c65d5c834e12164d667e7713e"], + "Filmliste": ["Sender", "Thema", "Titel", "Datum", "Zeit", "Dauer", "Größe [MB]", "Beschreibung", "Url", "Website", "Url Untertitel", "Url RTMP", "Url Klein", "Url RTMP Klein", "Url HD", "Url RTMP HD", "DatumL", "Url History", "Geo", "neu"], + "X": ["3Sat", "37 Grad", "37° Totgerast (Audiodeskription)", "30.05.2023", "22:15:00", "00:28:45", "405", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1685477700", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Ein Gen verändert unser Leben (Audiodeskription)", "16.05.2023", "22:15:00", "00:28:41", "414", "description \"37°\" with quotes", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1685477700", "", "DE-AT-CH", "false"], + "X": [""], + "X": ["", ""], + "X": ["", "", "", "", "37°: Ein Gen verändert unser Leben", "16.05.2023", "22:15:00", "00:28:41", "414", "Description \"37°\" with qoutes.", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 1", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 2", "11.10", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 3", "11.10.2022", "26:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 4", "11.10.2022", "22:15:00", "-a", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 5", "11.10.2022", "22:15:00", "00:28:42", "Z", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 6", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "ome.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 7", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 8", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 9", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "small.mp4", "", "21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 10", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "","hd.mp4", "", "1684268100", "", "DE-AT-CH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 11", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "","21|hd.mp4", "", "1684268100", "", "DdE-AdT-CsH", "false"], + "X": ["", "", "37°: Mein Tanz, mein Battle 12", "11.10.2022", "22:15:00", "00:28:42", "416", "description", "https://some.host.de/normal.mp4", "https://host.de/something/website.html", "https://host.de/23/05/230502_2215_sendung_37g/4/subtitle.xml", "", "21|small.mp4", "","21|hd.mp4", "", "1684268100", "", "DE-AT-CH", "d"], + "X": ["", ""], +} diff --git a/src/test/resources/TestFilmlistOldFormatWriter.json b/src/test/resources/TestFilmlistOldFormatWriter.json new file mode 100644 index 00000000..f9e3a0e3 --- /dev/null +++ b/src/test/resources/TestFilmlistOldFormatWriter.json @@ -0,0 +1 @@ +{"Filmliste":["30.05.2023, 19:21","30.05.2023, 17:21","4","MSearch [Vers.: 4.0.1]","7bc3d924-974f-42c4-8994-9d98dde17862"],"Filmliste":["Sender","Thema","Titel","Datum","Zeit","Dauer","Größe [MB]","Beschreibung","Url","Website","Url Untertitel","Url RTMP","Url Klein","Url RTMP Klein","Url HD","Url RTMP HD","DatumL","Url History","Geo","neu"],"X":["3Sat","37 Grad","37° Totgerast (Audiodeskription)","30.05.2023","22:15:00","00:28:45","405","Wer plötzlich Angehörige bei einem Unfall verliert, wacht in einem anderen Leben auf. Antonia verlor ihre Eltern und ihre Schwester, Steffen seine Frau und seinen Sohn.","https://rodlzdf-a.akamaihd.net/none/zdf/23/05/230530_2215_sendung_37g/2/230530_2215_sendung_37g_a3a4_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/37-grad/37-totgerast-102.html","","","101|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/zdf/23/05/230530_2215_sendung_37g/2/230530_2215_sendung_37g_a3a4_6660k_p37v17.mp4","","1685477700","","","false"],"X":["","","37°: Ein Gen verändert unser Leben (Audiodeskription)","16.05.2023","22:15:00","00:28:41","414","Eine Diagnose, die alles verändert: Milo hat einen Gendefekt. Wie wird das Leben werden mit einem Kind, das extrem viel Betreuung braucht? \"37°\" begleitet die Familie.","https://rodlzdf-a.akamaihd.net/none/zdf/23/05/230502_2215_sendung_37g/4/230502_2215_sendung_37g_a3a4_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/37-grad/37-ein-gen-veraendert-unser-leben-100.html","","","101|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/zdf/23/05/230502_2215_sendung_37g/4/230502_2215_sendung_37g_a3a4_6660k_p37v17.mp4","","1684268100","","","false"],"X":["","","37°: Mein Tanz, mein Battle (Audiodeskription)","11.10.2022","22:15:00","00:28:42","416","Joanna und Serhat teilen dieselbe Leidenschaft: Breakdance. 2024 feiert Breaken in Paris olympische Premiere. Eine Herausforderung für die Tänzer, wirklich alles zu geben.","https://rodlzdf-a.akamaihd.net/none/zdf/22/10/221011_2215_sendung_37g/3/221011_2215_sendung_37g_a3a4_2360k_p35v15.mp4","https://www.3sat.de/gesellschaft/37-grad/37-mein-tanz-mein-battle-100.html","","","101|808k_p11v15.mp4","","8|nrodlzdf-a.akamaihd.net/none/zdf/22/10/221011_2215_sendung_37g/3/221011_2215_sendung_37g_a3a4_3360k_p36v15.mp4","","1665519300","","","false"],"X":["","37 Grad Leben","Stroke Survivor – Ich geb' nicht auf! -","30.05.2023","09:03:00","00:27:07","377","Kaum ins Leben gestartet – und dann die Diagnose Schlaganfall. Wie kommen vor allem junge Betroffene, die sich gesund ernähren und sportlich leben, damit zurecht?","https://rodlzdf-a.akamaihd.net/none/zdf/23/05/230507_0903_sendung_sgl/1/230507_0903_sendung_sgl_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/37-grad-leben/stroke-survivor-ich-gebe-nicht-auf-102.html","https://utstreaming.zdf.de/mtt/zdf/23/05/230507_0903_sendung_sgl/2/F1039138_hoh_deu_37_Leben_Stroke_Survivors_neu.xml","","96|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/zdf/23/05/230507_0903_sendung_sgl/1/230507_0903_sendung_sgl_6660k_p37v17.mp4","","1685430180","","","false"],"X":["","","Ich lass mich taufen -","28.05.2023","09:03:00","00:27:08","390","Trotz vieler Kirchenaustritte gibt es immer wieder Menschen, die einen Weg in die Kirche finden, sich im Erwachsenenalter taufen lassen. \"37°Leben\" begleitet zwei junge Frauen bei ihrer Taufe.","https://rodlzdf-a.akamaihd.net/none/zdf/23/05/230528_0903_sendung_sgl/1/230528_0903_sendung_sgl_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/37-grad-leben/ich-lass-mich-taufen-102.html","https://utstreaming.zdf.de/mtt/zdf/23/05/230528_0903_sendung_sgl/2/F1039826_hoh_deu_37_Leben_Ich_lass_mich_taufen_280523.xml","","96|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/zdf/23/05/230528_0903_sendung_sgl/1/230528_0903_sendung_sgl_6660k_p37v17.mp4","","1685257380","","","false"],"X":["","","Körperideale: so what? -","14.05.2023","09:03:00","00:26:58","371","Federico ist 1,63 Meter groß. Als kleiner Mann selbstbewusst zu sein und sich begehrenswert zu fühlen, ist sein Weg. Bis heute muss er sich mit verletzenden Kommentaren auseinandersetzen.","https://rodlzdf-a.akamaihd.net/none/zdf/23/05/230514_0903_sendung_sgl/1/230514_0903_sendung_sgl_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/37-grad-leben/koerperideale-so-what-102.html","https://utstreaming.zdf.de/mtt/zdf/23/05/230514_0903_sendung_sgl/2/F1039665_hoh_deu_37_Grad_Leben_Koerperideale_so_what_ap_140523.xml","","96|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/zdf/23/05/230514_0903_sendung_sgl/1/230514_0903_sendung_sgl_6660k_p37v17.mp4","","1684047780","","","false"],"X":["","Besonders normal","Leben in Zeiten von Corona","08.07.2020","11:44:00","00:29:01","499","Menschen mit Behinderungen sind gerade in größter Sorge. Sie haben Angst vor Ansteckung und einem schweren Verlauf, vor der Einsamkeit in Isolation und einem Assistenz- und Pflegekräftemangel.","https://rodlzdf-a.akamaihd.net/none/3sat/20/05/200508__1140_sendung_besondersnormal/2/200508__1140_sendung_besondersnormal_2328k_p35v13.mp4","https://www.3sat.de/gesellschaft/besonders-normal/besonders-normal-vom-8-mai-2020-102.html","https://utstreaming.zdf.de/mtt/3sat/20/05/200508__1140_sendung_besondersnormal/2/F1026017_hoh_deu_Besonders_normal_Leben_in_Zeiten_von_Corona_080520.xml","","123|776k_p11v13.mp4","","123|3328k_p36v13.mp4","","1594201440","","","false"],"X":["","","Corona - Zwischen Sorge und Zuversicht","05.06.2020","11:30:00","00:28:56","499","Die Corona-Pandemie wirkt immer noch nach. Auch bei den Menschen mit Behinderungen und sozial Schwachen. Sie können nicht wie gewohnt arbeiten oder bangen um die berufliche Existenz.","https://rodlzdf-a.akamaihd.net/none/3sat/20/06/200605_1130_sendung_besondersnormal/2/200605_1130_sendung_besondersnormal_2328k_p35v13.mp4","https://www.3sat.de/gesellschaft/besonders-normal/besonders-normal-vom-5-juni-2020-100.html","https://utstreaming.zdf.de/mtt/3sat/20/06/200605_1130_sendung_besondersnormal/2/F1026188_hoh_deu_Besonders_normal_Corona_Zwischen_Zuversicht_und_Sorge_050620.xml","","121|776k_p11v13.mp4","","121|3328k_p36v13.mp4","","1591349400","","","false"],"X":["","","Beste Freunde","07.06.2019","12:29:00","00:29:27","509","Während die Politik und Gesellschaft über die Möglichkeiten von Inklusion und Teilhabe diskutieren, haben zwei kleine Mädchen, den Traum schon längst umgesetzt.","https://rodlzdf-a.akamaihd.net/none/3sat/19/06/190607_beste_freunde/1/190607_beste_freunde_2328k_p35v13.mp4","https://www.3sat.de/gesellschaft/besonders-normal/beste-freunde-102.html","","","91|776k_p11v13.mp4","","91|3296k_p15v13.mp4","","1559903340","","","false"],"X":["","Bier Royal","Bier Royal (1/2) - Familienkomödie, Deutschland 2019","30.01.2019","20:15:00","01:25:05","1467","München. Bier. Society. Und mittendrin eine alteingesessene Bierdynastie, in der zwei Frauen um Macht, Liebe und Anerkennung kämpfen.","https://rodlzdf-a.akamaihd.net/dach/3sat/19/12/191227_bier_royal1_fernsehfilm/2/191227_bier_royal1_fernsehfilm_2328k_p35v13.mp4","https://www.3sat.de/film/bier-royal/bier-royal-1-100.html","","","111|776k_p11v13.mp4","","111|3328k_p36v13.mp4","","1548875700","","DE-AT-CH","false"],"X":["","","Bier Royal (2/2) - Familienkomödie, Deutschland 2019","28.01.2019","20:15:00","01:27:30","1510","Die Münchner Brauerei droht im erbitterten Erbstreit unterzugehen. Gisela und Vicky müssen zusammenarbeiten, um das Unternehmen zu retten.","https://rodlzdf-a.akamaihd.net/dach/3sat/19/12/191227_bier_royal2_fernsehfilm/4/191227_bier_royal2_fernsehfilm_2328k_p35v13.mp4","https://www.3sat.de/film/bier-royal/bier-royal-2-100.html","","","111|776k_p11v13.mp4","","111|3328k_p36v13.mp4","","1548702900","","DE-AT-CH","false"],"X":["","Bilder aus Südtirol","Bilder aus Südtirol vom 20. Mai 2023","20.05.2023","09:35:00","00:23:32","327","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/23/05/230520_0935_sendung_suedtirol/1/230520_0935_sendung_suedtirol_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-20-mai-2023-100.html","","","109|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/3sat/23/05/230520_0935_sendung_suedtirol/1/230520_0935_sendung_suedtirol_6660k_p37v17.mp4","","1684568100","","","false"],"X":["","","Bilder aus Südtirol vom 13. Mai 2023","13.05.2023","09:37:00","00:22:38","314","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/23/05/230513_0935_sendung_suedtirol/1/230513_0935_sendung_suedtirol_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-13-mai-2023-100.html","","","109|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/3sat/23/05/230513_0935_sendung_suedtirol/1/230513_0935_sendung_suedtirol_6660k_p37v17.mp4","","1683963420","","","false"],"X":["","","Bilder aus Südtirol vom 6. Mai 2023","06.05.2023","09:39:00","00:24:21","336","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/23/05/230506_0935_sendung_suedtirol/1/230506_0935_sendung_suedtirol_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-6-mai-2023-100.html","","","109|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/3sat/23/05/230506_0935_sendung_suedtirol/1/230506_0935_sendung_suedtirol_6660k_p37v17.mp4","","1683358740","","","false"],"X":["","","Bilder aus Südtirol vom 22. April 2023","22.04.2023","09:39:00","00:23:52","337","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/23/04/230422_0935_sendung_suedtirol/1/230422_0935_sendung_suedtirol_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-22-april-2023-100.html","","","109|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/3sat/23/04/230422_0935_sendung_suedtirol/1/230422_0935_sendung_suedtirol_6660k_p37v17.mp4","","1682149140","","","false"],"X":["","","Bilder aus Südtirol vom 15. April 2023","15.04.2023","09:37:00","00:19:42","273","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/23/04/230415_0935_sendung_suedtirol/1/230415_0935_sendung_suedtirol_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-15-april-2023-100.html","","","109|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/3sat/23/04/230415_0935_sendung_suedtirol/1/230415_0935_sendung_suedtirol_6660k_p37v17.mp4","","1681544220","","","false"],"X":["","","Bilder aus Südtirol vom 8. April 2023","08.04.2023","09:36:00","00:22:56","323","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/23/04/230408_0935_sendung_suedtirol/1/230408_0935_sendung_suedtirol_2360k_p35v17.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-8-april-2023-100.html","","","109|808k_p11v17.mp4","","8|nrodlzdf-a.akamaihd.net/none/3sat/23/04/230408_0935_sendung_suedtirol/1/230408_0935_sendung_suedtirol_6660k_p37v17.mp4","","1680939360","","","false"],"X":["","","Bilder aus Südtirol vom 11. Dezember 2021","11.12.2021","09:35:00","00:24:35","335","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/21/12/211211_0935_sendung_suedtirol/1/211211_0935_sendung_suedtirol_2360k_p35v15.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-11-dezember-2021-100.html","","","109|808k_p11v15.mp4","","109|3360k_p36v15.mp4","","1639211700","","","false"],"X":["","","Bilder aus Südtirol vom 6. November 2021","06.11.2021","09:35:00","00:23:58","333","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/21/11/211106_0935_sendung_suedtirol/1/211106_0935_sendung_suedtirol_2360k_p35v15.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-6-november-2021-100.html","","","109|808k_p11v15.mp4","","109|3360k_p36v15.mp4","","1636187700","","","false"],"X":["","","Bilder aus Südtirol vom 25. Juli 2020","25.07.2020","09:35:00","00:23:41","407","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/20/07/200725_0935_sendung_suedtirol/1/200725_0935_sendung_suedtirol_2328k_p35v13.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-25-juli-2020-100.html","","","109|776k_p11v13.mp4","","109|3328k_p36v13.mp4","","1595662500","","","false"],"X":["","","Bilder aus Südtirol vom 20. Juni 2020","20.06.2020","09:36:00","00:24:16","416","\"Bilder aus Südtirol\" ist das Bundesländermagazin des ORF-Landesstudios Tirol.","https://rodlzdf-a.akamaihd.net/none/3sat/20/06/200620_0935_sendung_suedtirol/1/200620_0935_sendung_suedtirol_2328k_p35v13.mp4","https://www.3sat.de/gesellschaft/bilder-aus-suedtirol/bilder-aus-suedtirol-vom-20-juni-2020-100.html","","","109|776k_p11v13.mp4","","109|3328k_p36v13.mp4","","1592638560","","","false"]} \ No newline at end of file From 8d6c1806d78c79f0142389ea0df300a062ce86bb Mon Sep 17 00:00:00 2001 From: CodingPF Date: Fri, 27 Oct 2023 10:47:15 +0200 Subject: [PATCH 4/7] force sequential execution due to file lock issues --- .../de/mediathekview/mlib/config/ConfigManagerTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/java/de/mediathekview/mlib/config/ConfigManagerTest.java b/src/test/java/de/mediathekview/mlib/config/ConfigManagerTest.java index fb9a0b96..966f13ce 100644 --- a/src/test/java/de/mediathekview/mlib/config/ConfigManagerTest.java +++ b/src/test/java/de/mediathekview/mlib/config/ConfigManagerTest.java @@ -1,7 +1,9 @@ package de.mediathekview.mlib.config; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import java.io.IOException; import java.nio.file.Files; @@ -18,6 +20,7 @@ * * @author nicklas */ +@TestMethodOrder(org.junit.jupiter.api.MethodOrderer.OrderAnnotation.class) class ConfigManagerTest { private static final String TEST_CONFIG_FILE_NAME = "TestConfig.yaml"; @@ -40,16 +43,19 @@ protected Class getConfigClass() { } @Test + @Order(1) void testGetConfigFileName() { assertThat(new TestConfigManager().getConfigFileName()).isEqualTo(TEST_CONFIG_FILE_NAME); } @Test + @Order(2) void testGetConfigClass() { assertThat(new TestConfigManager().getConfigClass()).isEqualTo(TestConfigDTO.class); } @Test + @Order(3) void testReadClasspathConfig() { final TestConfigDTO classpathConfig = new TestConfigManager().getConfig(); assertThat(classpathConfig.getValueWithDefault()).isEqualTo("Hello World!"); @@ -57,6 +63,7 @@ void testReadClasspathConfig() { } @Test + @Order(4) void testReadFileConfig() throws IOException { writeTempTestFileConfig(); From 1502e78959e6df1050d2dc158eb26a81e9c02d70 Mon Sep 17 00:00:00 2001 From: CodingPF Date: Sun, 29 Oct 2023 12:26:46 +0100 Subject: [PATCH 5/7] remove stream support --- .../writer/AbstractFilmlistWriter.java | 3 -- .../writer/FilmlistOldFormatWriter.java | 34 ------------------- .../filmlisten/writer/FilmlistWriter.java | 9 ----- 3 files changed, 46 deletions(-) diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java index 6d1221bf..9a9a79fd 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/AbstractFilmlistWriter.java @@ -1,6 +1,5 @@ package de.mediathekview.mlib.filmlisten.writer; -import de.mediathekview.mlib.daten.Film; import de.mediathekview.mlib.daten.Filmlist; import de.mediathekview.mlib.messages.LibMessages; import de.mediathekview.mlib.messages.MessageCreator; @@ -13,7 +12,6 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.file.Path; -import java.util.stream.Stream; public abstract class AbstractFilmlistWriter extends MessageCreator { private static final Logger LOG = LogManager.getLogger(AbstractFilmlistWriter.class); @@ -27,7 +25,6 @@ protected AbstractFilmlistWriter(final MessageListener... aListeners) { } public abstract boolean write(Filmlist filmlist, OutputStream outputStream) throws IOException; - public abstract boolean write(Stream filmlist, OutputStream outputStream) throws IOException; public boolean write(Filmlist filmlist, Path savePath) { try (final OutputStream os = new FileOutputStream(savePath.toFile()); diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java index cbc3113f..dc9647cf 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java @@ -7,7 +7,6 @@ import de.mediathekview.mlib.daten.MediaResourceComperators; import de.mediathekview.mlib.daten.Podcast; import de.mediathekview.mlib.daten.Resolution; - import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -19,7 +18,6 @@ import java.time.format.DateTimeFormatter; import java.util.Collection; import java.util.Locale; -import java.util.stream.Stream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -45,38 +43,6 @@ public class FilmlistOldFormatWriter extends AbstractFilmlistWriter { protected String thema = ""; protected int cnt; - - @Override - public boolean write(Stream filmlist, OutputStream outputStream) throws IOException { - long start = System.currentTimeMillis(); - try { - LOG.info("start writting data"); - JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(outputStream,StandardCharsets.UTF_8)); - jsonWriter.beginObject(); - writeMetaHeader(new Filmlist(), jsonWriter); - writeColumnHeader(jsonWriter); - filmlist.forEach(aFilm -> { - try { - writeRecord(aFilm, jsonWriter); - cnt++; - if (cnt % 1000 == 0) { - jsonWriter.flush(); - } - } catch (IOException e) { - LOG.error(e); - } - }); - jsonWriter.endObject(); - jsonWriter.flush(); - LOG.info("done writting in " + ((System.currentTimeMillis()-start)/1000) + "sec for " + cnt + " elements"); - } catch (IOException e) { - LOG.error(e); - return false; - } - return true; - } - - @Override public boolean write(Filmlist filmlist, OutputStream outputStream) throws IOException { long start = System.currentTimeMillis(); diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java index 73b3a47d..7fa50b7c 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java @@ -3,7 +3,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import de.mediathekview.mlib.daten.Film; import de.mediathekview.mlib.daten.Filmlist; import de.mediathekview.mlib.daten.GsonDurationAdapter; import de.mediathekview.mlib.daten.GsonLocalDateTimeAdapter; @@ -16,8 +15,6 @@ import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.LocalDateTime; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class FilmlistWriter extends AbstractFilmlistWriter { @@ -44,10 +41,4 @@ public boolean write(Filmlist filmlist, OutputStream outputStream) throws IOExce return true; } - @Override - public boolean write(Stream filmlist, OutputStream outputStream) throws IOException { - Filmlist fl = new Filmlist(); - fl.addAllFilms(filmlist.collect(Collectors.toList())); - return write(fl, outputStream); - } } From 378225dd3e6108fcf057311b51ee05b886bd64f8 Mon Sep 17 00:00:00 2001 From: CodingPF Date: Sun, 29 Oct 2023 12:28:16 +0100 Subject: [PATCH 6/7] empty line --- .../de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java index 7fa50b7c..e3c8b5f4 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistWriter.java @@ -2,7 +2,6 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; - import de.mediathekview.mlib.daten.Filmlist; import de.mediathekview.mlib.daten.GsonDurationAdapter; import de.mediathekview.mlib.daten.GsonLocalDateTimeAdapter; @@ -40,5 +39,4 @@ public boolean write(Filmlist filmlist, OutputStream outputStream) throws IOExce return true; } - } From 33306251d6ccd290532c006431db3ba4d561ca88 Mon Sep 17 00:00:00 2001 From: CodingPF Date: Mon, 30 Oct 2023 20:36:28 +0100 Subject: [PATCH 7/7] sonarcloud --- TestConfig.yaml | 2 - .../reader/FilmlistOldFormatReader.java | 58 +++++++------------ .../writer/FilmlistOldFormatWriter.java | 2 +- .../FilmlistOldFormatReaderTest.java | 2 +- .../FilmlistOldFormatWriterTest.java | 2 +- 5 files changed, 23 insertions(+), 43 deletions(-) delete mode 100644 TestConfig.yaml diff --git a/TestConfig.yaml b/TestConfig.yaml deleted file mode 100644 index 9b389a4c..00000000 --- a/TestConfig.yaml +++ /dev/null @@ -1,2 +0,0 @@ -valueWithDefault: TestValue -valueWithoutDefault: Some other test value diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java b/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java index 042765e1..155efcf9 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/reader/FilmlistOldFormatReader.java @@ -14,8 +14,6 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -31,7 +29,6 @@ import java.time.format.DateTimeParseException; import java.util.*; -import static java.lang.String.format; import static java.time.format.FormatStyle.MEDIUM; public class FilmlistOldFormatReader extends AbstractFilmlistReader { @@ -47,23 +44,12 @@ public class FilmlistOldFormatReader extends AbstractFilmlistReader { private String sender = ""; private String thema = ""; private String debug = ""; - int cnt = 0; + private int cnt = 0; - public static void main(String[] args) throws FileNotFoundException { - new FilmlistOldFormatReader().read(new FileInputStream("C:/Users/steph/Desktop/Mediathek/oldFormat/Filmliste-akt-oldformat.json")); - } - @Override public Optional read(InputStream aInputStream) { long start = System.currentTimeMillis(); - /* - String bigFile = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmliste-akt-oldformat.json"; - String medium = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmlist - Kopie.json"; - String smallFile = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmlist.json"; - String broken = "C:/Users/steph/Desktop/Mediathek/oldFormat/Filmlist-broken.json"; - */ Filmlist filmlist = new Filmlist(); - int cnt = 0; debug = "LINE " + cnt; // @@ -74,10 +60,10 @@ public Optional read(InputStream aInputStream) { while (jsonReader.peek() != JsonToken.END_OBJECT) { try { - readRecrod(jsonReader).ifPresent(aFilm -> {filmlist.add(aFilm);}); + readRecrod(jsonReader).ifPresent(filmlist::add); } catch (Exception e) { if (!recoverParser(jsonReader)) { - System.out.println("error after " + ((System.currentTimeMillis()-start)/1000) + " on " + cnt + " elements (" + filmlist.getFilms().size()+")"); + LOG.error("error after {} sec on element {} of {} elements", ((System.currentTimeMillis()-start)/1000), cnt, filmlist.getFilms().size()); throw(e); } } @@ -87,7 +73,7 @@ public Optional read(InputStream aInputStream) { LOG.error(e); return Optional.of(filmlist); } - LOG.debug("done reading in " + ((System.currentTimeMillis()-start)/1000) + "sec for " + cnt + " elements (" + filmlist.getFilms().size()+")"); + LOG.debug("done reading in {} sec for {} elements resulting in {} elements", ((System.currentTimeMillis()-start)/1000), cnt, filmlist.getFilms().size()); return Optional.of(filmlist); } @@ -102,7 +88,7 @@ private boolean recoverParser(JsonReader jsonReader) { jsonReader.endArray(); return true; } catch (Exception e) { - // TODO: handle exception + LOG.error(e); } return false; } @@ -126,7 +112,7 @@ private LocalDateTime readHeader01CreationDate(String in) { try { return LocalDateTime.parse(in, FILMLIST_CREATIONDATE_PATTERN); } catch (DateTimeParseException e) { - LOG.warn(format("Error readHeader01CreationDate format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readHeader01CreationDate format string {} on line {} thorws {}", in, debug, e ); } } return LocalDateTime.now(); @@ -138,7 +124,7 @@ private UUID readHeader05Hash(String in) { try { return UUID.fromString(in); } catch (Exception e) { - LOG.warn("Error readHeader05Hash format string " + in); + LOG.warn("Error readHeader05Hash format string {}", in); } return UUID.randomUUID(); } @@ -167,7 +153,7 @@ private void headerColumns(JsonReader jsonReader) throws IOException { jsonReader.nextString(); // Geo jsonReader.nextString(); // neu jsonReader.endArray(); - }; + } private Optional readRecrod(JsonReader jsonReader) throws IOException { cnt++; @@ -226,22 +212,18 @@ private Optional readRecrod(JsonReader jsonReader) throws IOException { if (f.getUrls().size() > 0) { return Optional.of(f); } else { - LOG.warn(format("Error no urls for film %s", debug)); + LOG.warn("Error no urls for film {}", debug); return Optional.empty(); } } private Map generateUrls(URL urlNormal, String urlSmall, String urlHd, long size) { - Map urls = new HashMap<>(); + Map urls = new EnumMap<>(Resolution.class); if (urlNormal != null) { urls.put(Resolution.NORMAL, new FilmUrl(urlNormal, size)); - rebuildUrl(urlNormal, urlSmall).ifPresent( u -> { - urls.put(Resolution.SMALL, new FilmUrl(u, 0L)); - }); - rebuildUrl(urlNormal, urlHd).ifPresent( u -> { - urls.put(Resolution.HD, new FilmUrl(u, 0L)); - }); + rebuildUrl(urlNormal, urlSmall).ifPresent( u -> urls.put(Resolution.SMALL, new FilmUrl(u, 0L))); + rebuildUrl(urlNormal, urlHd).ifPresent( u -> urls.put(Resolution.HD, new FilmUrl(u, 0L))); } return urls; } @@ -256,7 +238,7 @@ private Optional rebuildUrl(URL urlNromal, String targetUrl) { } return Optional.of(new URL(targetUrl)); } catch (Exception e) { - LOG.warn(format("Error rebuildUrl format string %s on line %s throws %s", targetUrl, debug, e )); + LOG.warn("Error rebuildUrl format string {} on line {} throws {}", targetUrl, debug, e ); } } return Optional.empty(); @@ -289,7 +271,7 @@ protected LocalDate readRecord04Datum(String in) { try { return LocalDate.parse(in, DATE_FORMATTER); } catch (DateTimeParseException e) { - LOG.warn(format("Error readRecord04Datum format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord04Datum format string {} on line {} throws {}", in, debug, e ); } } return DEFAULT_DATE; @@ -300,7 +282,7 @@ protected LocalTime readRecord05Zeit(String in) { try { return LocalTime.parse(in, TIME_FORMATTER); } catch (DateTimeParseException e) { - LOG.warn(format("Error readRecord05Zeit format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord05Zeit format string {} on line {} throws {}", in, debug, e ); } } return LocalTime.MIDNIGHT; @@ -311,7 +293,7 @@ protected Duration readRecord06Dauer(String in) { try { return Duration.between(LocalTime.MIDNIGHT, LocalTime.parse(in)); } catch (DateTimeException | ArithmeticException e) { - LOG.info(format("Error readRecord06Dauer format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord06Dauer format string {} on line {} throws {}", in, debug, e ); } } return Duration.ZERO; @@ -322,7 +304,7 @@ protected long readRecord07Groesse(String in) { try { return Long.parseLong(in)*1024; // oldFilmlist format is MB - new DM is KB } catch (NumberFormatException e) { - LOG.warn(format("Error readRecord07Groesse format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord07Groesse format string {} on line {} throws {}", in, debug, e ); } } return 0L; @@ -337,7 +319,7 @@ protected URL readRecord09Url(String in) { try { return new URL(in); } catch (final MalformedURLException e) { - LOG.warn(format("Error readRecord09Url format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord09Url format string {} on line {} throws {}", in, debug, e ); } } return null; @@ -348,7 +330,7 @@ protected URL readRecord10Website(String in) { try { return new URL(in); } catch (final MalformedURLException e) { - LOG.warn(format("Error readRecord10Website format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord10Website format string {} on line {} throws {}", in, debug, e ); } } return null; @@ -359,7 +341,7 @@ protected URL readRecord11Untertitel(String in) { try { return new URL(in); } catch (final MalformedURLException e) { - LOG.warn(format("Error readRecord11Untertitel format string %s on line %s throws %s", in, debug, e )); + LOG.warn("Error readRecord11Untertitel format string {} on line {} throws {}", in, debug, e ); } } return null; diff --git a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java index dc9647cf..c17d2a46 100644 --- a/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java +++ b/src/main/java/de/mediathekview/mlib/filmlisten/writer/FilmlistOldFormatWriter.java @@ -62,7 +62,7 @@ public boolean write(Filmlist filmlist, OutputStream outputStream) throws IOExce }); jsonWriter.endObject(); jsonWriter.flush(); - LOG.info("done writting in " + ((System.currentTimeMillis()-start)/1000) + "sec for " + cnt + " elements (" + filmlist.getFilms().size()+")"); + LOG.info("done writting in {} sec reading {} elements resulting in {} elements", ((System.currentTimeMillis()-start)/1000), cnt, filmlist.getFilms().size()); } catch (IOException e) { LOG.error(e); return false; diff --git a/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java index 9ada0f36..9cda1dae 100644 --- a/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java +++ b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatReaderTest.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; -public class FilmlistOldFormatReaderTest { +class FilmlistOldFormatReaderTest { @Test void readFilmlistOldFormatIncludingBrokenRecords() diff --git a/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java index 0f01bf54..25138a32 100644 --- a/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java +++ b/src/test/java/de/mediathekview/mlib/filmlisten/FilmlistOldFormatWriterTest.java @@ -19,7 +19,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -public class FilmlistOldFormatWriterTest { +class FilmlistOldFormatWriterTest { @TempDir Path tempDir;