Skip to content

Instantly share code, notes, and snippets.

View negator's full-sized avatar

Naveen Gattu negator

View GitHub Profile
@negator
negator / Url.scala
Last active December 10, 2015 01:48
General purpose Url class for silky smooth url string manipulation and sugary Play! WS integration. Enjoy responsibly.
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:
@negator
negator / paging.scala
Last active May 18, 2017 15:15
Example paging enumerator using Play! WS.
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
@negator
negator / buildActivity.scala
Last active December 10, 2015 02:19
Build an activity from a post, using its associated like and comments.
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)
@negator
negator / activites.scala
Last active December 10, 2015 02:19
An enumerator of enumerator of activities
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
}
@negator
negator / flatten.scala
Last active December 10, 2015 02:18
The flattenEnumerator function, which converts an Enumerator of Enumerators into an Enumerator
/*
* 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))
/*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].
*/
@negator
negator / flatMap.scala
Last active December 10, 2015 02:18
flatMap for Enumerateess
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))
@negator
negator / stats.scala
Last active December 10, 2015 02:58
Status updating and reporting iteratee
/* 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")
}
@negator
negator / run.scala
Last active December 10, 2015 02:58
Hook up Enumerator to Enumeratee to Iteratee and run it
//The collect function below returns an Enumerator[Activity], given some target meta-data
val iterateePromise = collect(target) &> fileWriting |>> updatingCursor
iterateePromise.flatMap(_.run)
/**
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