Skip to content
This repository has been archived by the owner on Dec 10, 2018. It is now read-only.

Commit

Permalink
iss #22: [tmp] Client.getRepos draft
Browse files Browse the repository at this point in the history
  • Loading branch information
maizy committed Aug 5, 2014
1 parent 850e6e1 commit b715b21
Showing 1 changed file with 50 additions and 17 deletions.
67 changes: 50 additions & 17 deletions app/hedgehog/clients/github/Client.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,75 @@ package hedgehog.clients.github

import scala.concurrent.{Future, Promise}
import play.api.libs.ws.WS
import play.Logger
import hedgehog.models.{AccountSettings, Repo}
import play.api.libs.json.{JsSuccess, JsError}

import hedgehog.models.{AccountSettings, Repo}

/**
* Copyright (c) Nikita Kovaliov, maizy.ru, 2014
* See LICENSE.txt for details.
*/
class Client(val config: Config, implicit val context: scala.concurrent.ExecutionContext) {

val PER_PAGE = 100

def getRepos(accountSettings: AccountSettings): Future[Seq[Repo]] = {
val finish = Promise[Seq[Repo]]()
val resultPromise = Promise[Seq[Repo]]()

val proxyError: PartialFunction[Throwable, Unit] = {
//TODO: wrap errors
case err => resultPromise.failure(err)
}
val getFirstPage = getPage(accountSettings, page = 1, perPage = PER_PAGE)

getFirstPage onSuccess {
case PageRes(res, None, None) => resultPromise.success(res)
case PageRes(firstPageRes, _, Some(last)) => {
require(last > 1)
val otherPagesRes = Future.sequence(
for {
page <- 2 to last
} yield getPage(accountSettings, page, perPage = PER_PAGE)
)
otherPagesRes onSuccess {
case otherPages => resultPromise success (firstPageRes ++ otherPages.flatMap(_.repos))
}
otherPagesRes onFailure proxyError
}
}

getFirstPage onFailure proxyError
resultPromise.future
}

private def getPage(accountSettings: AccountSettings, page: Int, perPage: Int): Future[PageRes] = {
val account = accountSettings.account
val url = config.replaceBaseUrl(account.apiReposUrl)
val httpClient = WS.url(url).withQueryString("per_page" -> "100", "page" -> "1")

val httpClient = WS.url(url).withQueryString(
"per_page" -> perPage.toString,
"page" -> page.toString
)
httpClient.get map {
response =>
Logger.debug(s"GET ${httpClient.url}")
Logger.debug(s"body: " + response.body.toString.substring(0, 100) + "...")
Logger.debug(s"headers: "+ response.getAHCResponse.getHeaders.toString)
case response =>
response.status match {
case 200 => {
finish success List(Repo("a", accountSettings.account),
Repo("b", accountSettings.account))

GithubReades.repoSeqReads.reads(response.json) match {
case JsSuccess(res, _) => {
val nextLastTMP = if (account.name == "hhru") Some(2) else None //FIXME: tmp
PageRes(res, nextPage = nextLastTMP, lastPage = nextLastTMP)
}
case JsError(err) => throw new Exception(s"Unable to parse json $err")
}
}
//TODO: custom exceptions
case code: Int if code >= 400 && code < 599 =>
finish failure new Exception("no data")
case _ => new Exception("unknown error")
case code: Int if code >= 400 && code < 599 => throw new Exception("no data")
case _ => throw new Exception("unknown error")
}
}

finish.future
}
}


private case class PageRes(repos: Seq[Repo], nextPage: Option[Int], lastPage: Option[Int]) {
val currentPage: Option[Int] = nextPage map (_ - 1)
}

0 comments on commit b715b21

Please sign in to comment.