Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bandcamp] Handle paywalled tracks #1033

Merged
merged 2 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import org.schabi.newpipe.extractor.Page;
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ContentNotAvailableException;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.PaidContentException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandler;
import org.schabi.newpipe.extractor.playlist.PlaylistExtractor;
Expand Down Expand Up @@ -64,7 +64,7 @@ public void onFetchPage(@Nonnull final Downloader downloader)

if (trackInfo.isEmpty()) {
// Albums without trackInfo need to be purchased before they can be played
throw new ContentNotAvailableException("Album needs to be purchased");
throw new PaidContentException("Album needs to be purchased");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.PaidContentException;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.LinkHandler;
import org.schabi.newpipe.extractor.localization.DateWrapper;
Expand Down Expand Up @@ -57,6 +58,10 @@ public void onFetchPage(@Nonnull final Downloader downloader)
// In this case, we are actually viewing an album page!
throw new ExtractionException("Page is actually an album, not a track");
}

if (albumJson.getArray("trackinfo").getObject(0).isNull("file")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure that all tracks that have no streamable track are paid tracks? Can't the reason be different in some cases?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other possible reason is that it is not available yet because the album is currently up for pre-order. For example, this album is right now: https://tamarmitchell.bandcamp.com/album/samos-return

However it is impossible to see whether all of the tracks can be played for free after the album is released, or whether the tracks will require purchase to play. Therefore I think it is an okay option to throw this exception in either case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess otherwise we could test for unreleased_track and throw a different exception if that is true. Is there an appropriate exception for this case? Otherwise I would stick with PaidContentException.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I think ContentNotAvailableException is more appropriate, since the track is currently unavailable until the album is released, whether it's purchased or not.

However, it seems like the tracks that can't be played due to the album being in pre-order do not have their own pages yet. Therefore, I don't think it's a case that can occur in the StreamExtractor. Going to the album in NewPipe and clicking on one of those tracks causes an error because the URL for them gets set to https://tamarmitchell.bandcamp.com/null, so maybe it should be handled differently in the PlaylistExtractor?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I think I noticed the concatenation with null before but was unsure about the best way to fix it.

throw new PaidContentException("This track is not available without being purchased");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.schabi.newpipe.extractor.services.bandcamp;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.schabi.newpipe.extractor.ServiceList.Bandcamp;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.schabi.newpipe.downloader.DownloaderTestImpl;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.exceptions.PaidContentException;

public class BandcampPaidStreamExtractorTest {

@BeforeAll
public static void setUp() {
NewPipe.init(DownloaderTestImpl.getInstance());
}

@Test
public void testPaidTrack() throws ExtractionException {
final var extractor = Bandcamp.getStreamExtractor("https://radicaldreamland.bandcamp.com/track/hackmud-continuous-mix");
assertThrows(PaidContentException.class, extractor::fetchPage);
}
}