auto evaluation of reported users
This commit is contained in:
parent
0ddbb9988a
commit
a9682e8a87
|
@ -31,11 +31,18 @@ trait UserHelper { self: I18nHelper with StringHelper ⇒
|
|||
userIdOption: Option[String],
|
||||
cssClass: Option[String] = None,
|
||||
withOnline: Boolean = true,
|
||||
truncate: Option[Int] = None): Html = Html {
|
||||
truncate: Option[Int] = None,
|
||||
params: String = ""): Html = Html {
|
||||
userIdOption.fold(User.anonymous) { userId ⇒
|
||||
Env.user usernameOption userId map {
|
||||
_.fold(User.anonymous) { username ⇒
|
||||
userIdNameLink(userId, username, cssClass, withOnline, truncate)
|
||||
userIdNameLink(
|
||||
userId = userId,
|
||||
username = username,
|
||||
cssClass = cssClass,
|
||||
withOnline = withOnline,
|
||||
truncate = truncate,
|
||||
params = params)
|
||||
}
|
||||
} await
|
||||
}
|
||||
|
@ -70,10 +77,11 @@ trait UserHelper { self: I18nHelper with StringHelper ⇒
|
|||
username: String,
|
||||
cssClass: Option[String] = None,
|
||||
withOnline: Boolean = true,
|
||||
truncate: Option[Int] = None): String =
|
||||
truncate: Option[Int] = None,
|
||||
params: String = ""): String =
|
||||
"""<a %s %s>%s</a>""".format(
|
||||
userClass(userId, cssClass, withOnline),
|
||||
userHref(username),
|
||||
userHref(username, params = params),
|
||||
truncate.fold(username)(username.take)
|
||||
)
|
||||
|
||||
|
@ -107,8 +115,8 @@ trait UserHelper { self: I18nHelper with StringHelper ⇒
|
|||
|
||||
def perfTitle(perf: String): String = lila.user.Perf.titles get perf getOrElse perf
|
||||
|
||||
private def userHref(username: String) =
|
||||
"href=\"" + routes.User.show(username) + "\""
|
||||
private def userHref(username: String, params: String = "") =
|
||||
s"""href="${routes.User.show(username)}$params""""
|
||||
|
||||
protected def userClass(
|
||||
userId: String,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
}
|
||||
|
||||
@base.layout(
|
||||
title = title,
|
||||
title = title,
|
||||
moreCss = cssTag("report.css"),
|
||||
goodies = goodies.some) {
|
||||
|
||||
|
@ -23,23 +23,23 @@ goodies = goodies.some) {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@reports.map { r =>
|
||||
<tr class="@r.unprocessed.fold("new", "")">
|
||||
<td>@userIdLink(r.createdBy.some)@timeago(r.createdAt)</td>
|
||||
<td>@userIdLink(r.user.some)</td>
|
||||
<td>
|
||||
<strong>@r.reason.capitalize</strong>
|
||||
- @autoLink(r.text)
|
||||
</td>
|
||||
<td>@r.processedBy.map { u =>
|
||||
}.getOrElse {
|
||||
<form action="@routes.Report.process(r.id)" method="post">
|
||||
<button type="submit" class="button">Check</button>
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@reports.map { r =>
|
||||
<tr class="@r.unprocessed.fold("new", "")">
|
||||
<td>@userIdLink(r.createdBy.some)@timeago(r.createdAt)</td>
|
||||
<td>@userIdLink(r.user.some, params = "?mod")</td>
|
||||
<td>
|
||||
<strong>@r.reason.capitalize</strong>
|
||||
- @autoLink(r.text)
|
||||
</td>
|
||||
<td>@r.processedBy.map { u =>
|
||||
}.getOrElse {
|
||||
<form action="@routes.Report.process(r.id)" method="post">
|
||||
<button type="submit" class="button">Check</button>
|
||||
</form>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -9,13 +9,14 @@ import lila.common.PimpedConfig._
|
|||
final class Env(
|
||||
config: Config,
|
||||
db: lila.db.Env,
|
||||
evaluator: lila.user.Evaluator,
|
||||
hub: lila.hub.Env) {
|
||||
|
||||
private val CollectionReport = config getString "collection.report"
|
||||
|
||||
lazy val forms = new DataForm(hub.actor.captcher)
|
||||
|
||||
lazy val api = new ReportApi
|
||||
lazy val api = new ReportApi(evaluator)
|
||||
|
||||
private[report] lazy val reportColl = db(CollectionReport)
|
||||
}
|
||||
|
@ -25,5 +26,6 @@ object Env {
|
|||
lazy val current = "[boot] report" describes new Env(
|
||||
config = lila.common.PlayApp loadConfig "report",
|
||||
db = lila.db.Env.current,
|
||||
evaluator = lila.user.Env.current.evaluator,
|
||||
hub = lila.hub.Env.current)
|
||||
}
|
||||
|
|
|
@ -18,11 +18,15 @@ case class Report(
|
|||
|
||||
def isCreator(user: String) = user == createdBy
|
||||
|
||||
def isCheat = realReason == Reason.Cheat
|
||||
|
||||
def isManual = createdBy != "lichess"
|
||||
|
||||
def process(by: User) = copy(processedBy = by.id.some)
|
||||
|
||||
def unprocessed = processedBy.isEmpty
|
||||
|
||||
def realReason = Reason byName reason
|
||||
def realReason: Reason = Reason byName reason
|
||||
}
|
||||
|
||||
object Report {
|
||||
|
|
|
@ -4,10 +4,10 @@ import play.api.libs.json._
|
|||
|
||||
import lila.db.api._
|
||||
import lila.db.Implicits._
|
||||
import lila.user.User
|
||||
import lila.user.{ User, Evaluator }
|
||||
import tube.reportTube
|
||||
|
||||
final class ReportApi {
|
||||
final class ReportApi(evaluator: Evaluator) {
|
||||
|
||||
def create(setup: ReportSetup, by: User): Funit =
|
||||
Reason(setup.reason).fold[Funit](fufail("Invalid report reason " + setup.reason)) { reason ⇒
|
||||
|
@ -16,12 +16,14 @@ final class ReportApi {
|
|||
reason = reason,
|
||||
text = setup.text,
|
||||
createdBy = by)
|
||||
$insert(report)
|
||||
$insert(report) >> {
|
||||
(report.isCheat && report.isManual) ?? evaluator.generate(report.user, true).void
|
||||
}
|
||||
}
|
||||
|
||||
def process(id: String, by: User): Funit =
|
||||
def process(id: String, by: User): Funit =
|
||||
$update.field(id, "processedBy", by.id)
|
||||
|
||||
|
||||
def nbUnprocessed = $count(Json.obj("processedBy" -> $exists(false)))
|
||||
|
||||
def recent = $find($query.all sort $sort.createdDesc, 50)
|
||||
|
|
|
@ -11,29 +11,25 @@ import lila.db.api._
|
|||
import lila.db.JsTube.Helpers.{ rename, writeDate, readDate }
|
||||
import lila.db.Types._
|
||||
|
||||
private[user] final class Evaluator(coll: Coll, script: String) {
|
||||
final class Evaluator(coll: Coll, script: String) {
|
||||
|
||||
def findOrGenerate(user: User, deep: Boolean): Fu[Option[Evaluation]] = find(user) flatMap {
|
||||
case x@Some(eval) if (!deep || eval.isDeep) ⇒ fuccess(x)
|
||||
case _ ⇒ generate(user, deep)
|
||||
case _ ⇒ generate(user.id, deep)
|
||||
}
|
||||
|
||||
def find(user: User): Fu[Option[Evaluation]] =
|
||||
coll.find(Json.obj("_id" -> user.id)).one[JsObject] map { _ map readEvaluation }
|
||||
|
||||
def generate(user: User, deep: Boolean): Fu[Option[Evaluation]] = UserRepo byId user.id flatMap {
|
||||
_ ?? { user ⇒
|
||||
for {
|
||||
output ← run(user.id, deep).future
|
||||
evalJs ← (Json parse output).transform(evaluationTransformer) match {
|
||||
case JsSuccess(v, _) ⇒ fuccess(v)
|
||||
case JsError(e) ⇒ fufail(lila.common.LilaException(s"Can't parse evaluator output: $e on $output"))
|
||||
}
|
||||
eval ← scala.concurrent.Future(readEvaluation(evalJs))
|
||||
_ ← coll.update(Json.obj("_id" -> user.id), evalJs, upsert = true)
|
||||
} yield eval.some
|
||||
def generate(userId: String, deep: Boolean): Fu[Option[Evaluation]] = for {
|
||||
output ← run(userId, deep).future
|
||||
evalJs ← (Json parse output).transform(evaluationTransformer) match {
|
||||
case JsSuccess(v, _) ⇒ fuccess(v)
|
||||
case JsError(e) ⇒ fufail(lila.common.LilaException(s"Can't parse evaluator output: $e on $output"))
|
||||
}
|
||||
}
|
||||
eval ← scala.concurrent.Future(readEvaluation(evalJs))
|
||||
_ ← coll.update(Json.obj("_id" -> userId), evalJs, upsert = true)
|
||||
} yield eval.some
|
||||
|
||||
private def readEvaluation(js: JsValue): Evaluation =
|
||||
(readDate('date) andThen Evaluation.reader) reads js match {
|
||||
|
|
Loading…
Reference in a new issue