#lang scheme/base
(require scheme/contract
scheme/port
scheme/class
scheme/list
net/url
net/uri-codec
"../../compiler/version.ss"
"../../collects/moby/runtime/stx.ss"
"../../program-resources.ss"
"../helpers.ss")
(define current-server-url (make-parameter "http://localhost:8080/package/"
"http://go.cs.brown.edu/package/"))
(define (build-android-package name program/resources)
(let ([data (encode-parameters-in-data name program/resources)])
(with-handlers ([exn:fail:network?
(lambda (exn)
(handle-network-failure exn))])
(log-debug (format "Sending ~s ~s" (current-server-url) data))
(let* ([ip (post-impure-port (string->url (current-server-url))
data)]
[headers (purify-port ip)]
[status-code (get-status-code headers)])
(cond
[(= status-code 200)
(port->bytes ip)]
[else
(raise (make-exn:fail (bytes->string/utf-8 (port->bytes ip))
(current-continuation-marks)))])))))
(define (handle-network-failure exn)
(raise (make-exn:fail
(string-append "We are unable to build your Android package; the web service appears to be offline.\n"
"Please contact the Moby developers; in your response, include the following:\n"
(exn-message exn))
(current-continuation-marks))))
(define (get-status-code response-headers)
(log-debug (format "Response headers are ~s~n" response-headers))
(string->number (second (regexp-match #px"^[^\\s]+\\s([^\\s]+)" response-headers))))
(define (encode-parameters-in-data name program/resources)
(string->bytes/utf-8
(alist->form-urlencoded
(list* (cons 'name name)
(cons 'compiler-version VERSION)
(cons 'program-stx
(format "~s" (program->sexp
(program/resources-program program/resources))))
(map (lambda (a-resource)
(log-debug (format "Sending resource ~s~n" (send a-resource get-name)))
(cons 'resource (format "~s"
(list (send a-resource get-name)
(send a-resource get-bytes)))))
(program/resources-resources program/resources))))))
(provide/contract [build-android-package
(string? program/resources? . -> . bytes?)])