Skip to content

Commit

Permalink
Initial fork+merge
Browse files Browse the repository at this point in the history
  • Loading branch information
jlabusch committed Apr 5, 2015
0 parents commit c18d425
Show file tree
Hide file tree
Showing 28 changed files with 1,332 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.*.swp
*.log
*.tbz2
node_modules
ontario
build
622 changes: 622 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
include *.mk

.PHONY: all deploy-staging remove-staging deploy-prod remove-prod install run clean

all: $(GROUP_VARS) $(PACKAGE)
@echo $(PACKAGE)

deploy-staging: $(GROUP_VARS) $(PACKAGE)
cd ansible; ansible-playbook -i ./staging -K ./deploy.yml

remove-staging: $(GROUP_VARS)
cd ansible; ansible-playbook -i ./staging -K ./remove.yml

deploy-prod: $(GROUP_VARS) $(PACKAGE)
cd ansible; ansible-playbook -i ./production -K ./deploy.yml

remove-prod: $(GROUP_VARS)
cd ansible; ansible-playbook -i ./production -K ./remove.yml

$(GROUP_VARS): $(GROUP_VARS).pgp package.json
gpg -o $@ -d $<
@grep appname $(GROUP_VARS) || echo "appname: "$(NAME) >> $(GROUP_VARS)
@grep version $(GROUP_VARS) || echo "version: "$(VERSION) >> $(GROUP_VARS)
@grep extractdir $(GROUP_VARS) || echo "extractdir: /opt/"$(NAME)-$(VERSION) >> $(GROUP_VARS)
@grep installdir $(GROUP_VARS) || echo "installdir: /opt/"$(NAME) >> $(GROUP_VARS)

$(PACKAGE): package.json $(NODE_SOURCES)
npm install
test -f bower.json && ./node_modules/.bin/bower install || :
mkdir -p build
rsync -avz --include-from build-include . build/
mkdir -p $$(dirname $@)
cd build && tar -jcvf ../$@ *

clean:
rm -fr node_modules build $(PACKAGE) $(GROUP_VARS)

83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# reveal-sync &mdash; Synchronizing distributed Reveal.js presentations

### tl;dr

One person loads a Reveal.js presentation, creates a unique stream ID and
shares a link to the other participants. The participants load the presentation using
the unique ID and are automatically subscribed to "navigation" events from the presenter &mdash;
next slide, prev slide, next fragment, etc.

### Longer version...

Not too long ago I gave a presentation on
<a href="http://jlabusch.github.io/distributed-teams">working with distributed teams</a>.
Ironically, some members of the audience were joining remotely and for various tragic
reasons we couldn't share the slides over a video conferencing link. I shared a link
to the hosted slides so they could follow along, but keeping everyone on the same page
was an annoying distraction.

The next day I wrote `reveal-sync`.

`reveal-sync` is

* Designed to work with <a href="https://github.com/hakimel/reveal.js">Reveal.js</a> presentations
* Very easy to use
* Available as a free service using `sync.downlink.nz`
* Open source (GPLv3)

`reveal-sync` does require that the presentation be hosted in a place that all
participants have access to, e.g. <a href="http://github.io">GitHub.io</a>.

### How to use the free hosted service

Include the following in your presentation:

```diff
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
+ <script src="http://downlink.nz/js/socket.io.js"></script>
+ <script src="http://downlink.nz/js/reveal-sync.js"></script>

<script>
```

That's it! Next time you refresh your presentation you'll get a prompt with a copy-able link
like this

> http://example.com/presentation/?sync=8041e93e-0df8-4fe4-8d7d-eab26adeadfa
Share that with your team and they'll be automatically subscribed to your Reveal.js navigation events.

### Hosting your own service

Take a look at the `ansible` playbook in the repository. If you're using Nginx, Varnish or similar,
remember that you need to support websockets and HTTP 1.1.

In your presentation, specify your `reveal-sync` server's URI as follows:

```diff
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script src="http://downlink.nz/js/socket.io.js"></script>
+ <script>
+ var reveal_sync_uri = 'http://example.com/';
+ </script>
<script src="http://downlink.nz/js/reveal-sync.js"></script>
```

### License

Copyright (C) 2015 Jacques Labuschagne

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

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, see <http://www.gnu.org/licenses/>.
7 changes: 7 additions & 0 deletions ansible/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- hosts: ontario
remote_user: jacques
sudo: yes
gather_facts: yes
roles:
- reveal_sync
15 changes: 15 additions & 0 deletions ansible/group_vars/ontario.pgp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1

jA0EAwMCllA03WP5Ad1gycD1teQioD+n6NV69cDWiDQMPHE140bKV08guWDN5Ogq
Gh9Ig4gGG+Pft/MUOV0YG3lrHOZ86RP3n/F3Xyhy3GO+lw7yDlCY3c1s8qI9jOWJ
YQ4aroPbR/GyEmkyYXWToa+hxmhaeEq5QmzFCaB2j8UTIXEjDSC23bdny51M3nIa
/eTCs+M4RoowadY/Bu8BUjK3tsDG89oT4O6V+qgN03jXgnzmUnvx8wRtRsI/dUB9
gEnHoPBwLZaM5cF/V4JDbNC2Ay2HCPnuKFi/puXkqlMnOxN01z4PD6N0f4sxUtLn
1siVqi+lVSkp+Ld/KJ4reE8n7qLRBl7zc817VIkQQaiDhg6w0r7PxShCZXyCgwBc
aWYI39p7xmpfVnrOgiybC5BQK9Rm2I+UzRT2O4Wbfs+UeCXSAoVi9akHS6QxLhCB
XA4yw7D4yerOH5c8eAO+fmFadiuQXYP/gvF32Ff/noSxrWiBzqMZsY5/ZK05mPz9
50Sm9ahC6hNwpUaSj66a2/VE4qO44Gl+QE7RAlaKOI4fLh+agD2JNLtlKFqPpu3z
A0oxF2hmvMP9Wq+KY7aEWO9cBxDunKc=
=ZE5p
-----END PGP MESSAGE-----
2 changes: 2 additions & 0 deletions ansible/production
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ontario]
prod.downlink.nz
7 changes: 7 additions & 0 deletions ansible/remove.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- hosts: ontario
remote_user: jacques
sudo: yes
gather_facts: yes
roles:
- clean
3 changes: 3 additions & 0 deletions ansible/roles/clean/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: restart rsyslog
service: name=rsyslog state=restarted
20 changes: 20 additions & 0 deletions ansible/roles/clean/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- name: Stop app
shell: su downlink -c "./stop.sh"
args:
chdir: "{{ installdir }}"

- name: Remove rsyslog config
file: path=/etc/rsyslog.d/40-{{ appname }}.conf state=absent
notify:
- restart rsyslog

- name: Remove logrotate config
file: path=/etc/logrotate.d/{{ appname }} state=absent

- name: Remove symlink
file: path={{ installdir }} state=absent

- name: Remove extraction dir
file: path={{ extractdir }} state=absent

3 changes: 3 additions & 0 deletions ansible/roles/reveal_sync/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: restart rsyslog
service: name=rsyslog state=restarted
28 changes: 28 additions & 0 deletions ansible/roles/reveal_sync/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
- name: Check user exists
user: name=downlink shell=/bin/bash uid=1094 groups=www-data append=yes

- name: Remove symlink
file: path={{ installdir }} state=absent

- name: Extraction dir exists
file: path={{ extractdir }} state=directory owner=downlink group=www-data mode=0755

- name: Extract package files
unarchive: src={{ appname }}-{{ version }}.tbz2 dest={{ extractdir }} owner=downlink group=www-data

- name: Update symlink
file: path={{ installdir }} state=link src={{ extractdir }}

- name: Install rsyslog config
template: src=rsyslog.j2 dest=/etc/rsyslog.d/40-{{ appname }}.conf owner=root group=root mode=644
notify:
- restart rsyslog

- name: Install logrotate config
template: src=logrotate.j2 dest=/etc/logrotate.d/{{ appname }} owner=root group=root mode=644

- name: Restart app
shell: su downlink -c "./stop.sh; ./start.sh"
args:
chdir: "{{ installdir }}"
13 changes: 13 additions & 0 deletions ansible/roles/reveal_sync/templates/logrotate.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/var/log/{{ appname }}.log
{
rotate 7
daily
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
invoke-rc.d rsyslog reload >/dev/null 2>&1 || true
endscript
}
4 changes: 4 additions & 0 deletions ansible/roles/reveal_sync/templates/rsyslog.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
if $programname == '{{ appname }}' then /var/log/{{ appname }}.log
stop


2 changes: 2 additions & 0 deletions ansible/staging
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ontario]
staging.downlink.nz
15 changes: 15 additions & 0 deletions build-include
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
- .git
- .gitignore
- ansible
- ./build
- build-include
+ config
- global.mk
+ index.js
+ lib
+ LICENSE
- Makefile
+ node_modules
+ package.json
+ start.sh
+ stop.sh
10 changes: 10 additions & 0 deletions config/default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"daemon": true,
"port": 9000,
"workers": 1,
"pid_dir": "/tmp",
"log": {
"facility": "local4",
"level": "info"
}
}
77 changes: 77 additions & 0 deletions dist/reveal-sync.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
(function(){
var socket = io(typeof(reveal_sync_uri) === 'string' ? reveal_sync_uri : 'http://sync.downlink.nz/'),
search_parts = window.location.search.match(/sync=([-a-fA-f0-9]+)/),
handler = undefined;

if (search_parts){
handler = new SyncClient(search_parts[1]);
}else{
handler = new SyncOwner();
}

socket.on('connect', function(){ handler.connect() });
socket.on('nav', function(msg){ handler.remote_change(msg) });

['slidechanged', 'fragmentshown', 'fragmenthidden'].forEach(function(t){
Reveal.addEventListener(t, function(e){
handler.local_change(e, t);
});
});

function SyncClient(id){
this.id = id;
}

SyncClient.prototype.connect = function(){
console.log('client#connect');
socket.emit('join', this.id);
}

SyncClient.prototype.remote_change = function(msg){
console.log('client#remote_change(' + JSON.stringify(msg) + ')');
if (msg.id === this.id){
switch(msg.type){
case 'fragmentshown':
Reveal.nextFragment();
break;
case 'fragmenthidden':
Reveal.prevFragment();
break;
default:
Reveal.slide(msg.h, msg.v, msg.f);
break;
}
}
}

SyncClient.prototype.local_change = function(evt, type){
console.log('client#local_change(' + type + ') - ignored');
}

function SyncOwner(){
this.id = uuid();
window.prompt('Ask people to join your presentation at', window.location.origin + window.location.pathname + '?sync=' + this.id);
}

SyncOwner.prototype.connect = function(){
console.log('owner#connect');
socket.emit('create', this.id);
}

SyncOwner.prototype.remote_change = function(msg){
console.log('owner#remote_change(' + JSON.stringify(msg) + ') - ignored');
}

SyncOwner.prototype.local_change = function(evt, type){
var msg = {id: this.id, h: evt.indexh, v: evt.indexv, f: evt.indexf, type: type};
console.log('owner#local_change(' + JSON.stringify(msg) + ')');
socket.emit('nav', msg);
}

function uuid(){
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
})();
1 change: 1 addition & 0 deletions dist/socket.io.js
5 changes: 5 additions & 0 deletions global.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
GROUP_VARS=ansible/group_vars/ontario
NAME=$(shell node -e 'console.log(require("./package.json").name)')
VERSION=$(shell node -e 'console.log(require("./package.json").version)')
PACKAGE=ansible/roles/reveal_sync/files/$(NAME)-$(VERSION).tbz2
NODE_SOURCES=index.js $(wildcard lib/*.js)
Loading

0 comments on commit c18d425

Please sign in to comment.