28 hours later

The Sakai 2010 conference is going pretty well so far, lots of good stuff.

When I’ve had a little spare time the last few months I’ve been trying to look through the Etherpad code base so that we could make it a part of Sakai. After a bit of poking around it seemed like a better first step would be to Basic LTI-isize it, primarily because Etherpad does lots of Comet streaming stuff, requires JDK6, and I can imagine may require it’s own tuning. Also BLTI makes it easy to use all over the place. I can see some scenerios where it could end up in the same JVM as Sakai in the future. But this is a good first step.

I went to the BLTI workshop on Monday morning and after some hacking on the Denver Light Rail and random places Monday and Tuesday night got some basic stuff working. It still needs a lot of plumbing production work, but you can see fairly closely what it would actually look like.

There is a demo screencast here on blip.tv


Etherpad in Sakai 2

Etherpad in Sakai 2, click for bigger version. You can have multiple pads on the side bar. Eventually we need to write a Resource Type Shim for BLTI stuff.


Etherpad in Sakai 3

Etherpad in Sakai 3, click for bigger version.

When it comes to trying to enable a cloud service to be embedded in a container such as Sakai using BLTI you really only need to know one thing. It POST’s you a bunch of keys and then you serve the page. That’s about it.


BLTI Workflow

General workflow of Basic LTI backend interaction.

The above is a bit of a simplification, because there are particular rules on how you handle those POST keys, but I think it’s important to emphasize that that’s all it is. 1. POST some keys to a webapp. 2. Webapp uses the OAuth secret, provisions that user in it’s system, and serves stuff.

Sooo, obviously it’s not any sort of deep integration and could leave you wanting more, but if you have some neat webapp that would be cool in your class with just a rectangle on the page and list of users, then it’s pretty great.

One of the biggest questions going forward is which Etherpad Fork/Community to try and spearhead as a permanent sustainable community. There is the original Etherpad Open Source release, here, but it might be better to join one of the offshoots like Titanpad on Github since all the guys from the original project have to work on Wave now.

Hacking Etherpad

The build instructions
for setting up an etherpad server are pretty straight forward.

If you look at the src tree below, you can see that in the etherpad tree at one point it’s separated into ‘etherpad’ and ‘infrastructure’. For the most part (so far) we don’t need to touch infrastructure. That area contains the appjet engine framework that etherpad is built on top of. It is pretty cool, and written in Scala.


BLTI Workflow

Layout of Etherpad Source Tree.

The actual etherpad application code is in ‘etherpad/src’. Inside ‘etherpad/src/etherpad’ is all the server side code. The server side is all written in Rhino (Javascript on the JVM), so you can go in and work on code while the server is running, and it will reload the files. The static directory contains most of the client side js, images, css, etc. The templates contain the HTML templates. They are all *.ejs files, which are like JSP’s, but using javascript instead of Java.

Digging in for the hack

I’m still getting familiar with how appjet works, but it all starts in src/main.js. This file contains a bunch of initialization code and also some dispatchers. Dispatching URL’s in appjet looks fairly similar to other routes style and some python web frameworks.

var commonDispatcher = new Dispatcher();
  commonDispatcher.addLocations([
    [‘/favicon.ico’, forward(static_control)],
    [‘/robots.txt’, forward(static_control)],
    [‘/crossdomain.xml’, forward(static_control)],
    [PrefixMatcher(‘/static/’), forward(static_control)],
    [PrefixMatcher(‘/ep/genimg/’), genimg.renderPath],
    [PrefixMatcher(‘/blti’), pad_control.basic_lti],
    [PrefixMatcher(‘/ep/pad/’), forward(pad_control)],
    [PrefixMatcher(‘/ep/script/’), forward(scriptcontrol)],
    [/^\/([^\/]+)$/, pad_control.render_pad],
    [DirMatcher(‘/ep/unit-tests/’), forward(testcontrol)],
    [DirMatcher(‘/ep/pne-manual/’), forward(pne_manual_control)],
    [DirMatcher(‘/ep/pro-help/’), forward(pro_help_control)]
  ]);

For now I’m handling the BLTI POST with the /blti route, so that’s what you need to put into the configuration on the embedded widgets.

At the moment the rest of the parts I’ve had to hack are:

  • static/css/pad2_ejs.css
  • static/js/pad2.js
  • templates/html.ejs
  • templates/pad/pad_body2.ejs
  • etherpad/control/pad/pad_control.js

A few years ago, Josh Ryan and I hacked together a prototype of Google Docs in Sakai, and one of the crappy things was not having many options about what was being embedded. The great thing here is that we can strip out all the HTML Branding and other things we don’t need, which I’ve started to do in the static css/js and pad_body2.ejs.

Most of the work so far has been in pad_control.js, and a lot of poking around in sessions.js. One of the things we need to do is get the code for Etherpad Pro accounts back up and running so we can provision real accounts (in all the open source builds, the default configuration is just to use Guest Accounts). And then we can properly handle the OAuth tokens.

function basic_lti() {
  var reslinkid = request.params.resource_link_id;
  reslinkid = reslinkid.replace(/\//g,‘_’);

  var dispname = request.params.lis_person_name_full;
  var userid = request.params.user_id;

  sessions.setTrackingCookie();
  sessions.preRequestCookieCheck();
  getSession().instantCreate = reslinkid;
  getSession().guestDisplayName = dispname;

  var pad = padutils.getCurrentPad();
  padusers.userId = userid;
  response.redirect(‘/’+reslinkid+"?displayName="+dispname);
}

Our current basic lti handler in pad_control.js is pretty simple. We suck out the resource_link_id and user info so we can create a unique pad for the placement and make sure their user name shows up in the chat window. Again, we need to work on the session handling code a bit as we get familier with the etherpad code base (which is not actually all that large (probably because it’s written in javascript ) ), and set up the pro accounts. But it’s pretty close.

Another interesting use case is that we can create a version of the blti that just hides the actual pad editor and just use the chat window, since it’s actually nicer than the regular chat functionality in Sakai.

ONE MORE EXCITING THING!!

This gives us a great excuse to actually learn how to set up a server side open office installation, since that is what etherpad uses for all it’s office importing/exporting.

Awesome!

Will be checking in the patches on google code, github, bitbucket or somewhere soon.

One Response to “28 hours later”

  1. Bruce says:

    So how do you see this playing out in the future; say with Sakai 3? It seems like collaborative document authoring ought to be a core use case for the new system, so that etherpad-like functionality ought to be ubiquitous in the system?