diff --git a/build.gradle b/build.gradle index 0e66a245e..74c12f80e 100644 --- a/build.gradle +++ b/build.gradle @@ -28,8 +28,8 @@ allprojects { ext { nanojsonVersion = "1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751" - spotbugsVersion = "4.7.1" - junitVersion = "5.9.0" + spotbugsVersion = "4.7.2" + junitVersion = "5.9.1" checkstyleVersion = "9.3" // do not use latest version (10.0) as it requires compile JDK 11 } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java index 27c1ce9a1..94d3b0a62 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCRecentKiosk.java @@ -12,6 +12,7 @@ import org.schabi.newpipe.extractor.exceptions.ExtractionException; import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.kiosk.KioskExtractor; import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler; +import org.schabi.newpipe.extractor.localization.DateWrapper; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; @@ -49,12 +50,12 @@ public class MediaCCCRecentKiosk extends KioskExtractor { // Streams in the recent kiosk are not ordered by the release date. // Sort them to have the latest stream at the beginning of the list. - Comparator comparator = Comparator.comparing( - streamInfoItem -> streamInfoItem.getUploadDate().offsetDateTime()); - comparator = comparator.reversed(); - - final StreamInfoItemsCollector collector = - new StreamInfoItemsCollector(getServiceId(), comparator); + final Comparator comparator = Comparator + .comparing(StreamInfoItem::getUploadDate, Comparator + .nullsLast(Comparator.comparing(DateWrapper::offsetDateTime))) + .reversed(); + final StreamInfoItemsCollector collector = new StreamInfoItemsCollector(getServiceId(), + comparator); events.stream() .filter(JsonObject.class::isInstance) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java index d308eb831..13f1f1400 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/soundcloud/extractors/SoundcloudPlaylistExtractor.java @@ -1,13 +1,9 @@ package org.schabi.newpipe.extractor.services.soundcloud.extractors; -import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper.SOUNDCLOUD_API_V2_URL; -import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; - import com.grack.nanojson.JsonArray; import com.grack.nanojson.JsonObject; import com.grack.nanojson.JsonParser; import com.grack.nanojson.JsonParserException; - import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.Page; import org.schabi.newpipe.extractor.StreamingService; @@ -20,11 +16,15 @@ import org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper; import org.schabi.newpipe.extractor.stream.StreamInfoItem; import org.schabi.newpipe.extractor.stream.StreamInfoItemsCollector; +import javax.annotation.Nonnull; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Objects; -import javax.annotation.Nonnull; +import static org.schabi.newpipe.extractor.services.soundcloud.SoundcloudParsingHelper.SOUNDCLOUD_API_V2_URL; +import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; public class SoundcloudPlaylistExtractor extends PlaylistExtractor { private static final int STREAMS_PER_REQUESTED_PAGE = 15; @@ -171,9 +171,26 @@ public class SoundcloudPlaylistExtractor extends PlaylistExtractor { try { final JsonArray tracks = JsonParser.array().from(response); + // Response may not contain tracks in the same order as currentIds. + // The streams are displayed in the order which is used in currentIds on SoundCloud. + final HashMap idToTrack = new HashMap<>(); for (final Object track : tracks) { if (track instanceof JsonObject) { - collector.commit(new SoundcloudStreamInfoItemExtractor((JsonObject) track)); + final JsonObject o = (JsonObject) track; + idToTrack.put(o.getInt("id"), o); + } + } + for (final String strId : currentIds) { + final int id = Integer.parseInt(strId); + try { + collector.commit(new SoundcloudStreamInfoItemExtractor( + Objects.requireNonNull( + idToTrack.get(id), + "no track with id " + id + " in response" + ) + )); + } catch (final NullPointerException e) { + throw new ParsingException("Could not parse json response", e); } } } catch (final JsonParserException e) { diff --git a/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsHolder.java b/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsHolder.java index f7dc99630..1e87f202d 100644 --- a/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsHolder.java +++ b/timeago-parser/src/main/java/org/schabi/newpipe/extractor/timeago/PatternsHolder.java @@ -1,12 +1,13 @@ package org.schabi.newpipe.extractor.timeago; +import static java.util.Arrays.asList; + import java.time.temporal.ChronoUnit; import java.util.Collection; +import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.Map; -import static java.util.Arrays.asList; - public abstract class PatternsHolder { private final String wordSeparator; private final Collection seconds; @@ -17,7 +18,8 @@ public abstract class PatternsHolder { private final Collection months; private final Collection years; - private final Map> specialCases = new LinkedHashMap<>(); + private final Map> specialCases = + new EnumMap<>(ChronoUnit.class); protected PatternsHolder(String wordSeparator, Collection seconds, Collection minutes, Collection hours, Collection days, @@ -81,7 +83,7 @@ public abstract class PatternsHolder { } public Map> asMap() { - final Map> returnMap = new LinkedHashMap<>(); + final Map> returnMap = new EnumMap<>(ChronoUnit.class); returnMap.put(ChronoUnit.SECONDS, seconds()); returnMap.put(ChronoUnit.MINUTES, minutes()); returnMap.put(ChronoUnit.HOURS, hours());