Skip to content

Instantly share code, notes, and snippets.

@arschles
Created April 3, 2012 00:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arschles/2288158 to your computer and use it in GitHub Desktop.
Save arschles/2288158 to your computer and use it in GitHub Desktop.
Scala PhoneGap Build Client
val BaseBuildURL = "https://build.phonegap.com/api/v1"
val UTF8Charset = Charset.forName("UTF-8")
case class MultipartInfo(contentType: Header, contentEncoding: Option[Header])
val baseHeaders: List[Header] = {
val authRaw = "%s:%s".format(phoneGapCreds.username, phoneGapCreds.password)
val authBase64 = Base64.encodeBase64(authRaw.getBytes(UTF8Charset))
val authString = new String(authBase64, UTF8Charset)
List(
new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic %s".format(authString)),
new BasicHeader(HttpHeaders.ACCEPT, "*/*"),
new BasicHeader(HttpHeaders.EXPECT, "100-continue")
)
}
//...
//ProxyRequest is a simple case class that holds the request URL, headers and body
def getBaseProxyRequest(u: String) = ProxyRequest(url = u,headers = baseHeaders)
def createZipFile(files: Map[RawFile, Promise[String]]): Array[Byte] = {
val byteStream = new ByteArrayOutputStream
val zipOutputStream = new ZipOutputStream(byteStream)
files.foreach { tup: (RawFile, Promise[String]) =>
val filename = tup._1.filename
val fileContents = tup._2.get.getBytes
zipOutputStream.putNextEntry(new ZipEntry(filename))
zipOutputStream.write(fileContents)
zipOutputStream.closeEntry()
}
zipOutputStream.close()
byteStream.toByteArray
}
def generateMultipart(parts: Map[String, ContentBody]): (MultipartInfo, String) = {
val multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE)
parts.foreach(tup => multipartEntity.addPart(tup._1, tup._2))
val outStream = new ByteArrayOutputStream()
multipartEntity.writeTo(outStream)
val s = outStream.toString
outStream.close()
val multipartInfo = MultipartInfo(multipartEntity.getContentType, Option(multipartEntity.getContentEncoding))
(multipartInfo, s)
}
def addMultipartToProxyRequest(p: ProxyRequest,
multiparts: Map[String, AbstractContentBody]): ProxyRequest = {
val (multipartInfo, multipartBody) = generateMultipart(multiparts)
val newHeaders: List[Header] = p.headers ++
List(multipartInfo.contentType) ++
multipartInfo.contentEncoding.map(List(_)).getOrElse(List[Header]())
p.copy(body = multipartBody, headers = newHeaders)
}
def updateExistingApp(appID: String,
titleOpt: Option[String],
newVersionOpt: Option[String],
rawFiles: Map[RawFile, Promise[String]]) = {
val rawMetadata = Map[String, String]() ++
(titleOpt some(t => Map("title" -> t)) none (Map())) ++
(newVersionOpt some(v => Map("version" -> v)) none (Map()))
val multiparts = Map(
"file" -> new ByteArrayBody(createZipFile(rawFiles), "application/octet-stream", "app.zip"),
"data" -> new StringBody(jsonSerialize(rawMetadata), "application/json", UTF8Charset)
)
val req = addMultipartToProxyRequest(getBaseProxyRequest("%s/apps/%s".format(BaseBuildURL, appID)), multiparts)
logger.debug("Updating existing PhoneGap app with app ID %s".format(appID))
router.doHttpPut(req)
}
def createNewApp(title: String,
appVersionOpt: Option[String],
rawFiles: Map[RawFile, Promise[String]]) = {
val map = Map("create_method" -> "file") +
("title" -> title) ++
(appVersionOpt some(v => Map("version" -> v)) none (Map()))
val zipFile = createZipFile(rawFiles)
val json = jsonSerialize(map)
val multiparts = Map(
"file" -> new ByteArrayBody(zipFile, "application/octet-stream", "app.zip"),
"data" -> new StringBody(json, "application/json", UTF8Charset)
)
val req = addMultipartToProxyRequest(getBaseProxyRequest("%s/apps".format(BaseBuildURL)), multiparts)
logger.debug("Creating new phonegap app")
router.doHttpPost(req)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment