Created
January 22, 2015 17:17
-
-
Save xfyre/c50479d105cf8a05b059 to your computer and use it in GitHub Desktop.
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
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