integrate friend module

This commit is contained in:
Thibault Duplessis 2013-05-19 02:31:10 -03:00
parent 351da84389
commit 9566fb110d
18 changed files with 210 additions and 214 deletions

View file

@ -38,7 +38,8 @@ final class Env(config: Config, system: ActorSystem) {
Env.timeline,
Env.gameSearch,
Env.teamSearch,
Env.forumSearch)
Env.forumSearch,
Env.friend)
loginfo("[boot] Preloading complete")
if (Env.ai.isServer) println("Running as AI server")
@ -79,4 +80,5 @@ object Env {
def setup = lila.setup.Env.current
def importer = lila.importer.Env.current
def tournament = lila.tournament.Env.current
def friend = lila.friend.Env.current
}

View file

@ -1,26 +0,0 @@
package lila
package friend
import com.novus.salat.annotations.Key
import org.joda.time.DateTime
import user.User
case class Friend(
@Key("_id") id: String,
users: List[String],
date: DateTime) {
def contains(userId: String): Boolean = users contains userId
def contains(user: User): Boolean = contains(user.id)
}
object Friend {
def makeId(u1: String, u2: String) = List(u1, u2).sorted mkString "@"
def apply(u1: String, u2: String): Friend = new Friend(
id = makeId(u1, u2),
users = List(u1, u2),
date = DateTime.now)
}

View file

@ -1,48 +0,0 @@
package lila
package friend
import scalaz.effects._
import org.scala_tools.time.Imports._
import user.{ User, UserRepo }
final class FriendApi(
friendRepo: FriendRepo,
requestRepo: RequestRepo,
userRepo: UserRepo,
cached: Cached) {
def areFriends(u1: String, u2: String) = friendIds(u1) contains u2
val friendIds = cached friendIds _
def requestable(userId: String, friendId: String): IO[Boolean] =
requestRepo.exists(userId, friendId) map (!_)
def createRequest(friend: User, setup: RequestSetup, user: User): IO[Unit] = for {
able requestable(friend.id, user.id)
request = Request(user = user.id, friend = friend.id, message = setup.message)
_ requestRepo.add(request) >> io(cached invalidateNbRequests friend.id) doIf able
} yield ()
def requestsWithUsers(userId: String): IO[List[RequestWithUser]] = for {
requests requestRepo findByFriendId userId
users userRepo byOrderedIds requests.map(_.user)
} yield requests zip users map {
case (request, user) RequestWithUser(request, user)
}
def processRequest(userId: String, request: Request, accept: Boolean): IO[Unit] = for {
_ requestRepo remove request.id
_ io(cached invalidateNbRequests userId)
requesterOption userRepo byId request.user
_ ~requesterOption.map(requester
friendRepo.add(requester.id, userId) >>
io(cached.invalidateFriendIds(requester.id)) >>
io(cached.invalidateFriendIds(userId)) doIf accept
)
} yield ()
def friendsOf(userId: String): IO[List[User]] =
userRepo byIds friendIds(userId) map { _ sortBy (_.id) }
}

View file

@ -1,32 +0,0 @@
package lila
package friend
import core.Settings
import user.UserRepo
import message.LichessThread
import com.mongodb.casbah.MongoCollection
import scalaz.effects._
final class FriendEnv(
settings: Settings,
userRepo: UserRepo,
sendMessage: LichessThread IO[Unit],
mongodb: String MongoCollection) {
import settings._
lazy val friendRepo = new FriendRepo(mongodb(FriendCollectionFriend))
lazy val requestRepo = new RequestRepo(mongodb(FriendCollectionRequest))
lazy val api = new FriendApi(
friendRepo = friendRepo,
requestRepo = requestRepo,
userRepo = userRepo,
cached = cached)
lazy val forms = new DataForm(friendRepo)
lazy val cached = new Cached(friendRepo, requestRepo)
}

View file

@ -1,32 +0,0 @@
package lila
package friend
import com.novus.salat._
import com.novus.salat.dao._
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.query.Imports._
import scalaz.effects._
import org.joda.time.{ DateTime, Period }
import org.scala_tools.time.Imports._
import user.User
private[friend] final class FriendRepo(collection: MongoCollection)
extends SalatDAO[Friend, String](collection) {
def byId(id: String): IO[Option[Friend]] = io { findOneById(id) }
def friendUserIds(userId: String): IO[List[String]] = io {
collection.find(
DBObject("users" -> userId),
DBObject("users" -> true)
).map(_.getAs[List[String]]("users")).flatten.toList.flatten.filterNot(userId ==)
}
def add(u1: String, u2: String) = io {
insert(Friend(u1, u2))
}
def selectId(id: String): DBObject = DBObject("_id" -> id)
def selectId(friend: Friend): DBObject = selectId(friend.id)
}

View file

@ -1,44 +0,0 @@
package lila
package friend
import com.novus.salat._
import com.novus.salat.dao._
import com.mongodb.casbah.MongoCollection
import com.mongodb.casbah.Imports._
import scalaz.effects._
import org.joda.time.DateTime
// db.friend_request.ensureIndex({friend:1})
// db.friend_request.ensureIndex({date: -1})
private[friend] final class RequestRepo(collection: MongoCollection)
extends SalatDAO[Request, String](collection) {
def byId(id: String): IO[Option[Request]] = io { findOneById(id) }
def exists(userId: String, friendId: String): IO[Boolean] = io {
collection.find(idQuery(userId, friendId)).limit(1).size != 0
}
def find(userId: String, friendId: String): IO[Option[Request]] = io {
findOneById(id(userId, friendId))
}
def countByFriendId(friendId: String): IO[Int] = io {
count(friendIdQuery(friendId)).toInt
}
def findByFriendId(friendId: String): IO[List[Request]] = io {
find(friendIdQuery(friendId)).toList
}
def idQuery(userId: String, friendId: String) = DBObject("_id" -> id(userId, friendId))
def idQuery(id: String) = DBObject("_id" -> id)
def id(friendId: String, userId: String) = Request.makeId(friendId, userId)
def friendIdQuery(friendId: String) = DBObject("friend" -> friendId)
def sortQuery(order: Int = -1) = DBObject("date" -> order)
def add(request: Request): IO[Unit] = io { insert(request) }
def remove(id: String): IO[Unit] = io { remove(idQuery(id)) }
}

View file

@ -1,8 +0,0 @@
@(u: User, games: Paginator[DbGame], filters: lila.user.GameFilterMenu)(implicit ctx: Context)
<div class="games infinitescroll all_games">
@games.nextPage.map { np =>
<div class="pager none"><a href="@routes.User.showFilter(u.username, filters.current.name, np)">Next</a></div>
}
@game.widgets(games.currentPageResults, user = u.some, ownerLink = ctx is u)
</div>

View file

@ -5,11 +5,8 @@ import lila.db.api._
import tube.bookmarkTube
import play.api.libs.json._
import play.modules.reactivemongo.json.ImplicitBSONHandlers._
import org.joda.time.DateTime
import scala.concurrent.Future
case class Bookmark(game: lila.game.Game, user: lila.user.User)

View file

@ -1,13 +1,10 @@
package lila
package friend
package lila.friend
import user.User
import lila.user.User
import scala.collection.mutable
private[friend] final class Cached(
friendRepo: FriendRepo,
requestRepo: RequestRepo) {
private[friend] final class Cached {
def friendIds(userId: String): List[String] = FriendIdsCache(userId)
def invalidateFriendIds(userId: String) { FriendIdsCache invalidate userId }
@ -17,8 +14,9 @@ private[friend] final class Cached(
private object NbRequestsCache {
//TODO fix that crap
def apply(userId: String): Int = cache.getOrElseUpdate(userId,
(requestRepo countByFriendId userId).unsafePerformIO
(RequestRepo countByFriendId userId).await
)
def invalidate(userId: String) { cache -= userId }
@ -30,7 +28,7 @@ private[friend] final class Cached(
private object FriendIdsCache {
def apply(userId: String): List[String] = cache.getOrElseUpdate(userId,
(friendRepo friendUserIds userId).unsafePerformIO
(FriendRepo friendUserIds userId).await
)
def invalidate(userId: String) { cache -= userId }

View file

@ -1,13 +1,10 @@
package lila
package friend
package lila.friend
import play.api.data._
import play.api.data.Forms._
import play.api.data.validation.Constraints._
private[friend] final class DataForm(repo: FriendRepo) {
import lila.core.Form._
private[friend] final class DataForm {
}
private[friend] case class RequestSetup(

View file

@ -0,0 +1,38 @@
package lila.friend
import com.typesafe.config.Config
import lila.common.PimpedConfig._
import akka.actor._
import akka.pattern.pipe
final class Env(
config: Config,
db: lila.db.Env,
hub: lila.hub.Env) {
private val CollectionFriend = config getString "collection.friend"
private val CollectionRequest = config getString "collection.request"
// lazy val api = new FriendApi(
// friendRepo = friendRepo,
// requestRepo = requestRepo,
// userRepo = userRepo,
// cached = cached)
lazy val forms = new DataForm
lazy val cached = new Cached
private[friend] lazy val friendColl = db(CollectionFriend)
private[friend] lazy val requestColl = db(CollectionRequest)
}
object Env {
private def app = play.api.Play.current
lazy val current = "[boot] friend" describes new Env(
config = lila.common.PlayApp loadConfig "game",
db = lila.db.Env.current,
hub = lila.hub.Env.current)
}

View file

@ -0,0 +1,30 @@
package lila.friend
import org.joda.time.DateTime
import lila.user.User
case class Friend(id: String, users: List[String], date: DateTime) {
def contains(userId: String): Boolean = users contains userId
def contains(user: User): Boolean = contains(user.id)
}
object Friend {
def makeId(u1: String, u2: String) = List(u1, u2).sorted mkString "@"
def make(u1: String, u2: String): Friend = new Friend(
id = makeId(u1, u2),
users = List(u1, u2),
date = DateTime.now)
import lila.db.Tube
import Tube.Helpers._
import play.api.libs.json._
private[friend] lazy val tube = Tube[Friend](
__.json update readDate('date) andThen Json.reads[Friend],
Json.writes[Friend] andThen (__.json update writeDate('date))
)
}

View file

@ -0,0 +1,46 @@
package lila.friend
import org.scala_tools.time.Imports._
import lila.user.{ User, UserRepo }
// final class FriendApi(
// friendRepo: FriendRepo,
// requestRepo: RequestRepo,
// userRepo: UserRepo,
// cached: Cached) {
// def areFriends(u1: String, u2: String) = friendIds(u1) contains u2
// val friendIds = cached friendIds _
// def requestable(userId: String, friendId: String): IO[Boolean] =
// requestRepo.exists(userId, friendId) map (!_)
// def createRequest(friend: User, setup: RequestSetup, user: User): IO[Unit] = for {
// able requestable(friend.id, user.id)
// request = Request(user = user.id, friend = friend.id, message = setup.message)
// _ requestRepo.add(request) >> io(cached invalidateNbRequests friend.id) doIf able
// } yield ()
// def requestsWithUsers(userId: String): IO[List[RequestWithUser]] = for {
// requests requestRepo findByFriendId userId
// users userRepo byOrderedIds requests.map(_.user)
// } yield requests zip users map {
// case (request, user) RequestWithUser(request, user)
// }
// def processRequest(userId: String, request: Request, accept: Boolean): IO[Unit] = for {
// _ requestRepo remove request.id
// _ io(cached invalidateNbRequests userId)
// requesterOption userRepo byId request.user
// _ ~requesterOption.map(requester
// friendRepo.add(requester.id, userId) >>
// io(cached.invalidateFriendIds(requester.id)) >>
// io(cached.invalidateFriendIds(userId)) doIf accept
// )
// } yield ()
// def friendsOf(userId: String): IO[List[User]] =
// userRepo byIds friendIds(userId) map { _ sortBy (_.id) }
// }

View file

@ -0,0 +1,20 @@
package lila.friend
import lila.db.Implicits._
import lila.db.api._
import tube.friendTube
import play.api.libs.json._
import org.joda.time.DateTime
private[friend] object FriendRepo {
def byId(id: String): Fu[Option[Friend]] = $find byId id
def friendUserIds(userId: String): Fu[List[String]] =
$primitive(Json.obj("users" -> userId), "users")(_.asOpt[List[String]]) map {
_.flatten filterNot (userId ==)
}
def add(u1: String, u2: String): Funit = $insert(Friend.make(u1, u2))
}

View file

@ -1,13 +1,11 @@
package lila
package friend
package lila.friend
import user.User
import lila.user.User
import com.novus.salat.annotations.Key
import org.joda.time.DateTime
case class Request(
@Key("_id") id: String,
id: String,
user: String,
friend: String,
message: String,
@ -18,12 +16,21 @@ object Request {
def makeId(user: String, friend: String) = user + "@" + friend
def apply(user: String, friend: String, message: String): Request = new Request(
def make(user: String, friend: String, message: String): Request = new Request(
id = makeId(user, friend),
user = user,
friend = friend,
message = message.trim,
date = DateTime.now)
import lila.db.Tube
import Tube.Helpers._
import play.api.libs.json._
private[friend] lazy val tube = Tube[Request](
__.json update readDate('date) andThen Json.reads[Request],
Json.writes[Request] andThen (__.json update writeDate('date))
)
}
case class RequestWithUser(request: Request, user: User) {

View file

@ -0,0 +1,32 @@
package lila.friend
import lila.db.Implicits._
import lila.db.api._
import tube.requestTube
import play.api.libs.json._
import org.joda.time.DateTime
// db.friend_request.ensureIndex({friend:1})
// db.friend_request.ensureIndex({date: -1})
private[friend] object RequestRepo {
def byId(id: String): Fu[Option[Request]] = $find byId id
def exists(userId: String, friendId: String): Fu[Boolean] =
$count.exists(idQuery(userId, friendId))
def find(userId: String, friendId: String): Fu[Option[Request]] =
$find byId id(userId, friendId)
def countByFriendId(friendId: String): Fu[Int] =
$count(friendIdQuery(friendId))
def findByFriendId(friendId: String): Fu[List[Request]] =
$find(friendIdQuery(friendId))
def idQuery(userId: String, friendId: String) = Json.obj("_id" -> id(userId, friendId))
def id(friendId: String, userId: String) = Request.makeId(friendId, userId)
def friendIdQuery(friendId: String) = Json.obj("friend" -> friendId)
def sortQuery(order: Int = -1) = Json.obj("date" -> order)
}

View file

@ -0,0 +1,15 @@
package lila
import lila.db.Tube
package object friend extends PackageObject with WithPlay {
object tube {
private[friend] implicit lazy val friendTube =
Friend.tube inColl Env.current.friendColl
private[friend] implicit lazy val requestTube =
Request.tube inColl Env.current.requestColl
}
}

View file

@ -26,7 +26,7 @@ object ApplicationBuild extends Build {
message, notification, i18n, game, bookmark, search,
gameSearch, timeline, forum, forumSearch, team, teamSearch,
ai, analyse, mod, monitor, site, round, lobby, setup,
importer, tournament)
importer, tournament, friend)
lazy val moduleRefs = modules map projectToRef
lazy val moduleCPDeps = moduleRefs map classpathDependency
@ -117,6 +117,10 @@ object ApplicationBuild extends Build {
play.api, reactivemongo, playReactivemongo, spray.caching)
)
lazy val friend = project("friend", Seq(common, db, memo, hub, user)).settings(
libraryDependencies ++= provided(play.api, reactivemongo, playReactivemongo)
)
lazy val message = project("message", Seq(common, db, user, hub)).settings(
libraryDependencies ++= provided(
play.api, reactivemongo, playReactivemongo, spray.caching)