send coach and streamer pictures to zulip

pull/9771/head
Thibault Duplessis 2021-09-10 16:48:40 +02:00
parent bb82ab1846
commit fc2b5e8cbb
15 changed files with 64 additions and 39 deletions

View File

@ -1,16 +1,17 @@
package views.html
package coach
import controllers.routes
import lila.api.Context
import lila.app.templating.Environment._
import lila.app.ui.ScalatagsTemplate._
import controllers.routes
import lila.coach.Coach
import lila.user.User
object picture {
def apply(c: lila.coach.Coach.WithUser, error: Option[String] = None)(implicit ctx: Context) =
def apply(c: Coach.WithUser, error: Option[String] = None)(implicit ctx: Context) =
views.html.account.layout(
title = s"${c.user.titleUsername} coach picture",
evenMoreJs = jsTag("coach.form.js"),
@ -41,20 +42,19 @@ object picture {
}
object thumbnail {
val size = 350
def apply(c: lila.coach.Coach.WithUser, cssSize: Int = size) =
def apply(c: Coach.WithUser, cssSize: Int = Coach.imageSize) =
img(
widthA := size,
heightA := size,
widthA := Coach.imageSize,
heightA := Coach.imageSize,
width := cssSize,
height := cssSize,
cls := "picture",
src := url(c.coach),
alt := s"${c.user.titleUsername} Lichess coach picture"
)
def url(c: lila.coach.Coach) =
def url(c: Coach) =
c.picture match {
case Some(image) => picfitUrl.thumbnail(image, size, size)
case Some(image) => picfitUrl.thumbnail(image, Coach.imageSize, Coach.imageSize)
case _ => assetUrl("images/placeholder.png")
}
}

View File

@ -5,13 +5,14 @@ import controllers.routes
import lila.api.Context
import lila.app.templating.Environment._
import lila.app.ui.ScalatagsTemplate._
import lila.streamer.Streamer
import lila.user.User
object picture {
import trans.streamer._
def apply(s: lila.streamer.Streamer.WithUser, error: Option[String] = None)(implicit ctx: Context) =
def apply(s: Streamer.WithUser, error: Option[String] = None)(implicit ctx: Context) =
views.html.base.layout(
title = xStreamerPicture.txt(s.user.username),
moreJs = embedJsUnsafeLoadThen("""
@ -43,18 +44,17 @@ $('.streamer-picture form.upload input[type=file]').on('change', function() {
}
object thumbnail {
val size = 350
def apply(s: lila.streamer.Streamer, u: User) =
def apply(s: Streamer, u: User) =
img(
widthA := size,
heightA := size,
widthA := Streamer.imageSize,
heightA := Streamer.imageSize,
cls := "picture",
src := url(s),
alt := s"${u.titleUsername} Lichess streamer picture"
)
def url(s: lila.streamer.Streamer) =
def url(s: Streamer) =
s.picture match {
case Some(image) => picfitUrl.thumbnail(image, size, size)
case Some(image) => picfitUrl.thumbnail(image, Streamer.imageSize, Streamer.imageSize)
case _ => assetUrl("images/placeholder.png")
}
}

View File

@ -10,8 +10,6 @@ private[coach] object BsonHandlers {
implicit val CoachListedBSONHandler = booleanAnyValHandler[Coach.Listed](_.value, Coach.Listed.apply)
implicit val CoachAvailableBSONHandler =
booleanAnyValHandler[Coach.Available](_.value, Coach.Available.apply)
implicit val CoachPicturePathBSONHandler =
stringAnyValHandler[Coach.PicturePath](_.value, Coach.PicturePath.apply)
implicit val CoachProfileRichTextBSONHandler =
stringAnyValHandler[CoachProfile.RichText](_.value, CoachProfile.RichText.apply)

View File

@ -28,6 +28,8 @@ case class Coach(
object Coach {
val imageSize = 350
def make(user: lila.user.User) =
Coach(
_id = Id(user.id),
@ -46,9 +48,8 @@ object Coach {
def isListed = coach.listed.value && user.enabled && user.marks.clean
}
case class Id(value: String) extends AnyVal with StringValue
case class Listed(value: Boolean) extends AnyVal
case class Available(value: Boolean) extends AnyVal
case class PicturePath(value: String) extends AnyVal with StringValue
case class Id(value: String) extends AnyVal with StringValue
case class Listed(value: Boolean) extends AnyVal
case class Available(value: Boolean) extends AnyVal
case class User(rating: Int, seenAt: DateTime)
}

View File

@ -15,7 +15,8 @@ final class CoachApi(
userRepo: UserRepo,
picfitApi: PicfitApi,
cacheApi: lila.memo.CacheApi,
notifyApi: NotifyApi
notifyApi: NotifyApi,
irc: lila.irc.IrcApi
)(implicit ec: scala.concurrent.ExecutionContext) {
import BsonHandlers._
@ -72,7 +73,11 @@ final class CoachApi(
def uploadPicture(c: Coach.WithUser, picture: PicfitApi.FilePart): Funit =
picfitApi
.uploadFile(s"coach:${c.coach.id}", picture, userId = c.user.id) flatMap { pic =>
coachColl.update.one($id(c.coach.id), $set("picture" -> pic.id)).void
coachColl.update.one($id(c.coach.id), $set("picture" -> pic.id)) >>
irc.coachImage(
c.user,
imageUrl = picfitApi.url.thumbnail(pic.id, Coach.imageSize, Coach.imageSize)
)
}
private val languagesCache = cacheApi.unit[Set[String]] {

View File

@ -21,7 +21,8 @@ final class Env(
notifyApi: lila.notify.NotifyApi,
cacheApi: lila.memo.CacheApi,
db: lila.db.Db,
picfitApi: lila.memo.PicfitApi
picfitApi: lila.memo.PicfitApi,
irc: lila.irc.IrcApi
)(implicit ec: scala.concurrent.ExecutionContext, system: akka.actor.ActorSystem) {
private val config = appConfig.get[CoachConfig]("coach")(AutoConfig.loader)
@ -34,6 +35,7 @@ final class Env(
reviewColl = db(config.reviewColl),
picfitApi = picfitApi,
notifyApi = notifyApi,
irc = irc,
cacheApi = cacheApi
)

View File

@ -104,12 +104,27 @@ final class IrcApi(
imageUrl: String
): Funit =
zulip(_.image, "blog")(
s"[Blog image](${imageUrl
.replace("/display?", "/display.jpg?")}) in ${markdown
s"[Blog image](${markdown.fixImageUrl(imageUrl)}) in ${markdown
.lichessLink(s"/@/${user.username}/blog/$slug/$id", title)} by ${markdown
.userLink(user)}"
)
def coachImage(
user: User,
imageUrl: String
): Funit =
zulip(_.image, "coach")(
s"[Coach image](${markdown.fixImageUrl(imageUrl)}) by ${markdown.userLink(user)}"
)
def streamerImage(
user: User,
imageUrl: String
): Funit =
zulip(_.image, "coach")(
s"[Streamer image](${markdown.fixImageUrl(imageUrl)}) by ${markdown.userLink(user)}"
)
def ublogPost(
user: User,
id: String,
@ -217,5 +232,6 @@ object IrcApi {
val postReplace = lichessLink("/forum/$1", "$1")
def linkifyPosts(msg: String) = postRegex matcher msg replaceAll postReplace
def linkifyPostsAndUsers(msg: String) = linkifyPosts(linkifyUsers(msg))
def fixImageUrl(url: String) = url.replace("/display?", "/display.jpg?")
}
}

View File

@ -40,7 +40,7 @@ final class Env(
lazy val mongoRateLimitApi = wire[MongoRateLimitApi]
lazy val picfitApi = new PicfitApi(db(config.picfit.collection), ws, config.picfit)
lazy val picfitUrl = new lila.memo.PicfitUrl(config.picfit)
lazy val picfitApi = new PicfitApi(db(config.picfit.collection), picfitUrl, ws, config.picfit)
}

View File

@ -35,7 +35,7 @@ object PicfitImage {
implicit val imageBSONHandler = Macros.handler[PicfitImage]
}
final class PicfitApi(coll: Coll, ws: StandaloneWSClient, config: PicfitConfig)(implicit
final class PicfitApi(coll: Coll, val url: PicfitUrl, ws: StandaloneWSClient, config: PicfitConfig)(implicit
ec: ExecutionContext
) {

View File

@ -8,8 +8,6 @@ private object BsonHandlers {
implicit val StreamerIdBSONHandler = stringAnyValHandler[Streamer.Id](_.value, Streamer.Id.apply)
implicit val StreamerListedBSONHandler =
booleanAnyValHandler[Streamer.Listed](_.value, Streamer.Listed.apply)
implicit val StreamerPicturePathBSONHandler =
stringAnyValHandler[Streamer.PicturePath](_.value, Streamer.PicturePath.apply)
implicit val StreamerNameBSONHandler = stringAnyValHandler[Streamer.Name](_.value, Streamer.Name.apply)
implicit val StreamerHeadlineBSONHandler =
stringAnyValHandler[Streamer.Headline](_.value, Streamer.Headline.apply)

View File

@ -27,6 +27,7 @@ final class Env(
cacheApi: lila.memo.CacheApi,
picfitApi: lila.memo.PicfitApi,
notifyApi: lila.notify.NotifyApi,
irc: lila.irc.IrcApi,
userRepo: lila.user.UserRepo,
timeline: lila.hub.actors.Timeline,
db: lila.db.Db

View File

@ -38,6 +38,8 @@ case class Streamer(
object Streamer {
val imageSize = 350
def make(user: User) =
Streamer(
_id = Id(user.id),
@ -72,7 +74,6 @@ object Streamer {
chatEnabled: Boolean, // embed chat inside lichess
lastGrantedAt: Option[DateTime]
)
case class PicturePath(value: String) extends AnyVal with StringValue
case class Name(value: String) extends AnyVal with StringValue
case class Headline(value: String) extends AnyVal with StringValue
case class Description(value: String) extends AnyVal with StringValue

View File

@ -14,7 +14,8 @@ final class StreamerApi(
userRepo: UserRepo,
cacheApi: lila.memo.CacheApi,
picfitApi: PicfitApi,
notifyApi: lila.notify.NotifyApi
notifyApi: lila.notify.NotifyApi,
irc: lila.irc.IrcApi
)(implicit ec: scala.concurrent.ExecutionContext) {
import BsonHandlers._
@ -119,7 +120,11 @@ final class StreamerApi(
def uploadPicture(s: Streamer, picture: PicfitApi.FilePart, by: User): Funit =
picfitApi
.uploadFile(s"streamer:${s.id}", picture, userId = by.id) flatMap { pic =>
coll.update.one($id(s.id), $set("picture" -> pic.id)).void
coll.update.one($id(s.id), $set("picture" -> pic.id)) >>
irc.streamerImage(
by,
imageUrl = picfitApi.url.thumbnail(pic.id, Streamer.imageSize, Streamer.imageSize)
)
}
// unapprove after a week if you never streamed

View File

@ -13,7 +13,6 @@ final class Env(
userRepo: lila.user.UserRepo,
timeline: lila.hub.actors.Timeline,
picfitApi: lila.memo.PicfitApi,
picfitUrl: lila.memo.PicfitUrl,
ircApi: lila.irc.IrcApi,
relationApi: lila.relation.RelationApi,
captcher: lila.hub.actors.Captcher,

View File

@ -14,7 +14,6 @@ final class UblogApi(
rank: UblogRank,
userRepo: UserRepo,
picfitApi: PicfitApi,
picfitUrl: PicfitUrl,
timeline: lila.hub.actors.Timeline,
irc: lila.irc.IrcApi
)(implicit ec: ExecutionContext) {
@ -48,7 +47,7 @@ final class UblogApi(
timeline ! Propagate(
lila.hub.actorApi.timeline.UblogPost(user.id, post.id.value, post.slug, post.title)
).toFollowersOf(user.id)
if (!blog.modTier.isDefined) sendPostToZulip(user, blog, post).unit
if (blog.modTier.isEmpty) sendPostToZulip(user, blog, post).unit
}
}
@ -109,7 +108,7 @@ final class UblogApi(
id = post.id.value,
slug = post.slug,
title = post.title,
imageUrl = UblogPost.thumbnail(picfitUrl, imageId, _.Small)
imageUrl = UblogPost.thumbnail(picfitApi.url, imageId, _.Small)
)
}