ひよっこ。

I want to…

Posts Tagged ‘plugin’

JIRAのプラグインマネージャーをプロキシ経由で有効にする

Posted by hikaruworld : 2012 4月 14

JIRAというよりGreenHooperを試してみたくて、
ちょっとJIRAインストールしていました。

インストール自体は簡単だったんですが、
色々めんどくさいですね試用するだけでも。
ダウンロード先まで迷ってしまいました。

で、本題。

GreenHooperのインストールはJIRAの管理メニューから
プラグインマネージャーというものを利用して行います。

ただし、このプラグインマネージャー、
自分の環境だとproxy経由で接続しており、そのせいでプラグインサイトに接続できません。
プロキシ設定くらいならJIRA管理メニューで設定できんじゃね?と思ったら見つかりません。
ドキュメントに書いてあるかな?と思ったんですが見当たりません。

困ったなーと思いつつ、
JavaでTomcatだしなと思ってcatalina.shでJAVA_OPTSでプロキシ設定をしてみました。
こんな感じの設定をcatalina.shの冒頭に設定します。

JAVA_OPTS="$JAVA_OPTS -Dhttp.proxyHost=ホスト名 -Dhttp.proxyPort=ポート番号 -Dhttp.nonProxyHosts=プロキシを通さないURL"

そうすると無事プラグインマネージャーからGreenHooperをインストールできました。
多分ちゃんとGUIのどこかで設定できるとおもうんですけども….
以上です。

Posted in program | タグ: , , | Leave a Comment »

IPythonの拡張機能を作成する

Posted by hikaruworld : 2012 1月 5

bazaarのプラグインを書こうとしてIPythonを起動したら、
何故かIPythonのエクステンションの書き方を調べてしまったのでログとして残しておきます。

IPythonのextensionの書き方は公式サイトIPython extensionsが参考になります。
サンプルとなるエクステンションは、IPython/extensions以下を見るとよいかと思います。

IPythonでextensionを読み込ませるためには2つの手順が必要になります。

1. IPythonのロード設定

IPython起動時に指定したエクステンションをロードするようにProfileに設定を行います。
前回Profileについては簡単に触れていますが、
エクステンションをロードするときは以下のように設定します。

# A list of dotted module names of IPython extensions to load.
c.InteractiveShellApp.extensions = [
    'hello'
]

2.エクステンションの配備

上記のようにロード設定をした後には、
当然エクステンションを配備してあげる必要があります。
IPythonのエクステンションは

os.path.join(self.ipython_dir, 'extensions')

が認識されます。

つまり、ipython起動時に--ipython-dirを指定していない場合、
デフォルトでは$HOME/.config/ipythonが適用されますので、$HOME/.config/ipython/extensionsを作成すればよい事になります。
今回の例ではhelloというエクステンションを読み込んでいるので、ディレクトリ構成は以下のようになります。

$HOME/.config/ipython
└── extensions
    └── hello.py

※関連部分のみ抜粋

3.エクステンションの書き方

IPython起動時の処理

IPythonが起動/終了した場合に何か処理を行いたい場合、以下の関数を定義する事で自動で読み込まれます。

# 起動時の処理
def load_ipython_extension(ipython):
	pass

# 終了時の処理
def unload_ipython_extension(ipython):
	pass

引数で渡されるipythonはTerminalInteractiveShellやInteractiveShellAppなどのインスタンスになります。

マジックコマンドの設定

IPythonはマジックコマンドが定義されていて、色々便利ですよね。
マジックコマンドって何って人は%入力して<TAB>で一覧が確認出来ます。使い方は%XXX?で確認可能です。

In [3]: %
%alias                   %logstart                %pylab
%autocall                %logstate                %quickref
# いっぱいあるので以下省略。

In [3]: %pwd?
Type:       Magic function
Base Class: <type 'instancemethod'>
String Form:<bound method TerminalInteractiveShell.magic_pwd of <IPython.frontend.terminal.interactiveshell.TerminalInteractiveShell object at 0x1017a5ed0>>
Namespace:  IPython internal
File:       ~/.virtualenvs/bazaar/lib/python2.7/site-packages/IPython/core/magic.py
Definition: %pwd(self, parameter_s='')
Docstring:
Return the current working directory path.

Examples
--------
::

  In [9]: pwd
  Out[9]: '/home/tsuser/sprint/ipython'

で、本題。
エクステンションでも独自のマジックコマンドを定義する事が出来ます。
マジックコマンドを定義したい場合、

define_magic(magicname, func)

で登録する事が可能です。

たとえばsayというマジックコマンドを登録したい場合、この様に読み込ませます。

def say_impl(self, parameter_s=''):
	# sayコマンドの実体。引数はparameter_sに設定される。
    print 'Hello %s' % parameter_s

def load_ipython_extension(ipython):
	# ipythonが起動したタイミングで'say'というコマンドを定義する
	ipython.define_magic('say', say_impl)

これをipythonで起動して、実行するとこんな感じで表示されます。

In [1]: %say taro
Hello taro

マクロなどを定義したい場合はdefine_macro(name, themacro)という関数が準備されています。
自分は必要なかったので確認していませんが…。

以上です。
簡単ですね。日本語情報がないことをのぞけば….

Posted in program | タグ: , , | Leave a Comment »

bazaarのプラグインを作る(2)

Posted by hikaruworld : 2011 12月 26

前回の続きです。

hello_world.pyだと色々とやりづらいので、
plugins以下にhello_worldという形でモジュール化しておきます。

$ ls ~/.bazaar/plugins
hello_world.py
$ cd ~/.bazaar/plugins
$ mkdir hello_world
$ mv hello_world.py hello_world/__init__.py

2-4.helloコマンドに引数を与える

bzr stなどにLOCATIONを指定できるように、
自分で作ったプラグインにもコマンドライン引数を設定する事が可能です。
というわけで、helloコマンドにユーザ名を指定して
hello usernameという形に出力するようにプラグインを拡張してみます。

引数を指定したい場合はtakes_argsというプロパティをクラス内に定義して、
取得したい要素を配列で定義します。そしてそこで定義した値をrun関数の引数で受け取る事が可能です。

# __init__.py
# クラス部分だけ抜粋
class cmd_hello(Command):
    takes_args = ["username?"]
    
    def run(self, username=None):
        print "Hello %s" % username

末尾に?をつけると任意要素に、つけない場合は必須要素になります。
他に末尾に指定できる項目は、?, *, +, $あたりがあるようですが詳しくは追っていません。
bzlib.command.pyの_match_argformを見る感じだと、+だと最低1つは存在し、かつ以降の値をまとめるとかできる感じですね。
詳しくはTODOにして後で検証してみます。
必須項目にしていた場合に設定せずにコマンド起動すると、ちゃんとbzrが叱ってくれます。

bzr: ERROR: command ‘hello’ requires argument USERNAME

2-5.オプションの設定

bzrのコマンドには引数ではなく、各種Optionの設定を行う事が出来ます。
どのコマンドでも利用できる-vや-hと言ったオプションと、例えばremoveコマンド独自の–forceといったような2つに大別されます。
これらのオプションはtakes_optionsをtakes_argsと同じように設定する事で利用が可能になります。

但し、前者(-vや-h)はそのオプション名を文字列で指定すればよいのですが、
独自オプションを作る場合は、個別にOptionクラスRegistryOptionを定義する必要があります。

TODO RegistryOption周りの説明

ここでは、verboseというどのコマンドでも利用可能オプションと、
このコマンド特有のhideというオプションの設定を行います。

# __init__.py
from bzrlib.commands import Command, register_command
from bzrlib.option import Option

class cmd_hello(Command):

    takes_args = ["username"]
    takes_options = [Option("hide", "username print asterisk"), "verbose"]

    def run(self, username, hide=False, verbose=False):
        print "hello %s" % ("*" * len(username) if hide else username)

これで–hideというオプションを設定した場合は出力が***になります

$ bzr hello hogepiyo
hello hogepiyo
$ bzr hello hogepiyo --hide
hello ********

2-6. プラグインのテスト

プラグインのテストはselftestというコマンドで実行する事が可能です。
但し、testtoolsに依存していますので、
存在していないと、こんな感じで怒られます。

bzr: ERROR: No module named testtools
You may need to install this Python library separately.

pipなりeasy_installなりでインストールしておきます。

selftestの仕組みはプラグインにtest_suite関数が定義されていれば自動でテストを実行してくれます。
なので、こんな感じで関数を定義しておきます。

# from hello_world.py
# 対象箇所のみ抜粋
def test_suite():
	pass
    from bzrlib.tests.TestUtil import TestLoader
    import tests.test_hello
    from unittest import TestSuite

    result = TestSuite()

    result.addTest(TestLoader().loadTestsFromModule(tests.test_hello))

これだけだと、テストの実体がないのでテストを読み込んで実行するようにします。
以下のように構成されているとします。

$ cd ~/.bazaar/plugins/hello_world
$ mkdir tests
$ touch tests/__init__.py tests/test_hello.py
$ tree .
.
├── __init__.py
└── tests
    ├── __init__.py
    └── test_hello.py

test_hello.pyを以下のように記述します。

# test_hello.py
from bzrlib.tests import TestCase

class TestHelloWorld(TestCase):
    def test_hello(self):
    	# とりあえず失敗させる
        self.assertEqual(1, 0)

__init__.py側でも該当のモジュール読み込むようにします。
# この辺りはbzrtools辺りのtest_suiteの実装を参考にしています。

# __init__.py
def test_suite():
    from bzrlib.tests.TestUtil import TestLoader
    from unittest import TestSuite

    import tests.test_hello

    result = TestSuite()
    result.addTest(TestLoader().loadTestsFromModule(tests.test_hello))

    return result

pythonのunittest.TestSuiteにaddTestしているだけですね。
TestUtil.TestLoaderはunittest.TestLoaderを拡張しているので基本は同じはず…。

これでselftestを実行してみます。

$ bzr selftest hello_world
FAIL: bzrlib.plugins.hello_world.tests.test_hello.TestBase.test_hellost_hello                                                                                                       
    Empty attachments:
  log

Traceback (most recent call last):
  File "~/.bazaar/plugins/hello_world/tests/test_hello.py", line 6, in test_hello
    self.assertEqual(1, 0)
AssertionError: not equal:
a = 1
b = 0

======================================================================                                                                                                              
FAIL: bzrlib.plugins.hello_world.tests.test_hello.TestBase.test_hello
----------------------------------------------------------------------
_StringException: Empty attachments:
  log

Traceback (most recent call last):
  File "~/.bazaar/plugins/hello_world/tests/test_hello.py", line 6, in test_hello
    self.assertEqual(1, 0)
AssertionError: not equal:
a = 1
b = 0

----------------------------------------------------------------------
Ran 1 test in 0.154s

FAILED (failures=1)

テストが成功するように修正して実行してみます。

# test_hello.py
#self.assertEqual(1, 0)
self.assertEqual(0, 0)
$ bzr selftest hello_world
bzr selftest: /usr/local/Cellar/bazaar/2.4.2/libexec/bzr
   /usr/local/Cellar/bazaar/2.4.2/libexec/bzrlib
   bzr-2.4.2 python-2.6.1 Darwin-10.8.0-i386-64bit

----------------------------------------------------------------------                                                                                                              
Ran 1 test in 0.154s

ok

何も出ませんが、成功しています。
どのテストが実行されたかは、-vをつけると分かります。

running 1 tests...
bzr selftest: /usr/local/Cellar/bazaar/2.4.2/libexec/bzr
   /usr/local/Cellar/bazaar/2.4.2/libexec/bzrlib
   bzr-2.4.2 python-2.6.1 Darwin-10.8.0-i386-64bit

bzrlib.plugins.hello_world.tests.test_hello.TestBase.test_hello                                                                                                       OK        2ms
----------------------------------------------------------------------
Ran 1 test in 0.156s

OK

3. 補足

3-1. プラグインロード時の問題

bzrは起動時にこれらのコマンドを読み込むため、__init__.pyにいわゆる『重い』処理を書いておくと
最初のbzrの起動がとても重くなってしまうそうです(2回目以降はキャッシュされますが…)。
そのための回避策としてチュートリアルには2つ方法が提示されています。

初期の読み込みを最小限にする

bzrの起動時に読み込まれるのが最初の起動ファイル?だけのようです。
ここで記述されている必要があるのがCommandクラスの定義とコマンドの登録のみなので、
それ以外を全て別のファイルに追い出してしまうという方法のようです。

遅延読み込みの実装を行う

lazy_import.lazy_importを利用する方法です。
この方法はコマンドが起動されるまで依存するモジュールの読み込みを遅延できるようです。
ドキュメントやビルドインコマンドでは以下のように読み込まれる事が確認できます。

from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
from bzrlib import (
    branch as _mod_branch,
    option,
    workingtree,
    )
""")

ただ、一部のプラグインは、commands.plugin_cmds.register_lazyを利用して読み込んでいるものもありました。
この辺はまだ調べていないのでTODOで。

3-2. 参考にしたサイト

Developing a plugin

以上です。大体こんな感じでプラグインが作成できます。
簡単ですね。あとはIntegrating with Bazaarあたりを参考にいじっていけると思います。

以上です。

Posted in program | タグ: , , , | Leave a Comment »

bazaarのプラグインを作る(1)

Posted by hikaruworld : 2011 12月 25

bazaarのよいところの一つはpythonで簡単にプラグインを書ける事です。
知ってはいたんですが、作った事なかったのでHelloWorldしてみました。

1.基本的なルール

1-1.プラグインのインストール場所

bzrのプラグインは$HOME/.bazaar/plugins以下に配備すると自動でモジュールをロードしてくれます。
実際にどんなプラグインをインストールしているかは、

bzr plugins

とコマンドを打つことで確認できます。

1-2.参考にする実装

bzrは起動時にビルドインコマンドを読み込みます(bzr infoとかです)。
そのコマンド自体はbzrlib/builtins.pyで定義されているのでプラグインを作成するときには参考にしましょう。

2.helloプラグインの実装

2-1.プラグインの作成

プラグイン自体をbzrに認識させる方法は3つありますが、1つはビルドインコマンドなどが使う方法なので、通常は$HOME/.bazaar/pluginsに配備する方法で実現します。

1つ目のもっとも単純な方法は、plugins以下に任意のpythonファイルを置くことです。
例えば今回の場合であれば、以下のように配置し、bzr pluginsで確認してみると

$ cd ~/.bazaar/plugins
$ touch hello.py

hello
(no description)

という風に認識してくれます。

もう一つは、任意のディレクトリを作成して、__init__.pyを置くことです。
こちらの方が主流ですね(って、スクリプトだけのプラグインってみたことないですが)。

$ cd ~/.bazaar/plugins
$ mkdir hello
$ touch hello/__init__.py

但し、この状態ではプラグインのコマンドなどは定義されていないので、

$ bzr hello

とかやっても、こんな感じで怒られます。

invalid syntax (, line 1)
Unable to load ‘.hello’ in ‘~/.bazaar/plugins’ as a plugin because the file path isn’t a valid module name; try renaming it to ‘_hello’.
bzr: ERROR: unknown command “hello”

2-2.helloコマンドの作成

今回の目的はbzr helloとコマンドを打つと、
標準出力にHello Worldと出力するプラグインなので、
helloコマンドを新しく定義します。

bzrのコマンド(infoやbranchのようなもの)は
bzrlib.commands.Commandクラスを継承して実装する必要があります。
今回はhelloコマンドなので定義だけならこんな感じになります。
Defining a new commandに書いてあるままです。

from bzrlib.commands import Command, register_command

class cmd_hello(Command):
     pass

register_command(cmd_hello)

注意点は、クラス名のprefixとしてcmd_が付与されること、
アンダースコア(_)でつないだ場合にはコマンド時にはハイフンつなぎになる事くらいです。
# cmd_hoge_piyoはhoge-piyoというコマンドになります。

但し、このままではhelloコマンドを実行してもエラーになってしまいます。

bzr: ERROR: exceptions.NotImplementedError: no implementation of command ‘hello’

新しいコマンドを作成した場合は、run関数を実装してあげる必要があります。

from bzrlib.commands import Command, register_command

class cmd_hello(Command):
    def run(self):
        print “Hello World”

register_command(cmd_hello)

これでbzr helloと実行するとHelloWorldと表示してくれるプラグインが出来上がります。

$ bzr hello
Hello World

2-3.helloコマンドのプラグイン情報の記述

bzr pluginsやbzr help XXX(プラグインのコマンドとか)をしてみるとわかりますが、
プラグインにはさまざまなメタ情報が設定されています。

launchpad 2.4.1
Launchpad.net integration plugin for Bazaar.

この設定を行います。

バージョンの記述

バージョンの記述はプラグインを定義しているファイルにversion_infoという値をタプルで定義します。

version_info  = (0, 1, 2, "dev", 0)

上記のように定義してbzr pluginsで確認してみると0.1.2devという風に表示されます。
5番目の要素に0を指定した場合は空気読んで表示されないみたいですね。

プラグインの概要を記述する

bzr pluginsを実行したときにそのプラグインに関する概要が表示されると思います。
この設定もプラグインファイルの冒頭にコメントを記述することで表記可能です。

""" This plugin description"""

複数行書いても概要で表示されるのは1行目だけです。

これでHelloWorldプラグインは完成です。
こんな感じになります。

"""This plugin is print HelloWorld
"""
from bzrlib.commands import Command, register_command

class cmd_hello(Command):
    def run(self):
        print “Hello World”

version_info = (0, 1, 2, "dev", 0)

register_command(cmd_hello)

長くなってきたのでに続きます…。

Posted in program | タグ: , , | Leave a Comment »

vim-ref-html/vim-ref-html5/vim-ref-jsも作ってみた

Posted by hikaruworld : 2011 12月 6

前回に追加。

vim-ref-XXXシリーズ。

表題の通りですが、
vim-ref-htmlvim-ref-html5vim-ref-jsも作ってみました。
リソースは大体formAptanaさん。

tar.gzはこちら。
vim-ref-html
vim-ref-html5
vim-ref-jscore
vim-ref-jsdom

html5はhtmljp5をwgetさせてもらいましたが、w3mとかで見ると不要な情報があるのでarticle辺りで
スクレイピングすると良い感じです。一応scrape.pyもUPしておきます。

wgetのスクリプトもあげてますが利用する場合は自己責任で。

追記

jsdom版も作っておきました。
あとJSに関してはURL指定しても使えるように修正。

Posted in program | タグ: , , , | 1 Comment »

QuickJUnitのvim版が見当たらなかったので、それ風に作ってみた

Posted by hikaruworld : 2011 11月 6

QuickJUnitという、かゆいところに手が届くめちゃ便利なEclipseプラグインがあります。

一言で言うと、ショートカットキーでプロダクトコードとテストコードの簡単に行き来したり、
メソッドレベルで簡単にテストを実行する事が出来ます。

私はEclipse使いなのですが、動的言語はvimで書いたりするので、
vimにもそういったプラグインがないかなーと思って探していたのですが、
見当たらなかったので簡単に作ってみました。

機能としてはシンプルで、プロダクトコードとテストコードをで行き来します。
プロダクトコードがFizz.jsだった場合は相対パス場に存在する./test/Fizz_test.jsを探します。

簡単に実行したい時はQuickRunプラグイン辺りを入れましょう。

対象コードの検索のテスト名やfiletypeでのカスタマイズとか
簡単に実行とか欲しいものはありますが、
とりあえず今求めていた機能はこれがミニマムセットなので、
まぁ、気が向けば拡張しようと思います。

以下コードです。

function! QuickChange()
	let file_rh = expand("%:t:r")
	let index = matchend(file_rh, "_test")
	let file_h = expand("%:p:h")

	if index == -1 || index != strlen(file_rh)
		" main => test
		execute "args" file_h . "/test/" . file_rh . "_test." . expand("%:e") 
	else
		" test => main
		execute "args" file_h . "/../" . expand("%:s?_test??")
	endif
endfunction

" KeyMap
map <C-T> :QuickChange<CR>

" Command
command!	QuickChange		call QuickChange()

一応プラグイン化してbzrにUPしてあります。

以上です。

Posted in program | タグ: , , | Leave a Comment »

flotで日付のaxis表示がずれて焦るなど

Posted by hikaruworld : 2011 2月 25

jQueryのプラグインflotは便利です。
IEでなければ…ですが。

flotにおいて横軸はoptions.xaxisで整形出来ますが、
これに日付を設定していた場合にちょっとはまったのでメモしておきます。

たとえば、こんな風にミリ秒を与えて、xaxisのmodeを利用して整形しようとします。

var ticksData: [1298300400000, 1298905200000 /*...以下省略 */]

xaxis: {
	mode: "time",
	timeformat: "%m/%d",
	ticks: ticksData,
}

期待する値はは2/22,3/1ですが、
出力される結果は2/21,2/28になってしまいます。

これは日付を整形するflotの実装関数$.plot.formatDateが

getUTCDate()

になっているためでした。

まぁ、ローカル時間で渡していて世界標準時間で取ったらずれたという、よくあるパターン…
というわけで、tickFormatterを自分で定義しておきました。

xaxis: {
	ticks: ticksData,
	// 変換ロジックを定義
	tickFormatter: function (v, axis) {
		var d = new Date(v);
		var r = [];
		r.push(d.getMonth() + 1);
		r.push("/");
		r.push(d.getDate());

		return r.join("");
	}
}	

Posted in program | タグ: , , , | Leave a Comment »

jQueryでtablesorterを利用した場合にソートのカスタマイズを行う方法

Posted by hikaruworld : 2011 2月 8

jQuery1.4.4
tablesorter2.0

jQueryのプラグインの一つであるtablesorterを利用すると簡単にテーブルのソート処理を実装する事が出来ます。
基本的に空気を読んでソート処理をしてくれるんですが、
たまにカスタマイズしたくなるので、その方法を忘れないようにメモしておきます。

Parsers for sorting text, URIs, integers, currency, floats, IP addresses, dates (ISO, long and short formats), time. Add your own easily

ドキュメントにあるように、とあるように、基本的には上記のようなフィールドのソートに対応しています。

以下サンプルコードから。addParserでパーサーを設定します

  $.tablesorter.addParser({ 
      // パーサのidを設定
      id: 'grades', 
      // false時に自動でのソートを行わない
      is: function(s) { 
          return false; 
      }, 
      // ソートの実装
      format: function(s) { 
          // 対象の値に対して表示順をindexで指定
          return s.replace(/good/,2).replace(/medium/,1).replace(/bad/,0); 
      }, 
      // set type, either numeric or text 
      type: 'numeric' 
  }); 

利用時はIDを指定して、該当の動作を制御します。

    $(function() { 
        $("table").tablesorter({ 
            headers: { 
                6: { 
                    sorter:'grades' 
                } 
            } 
        }); 
    });                  

以上です。

Posted in program | タグ: , , , | Leave a Comment »

Tracの任意のWikiページをPDF出力するスクリプトを作ったよ(暫定版)

Posted by hikaruworld : 2010 1月 7

TracのPDF出力する方法は、以前の記事でも述べたようにいくつかあります。
が、その中で唯一日本語に対応しているTracWikiExportプラグインは、
残念な事にテーブル内に日本語構成が含まれていた場合にテーブル構造が崩れたり、

{{{#!html}}}

を正しく解釈できないという微妙な問題を含んでいます。

それで困っていたので、簡単にJavaのPDF出力ライブラリのiText5を利用して作ってみました。
サラッと作っただけでまだバグバグですが、コアとなるJavaの部分だけ晒しておきます。
launchpad.netにあげているので、ここからダウンロードできます。
目標としてはAdobeAirを利用したプレビュー機能&ダウンロード機能をつけたいですね。

ちなみに、プラグインとして作らずにAPIを利用して別アプリとして作ったのは、
PDF出力する状況を考えるとTrac上にプラグインとして存在する必要もないかなと思ったので。
むしろ、管理者レベルがある特定のタイミング(納期や外部との打ち合わせ)で利用するだけかなと。

使い方

実行可能jar形式なのでjava -jar で実行してください。
その際引数に、TracのXML-RPCプラグインのURL(認証には未対応),出力先,対象Wikiページ,の指定が必要になります。
以下サンプルです。

java -jar TracPDFConvertor.jar http://localhost:8080/trac/sample/xmlrpc /Output TracGuide,WikiFormatting,Hoge/HelloWorld,Piyo/*

いくつか補足します。
第一引数ではxmlrpcで接続先を指定するのでxmlrpcプラグインが必須です。
ただし、現状では認証に対応していませんので注意してください。

第三引数は、出力したいWikiページをカンマ区切りで指定します。
その際、サブディレクトリ構造を持つWikiページはそのまま指定してください(Hoge/HelloWorld)。
任意のサブディレクトリ構造以下を指定したい場合は*指定が使えます。上記のサンプル(Piyo/*)ではPiyo以下のすべてのWikiページを出力します。

出力結果は以下の通りです。

/Output/TracGuide.pdf
/Output/WikiFormatting.pdf
/Output/Hoge/HelloWorld.pdf
/Output/Piyo/1.pdf
/Output/Piyo/2.pdf

Wikiページ名+.pdfファイル名で出力が行われます。
また、サブディレクトリ指定の場合はサブディレクトリ単位でディレクトリが生成されます。

WikiFormattingの出力結果のファイルを添付しておきます。

TODO

  • AdobeAirのアプリケーションでラップする(JWSとかじゃないのは単なる趣味)
  • Wordへの出力
  • 出力形式の整形
  • Imageなどでリンク先のファイルが存在しない場合にIOExceptionで落ちる
  • スタイルシート及びフォントの設定などをプロパティから読み込めるようにする
  • 接続先Tracのスタイルシート設定の解析

ソースコードはここにあります。

xmlrpcclientで通信して、対象ページのHTMLを取得した後、iTextで書き出しているだけです。
また、外部ライブラリとして、iText5及びApacheXmlRpc、日本語フォントとしてIPAモナーフォントを利用しています。感謝。

以上です。

Posted in program | タグ: , , , , | Leave a Comment »

tracのstandalone.pyでログイン機構を利用する

Posted by hikaruworld : 2009 12月 27

tracには開発用にスタンドアローンで起動可能なスクリプトstandalone.py
trac/web以下に存在しており、大変便利です。

起動は、以前も書いたように

-p 8080 /PATH_TO_TRAC_PROJECT/sample

として、-pで起動ポート番号と対象のtracプロジェクトを指定するのみというお手軽さ。

これはこれで非常に便利なのですが、
権限テストなどを行うような場合はtracのログイン機構を利用したくなります。
要するに認証情報ですね。

tracdで起動した場合、認証機構は無効になっておりLoginを押下しても以下のようなエラーが出ます。

Trac Error
Authentication information not available. Please refer to the installation documentation.
TracGuide — The Trac User and Administration Guide

そのため認証を行いたい場合は、
認証用のhtdigestを作成しておいて、起動時に以下の様に引数を与える必要があります。

-a sample,/trac.htdigest,tracd

以下は認証用のhtdigestファイルです。最後の文字列はmd5でadminというパスワードを暗号化したものです。

admin:tracd:d1d5105feef38ad528a53373c8e5d556

ちなみに、standalone.pyには他にもこんな引数が準備されています(standalone.py -hで確認)。

Usage: standalone.py [options] [projenv] …

Options:
–version show program’s version number and exit
-h, –help show this help message and exit
-a DIGESTAUTH, –auth=DIGESTAUTH [projectdir],[htdigest_file],[realm]
–basic-auth=BASICAUTH [projectdir],[htpasswd_file],[realm]
-p PORT, –port=PORT the port number to bind to
-b HOSTNAME, –hostname=HOSTNAME the host name or IP address to bind to
–protocol=PROTOCOL http|scgi|ajp
-q, –unquote unquote PATH_INFO (may be needed when using ajp)
–http10 use HTTP/1.0 protocol version (default)
–http11 use HTTP/1.1 protocol version instead of HTTP/1.0
-e PARENTDIR, –env-parent-dir=PARENTDIR parent directory of the project environments
–base-path=BASE_PATH the initial portion of the request URL’s “path”
-r, –auto-reload restart automatically when sources are modified
-s, –single-env only serve a single project without the project list
-d, –daemonize run in the background as a daemon
–pidfile=PIDFILE When daemonizing, file to which to write pid
–umask=MASK When daemonizing, file mode creation mask to use, in octal notation (default 022)

以上です。

Posted in program | タグ: , | Leave a Comment »