Added unicode and HTML decoding to video titles.

This commit is contained in:
Koen 2023-09-28 10:31:39 +02:00
parent 3527d8bac6
commit c1a97f3843
6 changed files with 84 additions and 14 deletions

View file

@ -9,9 +9,7 @@ import android.graphics.BitmapFactory
import android.os.Build
import android.os.Looper
import android.os.OperationCanceledException
import android.util.DisplayMetrics
import android.util.TypedValue
import android.view.Display
import android.view.View
import android.view.WindowInsetsController
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.models.PlatformVideoWithTime
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.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.*
import java.util.concurrent.ThreadLocalRandom
import kotlin.math.abs
import kotlin.math.min
private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
fun getRandomString(sizeOfRandomString: Int): String {
@ -156,4 +149,57 @@ fun File.share(context: Context) {
val chooserIntent = Intent.createChooser(shareIntent, "Share");
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
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()
}

View file

@ -5,7 +5,7 @@ import com.futo.platformplayer.api.media.models.comments.IPlatformComment
import com.futo.platformplayer.api.media.models.playback.IPlaybackTracker
import com.futo.platformplayer.api.media.structures.IPager
interface IPlatformContentDetails: IPlatformContent {
interface IPlatformContentDetails : IPlatformContent {
fun getComments(client: IPlatformClient): IPager<IPlatformComment>?;

View file

@ -1,5 +1,6 @@
package com.futo.platformplayer.api.media.platforms.js.models
import androidx.core.text.HtmlCompat
import com.caoccao.javet.values.reference.V8ValueObject
import com.futo.platformplayer.api.media.IPluginSourced
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.IPlatformContent
import com.futo.platformplayer.api.media.platforms.js.SourcePluginConfig
import com.futo.platformplayer.decodeUnicode
import com.futo.platformplayer.getOrDefault
import com.futo.platformplayer.getOrThrow
import com.futo.platformplayer.logging.Logger
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.time.ZoneOffset
@ -38,7 +41,8 @@ open class JSContent : IPlatformContent, IPluginSourced {
val contextName = "PlatformContent";
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));
val datetimeInt = _content.getOrThrow<Int>(config, "datetime", contextName).toLong();

View file

@ -3,6 +3,7 @@ package com.futo.platformplayer.fragment.mainactivity.main
import android.annotation.SuppressLint
import android.graphics.drawable.Animatable
import android.os.Bundle
import android.text.Html
import android.util.Log
import android.view.LayoutInflater
import android.view.View

View file

@ -1,19 +1,19 @@
package com.futo.platformplayer
import com.futo.platformplayer.payment.StatePayment
import com.futo.platformplayer.states.StatePayment
import org.junit.Assert
import org.junit.Test
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
fun `check payment validation`() {
val lkey = "Q42S-48S8-EJJZ-N9HH-ARAZ-GKBC-F1JV-K49E";
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));
}
}*/
}

View file

@ -2,9 +2,12 @@ package com.futo.platformplayer
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertTrue
import org.junit.Assert.assertThrows
import org.junit.Test
import java.io.IOException
import java.net.SocketTimeoutException
class UtilityTests {
private val _allowedCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ";
@ -33,4 +36,20 @@ class UtilityTests {
val result = findNonRuntimeException(runtimeException)
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())
}
}