mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 15:23:00 +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
	 Profpatsch
					Profpatsch