Skip to content

Commit

Permalink
SubscriptionImportWorker: inputs as sealed class
Browse files Browse the repository at this point in the history
  • Loading branch information
Profpatsch committed Jan 22, 2025
1 parent 21973b3 commit dbd11a6
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
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;
Expand All @@ -22,31 +21,19 @@
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) {
Expand All @@ -57,17 +44,12 @@ public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
.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();
Expand All @@ -85,10 +67,6 @@ public Dialog onCreateDialog(@Nullable final Bundle savedInstanceState) {
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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
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;
Expand Down Expand Up @@ -164,8 +164,8 @@ private void onImportClicked() {
}

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() {
Expand All @@ -182,8 +182,8 @@ public void onImportFile() {
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));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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()
Expand Down Expand Up @@ -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")
}
}
}
}

0 comments on commit dbd11a6

Please sign in to comment.