forked from lichess-org/lila
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Push.scala
68 lines (61 loc) · 2.16 KB
/
Push.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package lila.timeline
import akka.actor._
import akka.pattern.{ ask, pipe }
import org.joda.time.DateTime
import play.api.libs.json._
import play.twirl.api.Html
import lila.hub.actorApi.lobby.NewForumPost
import lila.hub.actorApi.timeline.propagation._
import lila.hub.actorApi.timeline.{ Propagate, Atom, ForumPost, ReloadTimeline }
import lila.security.Granter
import lila.user.UserRepo
import makeTimeout.short
private[timeline] final class Push(
lobbySocket: ActorSelection,
renderer: ActorSelection,
getFriendIds: String => Fu[Set[String]],
getFollowerIds: String => Fu[Set[String]],
entryRepo: EntryRepo,
unsubApi: UnsubApi) extends Actor {
def receive = {
case Propagate(data, propagations) =>
data match {
case _: ForumPost => lobbySocket ! NewForumPost
case _ =>
}
propagate(propagations) flatMap { users =>
unsubApi.filterUnsub(data.channel, users)
} foreach { users =>
if (users.nonEmpty) makeEntry(users, data) >>-
(users foreach { u =>
lobbySocket ! ReloadTimeline(u)
})
}
}
private def propagate(propagations: List[Propagation]): Fu[List[String]] =
propagations.map {
case Users(ids) => fuccess(ids)
case Followers(id) => getFollowerIds(id)
case Friends(id) => getFriendIds(id)
case StaffFriends(id) => getFriendIds(id) flatMap UserRepo.byIds map {
_ filter Granter(_.StaffForum) map (_.id)
}
case ExceptUser(_) => fuccess(Nil)
}.sequence map { users =>
propagations.foldLeft(users.flatten.distinct) {
case (us, ExceptUser(id)) => us filter (id!=)
case (us, _) => us
}
}
private def makeEntry(users: List[String], data: Atom): Fu[Entry] =
Entry.make(users, data).fold(
fufail[Entry]("[timeline] invalid entry data " + data)
) { entry =>
entryRepo.findRecent(entry.typ, DateTime.now minusMinutes 50) flatMap { entries =>
entries.exists(_ similarTo entry) fold (
fufail[Entry]("[timeline] a similar entry already exists"),
entryRepo insert entry inject entry
)
}
}
}