@@ -4,6 +4,7 @@ import android.content.Context
44import android.content.pm.ServiceInfo
55import android.os.Build
66import android.os.Parcelable
7+ import android.util.Log
78import android.webkit.MimeTypeMap
89import android.widget.Toast
910import androidx.core.app.NotificationCompat
@@ -21,6 +22,7 @@ import kotlinx.coroutines.sync.Mutex
2122import kotlinx.coroutines.sync.withLock
2223import kotlinx.coroutines.withContext
2324import kotlinx.parcelize.Parcelize
25+ import org.schabi.newpipe.BuildConfig
2426import org.schabi.newpipe.R
2527import org.schabi.newpipe.extractor.NewPipe
2628import org.schabi.newpipe.local.subscription.SubscriptionManager
@@ -36,53 +38,55 @@ class SubscriptionImportWorker(
3638 }
3739
3840 override suspend fun doWork (): Result {
39- val input = SubscriptionImportInput .fromData(inputData)
40-
41- val subscriptions = withContext(Dispatchers .IO ) {
42- when (input) {
43- is SubscriptionImportInput .ChannelUrlMode ->
44- NewPipe .getService(input.serviceId).subscriptionExtractor
45- .fromChannelUrl(input.url)
46- .map { SubscriptionItem (it.serviceId, it.url, it.name) }
47-
48- is SubscriptionImportInput .InputStreamMode ->
49- applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
50- val contentType =
51- MimeTypeMap .getFileExtensionFromUrl(input.url).ifEmpty { DEFAULT_MIME }
52- NewPipe .getService(input.serviceId).subscriptionExtractor
53- .fromInputStream(it, contentType)
54- .map { SubscriptionItem (it.serviceId, it.url, it.name) }
55- }
56-
57- is SubscriptionImportInput .PreviousExportMode ->
58- applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
59- ImportExportJsonHelper .readFrom(it)
60- }
61- } ? : emptyList()
62- }
41+ val subscriptions =
42+ try {
43+ loadSubscriptionsFromInput(SubscriptionImportInput .fromData(inputData))
44+ } catch (e: Exception ) {
45+ if (BuildConfig .DEBUG ) {
46+ Log .e(TAG , " Error while loading subscriptions from path" , e)
47+ }
48+ withContext(Dispatchers .Main ) {
49+ Toast
50+ .makeText(applicationContext, R .string.subscriptions_import_unsuccessful, Toast .LENGTH_SHORT )
51+ .show()
52+ }
53+ return Result .failure()
54+ }
6355
6456 val mutex = Mutex ()
6557 var index = 1
6658 val qty = subscriptions.size
6759 var title =
6860 applicationContext.resources.getQuantityString(R .plurals.load_subscriptions, qty, qty)
6961
70- val channelInfoList = withContext(Dispatchers .IO .limitedParallelism(PARALLEL_EXTRACTIONS )) {
71- subscriptions
72- .map {
73- async {
74- val channelInfo =
75- ExtractorHelper .getChannelInfo(it.serviceId, it.url, true ).await()
76- val channelTab =
77- ExtractorHelper .getChannelTab(it.serviceId, channelInfo.tabs[0 ], true ).await()
78-
79- val currentIndex = mutex.withLock { index++ }
80- setForeground(createForegroundInfo(title, channelInfo.name, currentIndex, qty))
81-
82- channelInfo to channelTab
83- }
84- }.awaitAll()
85- }
62+ val channelInfoList =
63+ try {
64+ withContext(Dispatchers .IO .limitedParallelism(PARALLEL_EXTRACTIONS )) {
65+ subscriptions
66+ .map {
67+ async {
68+ val channelInfo =
69+ ExtractorHelper .getChannelInfo(it.serviceId, it.url, true ).await()
70+ val channelTab =
71+ ExtractorHelper .getChannelTab(it.serviceId, channelInfo.tabs[0 ], true ).await()
72+
73+ val currentIndex = mutex.withLock { index++ }
74+ setForeground(createForegroundInfo(title, channelInfo.name, currentIndex, qty))
75+
76+ channelInfo to channelTab
77+ }
78+ }.awaitAll()
79+ }
80+ } catch (e: Exception ) {
81+ if (BuildConfig .DEBUG ) {
82+ Log .e(TAG , " Error while loading subscription data" , e)
83+ }
84+ withContext(Dispatchers .Main ) {
85+ Toast .makeText(applicationContext, R .string.subscriptions_import_unsuccessful, Toast .LENGTH_SHORT )
86+ .show()
87+ }
88+ return Result .failure()
89+ }
8690
8791 title = applicationContext.resources.getQuantityString(R .plurals.import_subscriptions, qty, qty)
8892 setForeground(createForegroundInfo(title, null , 0 , 0 ))
@@ -98,14 +102,38 @@ class SubscriptionImportWorker(
98102 }
99103
100104 withContext(Dispatchers .Main ) {
101- Toast
102- .makeText(applicationContext, R .string.import_complete_toast, Toast .LENGTH_SHORT )
105+ Toast .makeText(applicationContext, R .string.import_complete_toast, Toast .LENGTH_SHORT )
103106 .show()
104107 }
105108
106109 return Result .success()
107110 }
108111
112+ private suspend fun loadSubscriptionsFromInput (input : SubscriptionImportInput ): List <SubscriptionItem > {
113+ return withContext(Dispatchers .IO ) {
114+ when (input) {
115+ is SubscriptionImportInput .ChannelUrlMode ->
116+ NewPipe .getService(input.serviceId).subscriptionExtractor
117+ .fromChannelUrl(input.url)
118+ .map { SubscriptionItem (it.serviceId, it.url, it.name) }
119+
120+ is SubscriptionImportInput .InputStreamMode ->
121+ applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
122+ val contentType =
123+ MimeTypeMap .getFileExtensionFromUrl(input.url).ifEmpty { DEFAULT_MIME }
124+ NewPipe .getService(input.serviceId).subscriptionExtractor
125+ .fromInputStream(it, contentType)
126+ .map { SubscriptionItem (it.serviceId, it.url, it.name) }
127+ }
128+
129+ is SubscriptionImportInput .PreviousExportMode ->
130+ applicationContext.contentResolver.openInputStream(input.url.toUri())?.use {
131+ ImportExportJsonHelper .readFrom(it)
132+ }
133+ } ? : emptyList()
134+ }
135+ }
136+
109137 private fun createForegroundInfo (
110138 title : String ,
111139 text : String? ,
@@ -142,6 +170,9 @@ class SubscriptionImportWorker(
142170 }
143171
144172 companion object {
173+ // Log tag length is limited to 23 characters on API levels < 24.
174+ private const val TAG = " SubscriptionImport"
175+
145176 private const val NOTIFICATION_ID = 4568
146177 private const val NOTIFICATION_CHANNEL_ID = " newpipe"
147178 private const val DEFAULT_MIME = " application/octet-stream"
0 commit comments