-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTv.scala
127 lines (111 loc) · 4.33 KB
/
Tv.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package controllers
import play.api.mvc._
import play.twirl.api.Html
import lila.api.Context
import lila.app._
import lila.game.{ GameRepo, Game => GameModel, Pov }
import views._
object Tv extends LilaController {
def index = onChannel(lila.tv.Tv.Channel.Best.key)
def onChannel(chanKey: String) = Open { implicit ctx =>
(lila.tv.Tv.Channel.byKey get chanKey).fold(notFound)(lichessTv)
}
def sides(chanKey: String, gameId: String, color: String) = Open { implicit ctx =>
lila.tv.Tv.Channel.byKey get chanKey match {
case None => notFound
case Some(channel) =>
OptionFuResult(GameRepo.pov(gameId, color)) { pov =>
Env.tv.tv.getChampions zip
Env.game.crosstableApi(pov.game) map {
case (champions, crosstable) => Ok(html.tv.sides(channel, champions, pov, crosstable, streams = Nil))
}
}
}
}
private def lichessTv(channel: lila.tv.Tv.Channel)(implicit ctx: Context) =
OptionFuResult(Env.tv.tv getGame channel) { game =>
val flip = getBool("flip")
val pov = flip.fold(Pov second game, Pov first game)
val onTv = lila.round.OnTv(channel.key, flip)
negotiate(
html = {
Env.api.roundApi.watcher(pov, lila.api.Mobile.Api.currentVersion, tv = onTv.some, withOpening = false) zip
Env.game.crosstableApi(game) zip
Env.tv.tv.getChampions map {
case ((data, cross), champions) => NoCache {
Ok(html.tv.index(channel, champions, pov, data, cross, flip))
}
}
},
api = apiVersion => Env.api.roundApi.watcher(pov, apiVersion, tv = onTv.some, withOpening = false) map { Ok(_) }
)
}
def games = gamesChannel(lila.tv.Tv.Channel.Best.key)
def gamesChannel(chanKey: String) = Open { implicit ctx =>
(lila.tv.Tv.Channel.byKey get chanKey).fold(notFound)(lichessGames)
}
private def lichessGames(channel: lila.tv.Tv.Channel)(implicit ctx: Context) =
Env.tv.tv.getChampions zip
Env.tv.tv.getGames(channel, 9) map {
case (champs, games) => NoCache {
Ok(html.tv.games(channel, games map lila.game.Pov.first, champs))
}
}
def streamIn(id: String) = Open { implicit ctx =>
OptionFuResult(Env.tv.streamerList find id) { streamer =>
Env.tv.streamsOnAir.all flatMap { streams =>
val others = streams.filter(_.id != id)
streams find (_.id == id) match {
case None => fuccess(Ok(html.tv.notStreaming(streamer, others)))
case Some(s) => fuccess(Ok(html.tv.stream(s, others)))
}
}
}
}
def feed = Action.async {
import makeTimeout.short
import akka.pattern.ask
import lila.round.TvBroadcast
import play.api.libs.EventSource
import akka.stream.scaladsl.Source
Env.round.tvBroadcast ? TvBroadcast.GetPublisher mapTo
manifest[TvBroadcast.PublisherType] map { publisher =>
val source = Source fromPublisher publisher
Ok.chunked(source via EventSource.flow).as("text/event-stream")
}
}
def streamConfig = Auth { implicit ctx =>
me =>
Env.tv.streamerList.store.get.map { text =>
Ok(html.tv.streamConfig(Env.tv.streamerList.form.fill(text)))
}
}
def streamConfigSave = SecureBody(_.StreamConfig) { implicit ctx =>
me =>
implicit val req = ctx.body
FormFuResult(Env.tv.streamerList.form) { err =>
fuccess(html.tv.streamConfig(err))
} { text =>
Env.tv.streamerList.store.set(text) >>
Env.mod.logApi.streamConfig(me.id) inject Redirect(routes.Tv.streamConfig)
}
}
def embed = Action { req =>
Ok {
val bg = get("bg", req) | "light"
val theme = get("theme", req) | "brown"
val url = s"""${req.domain + routes.Tv.frame}?bg=$bg&theme=$theme"""
s"""document.write("<iframe src='http://$url&embed=" + document.domain + "' class='lichess-tv-iframe' allowtransparency='true' frameBorder='0' style='width: 224px; height: 264px;' title='Lichess free online chess'></iframe>");"""
} as JAVASCRIPT withHeaders (CACHE_CONTROL -> "max-age=86400")
}
def frame = Action.async { req =>
Env.tv.tv.getBest map {
case None => NotFound
case Some(game) => Ok(views.html.tv.embed(
Pov first game,
get("bg", req) | "light",
lila.pref.Theme(~get("theme", req)).cssClass
))
}
}
}