pronto – little scripts with Web interfaces

I’ve long wanted to be able to write little scripts that are as easy to write as shell scripts but have Web interfaces. Part of the inspiration comes from GitHub’s Hubot, which has an IRC bot interface. I finally got around to hacking together the beginnings of a tool that accomplishes this. It uses Scala, Play Framework 2.0, WebSockets, and especially Akka dataflow concurrency. With it, you can write interactive scripts like this in your controller and run them in a page:

  def ws2 = ProntoWebSocket { implicit context =>
    // Set up two "windows", "right" and "left"
    print(div('class -> "container") { row {
      span('id -> "left", 'class -> "span4 box", 'style -> "height: 200px")() +
      span('id -> "right", 'class -> "span6 box", 'style -> "height: 200px; overflow: auto")()
    } })

    val form = Form(tuple("name" -> text, "age" -> number))
    println("right", "here are some instructions")
    val (name, age) = promptTo("left", form) { form =>
        prontoform() {
          inputText(form("name")) + inputText(form("age"), '_showConstraints -> false) +
          inputSubmit('value -> "Submit Yo", 'class -> "btn")
    println("right", Html("<b>we</b> got name = ") + htmlescape(name) + Html(" and age = " + age))
    println("right", "to continue click the button:")
    println("right", prontobutton() { Html("Hit Me!") })
    // Wait for the button to be clicked
    println("right", "Thanks for hitting the button")

Notice you can prompt for input and react to that input in an imperative style, yet the script runs in a non-blocking fashion (by virtue of using Akka dataflow, which in turn uses Scala delimited continuations). You can see more documentation and examples on the github. What’s committed now is an early release to demonstrate the idea. Potential use cases include: internal tools, devops tasks, bots, etc. A lot more could be done to flesh out the idea and make scripts even easier to write.

I like the idea of having a single Web framework (i.e. Play) that can flexibly span multiple paradigms. You can employ different styles suited to the task at hand, without having to switch frameworks (or languages) to do it. Play already supports both full MVC (comparable to RoR or Spring MVC), purely REST-style controllers (like Sinatra or JAX-RS), as well as a reactive style of programming (a la node.js) using iteratees. This module shows the seeds of a fourth style, similar to a continuations-based framework like Seaside. This flexibility of styles I think really demonstrates the completeness and elegance of the Play framework. Like the Scala language itself, Play can be a “scalable” framework for developing Web applications in both the small and the large.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s