• redmine 1.3.0にしたら wiki絡みの展開順が変わってた

    自作のwikiマクロの引数で、wikiリンクと同じ記法でリポジトリ上のリソースを指定させている。
    {{macro(source:path/to/file)}}
    
    redmine 1.3.0からwikiリンクとマクロの展開順が変わり、先にwikiリンクが処理されるようになったみたい。
    冒頭のマクロ引数に対してHTMLリンクに展開済の文字列(HTML)が渡ってくるようになった。

      Redmine::WikiFormatting::Macros.register do
        desc '略'
        macro :some_macro do |wiki_content_obj, args|
        end
    end
    1.2.xの場合、args[0]に「source:path/to/file」
    1.3.0の場合、args[0]に「<a href="https://passing.breeze.cc/mt/projects/sample/repository/entry/path/to/file" class="source">source:path/to/file</a>」
    という文字列が渡ってくる。

    「!」をつけると展開抑止になるので当面これで回避。
    {{macro(!source:path/to/file)}}
    

    あるいは引数の受け取り方を変えて
    {{macro(param=source:path/to/file)}}
    
    とすればHTMLリンクに展開されず引数を受け取れる。


  • astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その2


    embed-astah.png
    なんとなくアイデアを書いてからもう4カ月。書いたっきり手つかずで放置してたけど、突然やる気になってみた。

    astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その1

    ソースはgithubに。例によって無保証です。
    tckz's redmine_wiki_astah at master - GitHub

    前のエントリに書いたように、astaファイルから図をエクスポートするのは非常に時間がかかる。だから、wikiマクロでは、エクスポート対象astaファイルをDBに記録するだけにした。そして別途cronなどを使ってエクスポート処理を動かす、という流れ。

    主なfeature

    • wikiマクロ、{{astah_diagram}}を追加。
    • astaファイルは、public配下に置いたものまたは、リポジトリに入れたものを指定できる。
    {{astah_diagram}}マクロ

        {{astah_diagram(public:foo.asta, namespace/diagram)}}
    {{astah_diagram(source:/repo/path/foo.asta, namespace/diagram)}}
    {{astah_diagram(option=value...,public:foo.asta, namespace/diagram)}}

    • astaファイル:
      • public:path/to/.asta
        • RAILS_ROOT/public/配下に置いた.astaを指定する。
        • RAILS_ROOT/public/sample.astaなら、指定する値はpublic:sample.asta
      • source:repo/path/to/.asta
        • リポジトリに格納したastaを指定する。プロジェクトにリポジトリがないと意味がない。
        • wikiのsourceリンク展開と同じように記述。
        • リポジトリの直下にあるsample.astaなら、source:sample.asta
    • 図のpath:
      • Asta*で図をエクスポートした際のpathに準ずる。
      • 図や名前空間に「/」が含まれると、エクスポートの際に「_」に変換される。ので、マクロに指定する値も「_」に変換した値とする。他にもあるかもしれないが不明。
    オプション:
    • align=value
      • 埋め込まれた図のIMG要素に追加するalign属性
      • 例:right, left
    • width=value
      • 埋め込まれた図のIMG要素に追加するwidth属性
      • 例:100px, 100%
    • height=value
      • 埋め込まれた図のIMG要素に追加するheight属性
      • 例:100px, 100%
    • target={_blank|any}
      • 埋め込まれた図のIMG要素に追加するtarget属性
      • 別ウィンドウで開くなら_blank

    インストール

    事前に、astah(のGUI)を実行可能な状態に。↓のエントリで書いたように、図のエクスポートにはGUIが動くように、DISPLAYとライセンスを適切に設定する必要がある。
    astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その1

    1. プラグインをRAILS_ROOT/vendor/plugins/配下に置く。

        #{RAILS_ROOT}/vendor/
          plugins/
            redmine_wiki_astah/
    2. redmine_wiki_astah/run-astah.shを環境に合わせて編集する。
        ASTAH_HOME : Astah*を展開したディレクトリを設定。astah-pro.jarがあるディレクトリ。
        DISPLAY    : 当該環境のディスプレイをポイントする。自分ところでは前のエントリのとおり、vncserverを使っている。
    3. プラグインが使うテーブルを準備。
      rake db:migrate:plugins RAILS_ENV=production
    4. Redmineを再起動
    5. 管理者でredmineにログインする。
    6. プラグインの設定画面で'secret key'に適当な文字列を設定する。
    7. 図のエクスポートを定期的に行うようセットアップする。

    図をエクスポートする

    wikiに埋め込まれたastaをエクスポートして実際の図イメージを作成する。
    Astah.export_diagrams()を定期的に実行する必要がある。

    こんな感じで。
    #{RAILS_ROOT}/script/runner Astah.export_diagrams -e production

    エクスポートしたイメージをredmineを実行しているユーザから参照できるよう、実行ユーザに注意。


    おわり


    astaにたくさん図が含まれるとエクスポートに何分もかかってしまう。
    図のID(astaファイル中の内部的なID。APIで取得できる)があらかじめわかっていれば、特定の図だけをエクスポートすることで短縮もできるが・・・・。
    先のエントリに書いたように、大き目の図が多いせいでwikiに埋め込むと小さい。widthを付けることで収まりはよくなるが、リンクをクリックして図だけを表示しないと読み取るのは難しいかも。

    環境:
      CentOS 5.5 i386
        ruby-1.8.7-p299(from source)
          redmine-1.0.0
          sqlite3-ruby (1.3.1)
        sqlite-3.7.0-1
        astah* pro 6.2




  • astah*で図を書いて redmineの wikiに埋め込むプラグインを考える その1

    uc.png

    UMLその他モデルの作図にJudeを愛用している。
    ・・・というかastah*か。

    astah*で書いた図を、emfで(拡大縮小しても綺麗だから)ワードに張り付けるなどしているが、redmineのwikiに埋め込めるといいのにな~と思っていた。
    もちろん画像で出力してからアップロードすることはできるが面倒。
    せっかくリポジトリにastahのファイルを保管しているのだから、最新の図をwikiに自動反映できたら便利そう。

    最近知ったのだけど、PlantUMLというのがあって、一定の記法で書いたUMLを画像にしてくれるOSSがあるそうだ。じゃあ、astah APIでモデルの情報を抜き出してPlantUML記法で吐きだしたらどうか?と一瞬考えたものの、レンダリング結果がastah上の図とはかなり変わってしまうし、APIで取得できない情報が多数あるのでそもそも再現度が低い。

    やはり図の出力はastah*に任せたい。

    jude時代から、コマンドラインで図出力を実行することができるので、これを呼び出したらいいだろう。
    ※細かいことは、インストール先のCommandRunner.htmlに書いてある。

    自分ところで使っているredmineはどれもlinux上で動いているので、できればlinuxサーバで完結させたい。ということでまずは「linux上でコマンドラインで図出力」する手順を検討した。

    ポイントは以下のとおり。
    • コマンドライン図出力を実行するには、DISPLAY(Xサーバ)が必要。
      • APIの場合はXサーバなしでも動くけど、図出力はdisplayが初期化できないと先に進まない。
      • 図出力用のディスプレイという位置づけで、vncserverを使うことにした。
    • astahライセンスをセットアップする必要がある

    1. ディスプレイを用意

    • 図出力を実行するユーザ向けにvncserverのディスプレイを作る。
    • CentOSの場合、yumリポジトリにvnc-serverがあるのでこれをインストール。
    • 実行ユーザで一回vncserverを起動しておく。
      • 各種ファイルのひな型が作成されるのと、vncserverのパスワード設定を一度に出来るから。
        % vncserver

        You will require a password to access your desktops.

        Password:
        Verify:

        New 'somehost:1 (someuser)' desktop is host:1

        Creating default startup script /home/someuser/.vnc/xstartup
        Starting applications specified in /home/someuser/.vnc/xstartup
        Log file is /home/someuser/.vnc/somehost:1.log
    • 上で起動したvncserverはkillしちゃう。
      で、ひな型をちょこっと編集。CentOSの場合、xstartupは以下の内容になっていた。
      twmが動いていると、Xクライアントがウィンドウを作成するときに出現位置をユーザ操作で指定する流れになるので、図出力の自動化においては邪魔になってしまう。ので、twmの行を削除した。xtermも特に必要ないので削除。
      #!/bin/sh

      # Uncomment the following two lines for normal desktop:
      # unset SESSION_MANAGER
      # exec /etc/X11/xinit/xinitrc

      [ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
      [ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
      xsetroot -solid grey
      vncconfig -iconic &
      #xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
      #twm &
    • システム起動時の自動起動を考慮して/etc/sysconfig/vncserverに設定
      図出力を実行するユーザに合わせて編集。とりあえずディスプレイ番号は2のままにした。ジオメトリはもっと小さくてもいいはず。
      VNCSERVERS="2:someuser"
      VNCSERVERARGS[2]="-geometry 800x600 -nohttpd -localhost"
    • rootでrcスクリプトから起動
      # /etc/init.d/vncserver start
    2. astah*を用意

    • astah*のダウンロードサイトからzipを入手。「JREなし、インストーラなしのアーカイブ」と書かれているもの。
    • 適当な場所にunzipする。
    • 同梱されているastah-command.shは後半がちょいおかしい(pro 6.1.1)ので、ちびっと修正して、とりあえず同じディレクトリに「run.sh」という名前で保存した。実行権限を忘れない。
      #!/bin/sh

      ASTAH_HOME=`cd \`dirname $0\` && pwd`

      INITIAL_HEAP_SIZE=64m
      MAXIMUM_HEAP_SIZE=1024m
      STACK_SIZE=3m

      JAVA_OPTS="-Xms$INITIAL_HEAP_SIZE -Xmx$MAXIMUM_HEAP_SIZE -Xss$STACK_SIZE"

      java $JAVA_OPTS -cp "$ASTAH_HOME/astah-pro.jar" com.change_vision.jude.cmdline.JudeCommandRunner $*

    • ライセンスを配置。
      自分ところはJUDEのユーザライセンスがサポート時効前なのでJUDEのライセンスで。
      $HOME/.astah/professional/JUDE_License_User_Professional.xml
    3. 実行

    • path上にjavaコマンドがあることを確認。なければ適宜pathを通す。
    • 環境変数DISPLAYにvncserverを指定。
      自分はtcshスキーなので以下の通りだが、他のシェルの場合は適宜
      % setenv DISPLAY 127.0.0.1:2
    • 実行
      % /path/to/astah/run.sh -image all -f /path/to/some.asta -o /path/to/dir 

    おわり

    • で、出力されたのが冒頭のpng画像。
    • Windowsで出力したときとフォントが異なるので、見た目の違いはあるけど、元の図がキープされていることに意義はありそう。
    • 元の図が大きくなりがちなので、wikiに張り付けるのに向かないケースも多そう。
    • 図出力にはかなり時間がかかる&出力したい図を指定できない(種類は指定出来る)ので、運用上はcronで出力しておいてどーこーみたいな仕組みも必要っぽい。
    • wikiマクロ的には、.astaファイルと図のpath(名前空間+名前)を指定する感じか。


    環境:
      Windows 7 Ultimate x64
        JRE6 x86
          astah* professional 6.1.1
      CentOS 5.4 x64
        vnc-server-4.1.2-14.el5_3.1
        JRE6 x64
          astah* professional 6.1.1



  • redmine 0.9の Wikiとプラグイン

    Wiki Graphviz macro プラグイン
    例によって無保証です。
    redmineの wikiマクロで graphviz その1
    redmineの wikiマクロで graphviz その2
    redmineの wikiマクロで graphviz その3
    上のwikiマクロをgihubに置いている。
    tckz's redmine-wiki_graphviz_plugin at master - GitHub

    自分ところのredmineはまだ0.8.7なんだけど、早食いな人はもう0.9を使っているらしく、0.9で動かないよ、というメッセージが来た。
    せっせと自分のところでも環境を作って試してみると「Filter chain halted as [:authorize] rendered_or_redirected.」が出ている。

    リンクの作り方がまずいと言えばまずいんだけど、0.8.x時代のWikiのURLと0.9からのURLが異なることが原因みたい。
    0.8.7: http://example.com/wiki/project_id/WikiPage
    0.9-stableブランチ: http://example.com/projects/project_id/wiki/WikiPage
    それでは、とroutes.rbを書き換えてみるも反応なし。
    どうもプラグインROOT/config/routes.rbに置かないと読んでくれないっぽい。

    0.8系でも0.9系でも動くように二か所にroutes.rbを置くことにした。

    プラグインROOT/
     routes.rb ←(1):こっちは(2)をrequireするだけ
     config/
      routes.rb ←(2):redmineが0.9以降かどうかでURLマップを設定しわける

    (1)
    require File.join(File.dirname(__FILE__), "config", "routes.rb")

    (2)
    ActionController::Routing::Routes.draw do |map|

    if (Redmine::VERSION.to_a <=> [0, 9, 0]) >= 0
    # 0.9.0 or higher
    map.connect 'projects/:id/wiki/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'
    else
    map.connect 'wiki/:id/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'
    end
    end

    0.9もfeature freezeしたことだしリリースが待ち遠しい。
    「バージョンに状態(進行中、ロック中、終了)を設定出来て、チケットの編集画面に終了済みバージョンがドロップダウンに表示されない」機能が地味にうれしい。


    環境:
     CentOS 5.4
      ruby-1.8.7-p248(from source)
      mysql-server-5.0.77-3.el5
      graphviz-2.26.0(from source)
      redmine-0.9-stable branch at 2010/01/07(JST)


  • redmineの wikiマクロで graphviz その3

    Wiki Graphviz macro プラグイン
    例によって無保証です。
    説明はその2の方に。

    今回はハマったことというか知ったこととか。
    以下、redmine-0.8.0RC1前提で。


    redmineのwikiマクロに関して

    • ・{{macro_list}}マクロがデフォルトで入っていて、使えるマクロの一覧を表示できる。知らんかった。。
      • マクロ名と登録時に「desc」で指定した内容が表示される
    • {{include(Foo)}}マクロがデフォルトで入っていて、別ページをincludeできる。知らんかった。。
    • wikiマクロの登録は、Redmine::WikiFormatting::Macros.registerにブロックを渡す。
      • descにはwiki記法が使えるが、今にして思えばtextile以外のフォーマッタを使っている場合にマズイか・・・。
      Redmine::WikiFormatting::Macros.register do
        desc <<'EOF'
    Render graph image from the wiki page which is specified by macro-args.

      !{{graphviz(Foo)}}
      !{{graphviz(option=value...,Foo)}}

    * options are:
    ** format={png|jpg}
    ** layout={dot|neato|fdp|twopi|circo}
    ** target={_blank|any}
    ** with_source
    EOF
        macro :graphviz do |wiki_content_obj, args|
    (略)
    • マクロ本体はmacroにシンボルとブロックを指定する
      • ブロックの引数はWikiContentモデルとマクロの引数に指定した文字列を「,」で分割したArray
        • {{マクロ(引数)}}
    • wiki中の{{マクロ}}の都度ブロックが呼び出される
      • ブロックが返した文字列がマクロ展開後のHTMLとして出力される。
        nilを返すと元のマクロ記述がそのまま表示される
      • プレビュー時、ブロックが呼び出されたときに「プレビュー中のテキスト」を得られない
        • graphviz_meマクロで編集/プレビューしながら図を確認できたら便利だよなぁと思ったら渡ってくるのは保存済みのWikiContentモデルだった。
        • 新しいwikiページをプレビューするとobjにはnilが渡ってくる
      • ブロックはActionView::Baseのインスタンスから呼び出される
        • ブロック内でself.to_sしたら"#<ActionView::Base:0xxxxxxxxx>"だった
        • なのでself.controllerからキャッシュメソッドを呼び出したり出来る
        • graphvizマクロの場合、マクロ展開時(Viewのコンテキスト)、画像表示時(コントローラのコンテキスト)のコードをできるだけ共有したかったので都合がよかった
    • ブロックから例外を飛ばすとwikiビュー内にエラー表示できる
      Error executing the マクロ名 macro (メッセージ)

    redmineプラグインに関して

    • プラグインROOTのinit.rbで登録すると利用可能になる
      Redmine::Plugin.register :wiki_graphviz_plugin do
    • プラグイン固有のコントローラのrouteはプラグインROOTのroutes.rbで追加定義できる
      connect 'wiki/:id/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'

    プラグイン設定関係

    • 管理→プラグイン→(プラグインごとの)設定で表示されるプラグイン設定画面
    • Redmine::Plugin.register時に、settingsで:partialに指定した設定画面を表示できる。
      settings :default => {'cache_seconds' => '0'}, :partial => 'wiki_graphviz/settings'
    • テンプレートはvendor/plugins/プラグイン/app/views/に置く
      • 簡単で便利だけど、:partialの指定を他のプラグインと同じにしてしまうと別のプラグインのテンプレートが適用されてしまうことがある。
      • extra/sample_pluginをセットアップした状態で:partialに同じ値を設定しておいたらsample_pluginの設定ビューが出てきてかなり悩んだ。 
      • わざと存在しないテンプレート名を指定しておくとテンプレートの検索パスがログに出る。これを見る限り、プラグインの検索パスが連結された状態になっているようだ。
        Missing template wiki_graphviz/_settingsi.html.erb in view path 
        ・・・・/redmine-0.8.0_RC1/vendor/plugins/wiki_graphviz_plugin/app/views:
        ・・・・/redmine-0.8.0_RC1/vendor/plugins/sample_plugin/app/views:
        ・・・・/redmine-0.8.0_RC1/app/views 
      • stylesheet_link_tagみたいに:pluginを指定してなんとかしてくれんだろうか
    • プラグインの名前が長すぎると、設定値を保存できるが再表示した際に値が正しく表示されない(デフォルト値が表示される)
    mysql> desc settings;
    +------------+-------------+------+-----+---------+----------------+
    | Field      | Type        | Null | Key | Default | Extra          |
    +------------+-------------+------+-----+---------+----------------+
    | id         | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name       | varchar(30) | NO   |     |         |                |
    | value      | text        | YES  |     | NULL    |                |
    | updated_on | datetime    | YES  |     | NULL    |                |
    +------------+-------------+------+-----+---------+----------------+
    • 以前は「redmine_wiki_graphviz_plugin」という名前にしていた。redmine内部で「plugin_」が前置されて35文字になり、切れているのが原因っぽいが深追いしてない。プラグイン名を短くした。
    mysql> select * from settings;
    (中略)
    | 24 | plugin_redmine_wiki_graphviz_p | --- !map:HashWithIndifferentAccess
    cache_seconds: "2300"
    | 25 | plugin_wiki_graphviz_plugin    | --- !map:HashWithIndifferentAccess
    cache_seconds: "3600"
    (後略)

    Railsに関して
    ※redmine-0.8.0RC1同梱のもの。2.1?

    キャッシュ関係
    • config/environments/環境.rbに設定することで有効になる
      config.action_controller.perform_caching             = true
      config.action_controller.cache_store = :mem_cache_store, "localhost"
    • cache_storeの挙動が微妙に違う。
      • デフォルトのActiveSupport::Cache::MemoryStoreはrubyオブジェクトを格納/取り出しできる。当然といえば当然。
      • ActiveSupport::Cache::FileStoreは文字列前提
      • ActiveSupport::Cache::MemCacheStoreは、(内部で使っているMemCacheの挙動で)値の格納/取り出し時にマーシャリングが行われるので結果的にrubyオブジェクトを(大体)格納できる。
        • :rawオプションでマーシャリングをナシにできる。
    • Catalyst::Plugin::CacheのイメージでいたのでFileStoreからHashが復元されず「おっかしいな~?」てことになった。結局Graphvizマクロプラグインではmemcachedだけ対応とした。

    • ・viewからHEADに何か差し込みたい場合はcontent_forが使える。これは便利な仕組みだな~。
      <% content_for :header_tags do %>
         <%= stylesheet_link_tag "wiki_graphviz.css",
             :plugin => "wiki_graphviz_plugin", :media => :all %>
      <% end %>
    • 画像を出力するときは:text&:content_type指定かつlayoutナシのrender。
      render :text => img, :layout => false, :content_type => "image/png"
    • しかし、charsetをつけられてしまう。。。
      ActionController::Baseのassign_default_content_type_and_charsetを見るにContent-Transfer-Encodingがbinaryに設定されていないとデフォルトのcharsetがついてしまうようだ・・。