in pushservice/src/main/scala/com/twitter/frigate/pushservice/send_handler/generator/MagicFanoutSportsEventCandidateGenerator.scala [30:152]
final def getCandidate(
targetUser: Target,
notification: FrigateNotification,
basketballGameScoreStore: ReadableStore[QualifiedId, BasketballGameLiveUpdate],
baseballGameScoreStore: ReadableStore[QualifiedId, BaseballGameLiveUpdate],
cricketMatchScoreStore: ReadableStore[QualifiedId, CricketMatchLiveUpdate],
soccerMatchScoreStore: ReadableStore[QualifiedId, SoccerMatchLiveUpdate],
nflGameScoreStore: ReadableStore[QualifiedId, NflFootballGameLiveUpdate],
semanticCoreMegadataStore: ReadableStore[SemanticEntityForQuery, EntityMegadata],
): Future[RawCandidate] = {
/**
* frigateNotification recommendation type should be [[CommonRecommendationType.MagicFanoutSportsEvent]]
* AND pushId field should be set
*
* */
require(
notification.commonRecommendationType == CommonRecommendationType.MagicFanoutSportsEvent,
"MagicFanoutSports: unexpected CRT " + notification.commonRecommendationType
)
require(
notification.magicFanoutEventNotification.exists(_.pushId.isDefined),
"MagicFanoutSportsEvent: pushId is not defined")
val magicFanoutEventNotification = notification.magicFanoutEventNotification.get
val eventId = magicFanoutEventNotification.eventId
val _isScoreUpdate = magicFanoutEventNotification.isScoreUpdate.getOrElse(false)
val gameScoresFut: Future[Option[BaseGameScore]] = {
if (_isScoreUpdate) {
semanticCoreMegadataStore
.get(SemanticEntityForQuery(PushConstants.SportsEventDomainId, eventId))
.flatMap {
case Some(megadata) =>
if (megadata.domains.contains(Domains.BasketballGame)) {
basketballGameScoreStore
.get(QualifiedId(Domains.BasketballGame.value, eventId)).map {
case Some(game) if game.status.isDefined =>
val status = game.status.get
MagicFanoutSportsUtil.transformToGameScore(game.score, status)
case _ => None
}
} else if (megadata.domains.contains(Domains.BaseballGame)) {
baseballGameScoreStore
.get(QualifiedId(Domains.BaseballGame.value, eventId)).map {
case Some(game) if game.status.isDefined =>
val status = game.status.get
MagicFanoutSportsUtil.transformToGameScore(game.runs, status)
case _ => None
}
} else if (megadata.domains.contains(Domains.NflFootballGame)) {
nflGameScoreStore
.get(QualifiedId(Domains.NflFootballGame.value, eventId)).map {
case Some(game) if game.status.isDefined =>
val nflScore = MagicFanoutSportsUtil.transformNFLGameScore(game)
nflScore
case _ => None
}
} else if (megadata.domains.contains(Domains.SoccerMatch)) {
soccerMatchScoreStore
.get(QualifiedId(Domains.SoccerMatch.value, eventId)).map {
case Some(game) if game.status.isDefined =>
val soccerScore = MagicFanoutSportsUtil.transformSoccerGameScore(game)
soccerScore
case _ => None
}
} else {
// The domains are not in our list of supported sports
throw new InvalidSportDomainException(
s"Domain for entity ${eventId} is not supported")
}
case _ => Future.None
}
} else Future.None
}
val homeTeamInfoFut: Future[Option[TeamInfo]] = gameScoresFut.flatMap {
case Some(gameScore) =>
MagicFanoutSportsUtil.getTeamInfo(gameScore.home, semanticCoreMegadataStore)
case _ => Future.None
}
val awayTeamInfoFut: Future[Option[TeamInfo]] = gameScoresFut.flatMap {
case Some(gameScore) =>
MagicFanoutSportsUtil.getTeamInfo(gameScore.away, semanticCoreMegadataStore)
case _ => Future.None
}
val candidate = new RawCandidate
with MagicFanoutSportsEventCandidate
with MagicFanoutSportsScoreInformation {
override val target: Target = targetUser
override val eventId: Long = magicFanoutEventNotification.eventId
override val pushId: Long = magicFanoutEventNotification.pushId.get
override val candidateMagicEventsReasons: Seq[MagicEventsReason] =
magicFanoutEventNotification.eventReasons.getOrElse(Seq.empty)
override val momentId: Option[Long] = magicFanoutEventNotification.momentId
override val eventLanguage: Option[String] = magicFanoutEventNotification.eventLanguage
override val details: Option[MagicFanoutEventNotificationDetails] =
magicFanoutEventNotification.details
override val frigateNotification: FrigateNotification = notification
override val homeTeamInfo: Future[Option[TeamInfo]] = homeTeamInfoFut
override val awayTeamInfo: Future[Option[TeamInfo]] = awayTeamInfoFut
override val gameScores: Future[Option[BaseGameScore]] = gameScoresFut
override val isScoreUpdate: Boolean = _isScoreUpdate
}
Future.value(candidate)
}