Scala for Paragliders

How an application built on Scala Play Framework is helping outdoor enthusiasts

A ScalaSyd presentation by Chris Cooper

Image

http://chris-cooper.github.io/doarama-scala-syd/

The sports apps...

Image

The work we're doing @ NICTA...

http://subspace.nicta.com.au Image

cesiumjs.org

WebGL Virtual Globe and Map Engine

Image Image

Hmmm

doarama.com

Image

What is Doarama?


Upload
/
Live
Correlate Tweak Share Comment

Web | API

What we have...

  • Customisable virtual globe
  • Years of CG experience
  • Client side prototype


What's missing...
  • Web dev
  • Server
  • Database
  • Clue
Image
Image

@ NICTA (at the time)

Sidney Shek / Clinton Freeman / Mark Hibberd / Eric Torreborre / Tony Morris

FP / Scala / Web / scoobi / specs2 etc..

So...

  • Scala Play
  • PostgreSQL
  • Bootstrap
  • Heroku

Scala Play / PostgreSQL

Heroku

$ git push heroku master

dev | stage | production


Monitor


  • Google Analytics
  • Papertrail
  • New Relic
  • heroku pg:psql


Modules


Website Shared API
Controllers / Views Models / Services Controllers / Views

Model...


  def listByUserId(user_id: Long, page: Int = 0, pageSize: Int = 10): Page[ActivityWithVisualisations] = {
    val offset = pageSize * page

    DB.withConnection { implicit connection =>

      val items = SQL(
        """
          select * from activity 
          left join activitytype on activity.activitytype_id = activitytype.id
          where user_id = {user_id}
          order by activity.id desc
          limit {pageSize} offset {offset}
        """).on(
          'user_id -> user_id,
          'pageSize -> pageSize,
          'offset -> offset).as(Activity.withType2 *)
      ...
      
    }
  }

          

Controller...


  def list(page: Int) = SecuredAction { implicit request =>
    val user = Users.getUser(request.user)
    val activities = Activity.listByUserId(user.id, page)
    Ok(views.html.activities(Some(user), activities))
  }
          

View...


    
    @activities.map { case activity =>
  
    

@activity.label
@activity.location
@activity.activityType.name

...
}

Test...


    "create an activity" in {
      val requestStr = "{...}"
      val request = FakeRequest(POST, "/api/0.2/livetrack/activity", requestHeader, Json.parse(requestStr))
      val result = route(request).get
      status(result) must equalTo(OK)
      val resultJson = Json.parse(contentAsString(result))
      resultJson.asOpt[IdResult] must beSome[IdResult]
        


Stats

July 2013 -> March 2014 (now)

  • 200 to 500 unique hits / day
  • 5000 unique visitors
  • 7500 activities uploaded
  • 2100 users have uploaded
  • 2 active API users embedding Doarama visualisations in their sites
  • Heaviest user of Cesium terrain

Where to begin for YOUR app...

Some doarama vids