Skip to content

Commit

Permalink
Deduplicate code for fetching stream info when sparse
Browse files Browse the repository at this point in the history
  • Loading branch information
Stypox committed Mar 3, 2022
1 parent 05a5e43 commit 254d8d1
Show file tree
Hide file tree
Showing 48 changed files with 136 additions and 249 deletions.
5 changes: 3 additions & 2 deletions app/src/main/java/org/schabi/newpipe/QueueItemMenuUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.schabi.newpipe.player.playqueue.PlayQueue;
import org.schabi.newpipe.player.playqueue.PlayQueueItem;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.SaveUploaderUrlHelper;
import org.schabi.newpipe.util.SparseItemUtil;

import java.util.Collections;

Expand Down Expand Up @@ -62,7 +62,8 @@ public static void openPopupMenu(final PlayQueue playQueue,

return true;
case R.id.menu_item_channel_details:
SaveUploaderUrlHelper.saveUploaderUrlIfNeeded(context, item,
SparseItemUtil.fetchUploaderUrlIfSparse(context, item.getServiceId(),
item.getUrl(), item.getUploaderUrl(),
// An intent must be used here.
// Opening with FragmentManager transactions is not working,
// as PlayQueueActivity doesn't use fragments.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.schabi.newpipe.info_list.dialog;

import static org.schabi.newpipe.info_list.dialog.StreamDialogEntry.fetchItemInfoIfSparse;
import static org.schabi.newpipe.util.NavigationHelper.openChannelFragment;
import static org.schabi.newpipe.util.SparseItemUtil.fetchItemInfoIfSparse;
import static org.schabi.newpipe.util.SparseItemUtil.fetchUploaderUrlIfSparse;

import android.net.Uri;

Expand All @@ -14,7 +15,6 @@
import org.schabi.newpipe.local.dialog.PlaylistDialog;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.util.NavigationHelper;
import org.schabi.newpipe.util.SaveUploaderUrlHelper;
import org.schabi.newpipe.util.external_communication.KoreUtils;
import org.schabi.newpipe.util.external_communication.ShareUtils;

Expand All @@ -40,8 +40,8 @@
*/
public enum StreamDialogDefaultEntry {
SHOW_CHANNEL_DETAILS(R.string.show_channel_details, (fragment, item) ->
SaveUploaderUrlHelper.saveUploaderUrlIfNeeded(fragment, item,
uploaderUrl -> openChannelFragment(fragment, item, uploaderUrl))
fetchUploaderUrlIfSparse(fragment.requireContext(), item.getServiceId(), item.getUrl(),
item.getUploaderUrl(), url -> openChannelFragment(fragment, item, url))
),

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,7 @@
import androidx.annotation.StringRes;
import androidx.fragment.app.Fragment;

import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.local.history.HistoryRecordManager;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;
import org.schabi.newpipe.util.ExtractorHelper;

import java.util.function.Consumer;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class StreamDialogEntry {

Expand All @@ -40,52 +28,4 @@ public String getString(@NonNull final Context context) {
public interface StreamDialogEntryAction {
void onClick(Fragment fragment, StreamInfoItem infoItem);
}

/**
* Fetches a {@link StreamInfoItem} if it is incomplete and executes the callback.
* <br />
* This method is required if the info has been fetched
* via a {@link org.schabi.newpipe.extractor.feed.FeedExtractor}.
* FeedExtractors provide a fast and lightweight method to fetch info,
* but the info might be incomplete
* (see {@link org.schabi.newpipe.local.feed.service.FeedLoadService} for more details).
* @param context
* @param item the item which is checked and eventually loaded completely
* @param callback
*/
public static void fetchItemInfoIfSparse(@NonNull final Context context,
@NonNull final StreamInfoItem item,
@NonNull final Consumer<SinglePlayQueue> callback) {
if (!(item.getStreamType() == StreamType.LIVE_STREAM
|| item.getStreamType() == StreamType.AUDIO_LIVE_STREAM)
&& item.getDuration() < 0) {
// Sparse item: fetched by fast fetch
ExtractorHelper.getStreamInfo(
item.getServiceId(),
item.getUrl(),
false
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
final HistoryRecordManager recordManager =
new HistoryRecordManager(context);
recordManager.saveStreamState(result, 0)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnError(throwable -> ErrorUtil.showSnackbar(
context,
new ErrorInfo(throwable, UserAction.REQUESTED_STREAM,
item.getUrl(), item.getServiceId())))
.subscribe();

callback.accept(new SinglePlayQueue(result));
}, throwable -> ErrorUtil.createNotification(context,
new ErrorInfo(throwable, UserAction.REQUESTED_CHANNEL,
"Could not fetch missing stream info")));
} else {
callback.accept(new SinglePlayQueue(item));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.schabi.newpipe.util;

import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;

import android.content.Context;
import android.util.Log;
import android.view.View;
Expand All @@ -30,8 +32,6 @@

import org.schabi.newpipe.MainActivity;
import org.schabi.newpipe.R;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.util.external_communication.TextLinkifier;
import org.schabi.newpipe.extractor.Info;
import org.schabi.newpipe.extractor.InfoItem;
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
Expand All @@ -42,6 +42,7 @@
import org.schabi.newpipe.extractor.StreamingService;
import org.schabi.newpipe.extractor.channel.ChannelInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfo;
import org.schabi.newpipe.extractor.comments.CommentsInfoItem;
import org.schabi.newpipe.extractor.feed.FeedExtractor;
import org.schabi.newpipe.extractor.feed.FeedInfo;
import org.schabi.newpipe.extractor.kiosk.KioskInfo;
Expand All @@ -50,6 +51,7 @@
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor;
import org.schabi.newpipe.util.external_communication.TextLinkifier;

import java.util.Collections;
import java.util.List;
Expand All @@ -58,8 +60,6 @@
import io.reactivex.rxjava3.core.Single;
import io.reactivex.rxjava3.disposables.CompositeDisposable;

import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;

public final class ExtractorHelper {
private static final String TAG = ExtractorHelper.class.getSimpleName();
private static final InfoCache CACHE = InfoCache.getInstance();
Expand Down

This file was deleted.

124 changes: 124 additions & 0 deletions app/src/main/java/org/schabi/newpipe/util/SparseItemUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package org.schabi.newpipe.util;

import static org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM;
import static org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;

import android.content.Context;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.schabi.newpipe.NewPipeDatabase;
import org.schabi.newpipe.R;
import org.schabi.newpipe.database.stream.model.StreamEntity;
import org.schabi.newpipe.error.ErrorInfo;
import org.schabi.newpipe.error.ErrorUtil;
import org.schabi.newpipe.error.UserAction;
import org.schabi.newpipe.extractor.stream.StreamInfo;
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
import org.schabi.newpipe.player.playqueue.SinglePlayQueue;

import java.util.function.Consumer;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Completable;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
* Utility class for fetching additional data for stream items when needed.
*/
public final class SparseItemUtil {
private SparseItemUtil() {
}

/**
* Use this to certainly obtain an single play queue with all of the data filled in when the
* stream info item you are handling might be sparse, e.g. because it was fetched via a {@link
* org.schabi.newpipe.extractor.feed.FeedExtractor}. FeedExtractors provide a fast and
* lightweight method to fetch info, but the info might be incomplete (see
* {@link org.schabi.newpipe.local.feed.service.FeedLoadService} for more details).
*
* @param context the Android context
* @param item the item which is checked and eventually loaded completely
* @param callback the callback to call with the single play queue built from the original item
* if all info was available, otherwise from the fetched {@link
* org.schabi.newpipe.extractor.stream.StreamInfo}
*/
public static void fetchItemInfoIfSparse(@NonNull final Context context,
@NonNull final StreamInfoItem item,
@NonNull final Consumer<SinglePlayQueue> callback) {
if ((!(item.getStreamType() == LIVE_STREAM || item.getStreamType() == AUDIO_LIVE_STREAM)
&& item.getDuration() < 0) || isNullOrEmpty(item.getUploaderUrl())) {
fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), item.getUrl(),
streamInfo -> callback.accept(new SinglePlayQueue(streamInfo)));
} else {
// all info is already there, no need to fetch
callback.accept(new SinglePlayQueue(item));
}
}

/**
* Use this to certainly obtain an uploader url when the stream info item or play queue item you
* are handling might not have the uploader url (e.g. because it was fetched with {@link
* org.schabi.newpipe.extractor.feed.FeedExtractor}). A toast is shown if loading details is
* required.
*
* @param context the Android context
* @param serviceId the serviceId of the item
* @param url the item url
* @param uploaderUrl the uploaderUrl of the item; if null or empty will be fetched
* @param callback the callback called with either the original uploaderUrl, if it was a valid
* url, otherwise with the uploader url obtained by fetching the {@link
* org.schabi.newpipe.extractor.stream.StreamInfo} corresponding to the item
*/
public static void fetchUploaderUrlIfSparse(@NonNull final Context context,
final int serviceId,
@NonNull final String url,
@Nullable final String uploaderUrl,
@NonNull final Consumer<String> callback) {
if (isNullOrEmpty(uploaderUrl)) {
fetchStreamInfoAndSaveToDatabase(context, serviceId, url,
streamInfo -> callback.accept(streamInfo.getUploaderUrl()));
} else {
callback.accept(uploaderUrl);
}
}

/**
* Loads the stream info corresponding to the given data on an I/O thread, stores the result in
* the database and calls the callback on the main thread with the result. A toast will be shown
* to the user about loading stream details, so this needs to be called on the main thread.
*
* @param context the Android context
* @param serviceId the service id of the stream to load
* @param url the url of the stream to load
* @param callback the callback to call with the result
*/
private static void fetchStreamInfoAndSaveToDatabase(final Context context,
final int serviceId,
@NonNull final String url,
final Consumer<StreamInfo> callback) {
Toast.makeText(context, R.string.loading_stream_details, Toast.LENGTH_SHORT).show();
ExtractorHelper.getStreamInfo(serviceId, url, false)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(result -> {
Completable.fromAction(() -> NewPipeDatabase.getInstance(context)
.streamDAO().upsert(new StreamEntity(result)))
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.doOnError(throwable ->
ErrorUtil.createNotification(context,
new ErrorInfo(throwable, UserAction.REQUESTED_STREAM,
"Saving stream info to database", result)))
.subscribe();

callback.accept(result);
}, throwable -> ErrorUtil.createNotification(context,
new ErrorInfo(throwable, UserAction.REQUESTED_STREAM,
"Loading stream info: " + url, serviceId)
));
}
}
2 changes: 0 additions & 2 deletions app/src/main/res/values-ar/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,6 @@
<string name="seekbar_preview_thumbnail_title">معاينة مصغرة على شريط التمرير</string>
<string name="mark_as_watched">علّمه كفيديو تمت مشاهدته</string>
<string name="detail_heart_img_view_description">أُعجب بها منشئ المحتوى</string>
<string name="loading_channel_details">جاري تحميل تفاصيل القناة…</string>
<string name="error_show_channel_details">خطأ في عرض تفاصيل القناة</string>
<string name="show_image_indicators_summary">أظهر أشرطة ملونة لبيكاسو أعلى الصور تشير إلى مصدرها: الأحمر للشبكة والأزرق للقرص والأخضر للذاكرة</string>
<string name="show_image_indicators_title">إظهار مؤشرات الصور</string>
<string name="remote_search_suggestions">اقتراحات البحث عن بعد</string>
Expand Down
Loading

0 comments on commit 254d8d1

Please sign in to comment.