M12i.

学術書・マンガ・アニメ・映画の消費活動とプログラミングについて

Sphinxの拡張機能"sphinx-csharp"に機能を追加

Sphinx拡張機能"sphinx-csharp"に機能を追加したときのメモ。

やりたかったこと

pipを通じてインストールできるSphinx拡張機能"sphinx-csharp"に機能を追加したい。より具体的に言うと、この拡張機能が提供してくれるC#言語用のドメイン(ディレクティブとロールのセット*1)を拡張して、以下の3つをできるようにしたい:

  • メソッドのパラメータに修飾子(ref, out, params)を指定
  • メソッドの修飾子を複数指定
  • クラスのメンバーとしてインデクサーを記述(ディレクティブは.. indexer:: ...、ロールは:idxr:`...`

やったこと

#1. PyPIで調べる

PyPIサイトの"sphinx-csharp"のパッケージ・ページ(ここ)を参照。プロジェクトがGitHub上のリポジトリホスティングされれいることを確認。

f:id:m12i:20170103214529p:plain

#2. GitHubでForkする

まずはこのページに記載されているGitHub上のリポジトリここ)からプロジェクトをFork。私個人のリポジトリとしてPushできるようにしました(Fork先はここ)。

#3. ローカルにクローンを作成

Forkしたリポジトリを元にしてローカルにクローンを作成しました:

$ git clone https://github.com/mizukyf/sphinx-csharp.git

#4. Pythonコードを加筆修正

プロジェクトを構成するPythonスクリプト・ファイルをAtomテキスト・エディタでオープンして、色々変更を行いました。変更内容を知りたい場合は前述のFork後のリポジトリのCommit内容を確認してみてください(コミット一覧)。

#5. Sphinxプロジェクトで動作確認

Pythonコードの修正後、そもそもの動機の根源となっていたSphinxプロジェクト(もちろんC#で実装されたライブラリのAPIリファレンスを執筆しているプロジェクト)の設定ファイルconf.pyを修正:

import os
import sys
sys.path.append(os.path.abspath('/path/to/sphinx-csharp'))

クローンした"sphinx-csharp"が置かれているディレクトリをモジュール検索パスに追加します。生々しいですが、私的な用途なのと当面は動作確認も兼ねて使うことになるのでまあいいでしょう。

上記設定をした上でSphinxプロジェクトのreStructuredTextに追加したマークアップ(ディレクティブとロール)を利用したコードを記述。そしてビルドを行いました。

ふむ、まあまあかな?

構文サンプル

拡張されたメソッドおよびインデクサーのためのマークアップのサンプルを掲載しておきます。リポジトリにもコミットされている"/test/index.rst"を大幅に端折ったものです:

.. default-domain:: csharp

.. namespace:: MyNamespace

.. class:: MyClass

   This is a class with methods and properties.

   Here are some references to it's methods and properties:

       * :meth:`MyClass.MyMethod`
       * :meth:`MyMethod`
       * :prop:`MyClass.MyProperty`
       * :prop:`MyProperty`

   (・・・中略・・・)

   .. method:: int MyMethodHasParamModifiers(ref int arg0, params int[] arg1)

      A method with a parameter modifier.

   .. method:: public static MyMethodHasMultiModifiers()

      A method with multiple method modifiers.

   .. property:: string MyProperty { get; set; }

      A read/write property.

      (・・・中略・・・)

   .. indexer:: string this[int i] { get; set; }

   .. indexer:: string this[int i] { get; }

   .. indexer:: virtual string this[int i] { get; set; }

   .. indexer:: string this[int i, MyClass j] { get; set; }

      (・・・中略・・・)

Indexer ref :idxr:`MyClass.this[]`

*1:SphinxにはAPIを構成するクラスやそのメンバーをディレクティブ(Directive)でマークアップして、同じreStructuredTextファイルや別のファイルの中の対応するロール(Role)でマークアップした箇所から参照できるようにする機能があります。これらのディレクティブとロールはドメイン(Domain)という一種の名前空間を持っており、Python言語やGo言語などそれぞれのプログラミング言語ごとにその名を関したドメイン拡張機能(Extension)として配布されています。

重力キックはやはりイナズマキックだったらしい


『GRAVITY DAZE 2』 GRAVITY DAZE The Animation ~Ouverture~(Face A)

Gravity Daze 2の前日譚を描くアニメ。

「へえ、スタジオ・カラーがアニメ制作ねぇ・・・」と思っていましたが、キトゥンとクロウのダブル・重力キックのシーンで思い出しました。第1作目をプレイしているときに感じた「重力キックってなんかイナズマキックっぽくない?」という疑問もしくは予感を。ネヴィは宇宙怪獣もしくは重力変動源っぽいし、主人公・キトゥンは記憶喪失の重力姫、つまりノノ(記憶喪失)+ラルク(「姫」)だし、そう云えば劇中音楽もともに田中公平氏。

そして今回のアニメ版の問題のシーンはまるっきりそれ、つまり『トップをねらえ2!』の終盤でエグゼリオ変動重力源に対してノノとラルクが繰り出したダブル・イナズマキックでした・・・。カラーの、ということは元Gainaxのということですが、その制作陣お得意の自己流用に、ニヤニヤしてしまいました。

Let's EncryptでSSL証明書を発行・インストールした

「年末年始ならちょっとくらいサーバが止まっていても問題ないよね?」というわけで、月々1000円弱の代金で借り受けている仮想マシンに対して、Let's EncryptでSSL証明書を発行・インストールし、さらに当該サーバ上の名前ベース仮想ホストの1つでホスティングしているWebサイトに対してHTTPSアクセスを強制する設定をしてみました。試みた環境のOSはLinuxディストリビューションCentOS 6.8です。

#1. Let's Encryptの"Getting Started"を読む

まずはLet's Encryptの"Getting Started"を読みました。すごく斜め読みで。"We recommend that most people with shell access use the Certbot ACME client. It can automate certificate issuance and installation with no downtime."とのことなので、そちらのサイトに直行。

f:id:m12i:20170101150848p:plain

#2. Certbotですべきことを知る

Certbotのサイトに行くと、"I'm using <Software> on <System>"というフォームがあるので、「難しいこと考えずとりあえず入力してみる」という安易な対応をしました。今回は私の環境にあわせてソフトウェアとして「Apache」を、システムとして「Cent OS 6」を選びました:

f:id:m12i:20170101150935p:plain

すると自動的に以下のような説明文とコマンド例が表示されました:

f:id:m12i:20170101151402p:plain

#3. Certbotのスクリプトを実行する

これにしたがって以下のようなコマンドを順次実行しました(上述の説明文には書いてないようでしたが、コマンドを実行する前にrootユーザでログインしておきました):

$ su
$ wget https://dl.eff.org/certbot-auto
(・・・中略・・・)
$ chmod a+x certbot-auto
$ ./certbot-auto --apache

#4. ウィザードにしたがって設定を進めていく

前述のコマンドでCertbotのスクリプトを実行すると、yumによる必要なパッケージのインストールをはじめ、各種の設定作業が開始され、途中次のような質問画面が表示されます。まずはSSL証明書をつくるドメイン名です。複数しているする場合はカンマもしくは空白で句切るべしとのこと。今回は"www.unclazz.org,unclazz.org"と入力しました:

f:id:m12i:20170101152134p:plain

その次は各種の通知先として使用されるEメール・アドレスの入力です:

f:id:m12i:20170101152408p:plain

次はLet's Encryptのサービス利用規約に対する同意を求める画面です。[Agree]にフォーカスが当たっていることを確認の上でENTERキーを押します(今更のタイミングでこの質問を受けることにやや違和感がありますが・・・):

f:id:m12i:20170101152607p:plain

次はスクリプトを実行する環境によって選択肢を考えなくてはならないものかもしれません。

We were unable to find a vhost with a ServerName or Address of <先程入力したドメイン名>.
Which virtual host woud you like to choose?
(note: conf files with multiple vhosts are not yet supported)

──というメッセージとともによくわからない一覧が表示されます。メッセージ内容と一覧されているものとの関係性がいまいち理解できません。

結局のところ一覧と行っても私の環境の場合は"ssl.conf"の一択だったので、しばし躊躇した後、しかたなく[Select]にフォーカスが当たっていることを確認の上でENTERキーを押しました:

f:id:m12i:20170101153440p:plain

この質問画面が先程入力したドメイン名の個数x2回くらい表示されます。いえ白状すると、2回目は実は別の質問だったのではとも思うのですが、きちんと読んでおらずキャプチャも撮り忘れていたのでわかりません。。。

ともかく選択肢のない質問を4回切り抜けたあと(今回ドメイン名は2つ指定していたのでそのx2で合計4回)、最後にHTTP(80番ポート)アクセスを強制的にHTTPS(443番ポート)アクセスにリダイレクトする設定を埋め込むかどうかの質問が表示されます:

f:id:m12i:20170101154148p:plain

HTTPでのアクセスが可能だと2つのプロトコルをまたがるサイト・コンテンツのアクセスがあったときに面倒な制御が必要になるケースもあるので、どうせならと"Secure Make all requests redirect to secure HTTPS access"の方を選択しました。

が、これは失敗でした。後ほどの手順でこのオプションを選んだことで自動生成された設定ファイルは除去しています。同一サーバ上で複数の仮想ホストを運用している場合は"Easy ..."を選んでおくのが正解のようです。

これで設定が終わって祝辞が送られます:

f:id:m12i:20170101154532p:plain

#5. *.confの記載内容をカスタマイズする

Certbotのスクリプトによる設定が終わると"le-redirect-www.unclazz.org.conf"と"ssl.conf"(いずれも/etc/httpd/conf.d/配下)が新規作成され、そこにHTTPSアクセス時の設定が記載されていました。

Certbotスクリプトにより表示されていたウィザード画面でも言及されていたとおり、このスクリプトは同一サーバ上で複数の仮想ホストを運用している場合に、これにマッチした設定を自動生成することができないようです(まあたしかに機械的にやるのは難しいですよね)。

というわけで"le-redirect-www.unclazz.org.conf"は削除し(先程ウィザードの最後の質問で"Secure ..."を選択していた場合のみ)、"ssl.conf"の内容を書き換えてカスタマイズしてあげる必要がありました。これをしないとSSL証明書の発行・インストールの過程で指定したドメイン名以外のアクセス(=異なる仮想ホストへのアクセス)でも同一のSSL証明書が使用されてしまい、それらのサイトにアクセスしたとき強制的にHTTPSアクセスに切り替えさせられた挙句にブラウザのセキュリティ警告画面が表示されてしまいます。

"ssl.conf"の下記セクションに追記を行います(赤字の箇所):

##
## SSL Virtual Host Context
##

NameVirtualHost *:443

その下方にあるVirtualHostディレクティブの内容は書き換えて以下のような項目を含むように変更します。とくにVirtualHostディレクティブのパラメータを元の記載にある"_default_"から"*"に切り替えている点に注意してください(赤字の箇所):

<VirtualHost *:443>
(・・・中略・・・)
ServerName www.unclazz.org
ServerAlias unclazz.org *.unclazz.org
(・・・中略・・・)
DocumentRoot /path/to/htdocs
</VirtualHost>

さらに先程削除した"le-redirect-www.unclazz.org.conf"の代わりにhttpd.conf(/etc/httpd/conf/配下)に記載していた仮想ホストの情報も書き換えて、当該仮想ホストへのアクセスのときのみHTTPアクセスをHTTPSアクセスに強制的にリダイレクトする設定を追加します:

<VirtualHost *:80>
ServerName www.unclazz.org
ServerAlias unclazz.org *.unclazz.org
(・・・中略・・・)
# DocumentRoot /path/to/htdocs
(・・・中略・・・)
RewriteEngine On
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [L,QSA,R=permanent]

(・・・中略・・・)
</VirtualHost>

最後にApache Webサーバを再起動して設定を反映させました:

$ service httpd restart

試しにWebブラウザでアクセスをしてみるとちゃんとHTTPSアクセスができました:

f:id:m12i:20170101161331p:plain

めでたしめでたし(例によっていろいろ起こったけどね)。