This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import play.api.libs.ws._ | |
import play.api.libs.json._ | |
import scalaz._ | |
import Scalaz._ | |
import java.net.{ URL => JavaUrl } | |
/* This class makes url manipulation a piece of cake (dark chocolate). It also includes Play WS request generation. | |
Requires scalaz6 and Play 2.0.4 | |
Examples: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import play.api.libs.ws._ | |
import play.api.libs.iteratee._ | |
def pagingEnumerator(url:String):Enumerator[JsValue]={ | |
var maybeNextUrl = Some(url) //Next url to fetch | |
Enumerator.fromCallback[JsValue] ( retriever = { | |
val maybeResponsePromise = | |
maybeNextUrl map { nextUrl=> | |
WS.url(nextUrl).get.map { reponse => | |
val json = response.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type CommentsOrLikes = Either[Comments, Likes] | |
def buildActivity(post: Post): Promise[Activity] = { | |
val likeUrl = LIKE_URL % (post.id, target.token) | |
val commentsUrl = COMMENT_URL % (post.id, target.token) | |
/*Construct paging enumerators, mapping each value to either Left or Right*/ | |
val comments = pagingEnumerator(commentsUrl).map(Left.apply) | |
val likes = pagingEnumerator(likeUrl).map(Right.apply) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val posts:Enumerator[List[Post]] = pagingEnumerator(postsUrl) map parseToPostList | |
/* parseToPostList does exactly that. Creates a list of Post objects from json*/ | |
val activities:Enumerator[Enumerator[Activity]] = posts.map{ | |
postList => | |
Enumerator.apply(postList:_*) map buildActivity | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Flatten an enumerator of enumerators of some type into an enumerator of some type | |
*/ | |
def flatten[T](enumerator: Enumerator[Enumerator[T]]): Enumerator[T] = new Enumerator[T] { | |
def step[A](it: Iteratee[T, A])(in: Input[Enumerator[T]]): Iteratee[Enumerator[T], Iteratee[T, A]] = { | |
in match { | |
case Input.EOF => Done(Iteratee.flatten(it.feed(Input.EOF)), Input.EOF) | |
case Input.Empty => Cont(step(it)) | |
case Input.El(e) => { | |
val promise = e |>> Cont(removeEof(it)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*Enumeratee to manage writing to the file writer. Mapping any errors to Left*/ | |
type ErrorOrActivity = Either[Error,Activity] | |
def fileWriting: Enumeratee[Activity, ErrorOrActivity] = { | |
/* writeToFile returns a Promise, but the Enumeratee type constraint | |
* does not expect a Promise. flatMap will return an | |
* Enumeratee[Activity,ErrorOrActivity] given a function from Activity | |
* to Promise[ErrorOrActivity]. | |
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object KloutEnumeratee { | |
def flatMapInput[From] = new { | |
def apply[To](f: Input[From] => PlayPromise[Input[To]]) = | |
new Enumeratee.CheckDone[From, To] { //Checkdone is part of the Play Iteratee library | |
def step[A](k: K[To, A]): K[From, Iteratee[To, A]] = { | |
case in @ (Input.El(_) | Input.Empty) => | |
val promiseOfInput = f(in) | |
Iteratee.flatten(promiseOfInput map { input => | |
new CheckDone[From, To] { | |
def continue[A](k: K[To, A]) = Cont(step(k)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Status updating and reporting iteratee*/ | |
def updatingStatus:Iteratee[ErrorOrActivity,Unit] = Iteratee.foreach[ErrorOrActivity] { | |
case Left(error) => | |
reportError(error) | |
statsd("collector.error") | |
case Right(activity) => | |
reportSuccess(activity) | |
statsd("collector.success") | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//The collect function below returns an Enumerator[Activity], given some target meta-data | |
val iterateePromise = collect(target) &> fileWriting |>> updatingCursor | |
iterateePromise.flatMap(_.run) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
The Play (2.3) json combinator library is arguably the best in the scala world. However it doesnt | |
work with case classes with greater than 22 fields. | |
The following gist leverages the shapeless 'Automatic Typeclass Derivation' facility to work around this | |
limitation. Simply stick it in a common location in your code base, and use like so: | |
Note: ** Requires Play 2.3 and shapeless 2.0.0 | |
OlderNewer