From e603dddc54079cb9405ef0bfd27cc533485636cc Mon Sep 17 00:00:00 2001 From: talanc Date: Mon, 9 Aug 2021 20:19:04 +1000 Subject: [PATCH 1/2] Added support for CSV+ZIP subscriptions Updated import instructions string --- app/build.gradle | 2 +- .../subscription/services/SubscriptionsImportService.java | 8 +++++++- app/src/main/res/values/strings.xml | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d9ae26436..8e203db20 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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}" diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java index a843ad77c..638a2e4f7 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java @@ -26,6 +26,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.documentfile.provider.DocumentFile; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.reactivestreams.Subscriber; @@ -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) { @@ -113,6 +116,9 @@ public class SubscriptionsImportService extends BaseImportExportService { try { inputStream = new SharpInputStream( new StoredFileHelper(this, uri, DEFAULT_MIME).getStream()); + + final DocumentFile documentFile = DocumentFile.fromSingleUri(this, uri); + inputStreamType = documentFile.getType(); } catch (final IOException e) { handleError(e); return START_NOT_STICKY; @@ -282,7 +288,7 @@ public class SubscriptionsImportService extends BaseImportExportService { private Flowable> importFromInputStream() { return Flowable.fromCallable(() -> NewPipe.getService(currentServiceId) .getSubscriptionExtractor() - .fromInputStream(inputStream)); + .fromInputStream(inputStream, inputStreamType)); } private Flowable> importFromPreviousExport() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8199feb8b..bf1c74446 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -544,7 +544,7 @@ Previous export Could not import subscriptions Could not export subscriptions - 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. + 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 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. yourID, soundcloud.com/yourid Keep in mind this operation can be network expensive.\n\nDo you want to continue? From 5284072b8d838b692c71977c0b48269dc646a36e Mon Sep 17 00:00:00 2001 From: Stypox Date: Mon, 30 Aug 2021 15:26:42 +0200 Subject: [PATCH 2/2] Improve mime type deduction on subscription import --- .../services/SubscriptionsImportService.java | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java index 638a2e4f7..af598b106 100644 --- a/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java +++ b/app/src/main/java/org/schabi/newpipe/local/subscription/services/SubscriptionsImportService.java @@ -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; @@ -26,7 +29,6 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.documentfile.provider.DocumentFile; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import org.reactivestreams.Subscriber; @@ -47,6 +49,7 @@ import java.io.IOException; 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; @@ -55,9 +58,6 @@ import io.reactivex.rxjava3.functions.Consumer; 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; @@ -114,11 +114,20 @@ public class SubscriptionsImportService extends BaseImportExportService { } 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(); - final DocumentFile documentFile = DocumentFile.fromSingleUri(this, uri); - inputStreamType = documentFile.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; @@ -254,9 +263,9 @@ public class SubscriptionsImportService extends BaseImportExportService { 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); } @@ -286,6 +295,9 @@ public class SubscriptionsImportService extends BaseImportExportService { } private Flowable> importFromInputStream() { + Objects.requireNonNull(inputStream); + Objects.requireNonNull(inputStreamType); + return Flowable.fromCallable(() -> NewPipe.getService(currentServiceId) .getSubscriptionExtractor() .fromInputStream(inputStream, inputStreamType));