don't treat external stream titles as HTML

This commit is contained in:
Thibault Duplessis
2026-03-31 10:31:28 +02:00
parent a21a6f804c
commit 0d5002696a
4 changed files with 12 additions and 15 deletions
+1 -1
View File
@@ -30,7 +30,7 @@ final private class Publisher(
.liveMatching(
streamers,
s =>
s.status.value.toLowerCase.contains(keyword.toLowerCase) ||
s.status.toLowerCase.contains(keyword.toLowerCase) ||
alwaysFeatured().value.contains(s.streamer.id)
)
.zip(ytApi.liveMatching(streamers))
+2 -3
View File
@@ -13,7 +13,6 @@ import play.api.mvc.Headers
import lila.common.Json.given
import lila.core.config.Secret
import lila.core.config.NetConfig
import lila.core.data.Html
private object Twitch:
@@ -26,7 +25,7 @@ private object Twitch:
case class HelixStream(
user_id: TwitchId,
user_login: TwitchLogin,
title: Html,
title: String,
language: String,
`type`: String
):
@@ -115,7 +114,7 @@ final private class TwitchApi(
val title = ~(event \ "title").asOpt[String]
val lang = (event \ "language").asOpt[String].filter(_.nonEmpty).getOrElse("en")
logger.info(s"channel update: $login ($id) title: $title lang: $lang")
lives.updateWith(id)(_.map(_.copy(user_login = login, title = Html(title), language = lang)))
lives.updateWith(id)(_.map(_.copy(user_login = login, title = title, language = lang)))
case _ => ()
if done.isEmpty then logger.warn(s"Unknown Twitch event notification: $js")
fuccess(none)
+7 -9
View File
@@ -7,8 +7,6 @@ import play.api.libs.ws.DefaultBodyWritables.*
import play.api.libs.ws.JsonBodyReadables.*
import play.api.libs.ws.StandaloneWSClient
import lila.common.Json.given
import lila.common.String.html.unescapeHtml
import lila.common.autoconfig.ConfigName
import lila.core.config.{ NetConfig, Secret }
@@ -22,7 +20,7 @@ private class YoutubeConfig(
private[streamer] object Youtube:
case class Snippet(
channelId: String,
title: Html,
title: String,
liveBroadcastContent: String,
defaultAudioLanguage: Option[String]
)
@@ -32,21 +30,21 @@ private[streamer] object Youtube:
items
.withFilter: item =>
item.snippet.liveBroadcastContent == "live" &&
item.snippet.title.value.toLowerCase.contains(keyword.toLowerCase)
item.snippet.title.toLowerCase.contains(keyword.toLowerCase)
.flatMap: item =>
streamers
.find(s => s.youtube.exists(_.channelId == item.snippet.channelId))
.map:
YoutubeStream(
item.snippet.channelId,
unescapeHtml(item.snippet.title),
item.snippet.title,
item.id,
_,
item.snippet.defaultAudioLanguage.flatMap(Lang.get) | lila.core.i18n.defaultLang
)
case class YoutubeStream(
channelId: String,
status: Html,
status: String,
videoId: String,
streamer: Streamer,
lang: Lang
@@ -189,9 +187,9 @@ final private class YoutubeApi(
.map { rsp =>
rsp.body[JsValue].validate[Youtube.Result] match
case JsSuccess(data, _) =>
data.items.headOption.fold(false): item =>
item.snippet.liveBroadcastContent == "live" && item.snippet.title.value.toLowerCase
.contains(keyword.toLowerCase)
data.items.headOption.exists: item =>
item.snippet.liveBroadcastContent == "live" &&
item.snippet.title.toLowerCase.contains(keyword.toLowerCase)
case JsError(err) =>
logger.warn(s"ERROR: ${rsp.status} $err ${rsp.body[String].take(200)}")
false
+2 -2
View File
@@ -17,7 +17,7 @@ import lila.db.dsl.given
trait Stream:
val streamer: Streamer
def platform: Platform
def status: Html
def status: String
def lang: Lang
def urls: Stream.Urls
@@ -26,7 +26,7 @@ trait Stream:
def youtube = platform == "youtube"
def language = toLanguage(lang)
lazy val cleanStatus = status.map(s => removeMultibyteSymbols(s).trim)
def cleanStatus = removeMultibyteSymbols(status).trim
def redirectToLiveUrl: Option[Url] = Url.from:
streamer.twitch