<commit_before>package lila.history

import scala.concurrent.duration._

import play.api.libs.json._

import lila.rating.PerfType
import lila.user.User

final class RatingChartApi(
    historyApi: HistoryApi,
    mongoCache: lila.memo.MongoCache.Builder,
    cacheTtl: FiniteDuration
) {

  def apply(user: User): Fu[Option[String]] = cache(user) map { chart =>
    chart.nonEmpty option chart
  }

  def singlePerf(user: User, perfType: PerfType): Fu[JsArray] =
    historyApi.ratingsMap(user, perfType) map {
      ratingsMapToJson(user, _)
    } map JsArray.apply

  private val cache = mongoCache[User, String](
    prefix = "history:rating",
    f = user => build(user) map (~_),
    maxCapacity = 1024,
    timeToLive = cacheTtl,
    keyToString = _.id
  )

  private def ratingsMapToJson(user: User, ratingsMap: RatingsMap) = ratingsMap.map {
    case (days, rating) =>
      val date = user.createdAt plusDays days
      Json.arr(date.getYear, date.getMonthOfYear - 1, date.getDayOfMonth, rating)
  }

  private def build(user: User): Fu[Option[String]] =
    historyApi get user.id map2 { (history: History) =>
      Json stringify {
        Json.toJson {
          import lila.rating.PerfType._
          List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde, RacingKings, Crazyhouse, Puzzle, UltraBullet) map { pt =>
            Json.obj(
              "name" -> pt.name,
              "points" -> ratingsMapToJson(user, history(pt))
            )
          }
        }
      }
    }
}<commit_msg>display rating chart line if perf is established<commit_after>package lila.history

import scala.concurrent.duration._

import play.api.libs.json._

import lila.rating.PerfType
import lila.user.User

final class RatingChartApi(
    historyApi: HistoryApi,
    mongoCache: lila.memo.MongoCache.Builder,
    cacheTtl: FiniteDuration
) {

  def apply(user: User): Fu[Option[String]] = cache(user) map { chart =>
    chart.nonEmpty option chart
  }

  def singlePerf(user: User, perfType: PerfType): Fu[JsArray] =
    historyApi.ratingsMap(user, perfType) map {
      ratingsMapToJson(user, _)
    } map JsArray.apply

  private val cache = mongoCache[User, String](
    prefix = "history:rating",
    f = user => build(user) map (~_),
    maxCapacity = 1024,
    timeToLive = cacheTtl,
    keyToString = _.id
  )

  private def ratingsMapToJson(user: User, ratingsMap: RatingsMap) = ratingsMap.map {
    case (days, rating) =>
      val date = user.createdAt plusDays days
      Json.arr(date.getYear, date.getMonthOfYear - 1, date.getDayOfMonth, rating)
  }

  private def build(user: User): Fu[Option[String]] = {
    val nbEstablishedPerfs = user.perfs.perfs.count(_._2.established)
    historyApi get user.id map2 { (history: History) =>
      Json stringify {
        Json.toJson {
          perfTypes collect {
            case pt if nbEstablishedPerfs < 3 || user.perfs(pt).established =>
              Json.obj(
                "name" -> pt.name,
                "points" -> ratingsMapToJson(user, history(pt))
              )
          }
        }
      }
    }
  }

  private val perfTypes = {
    import lila.rating.PerfType._
    List(
      Bullet,
      Blitz,
      Classical,
      Correspondence,
      Chess960,
      KingOfTheHill,
      ThreeCheck,
      Antichess,
      Atomic,
      Horde,
      RacingKings,
      Crazyhouse,
      Puzzle,
      UltraBullet
    )
  }
}
{'fraction_non_alphanumeric': 0.10773240660295395, 'fraction_numerical': 0.005792064871126557, 'mean_word_length': 2.6281512605042017, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2757720', 'n_tokens_mistral': 1157, 'n_tokens_neox': 1114, 'n_words': 252}