recognize annotator in imported study chapter
parent
cd2e1e79a0
commit
f314fef303
|
@ -64,7 +64,7 @@ final class Syncache[K, V](
|
|||
else chm.computeIfAbsent(k, loadFunction)
|
||||
}
|
||||
|
||||
// maybe optimize later with cach batching
|
||||
// maybe optimize later with cache batching
|
||||
def asyncMany(ks: List[K]): Fu[List[V]] = ks.map(async).sequenceFu
|
||||
|
||||
def invalidate(k: K): Unit = cache invalidate k
|
||||
|
|
|
@ -10,7 +10,7 @@ import lila.user.User
|
|||
|
||||
private final class ChapterMaker(
|
||||
domain: String,
|
||||
lightUser: lila.common.LightUser.GetterSync,
|
||||
lightUser: lila.user.LightUserApi,
|
||||
chat: akka.actor.ActorSelection,
|
||||
importer: Importer,
|
||||
pgnFetch: PgnFetch
|
||||
|
@ -21,42 +21,44 @@ private final class ChapterMaker(
|
|||
def apply(study: Study, data: Data, order: Int, userId: User.ID): Fu[Option[Chapter]] =
|
||||
data.game.??(parsePov) flatMap {
|
||||
case None =>
|
||||
data.game.??(pgnFetch.fromUrl) map {
|
||||
case Some(pgn) => fromFenOrPgnOrBlank(study, data.copy(pgn = pgn.some), order, userId).some
|
||||
case None => fromFenOrPgnOrBlank(study, data, order, userId).some
|
||||
data.game.??(pgnFetch.fromUrl) flatMap {
|
||||
case Some(pgn) => fromFenOrPgnOrBlank(study, data.copy(pgn = pgn.some), order, userId) map some
|
||||
case _ => fromFenOrPgnOrBlank(study, data, order, userId) map some
|
||||
}
|
||||
case Some(pov) => fromPov(study, pov, data, order, userId)
|
||||
} map2 { (c: Chapter) =>
|
||||
if (c.name.value.isEmpty) c.copy(name = Chapter defaultName order) else c
|
||||
}
|
||||
|
||||
def fromFenOrPgnOrBlank(study: Study, data: Data, order: Int, userId: User.ID): Chapter =
|
||||
def fromFenOrPgnOrBlank(study: Study, data: Data, order: Int, userId: User.ID): Fu[Chapter] =
|
||||
data.pgn.filter(_.trim.nonEmpty) match {
|
||||
case Some(pgn) => fromPgn(study, pgn, data, order, userId)
|
||||
case None => fromFenOrBlank(study, data, order, userId)
|
||||
case None => fuccess(fromFenOrBlank(study, data, order, userId))
|
||||
}
|
||||
|
||||
private def fromPgn(study: Study, pgn: String, data: Data, order: Int, userId: User.ID): Chapter =
|
||||
PgnImport(pgn).toOption.fold(fromFenOrBlank(study, data, order, userId)) { res =>
|
||||
Chapter.make(
|
||||
studyId = study.id,
|
||||
name = (for {
|
||||
white <- Tag.find(res.tags, "White")
|
||||
black <- Tag.find(res.tags, "Black")
|
||||
if data.name.value.isEmpty || Chapter.isDefaultName(data.name)
|
||||
} yield Chapter.Name(s"$white - $black")) | data.name,
|
||||
setup = Chapter.Setup(
|
||||
none,
|
||||
res.variant,
|
||||
data.realOrientation
|
||||
),
|
||||
root = res.root,
|
||||
tags = res.tags,
|
||||
order = order,
|
||||
ownerId = userId,
|
||||
practice = data.isPractice,
|
||||
conceal = data.isConceal option Chapter.Ply(res.root.ply)
|
||||
)
|
||||
private def fromPgn(study: Study, pgn: String, data: Data, order: Int, userId: User.ID): Fu[Chapter] =
|
||||
lightUser.asyncMany(study.members.contributorIds.toList) map { contributors =>
|
||||
PgnImport(pgn, contributors.flatten).toOption.fold(fromFenOrBlank(study, data, order, userId)) { res =>
|
||||
Chapter.make(
|
||||
studyId = study.id,
|
||||
name = (for {
|
||||
white <- Tag.find(res.tags, "White")
|
||||
black <- Tag.find(res.tags, "Black")
|
||||
if data.name.value.isEmpty || Chapter.isDefaultName(data.name)
|
||||
} yield Chapter.Name(s"$white - $black")) | data.name,
|
||||
setup = Chapter.Setup(
|
||||
none,
|
||||
res.variant,
|
||||
data.realOrientation
|
||||
),
|
||||
root = res.root,
|
||||
tags = res.tags,
|
||||
order = order,
|
||||
ownerId = userId,
|
||||
practice = data.isPractice,
|
||||
conceal = data.isConceal option Chapter.Ply(res.root.ply)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private def fromFenOrBlank(study: Study, data: Data, order: Int, userId: User.ID): Chapter = {
|
||||
|
@ -106,7 +108,7 @@ private final class ChapterMaker(
|
|||
studyId = study.id,
|
||||
name =
|
||||
if (Chapter isDefaultName data.name)
|
||||
Chapter.Name(Namer.gameVsText(pov.game, withRatings = false)(lightUser))
|
||||
Chapter.Name(Namer.gameVsText(pov.game, withRatings = false)(lightUser.sync))
|
||||
else data.name,
|
||||
setup = Chapter.Setup(
|
||||
!pov.game.synthetic option pov.game.id,
|
||||
|
|
|
@ -79,7 +79,7 @@ final class Env(
|
|||
private lazy val chapterMaker = new ChapterMaker(
|
||||
importer = importer,
|
||||
pgnFetch = new PgnFetch,
|
||||
lightUser = lightUserApi.sync,
|
||||
lightUser = lightUserApi,
|
||||
chat = hub.actor.chat,
|
||||
domain = NetDomain
|
||||
)
|
||||
|
|
|
@ -3,10 +3,11 @@ package lila.study
|
|||
import scalaz.Validation.FlatMap._
|
||||
import scalaz.Validation.success
|
||||
|
||||
import chess.format.pgn.{ Tag, Glyphs, San, Dumper }
|
||||
import chess.format.pgn.{ Tag, Glyphs, San, Dumper, ParsedPgn }
|
||||
import chess.format.{ Forsyth, FEN, Uci, UciCharPair }
|
||||
|
||||
import chess.Centis
|
||||
import lila.common.LightUser
|
||||
import lila.importer.{ ImportData, Preprocessed }
|
||||
import lila.tree.Node.{ Comment, Comments, Shapes }
|
||||
|
||||
|
@ -18,10 +19,10 @@ private object PgnImport {
|
|||
tags: List[Tag]
|
||||
)
|
||||
|
||||
def apply(pgn: String): Valid[Result] =
|
||||
def apply(pgn: String, contributors: List[LightUser]): Valid[Result] =
|
||||
ImportData(pgn, analyse = none).preprocess(user = none).map {
|
||||
case prep @ Preprocessed(game, replay, result, initialFen, parsedPgn) =>
|
||||
val annotator = parsedPgn.tag("annotator").map(Comment.Author.External.apply)
|
||||
val annotator = findAnnotator(parsedPgn, contributors)
|
||||
parseComments(parsedPgn.initialPosition.comments, annotator) match {
|
||||
case (shapes, _, comments) =>
|
||||
val root = Node.Root(
|
||||
|
@ -62,6 +63,16 @@ private object PgnImport {
|
|||
}
|
||||
}
|
||||
|
||||
private def findAnnotator(pgn: ParsedPgn, contributors: List[LightUser]): Option[Comment.Author] =
|
||||
pgn tag "annotator" map { a =>
|
||||
val lowered = a.toLowerCase
|
||||
contributors.find { c =>
|
||||
c.name == lowered || c.titleName == lowered || lowered.endsWith(s"/${c.id}")
|
||||
} map { c =>
|
||||
Comment.Author.User(c.id, c.titleName)
|
||||
} getOrElse Comment.Author.External(a)
|
||||
}
|
||||
|
||||
private def endComment(prep: Preprocessed): Option[Comment] = {
|
||||
import lila.tree.Node.Comment
|
||||
import prep._
|
||||
|
|
|
@ -15,9 +15,9 @@ private final class StudyMaker(
|
|||
case None => createFromScratch(data, user)
|
||||
}
|
||||
|
||||
private def createFromScratch(data: DataForm.Data, user: User): Fu[Study.WithChapter] = fuccess {
|
||||
private def createFromScratch(data: DataForm.Data, user: User): Fu[Study.WithChapter] = {
|
||||
val study = Study.make(user, Study.From.Scratch)
|
||||
val chapter = chapterMaker.fromFenOrPgnOrBlank(study, ChapterMaker.Data(
|
||||
chapterMaker.fromFenOrPgnOrBlank(study, ChapterMaker.Data(
|
||||
game = none,
|
||||
name = Chapter.Name("Chapter 1"),
|
||||
variant = data.variantStr,
|
||||
|
@ -28,8 +28,9 @@ private final class StudyMaker(
|
|||
initial = true
|
||||
),
|
||||
order = 1,
|
||||
userId = user.id)
|
||||
Study.WithChapter(study withChapter chapter, chapter)
|
||||
userId = user.id) map { chapter =>
|
||||
Study.WithChapter(study withChapter chapter, chapter)
|
||||
}
|
||||
}
|
||||
|
||||
private def createFromPov(pov: Pov, initialFen: Option[FEN], user: User): Fu[Study.WithChapter] =
|
||||
|
|
Loading…
Reference in New Issue