Scala for Paragliders



Scala for Paragliders

0 0


doarama-scala-syd


On Github chris-cooper / doarama-scala-syd

Scala for Paragliders

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

A ScalaSyd presentation by Chris Cooper

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

The sports apps...

The work we're doing @ NICTA...

http://subspace.nicta.com.au

cesiumjs.org

WebGL Virtual Globe and Map Engine

Hmmm

doarama.com

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

@ 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 =>
  
    <table class="table table-striped"><tbody><tr><td>
    <div class="row">
      <div class="col-xs-4">
        <p><strong>@activity.label</strong><br>
        <small>@activity.location</small><br>
        <small>@activity.activityType.name</small></p>
        ...
      </div>
    </div></td></tr>
    </tbody></table>
    
    }
          

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