Skip to content

Instantly share code, notes, and snippets.

@xfyre
Created January 22, 2015 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xfyre/c50479d105cf8a05b059 to your computer and use it in GitHub Desktop.
Save xfyre/c50479d105cf8a05b059 to your computer and use it in GitHub Desktop.
package com.xdance.services
import spray.can.Http
import spray.http._
import spray.json.JsonFormat
import spray.json.DefaultJsonProtocol
import spray.httpx.SprayJsonSupport
import spray.client.pipelining._
import scala.concurrent._
import scala.collection.JavaConversions._
import duration._
import akka.actor.ActorSystem
import akka.pattern.ask
import akka.event.Logging
import akka.io.IO
import com.xdance.entities.Participant
import com.xdance.entities.Affiliation
import com.xdance.entities.AffiliationWsdc
import com.xdance.entities.AffiliationHsa
import com.xdance.enums.WsdcDivision
import com.xdance.enums.ContestSignupRole
import com.xdance.enums.DivisionEligibility
import scala.util.Try
import scala.util.Success
import scala.util.Failure
import com.xdance.enums.Affiliations
class AffiliationSupportImpl extends AffiliationSupport {
def checkCompetitorEligibility(competitor: Participant, affiliation: Affiliation, affiliationDivision: Enum[_ <: Any], role: ContestSignupRole): DivisionEligibility = {
affiliation.getAffiliationType match {
// WSDC level check
case Affiliations.WSDC => Option(affiliationDivision) match {
case Some(division: WsdcDivision) => {
val allowedDivisions = getAllowedDivisions(competitor, affiliation, role).asInstanceOf[Map[WsdcDivision, DivisionEligibility]]
allowedDivisions.get(division) match {
case Some(eligibility) => eligibility
case None => DivisionEligibility.UNKNOWN
}
}
// contest doesn't belong to affiliated division
case _ => DivisionEligibility.UNKNOWN
}
// HSA level check -- NOT IMPLEMENTED YET
case Affiliations.HSA => DivisionEligibility.UNKNOWN
case _ => DivisionEligibility.UNKNOWN
}
}
def getAllowedDivisions(competitor: Participant, affiliation: Affiliation, role: ContestSignupRole): Map[Any, DivisionEligibility] = {
affiliation.getAffiliationType match {
case Affiliations.WSDC => {
def divisionInfoPoints(divisionInfo: DivisionInfo) = role match {
case ContestSignupRole.LEADER => divisionInfo.leader_points
case ContestSignupRole.FOLLOWER => divisionInfo.follower_points
case _ => 0
}
def divisionInfoPlacements(divisionInfo: DivisionInfo) = role match {
case ContestSignupRole.LEADER => divisionInfo.leader_placements
case ContestSignupRole.FOLLOWER => divisionInfo.follower_placements
case _ => Array()
}
def divisionInfo(wsdcResponse: WsdcResponse, division: WsdcDivision) = {
wsdcResponse.results.flatMap(_.divisions).find(_.name.equalsIgnoreCase(division.toWsdcString))
}
val divisionsWithoutPointRequirements = Map(WsdcDivision.NEWCOMER -> DivisionEligibility.OK, WsdcDivision.NOVICE -> DivisionEligibility.OK)
Option(competitor.getWsdcNumber) match {
case Some(wsdcNumber) => {
Option(getWsdcRegistryInfo(wsdcNumber)) match {
// have valid WSDC database response
case Some(wsdcResponse) => WsdcDivision.values.map {
/* check if competitor has points, we have to meet the following criteria
* 1) competitor has enough points in lower division (for Intermediate, Advanced, All-Star)
* 2) competitor has no points in upper division (for Newcomer, Novice, Intermediate)
* 3) competitor doesn't have BOTH 1st place and enough points in current division
*/
thisDivision: WsdcDivision => {
val maybePrevDiv = Option(thisDivision.getPrevDivision)
val maybeNextDiv = Option(thisDivision.getNextDivision)
val maybePointsReq = Option(thisDivision.getMinimumPointsForNextDivision)
val allowFromNext = thisDivision.isCompetitorFromNextDivisionAllowed
val maybeThisDivisionInfo = divisionInfo(wsdcResponse, thisDivision)
val maybePrevDivisionInfo = maybePrevDiv.flatMap { divisionInfo(wsdcResponse, _) }
val maybeNextDivisionInfo = maybeNextDiv.flatMap { divisionInfo(wsdcResponse, _) }
val prevDivisionCheckPassed = maybePrevDiv match {
case Some(division) => Option(division.getMinimumPointsForNextDivision) match {
case Some(minPoints) => maybePrevDivisionInfo match {
case Some(divInfo) => divisionInfoPoints(divInfo) >= minPoints
case None => false
}
case None => true
}
case None => true
}
val thisDivisionCheckPassed = maybeThisDivisionInfo match {
case Some(divInfo) => Option(thisDivision.getMinimumPointsForNextDivision) match {
case Some(minPoints) => ! ( divisionInfoPlacements(divInfo).exists(_.result == 1) && divisionInfoPoints(divInfo) >= minPoints)
case None => true
}
case None => true
}
val nextDivisionCheckPassed = maybeNextDiv match {
case Some(division) => division.isCompetitorFromNextDivisionAllowed || maybeNextDivisionInfo.isEmpty
case None => true
}
(prevDivisionCheckPassed, nextDivisionCheckPassed, thisDivisionCheckPassed) match {
case (true, true, true) => (thisDivision -> DivisionEligibility.OK)
case (_, _, false) => (thisDivision -> DivisionEligibility.TOO_MANY_POINTS_WITH_1ST_PLACE)
case (_, false, _) => (thisDivision -> DivisionEligibility.HAS_NEXT_DIVISION_POINTS)
case (false, _, _) => (thisDivision -> DivisionEligibility.NOT_ENOUGH_POINTS)
case _ => (thisDivision -> DivisionEligibility.NOT_ELIGIBLE)
}
}
} toMap
// we don't have a valid response -- return empty map
case None => Map()
}
}
// competitor doesn't have WSDC number
case None => divisionsWithoutPointRequirements toMap
}
}
// TODO: HSA allowed divisions -- NOT IMPLEMENTED YET
case Affiliations.HSA => Map()
case _ => Map()
}
}
def getWsdcRegistryInfo(wsdcNumber: Int) = {
object WsdcJsonProtocol extends DefaultJsonProtocol {
implicit val wsdcRequestFormat = jsonFormat1(WsdcRequest)
implicit val placementInfoFormat = jsonFormat2(PlacementInfo)
implicit val divisionInfoFormat = jsonFormat5(DivisionInfo)
implicit val danceInfoFormat = jsonFormat2(DanceInfo)
implicit val wsdcResponseFormat = jsonFormat3(WsdcResponse)
}
implicit val system = ActorSystem("wsdc-request")
import system.dispatcher
import SprayJsonSupport._
import WsdcJsonProtocol._
val url = "http://swingdancecouncil.herokuapp.com/pages/dancer_point_history.json"
val pipeline: HttpRequest => Future[WsdcResponse] = sendReceive ~> unmarshal[WsdcResponse]
val response: Future[WsdcResponse] = pipeline(Post(url, WsdcRequest(wsdcNumber)))
Await.ready(response, 10 seconds).value.get match {
case Success(response) => response
case Failure(failure) => null
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment