mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-05-06 17:44:39 +02:00
Added unicode and HTML decoding to video titles.
This commit is contained in:
parent
3527d8bac6
commit
c1a97f3843
@ -9,9 +9,7 @@ import android.graphics.BitmapFactory
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.OperationCanceledException
|
import android.os.OperationCanceledException
|
||||||
import android.util.DisplayMetrics
|
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.Display
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.WindowInsetsController
|
import android.view.WindowInsetsController
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
@ -22,17 +20,12 @@ import com.futo.platformplayer.api.media.models.video.IPlatformVideo
|
|||||||
import com.futo.platformplayer.logging.Logger
|
import com.futo.platformplayer.logging.Logger
|
||||||
import com.futo.platformplayer.models.PlatformVideoWithTime
|
import com.futo.platformplayer.models.PlatformVideoWithTime
|
||||||
import com.futo.platformplayer.others.PlatformLinkMovementMethod
|
import com.futo.platformplayer.others.PlatformLinkMovementMethod
|
||||||
import com.futo.platformplayer.states.StatePlatform
|
|
||||||
import org.json.JSONArray
|
|
||||||
import org.json.JSONObject
|
|
||||||
import userpackage.Protocol
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ThreadLocalRandom
|
import java.util.concurrent.ThreadLocalRandom
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
|
private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
|
||||||
fun getRandomString(sizeOfRandomString: Int): String {
|
fun getRandomString(sizeOfRandomString: Int): String {
|
||||||
@ -157,3 +150,56 @@ fun File.share(context: Context) {
|
|||||||
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
context.startActivity(chooserIntent);
|
context.startActivity(chooserIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.decodeUnicode(): String {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
var i = 0
|
||||||
|
|
||||||
|
while (i < this.length) {
|
||||||
|
var ch = this[i]
|
||||||
|
|
||||||
|
if (ch == '\\' && i + 1 < this.length) {
|
||||||
|
i++
|
||||||
|
ch = this[i]
|
||||||
|
when (ch) {
|
||||||
|
'\\' -> sb.append('\\')
|
||||||
|
't' -> sb.append('\t')
|
||||||
|
'n' -> sb.append('\n')
|
||||||
|
'r' -> sb.append('\r')
|
||||||
|
'f' -> sb.append('\u000C')
|
||||||
|
'b' -> sb.append('\b')
|
||||||
|
'"' -> sb.append('"')
|
||||||
|
'\'' -> sb.append('\'')
|
||||||
|
'u' -> {
|
||||||
|
if (i + 4 < this.length) {
|
||||||
|
val unicode = this.substring(i + 1, i + 5)
|
||||||
|
try {
|
||||||
|
sb.append(unicode.toInt(16).toChar())
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
throw IOException("Invalid Unicode sequence: $unicode")
|
||||||
|
}
|
||||||
|
i += 4
|
||||||
|
} else {
|
||||||
|
throw IOException("Incomplete Unicode sequence")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in '0'..'7' -> {
|
||||||
|
val end = (i + 3).coerceAtMost(this.length)
|
||||||
|
val octal = this.substring(i, end).takeWhile { it in '0'..'7' }
|
||||||
|
try {
|
||||||
|
sb.append(octal.toInt(8).toChar())
|
||||||
|
i += octal.length - 1
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
throw IOException("Invalid Octal sequence: $octal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> sb.append(ch)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sb.append(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package com.futo.platformplayer.api.media.platforms.js.models
|
package com.futo.platformplayer.api.media.platforms.js.models
|
||||||
|
|
||||||
|
import androidx.core.text.HtmlCompat
|
||||||
import com.caoccao.javet.values.reference.V8ValueObject
|
import com.caoccao.javet.values.reference.V8ValueObject
|
||||||
import com.futo.platformplayer.api.media.IPluginSourced
|
import com.futo.platformplayer.api.media.IPluginSourced
|
||||||
import com.futo.platformplayer.api.media.PlatformID
|
import com.futo.platformplayer.api.media.PlatformID
|
||||||
@ -7,8 +8,10 @@ import com.futo.platformplayer.api.media.models.PlatformAuthorLink
|
|||||||
import com.futo.platformplayer.api.media.models.contents.ContentType
|
import com.futo.platformplayer.api.media.models.contents.ContentType
|
||||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||||
import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig
|
import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig
|
||||||
|
import com.futo.platformplayer.decodeUnicode
|
||||||
import com.futo.platformplayer.getOrDefault
|
import com.futo.platformplayer.getOrDefault
|
||||||
import com.futo.platformplayer.getOrThrow
|
import com.futo.platformplayer.getOrThrow
|
||||||
|
import com.futo.platformplayer.logging.Logger
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
import java.time.ZoneOffset
|
import java.time.ZoneOffset
|
||||||
@ -38,7 +41,8 @@ open class JSContent : IPlatformContent, IPluginSourced {
|
|||||||
val contextName = "PlatformContent";
|
val contextName = "PlatformContent";
|
||||||
|
|
||||||
id = PlatformID.fromV8(_pluginConfig, _content.getOrThrow(config, "id", contextName));
|
id = PlatformID.fromV8(_pluginConfig, _content.getOrThrow(config, "id", contextName));
|
||||||
name = _content.getOrThrow(config, "name", contextName);
|
name = HtmlCompat.fromHtml(_content.getOrThrow<String>(config, "name", contextName).decodeUnicode(), HtmlCompat.FROM_HTML_MODE_LEGACY).toString();
|
||||||
|
Logger.i("JSContent", "name=$name");
|
||||||
author = PlatformAuthorLink.fromV8(_pluginConfig, _content.getOrThrow(config, "author", contextName));
|
author = PlatformAuthorLink.fromV8(_pluginConfig, _content.getOrThrow(config, "author", contextName));
|
||||||
|
|
||||||
val datetimeInt = _content.getOrThrow<Int>(config, "datetime", contextName).toLong();
|
val datetimeInt = _content.getOrThrow<Int>(config, "datetime", contextName).toLong();
|
||||||
|
@ -3,6 +3,7 @@ package com.futo.platformplayer.fragment.mainactivity.main
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.drawable.Animatable
|
import android.graphics.drawable.Animatable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.text.Html
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
package com.futo.platformplayer
|
package com.futo.platformplayer
|
||||||
|
|
||||||
import com.futo.platformplayer.payment.StatePayment
|
import com.futo.platformplayer.states.StatePayment
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class PaymentTests {
|
class PaymentTests {
|
||||||
|
|
||||||
private val PAYMENT_KEY_TEST = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+PeflxecURXXi0WLVbXnUF0XwOKBleXOERBBGxW57X76mqIBC7FddogV/Z5Ym/YtxDNmAWxBRjO0iz8bz1iNT5AdGQ1y+kFvPaSKbJILmte2cWmFn2ga1uqAesUnLVVeWF9uA/nScABb7o1DaAhsONQfosfTz8X87S7r8g28A4wjYB5WR657NiSdXHOIyyIFrozM1JvHfGXQ7PlER1lBkbExDC6aLc7LRQY/++5pPWS9m/O+9EpeztqBkQZLIql6BvCZVYhOgMzLNCsYvvIN/mmY27eTYeCAm7v2fDWSZ1Badc083HOecpqDq2XCDewzf5Ea5t/SI93XhPiEi9UewIDAQAB";
|
/*private val PAYMENT_KEY_TEST = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+PeflxecURXXi0WLVbXnUF0XwOKBleXOERBBGxW57X76mqIBC7FddogV/Z5Ym/YtxDNmAWxBRjO0iz8bz1iNT5AdGQ1y+kFvPaSKbJILmte2cWmFn2ga1uqAesUnLVVeWF9uA/nScABb7o1DaAhsONQfosfTz8X87S7r8g28A4wjYB5WR657NiSdXHOIyyIFrozM1JvHfGXQ7PlER1lBkbExDC6aLc7LRQY/++5pPWS9m/O+9EpeztqBkQZLIql6BvCZVYhOgMzLNCsYvvIN/mmY27eTYeCAm7v2fDWSZ1Badc083HOecpqDq2XCDewzf5Ea5t/SI93XhPiEi9UewIDAQAB";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `check payment validation`() {
|
fun `check payment validation`() {
|
||||||
val lkey = "Q42S-48S8-EJJZ-N9HH-ARAZ-GKBC-F1JV-K49E";
|
val lkey = "Q42S-48S8-EJJZ-N9HH-ARAZ-GKBC-F1JV-K49E";
|
||||||
val activationKey = "m3VoUrXfhZumP4AoVqE6tRpxw5yJYSr49wRX_BO7-urNjjkAjWFFtNFR1Ytl8hsUo8zY_WP17uQP62W0Ocq8I8p46giyKXvFL8VbtqMSn4s4YUX6kYxgtKlzOd6-yNOF7RLd1DZJqHhpJ5juO3qmi9fKWfO9XiV368s-H7HNBWY8hSkprf40ANdKJ7m7QZ2Gf7kSM8Ld8KWmXCHooVfjfpl6vx5GXEvEumCPDKhwg-EYd2MBizUaDszdm_dufzcjC9EwpxO9SS-EjBdhpOSSRWU7gebDON8d4zTKBgkH0T6PBhF_iEuvFTmeIp7V5f_g1dCUuUCDEq6NvwikH3SrXA";
|
val activationKey = "m3VoUrXfhZumP4AoVqE6tRpxw5yJYSr49wRX_BO7-urNjjkAjWFFtNFR1Ytl8hsUo8zY_WP17uQP62W0Ocq8I8p46giyKXvFL8VbtqMSn4s4YUX6kYxgtKlzOd6-yNOF7RLd1DZJqHhpJ5juO3qmi9fKWfO9XiV368s-H7HNBWY8hSkprf40ANdKJ7m7QZ2Gf7kSM8Ld8KWmXCHooVfjfpl6vx5GXEvEumCPDKhwg-EYd2MBizUaDszdm_dufzcjC9EwpxO9SS-EjBdhpOSSRWU7gebDON8d4zTKBgkH0T6PBhF_iEuvFTmeIp7V5f_g1dCUuUCDEq6NvwikH3SrXA";
|
||||||
val validator = StatePayment.LicenseValidator(PAYMENT_KEY_TEST);
|
val validator = StatePayment(PAYMENT_KEY_TEST);
|
||||||
|
|
||||||
Assert.assertTrue(validator.validate(lkey, activationKey));
|
Assert.assertTrue(validator.validate(lkey, activationKey));
|
||||||
}
|
}*/
|
||||||
}
|
}
|
@ -2,9 +2,12 @@ package com.futo.platformplayer
|
|||||||
|
|
||||||
import junit.framework.TestCase.assertEquals
|
import junit.framework.TestCase.assertEquals
|
||||||
import junit.framework.TestCase.assertTrue
|
import junit.framework.TestCase.assertTrue
|
||||||
|
import org.junit.Assert.assertThrows
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import java.io.IOException
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
|
|
||||||
|
|
||||||
class UtilityTests {
|
class UtilityTests {
|
||||||
private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
|
private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
|
||||||
|
|
||||||
@ -33,4 +36,20 @@ class UtilityTests {
|
|||||||
val result = findNonRuntimeException(runtimeException)
|
val result = findNonRuntimeException(runtimeException)
|
||||||
assertEquals(innerException, result)
|
assertEquals(innerException, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDecodeString() {
|
||||||
|
assertThrows(IOException::class.java) { "\\u02-3".decodeUnicode() }
|
||||||
|
assertEquals("", "".decodeUnicode())
|
||||||
|
assertEquals("test", "test".decodeUnicode())
|
||||||
|
assertEquals("\ntest\b", "\\ntest\\b".decodeUnicode())
|
||||||
|
assertEquals("\u123425foo\ntest\b", "\\u123425foo\\ntest\\b".decodeUnicode())
|
||||||
|
assertEquals("'\u000coo\teste\r", "\\'\\u000coo\\teste\\r".decodeUnicode())
|
||||||
|
assertEquals("\\", "\\".decodeUnicode())
|
||||||
|
assertEquals("\uABCDx", "\\uabcdx".decodeUnicode())
|
||||||
|
assertEquals("\uABCDx", "\\uABCDx".decodeUnicode())
|
||||||
|
assertEquals("\uABCD", "\\uabcd".decodeUnicode())
|
||||||
|
assertEquals("\ud83d\udc80\ud83d\udd14", "\\ud83d\\udc80\\ud83d\\udd14".decodeUnicode())
|
||||||
|
assertEquals("String with a slash (/) in it", "String with a slash (/) in it".decodeUnicode())
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user