Skip to content

Commit

Permalink
Merge branch 'release/0.10.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
s-frei committed Jun 11, 2024
2 parents 6f5fd5a + 1e8d5b3 commit b8778a9
Show file tree
Hide file tree
Showing 16 changed files with 199 additions and 67 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
Changelog
=========

0.10.1
------

**Features:**

- Updated dependencies

**Bugfixes:**

- Fix YouTube tracks parsing through parse missing info on demand

0.10.0
------

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ There could be more added if there are interesting sources to go for.
<dependency>
<groupId>io.sfrei</groupId>
<artifactId>tracksearch</artifactId>
<version>0.10.0</version>
<version>0.10.1</version>
</dependency>
```

```kotlin
implementation("io.sfrei:tracksearch:0.10.0")
implementation("io.sfrei:tracksearch:0.10.1")
```

on [GitHub Packages](https://github.com/s-frei/TrackSearch/packages) or directly from
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>io.sfrei</groupId>
<artifactId>tracksearch</artifactId>
<version>0.10.0</version>
<version>0.10.1</version>

<packaging>jar</packaging>

Expand Down Expand Up @@ -49,7 +49,7 @@
<jsoup.version>1.17.2</jsoup.version>
<slf4j-api.version>2.0.13</slf4j-api.version>
<junit.version>5.10.2</junit.version>
<assertj-core.version>3.25.3</assertj-core.version>
<assertj-core.version>3.26.0</assertj-core.version>
<logback-classic.version>1.5.6</logback-classic.version>

<!-- test n report -->
Expand All @@ -60,11 +60,11 @@
<lombok-maven-plugin.version>1.18.20.0</lombok-maven-plugin.version>
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
<maven-source-plugin.version>3.3.1</maven-source-plugin.version>
<maven-javadoc-plugin.version>3.6.3</maven-javadoc-plugin.version>
<maven-javadoc-plugin.version>3.7.0</maven-javadoc-plugin.version>
<maven-release-plugin.version>3.0.1</maven-release-plugin.version>
<maven-scm-provider-gitexe.version>2.1.0</maven-scm-provider-gitexe.version>
<maven-scm-api.version>2.1.0</maven-scm-api.version>
<nexus-staging-maven-plugin.version>1.6.13</nexus-staging-maven-plugin.version>
<nexus-staging-maven-plugin.version>1.7.0</nexus-staging-maven-plugin.version>
<maven-gpg-plugin.version>3.2.4</maven-gpg-plugin.version>
</properties>

Expand Down
20 changes: 4 additions & 16 deletions src/main/java/io/sfrei/tracksearch/clients/SearchClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import io.sfrei.tracksearch.clients.common.ClientLogger;
import io.sfrei.tracksearch.clients.common.QueryType;
import io.sfrei.tracksearch.clients.common.SharedClient;
import io.sfrei.tracksearch.config.TrackSearchConfig;
import io.sfrei.tracksearch.exceptions.TrackSearchException;
import io.sfrei.tracksearch.tracks.Track;
import io.sfrei.tracksearch.tracks.TrackList;
Expand All @@ -31,7 +30,7 @@

public interface SearchClient<T extends Track> extends TrackSearchClient<T>, ClientLogger {

default void throwIfPagingValueMissing(SearchClient<?> source, TrackList<? extends Track> trackList)
default void throwIfPagingValueMissing(TrackProviders<? extends Track> source, TrackList<? extends Track> trackList)
throws TrackSearchException {

if (!hasPagingValues(trackList))
Expand All @@ -40,8 +39,8 @@ default void throwIfPagingValueMissing(SearchClient<?> source, TrackList<? exten
}

default TrackSearchException noTrackStreamAfterRetriesException(Function<String, TrackSearchException> exceptionConstructor,
int tries) {
return exceptionConstructor.apply(String.format("Not able to get stream URL after %s tries", tries));
int retries) {
return exceptionConstructor.apply(String.format("Not able to get stream URL after %s tries", retries + 1));
}

default TrackSearchException unsupportedQueryTypeException(Function<String, TrackSearchException> exceptionConstructor, QueryType queryType) {
Expand All @@ -64,7 +63,7 @@ default Optional<TrackStream> tryResolveTrackStream(T track, int retries) {
} catch (TrackSearchException e) {
retries--;
if (retries > 0) {
log().warn("Not able getting stream for - {} tries left: {}", retries, e.getMessage());
log().warn("Not able getting stream for: {} - {} tries left - cause: {}", track.getUrl(), retries, e.getMessage());
try {
log().trace("Refreshing track information...");
refreshTrackInfo(track);
Expand All @@ -90,15 +89,4 @@ default TrackList<T> provideNext(final TrackList<T> trackList) {
return null;
}


@Nullable
default TrackStream trackStreamProvider(final T track) {
try {
return getTrackStream(track, TrackSearchConfig.resolvingRetries);
} catch (TrackSearchException e) {
log().error("Error occurred acquiring stream URL for: {}", track.getUrl(), e);
}
return null;
}

}
51 changes: 51 additions & 0 deletions src/main/java/io/sfrei/tracksearch/clients/TrackProviders.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2024 s-frei (sfrei.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.sfrei.tracksearch.clients;

import io.sfrei.tracksearch.clients.common.ClientLogger;
import io.sfrei.tracksearch.config.TrackSearchConfig;
import io.sfrei.tracksearch.exceptions.TrackSearchException;
import io.sfrei.tracksearch.tracks.Track;
import io.sfrei.tracksearch.tracks.metadata.TrackStream;
import org.jetbrains.annotations.Nullable;

public interface TrackProviders<T extends Track> extends TrackSearchClient<T>, ClientLogger {


<I> I getTrackInfo(T track) throws TrackSearchException;

@Nullable
default <I> I trackInfoProvider(final T track) {
try {
return getTrackInfo(track);
} catch (TrackSearchException e) {
log().error("Error occurred acquiring track info for: {}", track.getUrl(), e);
}
return null;
}

@Nullable
default TrackStream trackStreamProvider(final T track) {
try {
return getTrackStream(track, TrackSearchConfig.resolvingRetries);
} catch (TrackSearchException e) {
log().error("Error occurred acquiring stream URL for: {}", track.getUrl(), e);
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,16 @@


import io.sfrei.tracksearch.clients.SearchClient;
import io.sfrei.tracksearch.clients.TrackProviders;
import io.sfrei.tracksearch.clients.common.QueryType;
import io.sfrei.tracksearch.clients.common.ResponseProviderFactory;
import io.sfrei.tracksearch.clients.common.ResponseWrapper;
import io.sfrei.tracksearch.clients.common.SharedClient;
import io.sfrei.tracksearch.config.TrackSearchConfig;
import io.sfrei.tracksearch.exceptions.SoundCloudException;
import io.sfrei.tracksearch.exceptions.TrackSearchException;
import io.sfrei.tracksearch.tracks.GenericTrackList;
import io.sfrei.tracksearch.tracks.SoundCloudTrack;
import io.sfrei.tracksearch.tracks.Track;
import io.sfrei.tracksearch.tracks.TrackList;
import io.sfrei.tracksearch.tracks.metadata.SoundCloudTrackFormat;
import io.sfrei.tracksearch.tracks.metadata.SoundCloudTrackInfo;
import io.sfrei.tracksearch.tracks.metadata.TrackStream;
import io.sfrei.tracksearch.tracks.*;
import io.sfrei.tracksearch.tracks.metadata.*;
import io.sfrei.tracksearch.utils.TrackFormatComparator;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -44,7 +40,7 @@
import static io.sfrei.tracksearch.clients.common.SharedClient.*;

@Slf4j
public class SoundCloudClient implements SearchClient<SoundCloudTrack> {
public class SoundCloudClient implements SearchClient<SoundCloudTrack>, TrackProviders<SoundCloudTrack> {

public static final String URL = "https://soundcloud.com";
private static final String INFORMATION_PREFIX = "sc";
Expand Down Expand Up @@ -124,10 +120,15 @@ public TrackList<SoundCloudTrack> getNext(@NonNull final TrackList<? extends Tra
}

@Override
public void refreshTrackInfo(SoundCloudTrack track) throws TrackSearchException {
@SuppressWarnings("unchecked")
public SoundCloudTrackInfo getTrackInfo(SoundCloudTrack track) throws TrackSearchException {
final String trackHTML = clientIDRequest(api.getForUrlWithClientID(track.getUrl(), clientID)).contentOrThrow();
final SoundCloudTrackInfo trackInfo = SoundCloudUtility.extractTrackInfoFromHTML(trackHTML);
track.setTrackInfo(trackInfo);
return SoundCloudUtility.extractTrackInfoFromHTML(trackHTML);
}

@Override
public void refreshTrackInfo(SoundCloudTrack track) throws TrackSearchException {
track.setTrackInfo(getTrackInfo(track));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.sfrei.tracksearch.clients.youtube;

import io.sfrei.tracksearch.clients.SearchClient;
import io.sfrei.tracksearch.clients.TrackProviders;
import io.sfrei.tracksearch.clients.common.QueryType;
import io.sfrei.tracksearch.clients.common.ResponseProviderFactory;
import io.sfrei.tracksearch.clients.common.SharedClient;
Expand Down Expand Up @@ -48,7 +49,7 @@
import static io.sfrei.tracksearch.clients.common.SharedClient.request;

@Slf4j
public class YouTubeClient implements SearchClient<YouTubeTrack> {
public class YouTubeClient implements SearchClient<YouTubeTrack>, TrackProviders<YouTubeTrack> {

public static final String URL = "https://www.youtube.com";
public static final String PAGING_KEY = "ctoken";
Expand Down Expand Up @@ -98,17 +99,14 @@ public YouTubeTrack getTrack(@NonNull final String url) throws TrackSearchExcept
throw new YouTubeException(String.format("%s not applicable for URL: %s", this.getClass().getSimpleName(), url));

final String trackJSON = request(api.getForUrlWithParams(url, TRACK_PARAMS)).contentOrThrow();
final YouTubeTrack youTubeTrack = YouTubeUtility.extractYouTubeTrack(trackJSON, this::trackStreamProvider);
final YouTubeTrackInfo trackInfo = YouTubeUtility.extractTrackInfo(trackJSON, url);
youTubeTrack.setTrackInfo(trackInfo);
return youTubeTrack;
return YouTubeUtility.extractYouTubeTrack(trackJSON, this::trackInfoProvider, this::trackStreamProvider);
}

private GenericTrackList<YouTubeTrack> getTracksForSearch(@NonNull final String search, @NonNull final Map<String, String> params, QueryType queryType)
throws TrackSearchException {

final String tracksJSON = request(api.getSearchForKeywords(search, params)).contentOrThrow();
return YouTubeUtility.extractYouTubeTracks(tracksJSON, queryType, search, this::provideNext, this::trackStreamProvider);
return YouTubeUtility.extractYouTubeTracks(tracksJSON, queryType, search, this::provideNext, this::trackInfoProvider, this::trackStreamProvider);
}

@Override
Expand All @@ -134,10 +132,16 @@ public TrackList<YouTubeTrack> getNext(@NonNull final TrackList<? extends Track>
throw unsupportedQueryTypeException(YouTubeException::new, trackListQueryType);
}

@Override
@SuppressWarnings("unchecked")
public YouTubeTrackInfo getTrackInfo(YouTubeTrack youTubeTrack) throws TrackSearchException {
final String trackJSON = request(api.getForUrlWithParams(youTubeTrack.getUrl(), TRACK_PARAMS)).contentOrThrow();
return YouTubeUtility.extractTrackInfo(trackJSON, youTubeTrack.getUrl());
}

@Override
public void refreshTrackInfo(YouTubeTrack youTubeTrack) throws TrackSearchException {
final String trackJSON = request(api.getForUrlWithParams(youTubeTrack.getUrl(), TRACK_PARAMS)).contentOrThrow();
final YouTubeTrackInfo trackInfo = YouTubeUtility.extractTrackInfo(trackJSON, youTubeTrack.getUrl());
final YouTubeTrackInfo trackInfo = this.getTrackInfo(youTubeTrack);
youTubeTrack.setTrackInfo(trackInfo);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@
import io.sfrei.tracksearch.clients.common.QueryType;
import io.sfrei.tracksearch.clients.common.SharedClient;
import io.sfrei.tracksearch.exceptions.YouTubeException;
import io.sfrei.tracksearch.tracks.GenericTrackList;
import io.sfrei.tracksearch.tracks.TrackListProvider;
import io.sfrei.tracksearch.tracks.TrackStreamProvider;
import io.sfrei.tracksearch.tracks.YouTubeTrack;
import io.sfrei.tracksearch.tracks.*;
import io.sfrei.tracksearch.tracks.deserializer.youtube.YouTubeListTrackDeserializer;
import io.sfrei.tracksearch.tracks.deserializer.youtube.YouTubeURLTrackDeserializer;
import io.sfrei.tracksearch.tracks.metadata.MimeType;
Expand Down Expand Up @@ -78,7 +75,9 @@ private static String wrap(String functionContent) {
return "(" + VAR_NAME + ":function" + functionContent + FUNCTION_END + ")";
}

static YouTubeTrack extractYouTubeTrack(final String json, final TrackStreamProvider<YouTubeTrack> trackStreamProvider)
static YouTubeTrack extractYouTubeTrack(final String json,
final TrackInfoProvider<YouTubeTrack, YouTubeTrackInfo> trackInfoProvider,
final TrackStreamProvider<YouTubeTrack> trackStreamProvider)
throws YouTubeException {

final JsonElement trackJsonElement = JsonElement.readTreeCatching(MAPPER, json)
Expand All @@ -87,12 +86,14 @@ static YouTubeTrack extractYouTubeTrack(final String json, final TrackStreamProv
return playerResponseFromTrackJSON(trackJsonElement)
.mapCatching(MAPPER, YouTubeTrack.URLYouTubeTrackBuilder.class).getBuilder()
.trackStreamProvider(trackStreamProvider)
.trackInfoProvider(trackInfoProvider)
.build();
}

static GenericTrackList<YouTubeTrack> extractYouTubeTracks(final String json, final QueryType queryType, final String query,
final TrackListProvider<YouTubeTrack> nextTrackListFunction,
final TrackStreamProvider<YouTubeTrack> trackStreamProvider)
final TrackListProvider<YouTubeTrack> nextTrackListFunction,
final TrackInfoProvider<YouTubeTrack, YouTubeTrackInfo> trackInfoProvider,
final TrackStreamProvider<YouTubeTrack> trackStreamProvider)
throws YouTubeException {

final JsonElement rootElement = JsonElement.readTreeCatching(MAPPER, json)
Expand Down Expand Up @@ -136,6 +137,7 @@ static GenericTrackList<YouTubeTrack> extractYouTubeTracks(final String json, fi
.filter(Objects::nonNull)
.map(YouTubeTrack.ListYouTubeTrackBuilder::getBuilder)
.peek(youTubeTrackBuilder -> youTubeTrackBuilder.trackStreamProvider(trackStreamProvider))
.peek(youTubeTrackBuilder -> youTubeTrackBuilder.trackInfoProvider(trackInfoProvider))
.map(YouTubeTrack.YouTubeTrackBuilder::build)
.collect(Collectors.toList());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public final class TrackSearchConfig {
public static final String HEADER_LANGUAGE_ENGLISH = "Accept-Language: en";
public static final String HEADER_YOUTUBE_CLIENT_NAME = "x-youtube-client-name: 1";
public static final String HEADER_YOUTUBE_CLIENT_VERSION = "x-youtube-client-version: 2.20211004.00.00";
public static final int DEFAULT_RESOLVING_RETIRES = 4;
private static final int DEFAULT_RESOLVING_RETRIES = 5;

public static Integer playListOffset = 20;
public static Integer resolvingRetries = DEFAULT_RESOLVING_RETIRES;
public static Integer resolvingRetries = DEFAULT_RESOLVING_RETRIES;

}
32 changes: 32 additions & 0 deletions src/main/java/io/sfrei/tracksearch/tracks/TrackInfoProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2024 s-frei (sfrei.io)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.sfrei.tracksearch.tracks;

import io.sfrei.tracksearch.tracks.metadata.TrackFormat;
import io.sfrei.tracksearch.tracks.metadata.TrackInfo;
import org.jetbrains.annotations.Nullable;

import java.util.function.Function;

@FunctionalInterface
public interface TrackInfoProvider<T extends Track, F extends TrackInfo<? extends TrackFormat>> extends Function<T, F> {

@Nullable
@Override
F apply(T t);

}
Loading

0 comments on commit b8778a9

Please sign in to comment.