API endpoints to follow/unfollow other players - closes #7920

pull/9637/head
Thibault Duplessis 2021-08-23 11:17:59 +02:00
parent e7ae31146d
commit 2f1b8c914d
5 changed files with 42 additions and 10 deletions

View File

@ -421,10 +421,12 @@ final class Api(
def toHttp(result: ApiResult): Result =
result match {
case Limited => rateLimitedJson
case NoData => NotFound
case Custom(result) => result
case Data(json) => JsonOk(json)
case Limited => rateLimitedJson
case ClientError(msg) => BadRequest(jsonError(msg))
case NoData => NotFound
case Custom(result) => result
case Done => jsonOkResult
case Data(json) => JsonOk(json)
}
def jsonStream(makeSource: => Source[JsValue, _])(implicit req: RequestHeader): Result =
@ -491,8 +493,10 @@ final class Api(
private[controllers] object Api {
sealed trait ApiResult
case class Data(json: JsValue) extends ApiResult
case object NoData extends ApiResult
case object Limited extends ApiResult
case class Custom(result: Result) extends ApiResult
case class Data(json: JsValue) extends ApiResult
case class ClientError(msg: String) extends ApiResult
case object NoData extends ApiResult
case object Done extends ApiResult
case object Limited extends ApiResult
case class Custom(result: Result) extends ApiResult
}

View File

@ -65,6 +65,20 @@ final class Relation(
}(rateLimitedFu)
}
def apiFollow(userId: String) =
Scoped(_.Follow.Write) { _ => me =>
FollowLimitPerUser[Fu[Api.ApiResult]](me.id) {
api.reachedMaxFollowing(me.id) flatMap {
case true =>
fuccess(
Api.ClientError(lila.msg.MsgPreset.maxFollow(me.username, env.relation.maxFollow.value).text)
)
case _ =>
api.follow(me.id, UserModel normalize userId).nevermind inject Api.Done
}
}(fuccess(Api.Limited)) map apiC.toHttp
}
def unfollow(userId: String) =
Auth { implicit ctx => me =>
FollowLimitPerUser(me.id) {
@ -72,6 +86,13 @@ final class Relation(
}(rateLimitedFu)
}
def apiUnfollow(userId: String) =
Scoped(_.Follow.Write) { _ => me =>
FollowLimitPerUser[Fu[Api.ApiResult]](me.id) {
api.unfollow(me.id, UserModel normalize userId) inject Api.Done
}(fuccess(Api.Limited)) map apiC.toHttp
}
def block(userId: String) =
Auth { implicit ctx => me =>
FollowLimitPerUser(me.id) {

View File

@ -38,6 +38,8 @@ GET /api/tv/:chanKey controllers.Tv.apiGamesChannel(chanKey: S
# Relation
POST /rel/follow/:userId controllers.Relation.follow(userId: String)
POST /rel/unfollow/:userId controllers.Relation.unfollow(userId: String)
POST /api/rel/follow/:userId controllers.Relation.apiFollow(userId: String)
POST /api/rel/unfollow/:userId controllers.Relation.apiUnfollow(userId: String)
POST /rel/block/:userId controllers.Relation.block(userId: String)
POST /rel/unblock/:userId controllers.Relation.unblock(userId: String)
GET /@/:username/following controllers.Relation.following(username: String, page: Int ?= 1)

View File

@ -39,6 +39,10 @@ object OAuthScope {
case object Write extends OAuthScope("team:write", "Join, leave, and manage teams")
}
object Follow {
case object Write extends OAuthScope("follow:write", "Follow and unfollow other players")
}
object Msg {
case object Write extends OAuthScope("msg:write", "Send private messages to other players")
}
@ -75,6 +79,7 @@ object OAuthScope {
Puzzle.Read,
Team.Read,
Team.Write,
Follow.Write,
Msg.Write,
Board.Play,
Bot.Play,

View File

@ -201,14 +201,14 @@ final class RelationApi(
def unfollow(u1: ID, u2: ID): Funit =
(u1 != u2) ?? {
fetchFollows(u1, u2) flatMap {
case true =>
_ ?? {
repo.unfollow(u1, u2) >>- {
countFollowersCache.update(u2, _ - 1)
countFollowingCache.update(u1, _ - 1)
Bus.publish(lila.hub.actorApi.relation.UnFollow(u1, u2), "relation")
lila.mon.relation.unfollow.increment().unit
}
case _ => funit
}
}
}