Skip to content

Commit

Permalink
New json parser implemented for search, tags
Browse files Browse the repository at this point in the history
Not wired up to the main API yet
  • Loading branch information
Graham Tackley committed Aug 27, 2010
1 parent 3017184 commit 08032af
Show file tree
Hide file tree
Showing 14 changed files with 732 additions and 1 deletion.
4 changes: 3 additions & 1 deletion project/build/ContentApiClient.scala
Expand Up @@ -4,6 +4,8 @@ class ContentApiClient(info: ProjectInfo) extends DefaultProject(info) with Idea

val joda = "joda-time" % "joda-time" % "1.6" withSources()
val httpClient = "commons-httpclient" % "commons-httpclient" % "3.1"


val lift_json = "net.liftweb" %% "lift-json" % "2.1-M1" withSources()

val scalaTest = "org.scalatest" % "scalatest" % "1.2" % "test" withSources()
}
Expand Up @@ -3,6 +3,7 @@ package com.gu.openplatform.contentapi.model
import org.joda.time.DateTime
import java.net.URL


class Response(
val format: String,
val status: String,
Expand Down
112 changes: 112 additions & 0 deletions src/main/scala/com/gu/openplatform/contentapi/model/NewModel.scala
@@ -0,0 +1,112 @@
package com.gu.openplatform.contentapi.model.json

import org.joda.time.DateTime

// NB:
// Due to the way lift-json parses lists and collections
// we have to be inconsitant with optional lists.
// Everywhere else where things are optional, we make then Options.
// But for lists, this doesn't work (you get back Some(Nil) even if
// the element is not present.
// So Lists are never Option[List], you will just get back Nil if the
// the element was not present in the response


// Responses

// /search
case class SearchResponse(
status: String,
userTier: String,
total: Long,
startIndex: Long,
pageSize: Long,
currentPage: Long,
pages: Long,
orderBy: String,
results: List[Content],
refinementGroups: List[RefinementGroup]
)

// /tags
case class TagsResponse(
status: String,
userTier: String,
total: Long,
startIndex: Long,
pageSize: Long,
currentPage: Long,
pages: Long,
results: List[Tag]
)





// Model classes
case class Content(
// the id of this item of content: this should always be the path
// to the item on www.guardian.co.uk
id: String,
// section is usually provided: some content (such as user help information)
// does not belong to any section
sectionId: Option[String],
sectionName: Option[String],
webPublicationDate: DateTime,
webTitle: String,
webUrl: String,
apiUrl: String,
fields: Option[Map[String, String]],
tags: List[Tag],
factboxes: List[Factbox],
mediaAssets: List[MediaAsset]
)


case class Tag(
id: String,
`type` : String,
sectionId: Option[String],
sectionName: Option[String],
webTitle: String,
webUrl: String,
apiUrl: String
) {
// for those that don't like backticks
def tagType = `type`
}

case class Factbox(
`type`: String,
heading: Option[String],
picture: Option[String],
fields: Option[Map[String, String]]
) {
def factboxType = `type`
}

case class MediaAsset(
`type`: String,
rel: String,
index: Int,
file: String,
fields: Option[Map[String, String]]
) {
def mediaAssetType = `type`
}

case class RefinementGroup(
`type`: String,
refinements: List[Refinement]
) {
def refinementType = `type`
}

case class Refinement(
count: Long,
refinedUrl: String,
displayName: String,
id: String,
apiUrl: String
)
@@ -0,0 +1,24 @@
package com.gu.openplatform.contentapi.parser

import org.joda.time.DateTime
import scala.PartialFunction
import net.liftweb.json.JsonAST._
import org.joda.time.format.ISODateTimeFormat
import net.liftweb.json.{MappingException, TypeInfo, Formats, Serializer}

class JodaJsonSerializer extends Serializer[DateTime] {
private val DateTimeClass = classOf[DateTime]
val formatter = ISODateTimeFormat.dateTimeNoMillis

def deserialize(implicit format: Formats): PartialFunction[(TypeInfo, JValue), DateTime] = {
case (TypeInfo(DateTimeClass, _), json) => json match {
case JString(s) => formatter.parseDateTime(s)
case x => throw new MappingException("Can't convert " + x + " to DateTime")
}
}

def serialize(implicit format: Formats): PartialFunction[Any, JValue] = {
case dt: DateTime => JString(formatter.print(dt))
}

}
@@ -0,0 +1,17 @@
package com.gu.openplatform.contentapi.parser

import scala.xml._
import org.joda.time.format.ISODateTimeFormat
import com.gu.openplatform.contentapi.model.json._
import java.net.URL
import net.liftweb.json.JsonParser._
import net.liftweb.json.JsonAST.JValue


class LiftJsonParser {
implicit val formats = net.liftweb.json.DefaultFormats + new JodaJsonSerializer

def parseSearch(json: String) = (parse(json) \ "response").extract[SearchResponse]
def parseTags(json: String) = (parse(json) \ "response").extract[TagsResponse]

}
@@ -0,0 +1,56 @@
{
"response":{
"status":"ok",
"userTier":"partner",
"total":1,
"startIndex":1,
"pageSize":2,
"currentPage":1,
"pages":1,
"orderBy":"newest",
"results":[{
"id":"music/picture/2010/aug/25/georgemichael-ukcrime",
"sectionId":"music",
"sectionName":"Music",
"webPublicationDate":"2010-08-25T11:08:53+01:00",
"webTitle":"Eyewitness: Wham! rap",
"webUrl":"http://www.guardian.co.uk/music/picture/2010/aug/25/georgemichael-ukcrime",
"apiUrl":"http://content.guardianapis.com/music/picture/2010/aug/25/georgemichael-ukcrime",
"factboxes":[{
"type":"photography-tip",
"fields":{
"proTip":"By using auto-focus, continuous shooting mode and holding his camera above the crowd, the photographer has managed to capture the scene"
}
}],
"mediaAssets":[{
"type":"picture",
"rel":"body",
"index":1,
"file":"http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2010/8/25/1282722354152/george-michael-appears-in-003.jpg",
"fields":{
"source":"Getty Images",
"photographer":"Peter Macdiarmid",
"height":"519",
"credit":"Peter Macdiarmid/Getty Images",
"altText":"george michael appears in court charged with driving offences",
"caption":"Singer George Michael leaves Highbury magistrates court surrounded by press and police. Michael pleaded guilty to driving under the influence of drugs and possessing cannabis after he crashed his car into a shop in London. The singer has been warned that he may face a custodial sentence after a previous similar offence",
"width":"780"
}
},{
"type":"picture",
"rel":"big-picture",
"index":1,
"file":"http://static.guim.co.uk/sys-images/Guardian/Pix/pictures/2010/8/25/1282722355694/george-michael-appears-in-004.jpg",
"fields":{
"source":"Getty Images",
"photographer":"Peter Macdiarmid",
"height":"768",
"credit":"Peter Macdiarmid/Getty Images",
"altText":"george michael appears in court charged with driving offences",
"caption":"Singer George Michael leaves Highbury magistrates court surrounded by press and police. Michael pleaded guilty to driving under the influence of drugs and possessing cannabis after he crashed his car into a shop in London. The singer has been warned that he may face a custodial sentence after a previous similar offence",
"width":"1024"
}
}]
}]
}
}

0 comments on commit 08032af

Please sign in to comment.