Skip to content

Commit

Permalink
Got an incredibly basic player working with interactivity.
Browse files Browse the repository at this point in the history
  • Loading branch information
rfk committed Aug 14, 2012
1 parent 231dee7 commit 42d2187
Show file tree
Hide file tree
Showing 10 changed files with 1,026 additions and 20 deletions.
339 changes: 339 additions & 0 deletions LICENSE.txt

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions README.rst
@@ -1,7 +1,10 @@

JavaScript player for playitagainsam terminal sessions.

It's currently GPL'd, because it uses GPL'd code from shellinabox.com.
The file "jschannel.js" is MPL1.1/GPL2.0/LGPL2/1 triple licensed.

It's GPL'd, because it uses GPL'd code from shellinabox.com.
More licensing detials will be fleshed out here soon.
More licensing detials will be fleshed out here soon. I am hoping to
get explicit permission from the shellinabox.com author to distribute
this under the MIT or similar license.

17 changes: 2 additions & 15 deletions playitagainsam-js/index.html
Expand Up @@ -10,21 +10,8 @@
<body>
<script>
$(function() {

var pias_data = "total 84\r\n-rw-r--r-- 1 rfk rfk 32 Aug 8 15:48 ChangeLog.txt\r\n-rw-r--r-- 1 rfk rfk 1054 Aug 8 15:48 LICENSE.txt\r\n-rw-r--r-- 1 rfk rfk 63 Aug 8 15:48 MANIFEST.in\r\ndrwxr-xr-x 2 rfk rfk 4096 Aug 8 16:37 \u001b[0m\u001b[01;34mplayitagainsam\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 0 Aug 8 15:48 README.rst\r\ndrwxr-xr-x 2 rfk rfk 4096 Aug 8 15:48 \u001b[01;34mscripts\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 10470 Aug 8 15:48 setup.py\r\nsrwxr-xr-x 1 rfk rfk 0 Aug 8 16:37 \u001b[01;35mSOCK\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 247 Aug 8 16:29 TODO.txt\r\nrfk@durian:playitagainsam$ ";

var frame = $("<iframe src='./terminal/terminal.html' width='800' height='240' />").appendTo($("body"))[0];
var piasChannel = Channel.build({
window: frame.contentWindow,
origin: "*",
scope: "pias",
onReady: function() {
piasChannel.notify({method: "write", params: "HELLO WORLD"});
}
});
piasChannel.bind("keysPressed", function(trans, chars) {
piasChannel.notify({method: "write", params: pias_data});
});
var player = new PIASPlayer($("body"));
player.play("./session.pias");
});
</script>
</body>
Expand Down
35 changes: 35 additions & 0 deletions playitagainsam-js/jschannel.js
@@ -1,4 +1,39 @@
/**
Version: MPL 1.1/GPL 2.0/LGPL 2.1
The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.
The Original Code is jschannel.
The Initial Developer of the Original Code is Lloyd Hilaiel.
Portions created by the Initial Developer are Copyright (C) 2010
the Initial Developer. All Rights Reserved.
Contributor(s):
Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.
* js_channel is a very lightweight abstraction on top of
* postMessage which defines message formats and semantics
* to support interactions more rich than just message passing
Expand Down
147 changes: 147 additions & 0 deletions playitagainsam-js/playitagainsam.js
@@ -0,0 +1,147 @@


function PIASPlayer(container) {
this.container = $(container);
this.events = [];
this.current_event = 0;
this.done_callback = null;
this.terminals = {};
}


PIASPlayer.prototype.loadDataFile = function(datafile, cb) {
var self = this;
$.ajax({
url: datafile,
dataType: "json",
error: function() { if(cb) { cb("failed to load datafile"); }},
success: function(data) {
var events = data["events"];
if(events) {
for(var i=0; i<events.length; i++) {
var event = events[i];
// Decompose ECHO events into alternating READ/WRITE.
// Decompose READ events into individual characters.
if(event.act == "ECHO") {
for(var j=0; j<event.data.length; j++) {
self.events.push({act: "READ",
term: event.term,
data: event.data.charAt(j)})
self.events.push({act: "WRITE",
term: event.term,
data: event.data.charAt(j)})
}
} else if(event.act == "READ") {
for(var j=0; j<event.data.length; j++) {
self.events.push({act: "READ",
term: event.term,
data: event.data.charAt(j)})
}
} else {
self.events.push(event);
}
}
}
if(cb) { cb(null) };
}
});
}


PIASPlayer.prototype.play = function(datafile, cb) {
console.log(["playing", datafile]);
var self = this;
this.events = [];
this.current_event = 0;
this.done_callback = cb;
this.loadDataFile(datafile, function(err) {
console.log(["loaded", datafile]);
if(err) {
return cb(err);
}
self.dispatchNextEvent();
});
}


PIASPlayer.prototype.dispatchNextEvent = function() {
var self = this;
if(this.current_event >= this.events.length) {
console.log(["done"]);
if(this.done_callback) {
this.done_callback(null);
delete this.done_callback;
}
} else {
console.log(["dispatch", this.current_event]);
var moveToNextEvent = function() {
self.current_event += 1;
setTimeout(function() { self.dispatchNextEvent(); }, 0);
}
var event = this.events[this.current_event];
if(event.act == "OPEN") {
new Terminal(this, function(err, term) {
self.terminals[event.term] = term;
moveToNextEvent();
});
} else if(event.act == "CLOSE") {
var term = this.terminals[event.term];
delete this.terminals[event.term];
term.close();
moveToNextEvent();
} else if (event.act == "PAUSE") {
setTimeout(moveToNextEvent, event.duration * 1000);
} else if (event.act == "WRITE") {
var term = this.terminals[event.term];
term.write(event.data);
moveToNextEvent();
}
}
}


PIASPlayer.prototype.handleKeyPress = function(c) {
if(this.current_event < this.events.length) {
var event = this.events[this.current_event];
if(event.act == "READ") {
console.log(["keypress", c, event.data]);
if(event.data == "\n" || event.data == "\r") {
if(c != "\n" && c != "\r") {
return;
}
}
this.current_event += 1;
this.dispatchNextEvent();
}
}
}


function Terminal(player, cb) {
var self = this;
this.player = player;
this.frame = $("<iframe src='./terminal/terminal.html' width='800' height='240' />").appendTo(player.container);
this.channel = Channel.build({
window: this.frame[0].contentWindow,
origin: "*",
scope: "pias",
onReady: function() {
self.channel.bind("keysPressed", function(trans, chars) {
for(var j=0; j<chars.length; j++) {
self.player.handleKeyPress(chars.charAt(j));
}
});
cb(null, self);
}
});
}


Terminal.prototype.write = function(data) {
this.channel.notify({ method: "write", params: data });
}


Terminal.prototype.close = function() {
this.frame.remove();
}
119 changes: 119 additions & 0 deletions playitagainsam-js/session.pias
@@ -0,0 +1,119 @@
{
"events": [
{
"act": "OPEN",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "PAUSE",
"duration": 0.07974720001220703
},
{
"act": "WRITE",
"data": "Traceback (most recent call last):\r\n File \"<string>\", line 1, in <module>\r\nImportError: No module named virtualenvwrapper.hook_loader\r\n",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "PAUSE",
"duration": 0.002897977828979492
},
{
"act": "WRITE",
"data": "virtualenvwrapper.sh: There was a problem running the initialization hooks. If Python could not import the module virtualenvwrapper.hook_loader, check that virtualenv has been installed for VIRTUALENVWRAPPER_PYTHON=/home/rfk/scratch/virtualenvs/oss/bin/python and that PATH is set properly.\r\n",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "PAUSE",
"duration": 0.28546595573425293
},
{
"act": "WRITE",
"data": "rfk@rambutan:playitagainsam$ ",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "ECHO",
"data": "ls -l\r",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "WRITE",
"data": "\n",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "PAUSE",
"duration": 0.004352092742919922
},
{
"act": "WRITE",
"data": "total 88\r\ndrwxr-xr-x 5 rfk rfk 4096 Aug 14 19:55 \u001b[0m\u001b[01;34mbuild\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 32 Aug 14 19:37 ChangeLog.txt\r\ndrwxr-xr-x 2 rfk rfk 4096 Aug 14 19:55 \u001b[01;34mdist\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 1054 Aug 14 19:35 LICENSE.txt\r\n-rw-r--r-- 1 rfk rfk 81 Aug 14 19:51 MANIFEST.in\r\ndrwxr-xr-x 2 rfk rfk 4096 Aug 14 21:26 \u001b[01;34mplayitagainsam\u001b[0m\r\ndrwxr-xr-x 2 rfk rfk 4096 Aug 14 20:31 \u001b[01;34mplayitagainsam.egg-info\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 0 Aug 14 19:35 README.rst\r\ndrwxr-xr-x 2 rfk rfk 4096 Aug 14 19:48 \u001b[01;34mscripts\u001b[0m\r\n-rw-r--r-- 1 rfk rfk 2406 Aug 14 20:31 setup.py\r\n-rw-r--r-- 1 rfk rfk 321 Aug 14 19:53 TODO.txt\r\nrfk@rambutan:playitagainsam$ ",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "OPEN",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "WRITE",
"data": "Traceback (most recent call last):\r\n File \"<string>\", line 1, in <module>\r\nImportError: No module named virtualenvwrapper.hook_loader\r\n",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "PAUSE",
"duration": 0.0030701160430908203
},
{
"act": "WRITE",
"data": "virtualenvwrapper.sh: There was a problem running the initialization hooks. If Python could not import the module virtualenvwrapper.hook_loader, check that virtualenv has been installed for VIRTUALENVWRAPPER_PYTHON=/home/rfk/scratch/virtualenvs/oss/bin/python and that PATH is set properly.\r\n",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "PAUSE",
"duration": 0.2855868339538574
},
{
"act": "WRITE",
"data": "rfk@rambutan:playitagainsam$ ",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "ECHO",
"data": "echo \"hello world\"\r",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "WRITE",
"data": "\nhello world\r\nrfk@rambutan:playitagainsam$ ",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "READ",
"data": "\u0004",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "WRITE",
"data": "exit\r\n",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "CLOSE",
"term": "5ead92d692c14400b4e35fdea4443796"
},
{
"act": "READ",
"data": "\u0004",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "WRITE",
"data": "exit\r\n",
"term": "96d0f606a80947aea413b5637500cc9b"
},
{
"act": "CLOSE",
"term": "96d0f606a80947aea413b5637500cc9b"
}
]
}
39 changes: 39 additions & 0 deletions playitagainsam-js/terminal/COPYING
@@ -0,0 +1,39 @@
Copyright (C) 2008-2010 Markus Gutschke <markus@shellinabox.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

In addition to these license terms, the author grants the following
additional rights:

If you modify this program, or any covered work, by linking or
combining it with the OpenSSL project's OpenSSL library (or a
modified version of that library), containing parts covered by the
terms of the OpenSSL or SSLeay licenses, the author
grants you additional permission to convey the resulting work.
Corresponding Source for a non-source form of such a combination
shall include the source code for the parts of OpenSSL used as well
as that of the covered work.

You may at your option choose to remove this additional permission from
the work, or from any part of it.

It is possible to build this program in a way that it loads OpenSSL
libraries at run-time. If doing so, the following notices are required
by the OpenSSL and SSLeay licenses:

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)

This product includes cryptographic software written by Eric Young
(eay@cryptsoft.com)

0 comments on commit 42d2187

Please sign in to comment.