Merge remote-tracking branch 'newpipe/dev' into rebase
This commit is contained in:
commit
ac5571a363
41 changed files with 1701 additions and 1505 deletions
82
app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt
Normal file
82
app/src/main/java/org/schabi/newpipe/util/ExceptionUtils.kt
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
package org.schabi.newpipe.util
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InterruptedIOException
|
||||
|
||||
class ExceptionUtils {
|
||||
companion object {
|
||||
/**
|
||||
* @return if throwable is related to Interrupted exceptions, or one of its causes is.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun isInterruptedCaused(throwable: Throwable): Boolean {
|
||||
return hasExactCause(throwable,
|
||||
InterruptedIOException::class.java,
|
||||
InterruptedException::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if throwable is related to network issues, or one of its causes is.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun isNetworkRelated(throwable: Throwable): Boolean {
|
||||
return hasAssignableCause(throwable,
|
||||
IOException::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls [hasCause] with the `checkSubtypes` parameter set to false.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun hasExactCause(throwable: Throwable, vararg causesToCheck: Class<*>): Boolean {
|
||||
return hasCause(throwable, false, *causesToCheck)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls [hasCause] with the `checkSubtypes` parameter set to true.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun hasAssignableCause(throwable: Throwable?, vararg causesToCheck: Class<*>): Boolean {
|
||||
return hasCause(throwable, true, *causesToCheck)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if throwable has some cause from the causes to check, or is itself in it.
|
||||
*
|
||||
* If `checkIfAssignable` is true, not only the exact type will be considered equals, but also its subtypes.
|
||||
*
|
||||
* @param throwable throwable that will be checked.
|
||||
* @param checkSubtypes if subtypes are also checked.
|
||||
* @param causesToCheck an array of causes to check.
|
||||
*
|
||||
* @see Class.isAssignableFrom
|
||||
*/
|
||||
@JvmStatic
|
||||
tailrec fun hasCause(throwable: Throwable?, checkSubtypes: Boolean, vararg causesToCheck: Class<*>): Boolean {
|
||||
if (throwable == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if throwable is a subtype of any of the causes to check
|
||||
causesToCheck.forEach { causeClass ->
|
||||
if (checkSubtypes) {
|
||||
if (causeClass.isAssignableFrom(throwable.javaClass)) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
if (causeClass == throwable.javaClass) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val currentCause: Throwable? = throwable.cause
|
||||
// Check if cause is not pointing to the same instance, to avoid infinite loops.
|
||||
if (throwable !== currentCause) {
|
||||
return hasCause(currentCause, checkSubtypes, *causesToCheck)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,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.exceptions.ContentNotAvailableException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ContentNotSupportedException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
|
||||
import org.schabi.newpipe.extractor.feed.FeedExtractor;
|
||||
|
|
@ -51,8 +52,6 @@ import org.schabi.newpipe.extractor.suggestion.SuggestionExtractor;
|
|||
import org.schabi.newpipe.report.ErrorActivity;
|
||||
import org.schabi.newpipe.report.UserAction;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -289,10 +288,12 @@ public final class ExtractorHelper {
|
|||
Intent intent = new Intent(context, ReCaptchaActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
} else if (exception instanceof IOException) {
|
||||
} else if (ExceptionUtils.isNetworkRelated(exception)) {
|
||||
Toast.makeText(context, R.string.network_error, Toast.LENGTH_LONG).show();
|
||||
} else if (exception instanceof ContentNotAvailableException) {
|
||||
Toast.makeText(context, R.string.content_not_available, Toast.LENGTH_LONG).show();
|
||||
} else if (exception instanceof ContentNotSupportedException) {
|
||||
Toast.makeText(context, R.string.content_not_supported, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
int errorId = exception instanceof YoutubeStreamExtractor.DecryptException
|
||||
? R.string.youtube_signature_decryption_error
|
||||
|
|
@ -306,85 +307,4 @@ public final class ExtractorHelper {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if throwable have the cause that can be assignable from the causes to check.
|
||||
*
|
||||
* @see Class#isAssignableFrom(Class)
|
||||
* @param throwable the throwable to be checked
|
||||
* @param causesToCheck the causes to check
|
||||
* @return whether the exception is an instance of a subclass of one of the causes
|
||||
* or is caused by an instance of a subclass of one of the causes
|
||||
*/
|
||||
public static boolean hasAssignableCauseThrowable(final Throwable throwable,
|
||||
final Class<?>... causesToCheck) {
|
||||
// Check if getCause is not the same as cause (the getCause is already the root),
|
||||
// as it will cause a infinite loop if it is
|
||||
Throwable cause;
|
||||
Throwable getCause = throwable;
|
||||
|
||||
// Check if throwable is a subclass of any of the filtered classes
|
||||
final Class throwableClass = throwable.getClass();
|
||||
for (Class<?> causesEl : causesToCheck) {
|
||||
if (causesEl.isAssignableFrom(throwableClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Iteratively checks if the root cause of the throwable is a subclass of the filtered class
|
||||
while ((cause = throwable.getCause()) != null && getCause != cause) {
|
||||
getCause = cause;
|
||||
final Class causeClass = cause.getClass();
|
||||
for (Class<?> causesEl : causesToCheck) {
|
||||
if (causesEl.isAssignableFrom(causeClass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if throwable have the exact cause from one of the causes to check.
|
||||
*
|
||||
* @param throwable the throwable to be checked
|
||||
* @param causesToCheck the causes to check
|
||||
* @return whether the exception is an instance of one of the causes
|
||||
* or is caused by an instance of one of the causes
|
||||
*/
|
||||
public static boolean hasExactCauseThrowable(final Throwable throwable,
|
||||
final Class<?>... causesToCheck) {
|
||||
// Check if getCause is not the same as cause (the getCause is already the root),
|
||||
// as it will cause a infinite loop if it is
|
||||
Throwable cause;
|
||||
Throwable getCause = throwable;
|
||||
|
||||
for (Class<?> causesEl : causesToCheck) {
|
||||
if (throwable.getClass().equals(causesEl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
while ((cause = throwable.getCause()) != null && getCause != cause) {
|
||||
getCause = cause;
|
||||
for (Class<?> causesEl : causesToCheck) {
|
||||
if (cause.getClass().equals(causesEl)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if throwable have Interrupted* exception as one of its causes.
|
||||
*
|
||||
* @param throwable the throwable to be checkes
|
||||
* @return whether the throwable is caused by an interruption
|
||||
*/
|
||||
public static boolean isInterruptedCaused(final Throwable throwable) {
|
||||
return ExtractorHelper.hasExactCauseThrowable(throwable,
|
||||
InterruptedIOException.class,
|
||||
InterruptedException.class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import androidx.annotation.StringRes;
|
|||
import org.ocpsoft.prettytime.PrettyTime;
|
||||
import org.ocpsoft.prettytime.units.Decade;
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.extractor.ListExtractor;
|
||||
import org.schabi.newpipe.extractor.localization.ContentCountry;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
|
@ -151,8 +152,30 @@ public final class Localization {
|
|||
}
|
||||
|
||||
public static String localizeStreamCount(final Context context, final long streamCount) {
|
||||
return getQuantity(context, R.plurals.videos, R.string.no_videos, streamCount,
|
||||
localizeNumber(context, streamCount));
|
||||
switch ((int) streamCount) {
|
||||
case (int) ListExtractor.ITEM_COUNT_UNKNOWN:
|
||||
return "";
|
||||
case (int) ListExtractor.ITEM_COUNT_INFINITE:
|
||||
return context.getResources().getString(R.string.infinite_videos);
|
||||
case (int) ListExtractor.ITEM_COUNT_MORE_THAN_100:
|
||||
return context.getResources().getString(R.string.more_than_100_videos);
|
||||
default:
|
||||
return getQuantity(context, R.plurals.videos, R.string.no_videos, streamCount,
|
||||
localizeNumber(context, streamCount));
|
||||
}
|
||||
}
|
||||
|
||||
public static String localizeStreamCountMini(final Context context, final long streamCount) {
|
||||
switch ((int) streamCount) {
|
||||
case (int) ListExtractor.ITEM_COUNT_UNKNOWN:
|
||||
return "";
|
||||
case (int) ListExtractor.ITEM_COUNT_INFINITE:
|
||||
return context.getResources().getString(R.string.infinite_videos_mini);
|
||||
case (int) ListExtractor.ITEM_COUNT_MORE_THAN_100:
|
||||
return context.getResources().getString(R.string.more_than_100_videos_mini);
|
||||
default:
|
||||
return String.valueOf(streamCount);
|
||||
}
|
||||
}
|
||||
|
||||
public static String localizeWatchingCount(final Context context, final long watchingCount) {
|
||||
|
|
|
|||
|
|
@ -120,9 +120,6 @@ public final class NavigationHelper {
|
|||
final boolean isMuted) {
|
||||
return getPlayerIntent(context, targetClazz, playQueue, playbackQuality, resumePlayback)
|
||||
.putExtra(BasePlayer.REPEAT_MODE, repeatMode)
|
||||
.putExtra(BasePlayer.PLAYBACK_SPEED, playbackSpeed)
|
||||
.putExtra(BasePlayer.PLAYBACK_PITCH, playbackPitch)
|
||||
.putExtra(BasePlayer.PLAYBACK_SKIP_SILENCE, playbackSkipSilence)
|
||||
.putExtra(BasePlayer.START_PAUSED, startPaused)
|
||||
.putExtra(BasePlayer.IS_MUTED, isMuted);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,10 +48,12 @@ public final class ServiceHelper {
|
|||
case "all":
|
||||
return c.getString(R.string.all);
|
||||
case "videos":
|
||||
case "music_videos":
|
||||
return c.getString(R.string.videos_string);
|
||||
case "channels":
|
||||
return c.getString(R.string.channels);
|
||||
case "playlists":
|
||||
case "music_playlists":
|
||||
return c.getString(R.string.playlists);
|
||||
case "tracks":
|
||||
return c.getString(R.string.tracks);
|
||||
|
|
@ -61,6 +63,12 @@ public final class ServiceHelper {
|
|||
return c.getString(R.string.conferences);
|
||||
case "events":
|
||||
return c.getString(R.string.events);
|
||||
case "music_songs":
|
||||
return c.getString(R.string.songs);
|
||||
case "music_albums":
|
||||
return c.getString(R.string.albums);
|
||||
case "music_artists":
|
||||
return c.getString(R.string.artists);
|
||||
default:
|
||||
return filter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ public final class ThemeHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a resource id from a resource styled according to the the context's theme.
|
||||
* Get a resource id from a resource styled according to the context's theme.
|
||||
*
|
||||
* @param context Android app context
|
||||
* @param attr attribute reference of the resource
|
||||
|
|
@ -208,10 +208,10 @@ public final class ThemeHelper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a color from an attr styled according to the the context's theme.
|
||||
* Get a color from an attr styled according to the context's theme.
|
||||
*
|
||||
* @param context Android app context
|
||||
* @param attrColor attribute reference of the resource
|
||||
* @param context Android app context
|
||||
* @param attrColor attribute reference of the resource
|
||||
* @return the color
|
||||
*/
|
||||
public static int resolveColorFromAttr(final Context context, @AttrRes final int attrColor) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue