- Jul
- 17
- 2014
Slide
Scalive from Takeharu Oshida
- Nov
- 11
- 2012
Phantom.jsとimageMagickで.html to .png to .pdf
年末のプレゼンに向けてこんなの作ってみた。 テスト一切書いてなかったり、Cakefileが微妙だったり、デザインがやっつけだったりまだまだ改善の余地ありですが、一旦完成。
express + socket.IOでスライドショーを共有するみたいな感じです。
Jxck/SlideStream
の劣化版といえばそれまでですが、 js,coffeescriptの勉強という意味で以下の分厚い本を読みつつ1から自分で作ってみた。
|
|
webサーバはexpressでadminログインしたプレゼンターの操作をsocket.IOでブロードキャストで基本的なアイデアや作りは冒頭申したとおり、
Jxck/SlideStream
まんまなんですが、
以下の構成パッケージで、socket.IOとexpressでセッション共有する際にJxckさんのブログのままだと動かなかったのでcookieのとりかたは pxsta's Memo さんを参考にcookieのパースが必要みたい。
以下の構成パッケージで、socket.IOとexpressでセッション共有する際にJxckさんのブログのままだと動かなかったのでcookieのとりかたは pxsta's Memo さんを参考にcookieのパースが必要みたい。
package.json
"dependencies": {
"express": "3.0.0",
"ejs": ">= 0.0.1",
"connect": "2.6.0",
"socket.io": "0.9.10",
"connect-redis": "~1.4.5",
"cookie": "0.0.5",
"underscore": "~1.4.2"
}
expressサーバ側
app.use util.parallel(
express.methodOverride(),
express.session
store: sessionStore
secret: config.session.secret
maxAge: false
cookie:
httpOnly: false
)
socket.IOサーバ側
io.set 'authorization', (handshakeData, callback) ->
if handshakeData.headers.cookie
singedCookie = slideBaseUtil.parseCookie decodeURIComponent(handshakeData.headers.cookie)
cookie = slideBaseUtil.parseSignedCookies singedCookie
sessionID = cookie['connect.sid']
store.get sessionID ,(err,session) ->
if err
log "err", err
callback err.message, false
else if !session
callback "session not found", false
else
log "session found"
handshakeData.cookie = cookie
handshakeData.sessionID = sessionID
handshakeData.session = session
callback null, true
else
callback "cookie not found", true
slideBaseUtilの中身はこんな感じ
connect = require 'connect'
cookie = require 'cookie'
parseCookie: (target) ->
cookie.parse target
parseSignedCookies: (singedCookie) ->
connect.utils.parseSignedCookies singedCookie, config.session.secret
クライアントサイドでプラグインみたいに別ファイルのいろんなところからsocketを使えるようにするには
execEmit: (name,data) ->
console.log "execEmit "+name
obj =
name:'plugin'
plugin:
name:name
data:data
$('body').trigger 'execEmit', obj
socket?.on 'connect', ->
$('body').on 'execEmit', (event,obj) ->
socket.emit obj.name, obj
みたいにbodyにイベント作ってそれを外から呼ぶみたいにしてみた。
あとはサーバ側にもpluginで受けたらそのままブロードキャストするようにかいて
socket.on 'plugin', (data) ->
socket.broadcast.volatile.emit "plugin", data
クライアントサイドはpluginを受けたらpluginとして登録してある関数を呼ぶみたいな感じにしておけば未定義のものが仮に送られてきても大丈夫みたいな感じ。
socket.on 'plugin', (obj) ->
if not obj.plugin or not obj.plugin.name then return false
if not isEnableServerPush obj.plugin.name then return false
func = sbClient.plugins[obj.plugin.name].get("callback") || {}
func(obj.data)
さて、タイトルにあるとおり感動したのはPhantom.js。
このやり方もJxckさんの
ブログ
を参考にしたのですが、チョット違うのはPhantom.jsからクリックイベントを呼んでページ遷移させるとこと、sam2pとpdftkの代わりに
imageMagick
っていうツールを使いました。imageMagickを使うと、複数pngから一発で1枚のpdfに変換することができました。
Phantom.jsからクリックイベントを呼ぶには
page.includeJs 'http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js',->
offset = page.evaluate ->
$('#next').offset()
page.sendEvent 'click', offset.left+1, offset.top+1
みたいな感じで、叩きたいボタンや場所のoffsetを取得してpage.sendEvent('イベント',top,left)を呼べばOK。これでページ送りができますが、それぞれ非同期でやってる?ようなので、この直後にpage.render(outout)を呼んじゃうとまだクリックされてなかったりするのでsetTimeoutで微妙な調整がいるかも。sendEventの完了タイミングとれたりすると便利なのに。
さて、imageMagickインストールはhomebrew経由でカンタン。
brew install imagemagick
これでこんな感じでいくつかコマンドが使えるようになります。
22:26:33:oshidatakeharu@george-on-mba.local:/usr/local/Cellar/imagemagick/6.7.7-6/bin:master$ ll total 304 -r-xr-xr-x 1 oshidatakeharu admin 1290 Nov 11 12:08 Magick++-config -r-xr-xr-x 1 oshidatakeharu admin 1256 Nov 11 12:08 Magick-config -r-xr-xr-x 1 oshidatakeharu admin 1264 Nov 11 12:08 MagickCore-config -r-xr-xr-x 1 oshidatakeharu admin 1269 Nov 11 12:08 MagickWand-config -r-xr-xr-x 1 oshidatakeharu admin 1251 Nov 11 12:08 Wand-config -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 animate -r-xr-xr-x 1 oshidatakeharu admin 9260 Nov 11 12:08 compare -r-xr-xr-x 1 oshidatakeharu admin 9204 Nov 11 12:08 composite -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 conjure -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 convert -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 display -r-xr-xr-x 1 oshidatakeharu admin 9260 Nov 11 12:08 identify -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 import -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 mogrify -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 montage -r-xr-xr-x 1 oshidatakeharu admin 9196 Nov 11 12:08 stream
このうちconvertっていうのがファイル変換してくれるやつで、
convert src/*.png dest/output.pdf
とかあるいは
convert -append 1.png 2.png output.pdf
みたいな感じでpngが複数ページ構成のpdfファイルに1つにまとまります。
カンタンでイイね。
カンタンでイイね。
あーなんか断片的でまとまりのないエントリーですみません。