framework
framework copied to clipboard
Add helpers to URL rewriting so it's more DSLy
Some code that can help us create a better DSL:
import net.liftweb.http._
import net.liftweb.http.LiftRules
import com.gu.sport.microapp.Endpoints
import org.joda.time.format.DateTimeFormat
import net.liftweb.util.Helpers._
import com.gu.management.{Manifest, Management}
import net.liftweb.util.NamedPF
import net.liftweb.common.Empty
import com.gu.sport.microapp.snippet.Scoped
import org.joda.time.{DateTimeZone, DateMidnight, DateTime}
import com.gu.sport.microapp.repository.{SportMicroappMatchRepository, SportMicroappCompetitionRepository, SportMicroappMatchSearcher}
import com.gu.opta.model.match
.Match
import com.gu.opta.model.competition.{Matches, TeamMatches, Competition}
class Boot { SportMicroappMatchSearcher.start SportMicroappCompetitionRepository.start
def boot = {
DateTimeZone setDefault(DateTimeZone forID ("Europe/London"))
LiftRules.addToPackages("com.gu.sport.microapp")
LiftRules.early.append(_.setCharacterEncoding("UTF-8"))
// Render view templates as HTML5 by default
LiftRules.htmlProperties.default.set((r: Req) => new Html5Properties(r.userAgent))
LiftRules.autoIncludeAjax = _ => false
LiftRules.autoIncludeComet = _ => false
LiftRules.enableContainerSessions = false
LiftRules.getLiftSession = req => new LiftSession(req.contextPath, "dummySession", Empty)
LiftRules.sessionCreator = (i1, i2) => error("no sessions here please")
//all paths are stateless (removes lift_page JS on bottom of page
LiftRules.statelessTest.prepend({
case _ => true
})
LiftRules.defaultHeaders = {
case _ =>
List("Date" -> nowAsInternetDate, "Cache-Control" -> "public, max-age=60")
}
object DatedPath {
val fmt = DateTimeFormat.forPattern("yyyyMMMdd")
def unapply(datedPath: List[String]): Option[DateMidnight] = datedPath match {
case year::month::day::postfix::Nil => tryo(fmt.parseDateTime(year+month+day).toDateMidnight)
case _ => None
}
}
object DatedMatch {
val fmt = DateTimeFormat.forPattern("yyyyMMMdd")
val IdBased = """(\d+)""".r
val TeamBased = """([\w|-]+)-v-([\w|-]+)""".r
def unapply(datedPath: List[String]): Option[Match] = datedPath match {
case year::month::day::IdBased(matchId)::Nil => tryo {
val matchDate = fmt.parseDateTime(year+month+day).toDateMidnight
val theMatch = SportMicroappMatchRepository.getMatch(matchId)
if (theMatch.dateTime.toDateMidnight != matchDate) throw new IllegalStateException("Url date and match date do not match")
theMatch
}
case year::month::day::TeamBased(homeTeam, awayTeam)::Nil => {
tryo {
SportMicroappCompetitionRepository.findMatchSummary(fmt.parseDateTime(year+month+day), homeTeam, awayTeam) match {
case Some(summary) => SportMicroappMatchRepository.getMatch(summary.id)
case _ => throw new IllegalStateException("Url date and match date do not match")
}
}
}
case _ => None
}
}
object MatchesFromWordsForUrl {
def unapply(wordsForUrl: String): Option[Matches] = SportMicroappCompetitionRepository.getMatchesFor(wordsForUrl)
}
object MatchId {
def unapply(matchId: String): Option[Match] = tryo{SportMicroappMatchRepository.getMatch(matchId)}
}
//TODO see if this can sensibly be moved to its own file
LiftRules.statelessRewrite.prepend(NamedPF("resources") {
// /resource/football/2011/jan/01/matches
case RewriteRequest(ParsePath("resource" :: "football" :: DatedPath(date), _, _, _), _, _) => {
Scoped.date.set(date)
RewriteResponse("resource" :: "football" :: "matches-on-date" :: Nil, Map.empty[String, String])
}
// /resource/football/matches
case RewriteRequest(ParsePath("resource" :: "football" :: "matches" :: Nil, _, _, _), _, _) =>
RewriteResponse("resource" :: "football" :: "matches-on-date" :: Nil, Map.empty[String, String])
// /resource/football/match/2011/jan/02/1234/popup
// /resource/football/match/2011/jan/02/everton-chelsea/popup
case RewriteRequest(ParsePath("resource" :: "football" :: "match-popup" :: DatedMatch(theMatch), _, _, _), _, _) => {
Scoped.theMatch.set(theMatch)
RewriteResponse("resource" :: "football" :: "match-stats-popup" :: Nil, Map.empty[String, String])
}
// /resource/football/match/2011/jan/02/1234
// /resource/football/match/2011/jan/02/everton-v-chelsea
case RewriteRequest(ParsePath("resource" :: "football" :: "match" :: DatedMatch(theMatch), _, _, _), _, _) => {
Scoped.theMatch.set(theMatch)
RewriteResponse("resource" :: "football" :: "match-stats" :: Nil, Map.empty[String, String])
}
// /resource/football/premierleague/fixtures
// /resource/football/everton/fixtures
case RewriteRequest(ParsePath("resource" :: "football" :: MatchesFromWordsForUrl(matches) :: "fixtures" :: Nil, _, _, _), _, _) => {
Scoped.matches.set(matches)
RewriteResponse("resource" :: "football" :: "fixtures" :: Nil, Map.empty[String, String])
}
// /resource/football/premierleague/results
// /resource/football/everton/results
case RewriteRequest(ParsePath("resource" :: "football" :: MatchesFromWordsForUrl(matches) :: "results" :: Nil, _, _, _), _, _) => {
Scoped.matches.set(matches)
RewriteResponse("resource" :: "football" :: "results" :: Nil, Map.empty[String, String])
}
//TODO make me work
// /resource/football/premierleague/tables
case RewriteRequest(ParsePath("resource" :: "football" :: standings :: "tables" :: Nil, _, _, _), _, _) => {
RewriteResponse("resource" :: "football" :: "tables" :: Nil, Map("optaId" -> standings))
}
})
object CompetitionId {
val CompetitionRegex = """(\d+)/(\d+)""".r
def unapply(id: List[String]): Option[Competition] = id.mkString("/") match {
case CompetitionRegex(id, season) => tryo{SportMicroappCompetitionRepository.getCompetition(id, season)}
case _ => None
}
}
object TeamId {
val TeamRegex = """(\d+)""".r
def unapply(id: String): Option[TeamMatches] = id match {
case TeamRegex(id) => tryo{
val fromDate = new DateTime().minusMonths(6)
SportMicroappCompetitionRepository.getMatchesForTeam(id, Some(fromDate), None)
}
case _ => None
}
}
LiftRules.statelessRewrite.prepend(NamedPF("components") {
// /component/football/tournament-fixtures/1234
case RewriteRequest(ParsePath("component" :: "football" :: "competition-summary" ::CompetitionId(competition), _, _, _), _, _) =>
Scoped.competition.set(competition)
RewriteResponse("component" :: "football" :: "competition-summary" :: Nil, Map.empty[String, String])
case RewriteRequest(ParsePath("component" :: "football" :: "team-summary" ::TeamId(team):: Nil, _, _, _), _, _) =>
Scoped.team.set(team)
RewriteResponse("component" :: "football" :: "team-summary" :: Nil, Map.empty[String, String])
// /component/football/tabs-and-score/1234
case RewriteRequest(ParsePath("component" :: "football" :: "tabs-and-score" :: MatchId(theMatch) :: Nil, _, _, _), _, _) => {
Scoped.theMatch.set(theMatch)
RewriteResponse("component" :: "football" :: "tabs-and-score" :: Nil, Map.empty[String, String])
}
// /component/football/calendar
//probably does not need a rewrite
})
LiftRules.statelessDispatchTable
.append(Endpoints)
.append(Management.publishWithIndex(Manifest))
} }
Updating tickets (#919, #938, #950, #956, #976, #980, #982, #999, #1008, #1024, #1025, #1032, #1034, #1051)
Updating tickets (#950, #956, #976, #980, #982, #999, #1008, #1053, #1078, #1092, #1097)
Pushed pending tickets to 2.4-M5
Updating tickets (#956, #976, #980, #982, #1008, #1053, #1078, #1092, #1097, #1128)
Updating tickets (#906, #950, #956, #960, #976, #980, #982, #997, #999, #1008, #1053, #1078, #1090, #1092, #1097, #1128, #1134, #1155, #1168)
Imported from Assembla: http://www.assembla.com/spaces/liftweb/tickets/976
At this point we suggest folks avoid using RewriteRequests
; should we close this ticket accordingly?