Skip to content

Commit 6ab8716

Browse files
TobiGrStypox
authored andcommitted
Extract actual feed loading code into separate method
Increase readability
1 parent 5c7c382 commit 6ab8716

1 file changed

Lines changed: 104 additions & 93 deletions

File tree

app/src/main/java/org/schabi/newpipe/local/feed/service/FeedLoadManager.kt

Lines changed: 104 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.schabi.newpipe.local.feed.service
22

33
import android.content.Context
4+
import android.content.SharedPreferences
45
import androidx.preference.PreferenceManager
56
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
67
import io.reactivex.rxjava3.core.Completable
@@ -13,6 +14,7 @@ import io.reactivex.rxjava3.schedulers.Schedulers
1314
import org.schabi.newpipe.R
1415
import org.schabi.newpipe.database.feed.model.FeedGroupEntity
1516
import org.schabi.newpipe.database.subscription.NotificationMode
17+
import org.schabi.newpipe.database.subscription.SubscriptionEntity
1618
import org.schabi.newpipe.extractor.Info
1719
import org.schabi.newpipe.extractor.NewPipe
1820
import org.schabi.newpipe.extractor.feed.FeedInfo
@@ -108,99 +110,7 @@ class FeedLoadManager(private val context: Context) {
108110
.runOn(Schedulers.io(), PARALLEL_EXTRACTIONS * 2)
109111
.filter { !cancelSignal.get() }
110112
.map { subscriptionEntity ->
111-
var error: Throwable? = null
112-
val storeOriginalErrorAndRethrow = { e: Throwable ->
113-
// keep original to prevent blockingGet() from wrapping it into RuntimeException
114-
error = e
115-
throw e
116-
}
117-
118-
try {
119-
// check for and load new streams
120-
// either by using the dedicated feed method or by getting the channel info
121-
var originalInfo: Info? = null
122-
var streams: List<StreamInfoItem>? = null
123-
val errors = ArrayList<Throwable>()
124-
125-
if (useFeedExtractor) {
126-
NewPipe.getService(subscriptionEntity.serviceId)
127-
.getFeedExtractor(subscriptionEntity.url)
128-
?.also { feedExtractor ->
129-
// the user wants to use a feed extractor and there is one, use it
130-
val feedInfo = FeedInfo.getInfo(feedExtractor)
131-
errors.addAll(feedInfo.errors)
132-
originalInfo = feedInfo
133-
streams = feedInfo.relatedItems
134-
}
135-
}
136-
137-
if (originalInfo == null) {
138-
// use the normal channel tabs extractor if either the user wants it, or
139-
// the current service does not have a dedicated feed extractor
140-
141-
val channelInfo = getChannelInfo(
142-
subscriptionEntity.serviceId,
143-
subscriptionEntity.url, true
144-
)
145-
.onErrorReturn(storeOriginalErrorAndRethrow)
146-
.blockingGet()
147-
errors.addAll(channelInfo.errors)
148-
originalInfo = channelInfo
149-
150-
streams = channelInfo.tabs
151-
.filter { tab ->
152-
ChannelTabHelper.fetchFeedChannelTab(
153-
context,
154-
defaultSharedPreferences,
155-
tab
156-
)
157-
}
158-
.map {
159-
Pair(
160-
getChannelTab(subscriptionEntity.serviceId, it, true)
161-
.onErrorReturn(storeOriginalErrorAndRethrow)
162-
.blockingGet(),
163-
it
164-
)
165-
}
166-
.flatMap { (channelTabInfo, linkHandler) ->
167-
errors.addAll(channelTabInfo.errors)
168-
if (channelTabInfo.relatedItems.isEmpty() &&
169-
channelTabInfo.nextPage != null
170-
) {
171-
val infoItemsPage = getMoreChannelTabItems(
172-
subscriptionEntity.serviceId,
173-
linkHandler, channelTabInfo.nextPage
174-
)
175-
.blockingGet()
176-
177-
errors.addAll(infoItemsPage.errors)
178-
return@flatMap infoItemsPage.items
179-
} else {
180-
return@flatMap channelTabInfo.relatedItems
181-
}
182-
}
183-
.filterIsInstance<StreamInfoItem>()
184-
}
185-
186-
return@map Notification.createOnNext(
187-
FeedUpdateInfo(
188-
subscriptionEntity,
189-
originalInfo!!,
190-
streams!!,
191-
errors,
192-
)
193-
)
194-
} catch (e: Throwable) {
195-
val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}"
196-
val wrapper = FeedLoadService.RequestException(
197-
subscriptionEntity.uid,
198-
request,
199-
// do this to prevent blockingGet() from wrapping into RuntimeException
200-
error ?: e
201-
)
202-
return@map Notification.createOnError<FeedUpdateInfo>(wrapper)
203-
}
113+
loadStreams(subscriptionEntity, useFeedExtractor, defaultSharedPreferences)
204114
}
205115
.sequential()
206116
.observeOn(AndroidSchedulers.mainThread())
@@ -226,6 +136,107 @@ class FeedLoadManager(private val context: Context) {
226136
)
227137
}
228138

139+
private fun loadStreams(
140+
subscriptionEntity: SubscriptionEntity,
141+
useFeedExtractor: Boolean,
142+
defaultSharedPreferences: SharedPreferences
143+
):
144+
Notification<FeedUpdateInfo> {
145+
var error: Throwable? = null
146+
val storeOriginalErrorAndRethrow = { e: Throwable ->
147+
// keep original to prevent blockingGet() from wrapping it into RuntimeException
148+
error = e
149+
throw e
150+
}
151+
152+
try {
153+
// check for and load new streams
154+
// either by using the dedicated feed method or by getting the channel info
155+
var originalInfo: Info? = null
156+
var streams: List<StreamInfoItem>? = null
157+
val errors = ArrayList<Throwable>()
158+
159+
if (useFeedExtractor) {
160+
NewPipe.getService(subscriptionEntity.serviceId)
161+
.getFeedExtractor(subscriptionEntity.url)
162+
?.also { feedExtractor ->
163+
// the user wants to use a feed extractor and there is one, use it
164+
val feedInfo = FeedInfo.getInfo(feedExtractor)
165+
errors.addAll(feedInfo.errors)
166+
originalInfo = feedInfo
167+
streams = feedInfo.relatedItems
168+
}
169+
}
170+
171+
if (originalInfo == null) {
172+
// use the normal channel tabs extractor if either the user wants it, or
173+
// the current service does not have a dedicated feed extractor
174+
175+
val channelInfo = getChannelInfo(
176+
subscriptionEntity.serviceId,
177+
subscriptionEntity.url, true
178+
)
179+
.onErrorReturn(storeOriginalErrorAndRethrow)
180+
.blockingGet()
181+
errors.addAll(channelInfo.errors)
182+
originalInfo = channelInfo
183+
184+
streams = channelInfo.tabs
185+
.filter { tab ->
186+
ChannelTabHelper.fetchFeedChannelTab(
187+
context,
188+
defaultSharedPreferences,
189+
tab
190+
)
191+
}
192+
.map {
193+
Pair(
194+
getChannelTab(subscriptionEntity.serviceId, it, true)
195+
.onErrorReturn(storeOriginalErrorAndRethrow)
196+
.blockingGet(),
197+
it
198+
)
199+
}
200+
.flatMap { (channelTabInfo, linkHandler) ->
201+
errors.addAll(channelTabInfo.errors)
202+
if (channelTabInfo.relatedItems.isEmpty() &&
203+
channelTabInfo.nextPage != null
204+
) {
205+
val infoItemsPage = getMoreChannelTabItems(
206+
subscriptionEntity.serviceId,
207+
linkHandler, channelTabInfo.nextPage
208+
)
209+
.blockingGet()
210+
211+
errors.addAll(infoItemsPage.errors)
212+
return@flatMap infoItemsPage.items
213+
} else {
214+
return@flatMap channelTabInfo.relatedItems
215+
}
216+
}
217+
.filterIsInstance<StreamInfoItem>()
218+
}
219+
220+
return Notification.createOnNext(
221+
FeedUpdateInfo(
222+
subscriptionEntity,
223+
originalInfo!!,
224+
streams!!,
225+
errors,
226+
)
227+
)
228+
} catch (e: Throwable) {
229+
val request = "${subscriptionEntity.serviceId}:${subscriptionEntity.url}"
230+
val wrapper = FeedLoadService.RequestException(
231+
subscriptionEntity.uid,
232+
request,
233+
// do this to prevent blockingGet() from wrapping into RuntimeException
234+
error ?: e
235+
)
236+
return Notification.createOnError(wrapper)
237+
}
238+
}
239+
229240
/**
230241
* Keep the feed and the stream tables small
231242
* to reduce loading times when trying to display the feed.

0 commit comments

Comments
 (0)