<commit_before>package controllers

import scala.util.{ Success, Failure }

import akka.pattern.ask
import play.api.http.ContentTypes
import play.api.mvc._
import play.api.templates.Html

import lila.analyse.{ TimeChart, TimePie }
import lila.app._
import lila.game.{ Pov, GameRepo, PgnRepo, PgnDump }
import lila.hub.actorApi.map.Tell
import lila.round.actorApi.AnalysisAvailable
import lila.round.{ RoomRepo, WatcherRoomRepo }
import lila.tournament.{ TournamentRepo, Tournament ⇒ Tourney }
import lila.user.{ UserRepo }
import views._

object Analyse extends LilaController {

  private def env = Env.analyse
  private def bookmarkApi = Env.bookmark.api
  private lazy val timeChart = TimeChart(Env.user.usernameOrAnonymous) _

  def computer(id: String, color: String) = Auth { implicit ctx ⇒
    me ⇒
      env.analyser.getOrGenerate(id, me.id, isGranted(_.MarkEngine)) effectFold (
        e ⇒ logerr("[analysis] " + e.getMessage),
        _ ⇒ Env.round.socketHub ! Tell(id, AnalysisAvailable)
      )
      Redirect(routes.Analyse.replay(id, color)).fuccess
  }

  def replay(id: String, color: String) = Open { implicit ctx ⇒
    OptionFuOk(GameRepo.pov(id, color)) { pov ⇒
      PgnRepo get id flatMap { pgnString ⇒
        (WatcherRoomRepo room pov.gameId map { room ⇒
          html.round.watcherRoomInner(room.decodedMessages)
        }) zip
          Env.round.version(pov.gameId) zip
          (bookmarkApi userIdsByGame pov.game) zip
          Env.game.pgnDump(pov.game, pgnString) zip
          (env.analyser get pov.game.id) zip
          (pov.game.tournamentId ?? TournamentRepo.byId) map {
            case (((((roomHtml, version), bookmarkers), pgn), analysis), tour) ⇒
              html.analyse.replay(
                pov,
                analysis.fold(pgn)(a ⇒ Env.analyse.annotator(pgn, a)).toString,
                roomHtml,
                bookmarkers,
                chess.OpeningExplorer openingOf pgnString,
                analysis,
                version,
                tour)
          }
      }
    }
  }

  def stats(id: String) = Open { implicit ctx ⇒
    OptionFuOk(GameRepo game id) { game ⇒
      timeChart(game) map { chart ⇒
        html.analyse.stats(
          game = game,
          timeChart = chart,
          timePies = Pov(game) map { new TimePie(_) })
      }
    }
  }

  def pgn(id: String) = Open { implicit ctx ⇒
    OptionFuResult(GameRepo game id) { game ⇒
      for {
        pgnString ← game.pgnImport.map(_.pgn).fold(PgnRepo get id)(fuccess(_))
        content ← game.pgnImport.map(_.pgn).fold(Env.game.pgnDump(game, pgnString) map (_.toString))(fuccess(_))
        filename ← Env.game.pgnDump filename game
      } yield Ok(content).withHeaders(
        CONTENT_LENGTH -> content.size.toString,
        CONTENT_TYPE -> ContentTypes.TEXT,
        CONTENT_DISPOSITION -> ("attachment; filename=" + filename)
      )
    }
  }

  def fen(id: String) = Open { implicit ctx ⇒
    OptionOk(GameRepo game id) { game ⇒
      chess.format.Forsyth >> game.toChess
    }
  }
}
<commit_msg>serve fully annotated pgn<commit_after>package controllers

import scala.util.{ Success, Failure }

import akka.pattern.ask
import play.api.http.ContentTypes
import play.api.mvc._
import play.api.templates.Html

import lila.analyse.{ TimeChart, TimePie }
import lila.app._
import lila.game.{ Pov, GameRepo, PgnRepo, PgnDump }
import lila.hub.actorApi.map.Tell
import lila.round.actorApi.AnalysisAvailable
import lila.round.{ RoomRepo, WatcherRoomRepo }
import lila.tournament.{ TournamentRepo, Tournament ⇒ Tourney }
import lila.user.{ UserRepo }
import views._

object Analyse extends LilaController {

  private def env = Env.analyse
  private def bookmarkApi = Env.bookmark.api
  private lazy val timeChart = TimeChart(Env.user.usernameOrAnonymous) _

  def computer(id: String, color: String) = Auth { implicit ctx ⇒
    me ⇒
      env.analyser.getOrGenerate(id, me.id, isGranted(_.MarkEngine)) effectFold (
        e ⇒ logerr("[analysis] " + e.getMessage),
        _ ⇒ Env.round.socketHub ! Tell(id, AnalysisAvailable)
      )
      Redirect(routes.Analyse.replay(id, color)).fuccess
  }

  def replay(id: String, color: String) = Open { implicit ctx ⇒
    OptionFuOk(GameRepo.pov(id, color)) { pov ⇒
      PgnRepo get id flatMap { pgnString ⇒
        (WatcherRoomRepo room pov.gameId map { room ⇒
          html.round.watcherRoomInner(room.decodedMessages)
        }) zip
          Env.round.version(pov.gameId) zip
          (bookmarkApi userIdsByGame pov.game) zip
          Env.game.pgnDump(pov.game, pgnString) zip
          (env.analyser get pov.game.id) zip
          (pov.game.tournamentId ?? TournamentRepo.byId) map {
            case (((((roomHtml, version), bookmarkers), pgn), analysis), tour) ⇒
              html.analyse.replay(
                pov,
                analysis.fold(pgn)(a ⇒ Env.analyse.annotator(pgn, a)).toString,
                roomHtml,
                bookmarkers,
                chess.OpeningExplorer openingOf pgnString,
                analysis,
                version,
                tour)
          }
      }
    }
  }

  def stats(id: String) = Open { implicit ctx ⇒
    OptionFuOk(GameRepo game id) { game ⇒
      timeChart(game) map { chart ⇒
        html.analyse.stats(
          game = game,
          timeChart = chart,
          timePies = Pov(game) map { new TimePie(_) })
      }
    }
  }

  def pgn(id: String) = Open { implicit ctx ⇒
    OptionFuResult(GameRepo game id) { game ⇒
      (game.pgnImport match {
        case Some(i) ⇒ fuccess(i.pgn)
        case None ⇒ for {
          pgnMoves ← PgnRepo get id
          pgn ← Env.game.pgnDump(game, pgnMoves)
          analysis ← env.analyser get game.id
        } yield analysis.fold(pgn)(a ⇒ Env.analyse.annotator(pgn, a)).toString
      }) flatMap { content ⇒
        Env.game.pgnDump filename game map { filename ⇒
          Ok(content).withHeaders(
            CONTENT_LENGTH -> content.size.toString,
            CONTENT_TYPE -> ContentTypes.TEXT,
            CONTENT_DISPOSITION -> ("attachment; filename=" + filename))
        }
      }
    }
  }

  def fen(id: String) = Open { implicit ctx ⇒
    OptionOk(GameRepo game id) { game ⇒
      chess.format.Forsyth >> game.toChess
    }
  }
}

{'fraction_non_alphanumeric': 0.10899487836107555, 'fraction_numerical': 0.0, 'mean_word_length': 2.396195652173913, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, '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': '4599352', 'n_tokens_mistral': 2075, 'n_tokens_neox': 2096, 'n_words': 485}