mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2025-11-11 20:53:01 +00:00
SubscriptionImportWorker: inputs as sealed class
This commit is contained in:
@@ -11,7 +11,6 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.work.Constraints;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.ExistingWorkPolicy;
|
||||
import androidx.work.NetworkType;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
@@ -22,31 +21,19 @@ import com.evernote.android.state.State;
|
||||
import com.livefront.bridge.Bridge;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportWorker;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
|
||||
public class ImportConfirmationDialog extends DialogFragment {
|
||||
@State
|
||||
protected int mode;
|
||||
@State
|
||||
protected String value;
|
||||
@State
|
||||
protected int serviceId;
|
||||
protected SubscriptionImportInput input;
|
||||
|
||||
public static void show(@NonNull final Fragment fragment, final int mode,
|
||||
@Nullable final String value, final int serviceId) {
|
||||
public static void show(@NonNull final Fragment fragment, final SubscriptionImportInput input) {
|
||||
final var confirmationDialog = new ImportConfirmationDialog();
|
||||
confirmationDialog.setData(mode, value, serviceId);
|
||||
confirmationDialog.input = input;
|
||||
confirmationDialog.show(fragment.getParentFragmentManager(), null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("HiddenField")
|
||||
public void setData(final int mode, final String value, final int serviceId) {
|
||||
this.mode = mode;
|
||||
this.value = value;
|
||||
this.serviceId = serviceId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
|
||||
@@ -57,17 +44,12 @@ public class ImportConfirmationDialog extends DialogFragment {
|
||||
.setCancelable(true)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(R.string.ok, (dialogInterface, i) -> {
|
||||
final var inputData = new Data.Builder()
|
||||
.putString(SubscriptionImportWorker.KEY_VALUE, value)
|
||||
.putInt(SubscriptionImportWorker.KEY_MODE, mode)
|
||||
.putInt(Constants.KEY_SERVICE_ID, serviceId)
|
||||
.build();
|
||||
final var constraints = new Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build();
|
||||
|
||||
final var req = new OneTimeWorkRequest.Builder(SubscriptionImportWorker.class)
|
||||
.setInputData(inputData)
|
||||
.setInputData(input.toData())
|
||||
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||
.setConstraints(constraints)
|
||||
.build();
|
||||
@@ -85,10 +67,6 @@ public class ImportConfirmationDialog extends DialogFragment {
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (mode == 0 && value == null && serviceId == 0) {
|
||||
throw new IllegalStateException("Input data not provided");
|
||||
}
|
||||
|
||||
Bridge.restoreInstanceState(this, savedInstanceState);
|
||||
}
|
||||
|
||||
|
||||
@@ -49,11 +49,10 @@ import org.schabi.newpipe.local.subscription.item.GroupsHeader
|
||||
import org.schabi.newpipe.local.subscription.item.Header
|
||||
import org.schabi.newpipe.local.subscription.item.ImportSubscriptionsHintPlaceholderItem
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionExportWorker
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportWorker
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput
|
||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard
|
||||
import org.schabi.newpipe.streams.io.StoredFileHelper
|
||||
import org.schabi.newpipe.ui.emptystate.setEmptyStateComposable
|
||||
import org.schabi.newpipe.util.NO_SERVICE_ID
|
||||
import org.schabi.newpipe.util.NavigationHelper
|
||||
import org.schabi.newpipe.util.OnClickGesture
|
||||
import org.schabi.newpipe.util.ServiceHelper
|
||||
@@ -231,7 +230,7 @@ class SubscriptionFragment : BaseStateFragment<SubscriptionState>() {
|
||||
val data = result.data?.dataString
|
||||
if (data != null && result.resultCode == Activity.RESULT_OK) {
|
||||
ImportConfirmationDialog.show(
|
||||
this, SubscriptionImportWorker.PREVIOUS_EXPORT_MODE, data, NO_SERVICE_ID
|
||||
this, SubscriptionImportInput.PreviousExportMode(data)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.schabi.newpipe.error.UserAction;
|
||||
import org.schabi.newpipe.extractor.NewPipe;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.subscription.SubscriptionExtractor;
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportWorker;
|
||||
import org.schabi.newpipe.local.subscription.workers.SubscriptionImportInput;
|
||||
import org.schabi.newpipe.streams.io.NoFileManagerSafeGuard;
|
||||
import org.schabi.newpipe.streams.io.StoredFileHelper;
|
||||
import org.schabi.newpipe.util.Constants;
|
||||
@@ -164,8 +164,8 @@ public class SubscriptionsImportFragment extends BaseFragment {
|
||||
}
|
||||
|
||||
public void onImportUrl(final String value) {
|
||||
ImportConfirmationDialog.show(this, SubscriptionImportWorker.CHANNEL_URL_MODE, value,
|
||||
currentServiceId);
|
||||
ImportConfirmationDialog.show(this,
|
||||
new SubscriptionImportInput.ChannelUrlMode(currentServiceId, value));
|
||||
}
|
||||
|
||||
public void onImportFile() {
|
||||
@@ -182,8 +182,8 @@ public class SubscriptionsImportFragment extends BaseFragment {
|
||||
private void requestImportFileResult(final ActivityResult result) {
|
||||
final String data = result.getData() != null ? result.getData().getDataString() : null;
|
||||
if (result.getResultCode() == Activity.RESULT_OK && data != null) {
|
||||
ImportConfirmationDialog.show(this, SubscriptionImportWorker.INPUT_STREAM_MODE,
|
||||
data, currentServiceId);
|
||||
ImportConfirmationDialog.show(this,
|
||||
new SubscriptionImportInput.InputStreamMode(currentServiceId, data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@ package org.schabi.newpipe.local.subscription.workers
|
||||
import android.content.Context
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.os.Build
|
||||
import android.os.Parcelable
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.Data
|
||||
import androidx.work.ForegroundInfo
|
||||
import androidx.work.WorkManager
|
||||
import androidx.work.WorkerParameters
|
||||
@@ -18,12 +20,11 @@ import kotlinx.coroutines.rx3.await
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.schabi.newpipe.R
|
||||
import org.schabi.newpipe.extractor.NewPipe
|
||||
import org.schabi.newpipe.local.subscription.SubscriptionManager
|
||||
import org.schabi.newpipe.util.ExtractorHelper
|
||||
import org.schabi.newpipe.util.KEY_SERVICE_ID
|
||||
import org.schabi.newpipe.util.NO_SERVICE_ID
|
||||
|
||||
class SubscriptionImportWorker(
|
||||
appContext: Context,
|
||||
@@ -35,27 +36,29 @@ class SubscriptionImportWorker(
|
||||
}
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
val mode = inputData.getInt(KEY_MODE, CHANNEL_URL_MODE)
|
||||
val serviceId = inputData.getInt(KEY_SERVICE_ID, NO_SERVICE_ID)
|
||||
val value = inputData.getString(KEY_VALUE)!!
|
||||
val input = SubscriptionImportInput.fromData(inputData)
|
||||
|
||||
val subscriptions = withContext(Dispatchers.IO) {
|
||||
if (mode == CHANNEL_URL_MODE) {
|
||||
NewPipe.getService(serviceId).subscriptionExtractor
|
||||
.fromChannelUrl(value)
|
||||
.map { SubscriptionItem(it.serviceId, it.url, it.name) }
|
||||
} else {
|
||||
applicationContext.contentResolver.openInputStream(value.toUri())?.use {
|
||||
if (mode == INPUT_STREAM_MODE) {
|
||||
val contentType = MimeTypeMap.getFileExtensionFromUrl(value).ifEmpty { DEFAULT_MIME }
|
||||
NewPipe.getService(serviceId).subscriptionExtractor
|
||||
when (input) {
|
||||
is SubscriptionImportInput.ChannelUrlMode ->
|
||||
NewPipe.getService(input.serviceId).subscriptionExtractor
|
||||
.fromChannelUrl(input.url)
|
||||
.map { SubscriptionItem(it.serviceId, it.url, it.name) }
|
||||
|
||||
is SubscriptionImportInput.InputStreamMode ->
|
||||
applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
|
||||
val contentType =
|
||||
MimeTypeMap.getFileExtensionFromUrl(input.url).ifEmpty { DEFAULT_MIME }
|
||||
NewPipe.getService(input.serviceId).subscriptionExtractor
|
||||
.fromInputStream(it, contentType)
|
||||
.map { SubscriptionItem(it.serviceId, it.url, it.name) }
|
||||
} else {
|
||||
}
|
||||
|
||||
is SubscriptionImportInput.PreviousExportMode ->
|
||||
applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
|
||||
ImportExportJsonHelper.readFrom(it)
|
||||
}
|
||||
} ?: emptyList()
|
||||
}
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
val mutex = Mutex()
|
||||
@@ -146,10 +149,69 @@ class SubscriptionImportWorker(
|
||||
private const val BUFFER_COUNT_BEFORE_INSERT = 50
|
||||
|
||||
const val WORK_NAME = "SubscriptionImportWorker"
|
||||
const val CHANNEL_URL_MODE = 0
|
||||
const val INPUT_STREAM_MODE = 1
|
||||
const val PREVIOUS_EXPORT_MODE = 2
|
||||
const val KEY_MODE = "key_mode"
|
||||
const val KEY_VALUE = "key_value"
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SubscriptionImportInput : Parcelable {
|
||||
@Parcelize
|
||||
data class ChannelUrlMode(val serviceId: Int, val url: String) : SubscriptionImportInput()
|
||||
@Parcelize
|
||||
data class InputStreamMode(val serviceId: Int, val url: String) : SubscriptionImportInput()
|
||||
@Parcelize
|
||||
data class PreviousExportMode(val url: String) : SubscriptionImportInput()
|
||||
|
||||
fun toData(): Data {
|
||||
return when (this) {
|
||||
is ChannelUrlMode -> Data.Builder()
|
||||
.putInt("mode", CHANNEL_URL_MODE)
|
||||
.putInt("service_id", serviceId)
|
||||
.putString("url", url)
|
||||
.build()
|
||||
is InputStreamMode ->
|
||||
Data.Builder()
|
||||
.putInt("mode", INPUT_STREAM_MODE)
|
||||
.putInt("service_id", serviceId)
|
||||
.putString("url", url)
|
||||
.build()
|
||||
is PreviousExportMode ->
|
||||
Data.Builder()
|
||||
.putInt("mode", PREVIOUS_EXPORT_MODE)
|
||||
.putString("url", url)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val CHANNEL_URL_MODE = 0
|
||||
private const val INPUT_STREAM_MODE = 1
|
||||
private const val PREVIOUS_EXPORT_MODE = 2
|
||||
|
||||
fun fromData(data: Data): SubscriptionImportInput {
|
||||
val mode = data.getInt("mode", PREVIOUS_EXPORT_MODE)
|
||||
when (mode) {
|
||||
CHANNEL_URL_MODE -> {
|
||||
val serviceId = data.getInt("service_id", -1)
|
||||
if (serviceId == -1) {
|
||||
throw IllegalArgumentException("No service id provided")
|
||||
}
|
||||
val url = data.getString("url")!!
|
||||
return ChannelUrlMode(serviceId, url)
|
||||
}
|
||||
INPUT_STREAM_MODE -> {
|
||||
val serviceId = data.getInt("service_id", -1)
|
||||
if (serviceId == -1) {
|
||||
throw IllegalArgumentException("No service id provided")
|
||||
}
|
||||
val url = data.getString("url")!!
|
||||
return InputStreamMode(serviceId, url)
|
||||
}
|
||||
PREVIOUS_EXPORT_MODE -> {
|
||||
val url = data.getString("url")!!
|
||||
return PreviousExportMode(url)
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unknown mode: $mode")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user