rcmdnk's blog

Introducing GitHub: A Non-Technical Guide

GistはGitHubのメモみたいなサービスですが、 ちょっとしたコードやパッチを公開するのに便利で 色々な物がGistで公開されています。

使う時にはrawな状態が欲しいのでraw用のURLを使うわけですが、 これに対するURLが今までも色々変わってきていて、 数日前に古いURLの方法が使えなくなってしまった様です。

OctopressでGistを取ってきたりもしてるので、その辺の対応についてなど。

Gistのraw url

上のGistに関して、Gistの通常のURLは

となっていて、

https://gist.github.com(/USER)/GIST_ID

みたいな形になっています。 これに関してUSERを除いてもアクセスできます(上のURLにリダイレクトします)。

このrawなファイルのURLは

となっています。

https://gist.github.com/USER/GIST_ID/raw(/HASH)(/FILE_NAME)

な感じ。

また、URLからFILE_NAMEHASHを除いてもアクセス出来ます。USERは除けません。

ただし、複数のファイルを持つGistの場合、FILE_NAMEを除くと アルファベット順で最初のもの(Gist通常ページで一番上にあるもの)の rawなページにアクセスします。

HASHに関してはGistをアップデートすると変わるので 古いGistもURLが分かればアクセス出来る様になっています。

これは上のGistの古い物。 HASHなしだと最新のものが表示されます。

これが現状。

rawなURLに関しては前にも変更があって、

に書いたように2013年ころに一回大きく変わっています。

最初は

 https://raw.github.com/gist/GIST_ID(/FILE_NAME)

と言った形だったのが

 https://gist.github.com(/USER)/GIST_ID/raw(/HASH)(/FILE_NAME)

と言った形になっていました。

ドメインがgist.github.comになっていますが、 上の現在のものでも

と、gist.github.comを使ってアクセス出来ますが gist.githubusercontent.comにリダイレクトされます。

この変更自体は2014年に行われています。

Gist raw file URI change GitHub Developer Guide

で、つい先日までUSER無しのURLでアクセス出来てたと思いますが、 今はUSERなしだとアクセス出来ない様になっています。

これまでGIST_IDさえわかっていれば最新のGistにはアクセス出来たわけですが、 今はUSERも必要になります。

なのでこれまでGIST_IDだけを使って管理してたりするとちょっと面倒な自体になります。

rawなurlをGIST_IDだけから取得する

ということでUSERというかrawのURLをなんとかGIST_IDだけから取りたいと思うわけですが、 GistにはAPIが用意されているのでそれを叩いて取得してみます。

と、https://api.github.com/gists/GIST_IDにアクセスすると、

{
  "url": "https://api.github.com/gists/4ba41bda1d0cc94f8af33b0f35e008b3",
  ...
  "files": {
    "mygist.txt": {
      "filename": "mygist.txt",
      "type": "text/plain",
      "language": "Text",
      "raw_url": "https://gist.githubusercontent.com/rcmdnk/4ba41bda1d0cc94f8af33b0f35e008b3/raw/6590bc0a36246d60c9574fed05a68337b71c934c/mygist.txt",
      "size": 6,
      "truncated": false,
      "content": "mygist"
    }
  },
  "public": true,
  ...
}

みたいなJSONが取れます。 この中にraw_urlという値があるので、 後はこれを好きな方法で取ってきて使ってあげればOKな訳です。

Octopressのgist_tag.rb

Gistのページに行くと、Embedという表示が右上にあるので ここにあるコードを見ると、

<script src="https://gist.github.com/rcmdnk/4ba41bda1d0cc94f8af33b0f35e008b3.js"></script>

と行った感じのJavaScriptが載っていて、 これをブログなりナンなりに貼り付けるとその場に

こんな感じの表示が出来ます。

このJavaScriptのURLは

https://gist.github.com(/USER)/GIST_ID.js

となっていて、USER部分は省略することが出来ます。

一方、Octopressにはgist_tag.rb という、GIST_IDからGistの表示を作ってくれるプラグインがあります。

この中でやっていることは上のJavaScriptのコードを作る事と、 JavaScriptが無効な場合にrawなファイルを取ってきてそれを直接 表示させる様にすることです。

このrawを取ってくる所で、

gist_tag.rb
1
2
3
def get_gist_url_for(gist, file)
  "https://gist.githubusercontent.com/raw/#{gist}/#{file}"
end

と言った感じのURLを作って居て、これが今はUSERが入ってないのでエラーを出してしまいます。

のでちょっと変更を加えてみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@@ -9,6 +9,7 @@
 require 'digest/md5'
 require 'net/https'
 require 'uri'
+require "json"

 module Jekyll
   class GistTag < Liquid::Tag
@@ -50,7 +51,11 @@
     end

     def get_gist_url_for(gist, file)
-      "https://gist.githubusercontent.com/raw/#{gist}/#{file}"
+      data = JSON.parse(get_web_content("https://api.github.com/gists/#{gist}").body)
+      if file == ""
+        file = data["files"].keys[0]
+      end
+      data["files"][file]["raw_url"]
     end

     def cache(gist, file, data)

こんな感じ。gist_tag.rbには以下の様な get_web_contentという関数が用意されているのでそれを使って データを取得し、JSONをパースして["files"][file]["raw_url"]を取得しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
require 'net/https'
require 'uri'

def get_web_content(url)
  raw_uri           = URI.parse url
  proxy             = ENV['http_proxy']
  if proxy
    proxy_uri       = URI.parse(proxy)
    https           = Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port).new raw_uri.host, raw_uri.port
  else
    https           = Net::HTTP.new raw_uri.host, raw_uri.port
  end
  https.use_ssl     = true
  https.verify_mode = OpenSSL::SSL::VERIFY_NONE
  request           = Net::HTTP::Get.new raw_uri.request_uri
  data              = https.request request
end

gist_tag.rbではファイル名を与える事も出来、 ファイル名がある場合はそのファイルを、 そうでない時は一番最初にあるファイル名を使う様にしています。

これを使うと以下の様な出力が得られます。

<div><script src="https://gist.github.com/4ba41bda1d0cc94f8af33b0f35e008b3.js"></script>
<noscript><pre><code>mygist</code></pre></noscript></div>

下の<noscript>の中に取ってきたrawのコンテンツが入るようになっています。

注意として、 複数ファイルの場合、JavaScriptバージョンだとファイルを指定しないでも 全てのファイルを表示しますが、rawを使ったnoscriptだと一つしか表示しません。

これに関しては、noscriptの方だとファイル名とかも表示してなかったり 色々改善の余地がありますが、取り敢えず以前からこうだったので 以前と同じ様な事は出来る様になっています。

この辺octopress本体にPull Requestを送っても良いんですが、 Octopress(2.x)も、さらにはその将来系のOctopress 3.xの方も 最後の編集が数カ月前で 特にOctopress(2.x)の方はPull Requestが100近く溜まってる状態です。

作者の人はちょっと休んでるんだよ、ということですが1 Octopressは今後どうなっていくのかな、と。 (まあ、取り敢えず今あるものでも暫くは動くので他に移ることは余り考えてませんが。)

Sponsored Links
Sponsored Links

« GNU screenインストール時にutmp.c内でe_terminationが定義されて無い等のエラーが出る場合の対処法 Homebrew Servicesを使ってサービスを管理する »

}