Skip to content

Commit

Permalink
more ublog tier/rank system
Browse files Browse the repository at this point in the history
  • Loading branch information
ornicar committed Sep 7, 2021
1 parent 2a8e423 commit 1257ef1
Show file tree
Hide file tree
Showing 17 changed files with 174 additions and 84 deletions.
29 changes: 24 additions & 5 deletions app/controllers/Ublog.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ import lila.user.{ User => UserModel }

final class Ublog(env: Env) extends LilaController(env) {

import views.html.ublog.post.{ editUrlOf, urlOf }
import views.html.ublog.post.{ editUrlOfPost, urlOfPost }
import views.html.ublog.blog.{ urlOfBlog }
import lila.common.paginator.Paginator.zero

def index(username: String, page: Int) = Open { implicit ctx =>
NotForKids {
OptionFuResult(env.user.repo named username) { user =>
env.ublog.api.getUserBlog(user) flatMap { blog =>
(canViewBlogOf(user, blog) ?? env.ublog.paginator.byUser(user, true, page)) map { posts =>
Ok(html.ublog.index(user, posts))
Ok(html.ublog.blog(user, blog, posts))
}
}
}
Expand All @@ -42,7 +43,7 @@ final class Ublog(env: Env) extends LilaController(env) {
env.ublog.api.getUserBlog(user) flatMap { blog =>
env.ublog.api.findByIdAndBlog(UblogPost.Id(id), blog.id) flatMap {
_.filter(canViewPost(user, blog)) ?? { post =>
if (slug != post.slug) Redirect(urlOf(post)).fuccess
if (slug != post.slug) Redirect(urlOfPost(post)).fuccess
else {
env.ublog.api.otherPosts(UblogBlog.Id.User(user.id), post) zip
ctx.me.??(env.ublog.like.liked(post)) map { case (others, liked) =>
Expand Down Expand Up @@ -94,7 +95,7 @@ final class Ublog(env: Env) extends LilaController(env) {
CreateLimitPerUser(me.id, cost = if (me.isVerified) 1 else 3) {
env.ublog.api.create(data, me) map { post =>
lila.mon.ublog.create(me.id).increment()
Redirect(editUrlOf(post)).flashSuccess
Redirect(editUrlOfPost(post)).flashSuccess
}
}(rateLimitedFu)
)
Expand All @@ -120,7 +121,7 @@ final class Ublog(env: Env) extends LilaController(env) {
err => BadRequest(html.ublog.form.edit(me, prev, err)).fuccess,
data =>
env.ublog.api.update(data, prev, me) map { post =>
Redirect(urlOf(post)).flashSuccess
Redirect(urlOfPost(post)).flashSuccess
}
)
}
Expand All @@ -144,6 +145,24 @@ final class Ublog(env: Env) extends LilaController(env) {
}
}

def setTier(blogId: String) = SecureBody(_.ModerateBlog) { implicit ctx => me =>
UblogBlog.Id(blogId).??(env.ublog.api.getBlog) flatMap {
_ ?? { blog =>
implicit val body = ctx.body
lila.ublog.UblogForm.tier
.bindFromRequest()
.fold(
err => Redirect(urlOfBlog(blog)).flashFailure.fuccess,
tier =>
env.ublog.api.setTier(blog.id, tier) >>
env.ublog.like.recomputeRankOfAllPosts(blog.id) >> env.mod.logApi
.blogTier(lila.report.Mod(me.user), blog.id.full, tier)
inject Redirect(urlOfBlog(blog)).flashSuccess
)
}
}
}

private val ImageRateLimitPerIp = lila.memo.RateLimit.composite[lila.common.IpAddress](
key = "ublog.image.ip"
)(
Expand Down
56 changes: 56 additions & 0 deletions app/views/ublog/blog.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package views.html.ublog

import controllers.routes

import lila.api.Context
import lila.app.templating.Environment._
import lila.app.ui.ScalatagsTemplate._
import lila.common.paginator.Paginator
import lila.ublog.{ UblogBlog, UblogPost }
import lila.user.User

object blog {

import views.html.ublog.{ post => postView }

def apply(user: User, blog: UblogBlog, posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) =
views.html.base.layout(
moreCss = cssTag("ublog"),
moreJs = frag(
posts.hasNextPage option infiniteScrollTag,
ctx.isAuth option jsModule("ublog")
),
title = trans.ublog.xBlog.txt(user.username)
) {
main(cls := "box box-pad page page-small ublog-index")(
div(cls := "box__top")(
h1(trans.ublog.xBlog(userLink(user))),
if (ctx is user)
div(cls := "box__top__actions")(
a(href := routes.Ublog.drafts(user.username))(trans.ublog.drafts()),
postView.newPostLink
)
else isGranted(_.ModerateBlog) option tierForm(blog)
),
standardFlash(),
if (posts.nbResults > 0)
div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")(
posts.currentPageResults map { postView.card(_) },
pagerNext(posts, np => s"${routes.Ublog.index(user.username, np).url}")
)
else
div(cls := "ublog-index__posts--empty")(
trans.ublog.noPostsInThisBlogYet()
)
)
}

def urlOfBlog(blog: UblogBlog) = blog.id match {
case UblogBlog.Id.User(userId) => routes.Ublog.index(usernameOrId(userId))
}

private def tierForm(blog: UblogBlog) = postForm(action := routes.Ublog.setTier(blog.id.full)) {
val form = lila.ublog.UblogForm.tier.fill(blog.tier)
form3.select(form("tier"), lila.ublog.UblogBlog.Tier.options)
}
}
4 changes: 3 additions & 1 deletion app/views/ublog/form.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ object form {
views.html.base.captcha(form, c)
},
form3.actions(
a(href := post.fold(routes.Ublog.index(user.username))(views.html.ublog.post.urlOf))(trans.cancel()),
a(href := post.fold(routes.Ublog.index(user.username))(views.html.ublog.post.urlOfPost))(
trans.cancel()
),
form3.submit(trans.apply())
)
)
Expand Down
47 changes: 2 additions & 45 deletions app/views/ublog/index.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,6 @@ object index {

import views.html.ublog.{ post => postView }

def apply(user: User, posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) =
views.html.base.layout(
moreCss = cssTag("ublog"),
moreJs = frag(
posts.hasNextPage option infiniteScrollTag,
ctx.isAuth option jsModule("ublog")
),
title = trans.ublog.xBlog.txt(user.username)
) {
main(cls := "box box-pad page page-small ublog-index")(
div(cls := "box__top")(
h1(trans.ublog.xBlog(userLink(user))),
if (ctx is user)
div(cls := "box__top__actions")(
a(href := routes.Ublog.drafts(user.username))(trans.ublog.drafts()),
newPostLink
)
else if (isGranted(_.ModerateBlog) && user.marks.troll)
badTag("Not visible to the public")
else emptyFrag
),
standardFlash(),
if (posts.nbResults > 0)
div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")(
posts.currentPageResults map { postView.card(_) },
pagerNext(posts, np => s"${routes.Ublog.index(user.username, np).url}")
)
else
div(cls := "ublog-index__posts--empty")(
trans.ublog.noPostsInThisBlogYet()
)
)
}

def drafts(user: User, posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) =
views.html.base.layout(
moreCss = frag(cssTag("ublog")),
Expand All @@ -58,12 +24,12 @@ object index {
h1(trans.ublog.drafts()),
div(cls := "box__top__actions")(
a(href := routes.Ublog.index(user.username))(trans.ublog.published()),
newPostLink
postView.newPostLink
)
),
if (posts.nbResults > 0)
div(cls := "ublog-index__posts ublog-index__posts--drafts ublog-post-cards infinite-scroll")(
posts.currentPageResults map { postView.card(_, postView.editUrlOf) },
posts.currentPageResults map { postView.card(_, postView.editUrlOfPost) },
pagerNext(posts, np => routes.Ublog.drafts(user.username, np).url)
)
else
Expand Down Expand Up @@ -117,13 +83,4 @@ object index {
)
)
}

private def newPostLink(implicit ctx: Context) = ctx.me map { u =>
a(
href := routes.Ublog.form(u.username),
cls := "button button-green",
dataIcon := "",
title := trans.ublog.newPost.txt()
)
}
}
19 changes: 14 additions & 5 deletions app/views/ublog/post.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ object post {
if (post.live) trans.ublog.thisPostIsPublished() else trans.ublog.thisIsADraft()
),
a(
href := editUrlOf(post),
href := editUrlOfPost(post),
cls := "button button-empty text",
dataIcon := ""
)(trans.edit())
Expand All @@ -71,7 +71,7 @@ object post {
a(
titleOrText(trans.reportXToModerators.txt(user.username)),
cls := "button button-empty ublog-post__meta__report",
href := s"${routes.Report.form}?username=${user.username}&postUrl=${urlencode(s"${netBaseUrl}${urlOf(post).url}")}&reason=comm",
href := s"${routes.Report.form}?username=${user.username}&postUrl=${urlencode(s"${netBaseUrl}${urlOfPost(post).url}")}&reason=comm",
dataIcon := ""
)
),
Expand All @@ -86,7 +86,7 @@ object post {

def card(
post: UblogPost.BasePost,
makeUrl: UblogPost.BasePost => Call = urlOf,
makeUrl: UblogPost.BasePost => Call = urlOfPost,
showAuthor: Boolean = false
)(implicit ctx: Context) =
a(cls := "ublog-post-card", href := makeUrl(post))(
Expand All @@ -99,12 +99,21 @@ object post {
)
)

def urlOf(post: UblogPost.BasePost) = post.blog match {
def urlOfPost(post: UblogPost.BasePost) = post.blog match {
case UblogBlog.Id.User(userId) =>
routes.Ublog.post(usernameOrId(userId), post.slug, post.id.value)
}

def editUrlOf(post: UblogPost.BasePost) = routes.Ublog.edit(post.id.value)
def editUrlOfPost(post: UblogPost.BasePost) = routes.Ublog.edit(post.id.value)

private[ublog] def newPostLink(implicit ctx: Context) = ctx.me map { u =>
a(
href := routes.Ublog.form(u.username),
cls := "button button-green",
dataIcon := "",
title := trans.ublog.newPost.txt()
)
}

object thumbnail {
def apply(post: UblogPost.BasePost, size: UblogPost.thumbnail.SizeSelector) =
Expand Down
2 changes: 2 additions & 0 deletions bin/mongodb/ublog-blog.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ db.ublog_post.find({ blog: { $exists: false } }).forEach(p => {
at: p.liveAt,
}
: undefined,
likers: [],
likes: NumberInt(0),
},
$unset: {
user: 1,
Expand Down
1 change: 1 addition & 0 deletions conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ GET /ublog/$id<\w{8}>/edit controllers.Ublog.edit(id: String)
POST /ublog/$id<\w{8}>/edit controllers.Ublog.update(id: String)
POST /ublog/$id<\w{8}>/del controllers.Ublog.delete(id: String)
POST /ublog/$id<\w{8}>/like controllers.Ublog.like(id: String, v: Boolean)
POST /ublog/:blogId/tier controllers.Ublog.setTier(blogId: String)
POST /upload/image/ublog/$id<\w{8}> controllers.Ublog.image(id: String)

# User
Expand Down
2 changes: 2 additions & 0 deletions modules/mod/src/main/ModActivity.scala
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ object ModActivity {
case object Appeal extends Action
case object SetEmail extends Action
case object Streamer extends Action
case object Blog extends Action
case object ForumAdmin extends Action
val dbMap = Map(
"modMessage" -> Message,
Expand All @@ -191,6 +192,7 @@ object ModActivity {
"streamerDecline" -> Streamer,
"streamerunlist" -> Streamer,
"streamerTier" -> Streamer,
"blogTier" -> Blog,
"deletePost" -> ForumAdmin,
"closeTopic" -> ForumAdmin
)
Expand Down
2 changes: 2 additions & 0 deletions modules/mod/src/main/Modlog.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ case class Modlog(
case Modlog.streamerFeature => "feature streamer" // BC
case Modlog.streamerUnfeature => "unfeature streamer" // BC
case Modlog.streamerTier => "set streamer tier"
case Modlog.blogTier => "set blog tier"
case Modlog.teamKick => "kick from team"
case Modlog.teamEdit => "edited team"
case Modlog.appealPost => "posted in appeal"
Expand Down Expand Up @@ -135,6 +136,7 @@ object Modlog {
val streamerFeature = "streamerFeature" // BC
val streamerUnfeature = "streamerUnfeature" // BC
val streamerTier = "streamerTier"
val blogTier = "blogTier"
val teamKick = "teamKick"
val teamEdit = "teamEdit"
val appealPost = "appealPost"
Expand Down
4 changes: 4 additions & 0 deletions modules/mod/src/main/ModlogApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ final class ModlogApi(repo: ModlogRepo, userRepo: UserRepo, ircApi: IrcApi)(impl
add {
Modlog(mod.user.id, streamerId.some, Modlog.streamerTier, v.toString.some)
}
def blogTier(mod: Mod, blogId: String, v: Int) =
add {
Modlog(mod.user.id, blogId.some, Modlog.blogTier, v.toString.some)
}

def practiceConfig(mod: User.ID) =
add {
Expand Down
1 change: 0 additions & 1 deletion modules/round/src/main/Titivate.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package lila.round
import akka.actor._
import akka.stream.scaladsl._
import org.joda.time.DateTime

import scala.concurrent.duration._

import lila.common.LilaStream
Expand Down
4 changes: 3 additions & 1 deletion modules/ublog/src/main/Env.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ final class Env(
val form = wire[UblogForm]

lila.common.Bus.subscribeFun("shadowban") { case lila.hub.actorApi.mod.Shadowban(userId, v) =>
api.setShadowban(userId, v).unit
api.setShadowban(userId, v) >>
like.recomputeRankOfAllPosts(UblogBlog.Id.User(userId))
()
}
}

Expand Down
2 changes: 1 addition & 1 deletion modules/ublog/src/main/UblogApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ final class UblogApi(

def setTier(blog: UblogBlog.Id, tier: Int): Funit =
colls.blog.update
.one($id(blog), $set("modTier" -> tier, "tier" -> tier))
.one($id(blog), $set("modTier" -> tier, "tier" -> tier), upsert = true)
.void

private[ublog] def setShadowban(userId: User.ID, v: Boolean) = {
Expand Down
14 changes: 12 additions & 2 deletions modules/ublog/src/main/UblogBlog.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ case class UblogBlog(
_id: UblogBlog.Id,
title: Option[String],
intro: Option[String],
tier: Int, // actual tier, auto or set by a mod
modTier: Option[Int] // tier set by a mod
tier: UblogBlog.Tier, // actual tier, auto or set by a mod
modTier: Option[UblogBlog.Tier] // tier set by a mod
) {
def id = _id
def visible = tier >= UblogBlog.Tier.VISIBLE
Expand All @@ -26,6 +26,7 @@ object UblogBlog {
}
}

type Tier = Int
object Tier {
val HIDDEN = 0 // not visible
val VISIBLE = 1 // not listed in community page
Expand All @@ -38,6 +39,15 @@ object UblogBlog {
if (user.marks.troll) Tier.HIDDEN
else if (user.hasTitle || user.perfs.standard.glicko.establishedIntRating.exists(_ > 2200)) Tier.NORMAL
else Tier.LOW

val options = List(
HIDDEN -> "Hidden",
VISIBLE -> "Unlisted",
LOW -> "Low tier",
NORMAL -> "Normal tier",
HIGH -> "High tier",
BEST -> "Best tier"
)
}

def make(user: User) = UblogBlog(
Expand Down
4 changes: 3 additions & 1 deletion modules/ublog/src/main/UblogForm.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ object UblogForm {
created = UblogPost.Recorded(user.id, DateTime.now),
updated = none,
lived = none,
likes = UblogPost.Likes(0)
likes = UblogPost.Likes(1)
)

def update(user: User, prev: UblogPost) =
Expand All @@ -85,4 +85,6 @@ object UblogForm {
lived = prev.lived orElse live.option(UblogPost.Recorded(user.id, DateTime.now))
)
}

val tier = Form(single("tier" -> number(min = UblogBlog.Tier.HIDDEN, max = UblogBlog.Tier.BEST)))
}
Loading

0 comments on commit 1257ef1

Please sign in to comment.