Created
April 3, 2012 00:06
-
-
Save arschles/2288158 to your computer and use it in GitHub Desktop.
Scala PhoneGap Build Client
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
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