PIYO - Tech & Life -

slideshareをPDFダウンロードするRubyスクリプト&Webアプリ

Sinatra Ruby

slideshareのスライドをPDFでダウンロードしてEvernoteに入れてあとで閲覧する、っていうフローで読むことがあります。ところが、たまにSAVEできないスライドがあってそれができなくて困ったりします。

そういう場合は諦めてWebで読めば問題ないと言えば問題ないのですが、Evernoteに突っ込めないっていうのが気持ち悪いと感じてしまいます。 かといって1スライドごとにスクリーンショットを撮ってスライド化するのもバカみたいだし。

幸い僕はプログラマーなのでslideshareのスライドをPDF化するスクリプトを作り、さらにSinatraでWebアプリケーション化しました。

※規約を読んで問題ないんじゃないかと判断してこのようなコードを書いていますが、英語の理解力が足りなくてそう思い込んでいる可能性もあるので間違ってたらどうしよう。

まずはRubyスクリプト

全体像はGistに。 download slideshare slide as PDF

ざっくり言うと、スライドのURLからスライド1枚ごとの画像のURLを抽出して保存。それをprawnというgemでPDF化します。

以下、一部解説します。

各スライドを画像としてダウンロード

# 対象のスライド(@nippondanjiさんの偉大なスライドをリスペクト!)
url = "http://www.slideshare.net/nippondanji/db-engineerstudyanim"

# ..略..

# スライドページのHTMLをパースして、、
doc = Nokogiri::HTML.parse(html,nil,charset)

# スライドの一覧が載っているXMLのURLを作る
item = doc.xpath('/html/head/meta[@name="thumbnail"]').first
thumbnail_url = item.attributes["content"].value
xml_url = thumbnail_url.gsub(/phpapp(\d+)?(.+)$/,'phpapp\1').gsub(/ss_thumbnails\//,'') + ".xml"
xml = open(xml_url) do |f|
  f.read
end

# XMLをパースしてスライドの枚数をカウント
xml_doc = Nokogiri::XML(xml)
slide_count = xml_doc.xpath("/Show/Slide").count

# 一時ディレクトリで
Dir.mktmpdir do |dir|
  Dir.chdir(dir) do

    slide_count.times do |i|
      # 各スライドの画像が置いてあるURLを作成しダウンロード
      path = "http://image.slidesharecdn.com/#{slide_name}/95/slide-#{i+1}-1024.jpg"
      puts "downloading #{path} ..."
      filename = File.basename(path)
      open(filename, 'wb') do |out|
        open(path) do |data|
          out.write(data.read)
        end
      end
    end

    # ..略..
  end
end

保存した画像をPDFに変換

Dir.mktmpdir do |dir|
  Dir.chdir(dir) do

    # ..画像をダウンロード..

    # ダウンロードした画像名を番号順にして保持
    images = Dir.glob("slide-*.jpg")
    images = images.sort_by{|str| str[/\d+/].to_i}

    puts "generating #{pdf_file.path} ..."

    # prawnを使ってPDFを生成
    Prawn::Document.generate(
      pdf_file.path, # 出力ファイル名
      page_size:[1024,768], # 1枚のサイズは1024x768
      margin:0
    ) do
      images.each do |img|
        # imgというファイルパスを画像としてページに追加、という意味
        image(
          img,
          fit:[1024,768]
        )
        start_new_page # 新しいページに移る
      end
    end
  end
end

Webアプリケーション版

Sinatra on Herokuで超シンプルなアプリケーションを作りました。

pi-chan/slideshare-downloader

slideshare-downloader

フォームにslideshareの該当スライドのURLを入れてボタンを押すだけ!超カンタンです。動かないパターンがある気がするのでその場合は教えて欲しいです。