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

Add support for CSV+ZIP subscriptions (Google Takeout) #6882

Merged
merged 2 commits into from
Aug 31, 2021
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
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ dependencies {
// name and the commit hash with the commit hash of the (pushed) commit you want to test
// This works thanks to JitPack: https://jitpack.io/
implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:v0.21.9'
implementation 'com.github.TeamNewPipe:NewPipeExtractor:68f1fa994af78d2cd0f354f9226d5dbe3dc03d54'

/** Checkstyle **/
checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

package org.schabi.newpipe.local.subscription.services;

import static org.schabi.newpipe.MainActivity.DEBUG;
import static org.schabi.newpipe.streams.io.StoredFileHelper.DEFAULT_MIME;

import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
Expand Down Expand Up @@ -46,6 +49,7 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Flowable;
Expand All @@ -54,9 +58,6 @@
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;

import static org.schabi.newpipe.MainActivity.DEBUG;
import static org.schabi.newpipe.streams.io.StoredFileHelper.DEFAULT_MIME;

public class SubscriptionsImportService extends BaseImportExportService {
public static final int CHANNEL_URL_MODE = 0;
public static final int INPUT_STREAM_MODE = 1;
Expand Down Expand Up @@ -89,6 +90,8 @@ public class SubscriptionsImportService extends BaseImportExportService {
private String channelUrl;
@Nullable
private InputStream inputStream;
@Nullable
private String inputStreamType;

@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
Expand All @@ -111,8 +114,20 @@ public int onStartCommand(final Intent intent, final int flags, final int startI
}

try {
inputStream = new SharpInputStream(
new StoredFileHelper(this, uri, DEFAULT_MIME).getStream());
final StoredFileHelper fileHelper = new StoredFileHelper(this, uri, DEFAULT_MIME);
inputStream = new SharpInputStream(fileHelper.getStream());
inputStreamType = fileHelper.getType();

if (inputStreamType == null || inputStreamType.equals(DEFAULT_MIME)) {
// mime type could not be determined, just take file extension
final String name = fileHelper.getName();
final int pointIndex = name.lastIndexOf('.');
if (pointIndex == -1 || pointIndex >= name.length() - 1) {
inputStreamType = DEFAULT_MIME; // no extension, will fail in the extractor
} else {
inputStreamType = name.substring(pointIndex + 1);
}
}
} catch (final IOException e) {
handleError(e);
return START_NOT_STICKY;
Expand Down Expand Up @@ -248,9 +263,9 @@ private Consumer<Notification<ChannelInfo>> getNotificationsConsumer() {
final Throwable error = notification.getError();
final Throwable cause = error.getCause();
if (error instanceof IOException) {
throw (IOException) error;
throw error;
} else if (cause instanceof IOException) {
throw (IOException) cause;
throw cause;
} else if (ExceptionUtils.isNetworkRelated(error)) {
throw new IOException(error);
}
Expand Down Expand Up @@ -280,9 +295,12 @@ private Flowable<List<SubscriptionItem>> importFromChannelUrl() {
}

private Flowable<List<SubscriptionItem>> importFromInputStream() {
Objects.requireNonNull(inputStream);
Objects.requireNonNull(inputStreamType);

return Flowable.fromCallable(() -> NewPipe.getService(currentServiceId)
.getSubscriptionExtractor()
.fromInputStream(inputStream));
.fromInputStream(inputStream, inputStreamType));
}

private Flowable<List<SubscriptionItem>> importFromPreviousExport() {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@
<string name="previous_export">Previous export</string>
<string name="subscriptions_import_unsuccessful">Could not import subscriptions</string>
<string name="subscriptions_export_unsuccessful">Could not export subscriptions</string>
<string name="import_youtube_instructions">Import YouTube subscriptions from Google takeout:\n\n1. Go to this URL: %1$s\n2. Log in when asked\n3. Click on \"All data included\", then on \"Deselect all\", then select only \"subscriptions\" and click \"OK\"\n4. Click on \"Next step\" and then on \"Create export\"\n5. Click on the \"Download\" button after it appears and \n6. From the downloaded takeout zip extract the .json file (usually under \"YouTube and YouTube Music/subscriptions/subscriptions.json\") and import it here.</string>
<string name="import_youtube_instructions">Import YouTube subscriptions from Google takeout:\n\n1. Go to this URL: %1$s\n2. Log in when asked\n3. Click on \"All data included\", then on \"Deselect all\", then select only \"subscriptions\" and click \"OK\"\n4. Click on \"Next step\" and then on \"Create export\"\n5. Click on the \"Download\" button after it appears\n6. Click on IMPORT FILE below and select the downloaded zip file\n7. [If the zip import fails] Extract the .csv file (usually under \"YouTube and YouTube Music/subscriptions/subscriptions.csv\"), click on IMPORT FILE below and select the extracted csv file</string>
<string name="import_soundcloud_instructions">Import a SoundCloud profile by typing either the URL or your ID:\n\n1. Enable \"desktop mode\" in a web-browser (the site is not available for mobile devices)\n2. Go to this URL: %1$s\n3. Log in when asked\n4. Copy the profile URL you were redirected to.</string>
<string name="import_soundcloud_instructions_hint">yourID, soundcloud.com/yourid</string>
<string name="import_network_expensive_warning">Keep in mind this operation can be network expensive.\n\nDo you want to continue?</string>
Expand Down