2016年2月25日木曜日

Redmineでクリックすると値が加算されるフィールドを作る

Redmineのカスタムフィールドを使用して、値をクリックすると+1されるフィールドなんてものを作ってみました。早い話が「いいね!」ボタンです。

Wiki Extensionにはvoteがあるのでいいね!が使えますが、チケットにはありません。
 チケットでもやりたくなりいろいろ考えたところ、カスタムフィールドのURLリンク機能を使い、そこにJavascriptを直接記述する、という方法を見つけました。
我ながらなかなかイカス方法と思います。

・環境
Redmine 2.6.5(bitnami)

・設定

(Redmine管理者)
REST APIを有効に。
カスタムフィールドを作成し、整数、初期値0とする。ここでは「いいね!」という名前にしておく。
(プロジェクト担当者)
使うプロジェクトでこのカスタムフィールドを使うように設定。

・jsでのプログラム

下記プログラムを作成。
なお、cfid="1"とありますが、これはカスタムフィールドのIDです。作成したカスタムフィールドのIDに置き換えてください。
あとパスも環境に合わせて直してください。


javascript:
cfid="1";
var keyreq=new XMLHttpRequest();
keyreq.open("GET", "/redmine/my/account", true);
keyreq.onreadystatechange=function(){
        if(keyreq.readyState == 4 && keyreq.status == 200) {
                keyres = keyreq.responseText;
                var key = "";
                result = keyres.match(/\<pre id\=\'api-access-key\'.*\>([0-9a-zA-Z]*)\<\/pre\>/);
                if(result != null){
                        key = result[1];
                }else{
                        alert("ng");
                        return;
                }

                var rreq=new XMLHttpRequest();

                rreq.open("GET", "/redmine/issues/%id%.xml?format=xml&key=" + key, true);
                rreq.onreadystatechange=function(){
                        if(rreq.readyState == 4 && rreq.status == 200){
                                var xml = rreq.responseXML;
                                var value = %value%;
                                cfs = xml.getElementsByTagName("custom_field");
                                for (i = 0; i < cfs.length; i ++) {
if (cfs[i].getAttribute("id") == cfid) {
value = parseInt(cfs[i].getElementsByTagName("value")[0].textContent, 10);
}
                                }

                                var req=new XMLHttpRequest();
                                req.onreadystatechange=function(){
if (req.readyState == 4) {
location.reload()
}
                                };
                                req.open('PUT',"/redmine/issues/" + %id% + ".xml?format=xml&key=" + key);
                                req.setRequestHeader("content-type","application/xml");
                                req.send('<?xml version="1.0" encoding="UTF-8" ?>\n<issue><custom_fields type="array"><custom_field id="' + cfid + '"><value>' + (value + 1).toString(10) + '</value></custom_field></custom_fields></issue>');
                        }
                };
                rreq.send("");

        }
};
keyreq.send("");




これを、一行に直し、カスタムフィールドのリンクURLに設定する。

・動作原理
カスタムフィールドにはリンクを設定できるが、そこにjavascriptのコードが直接書けるようだ。
そこで、カスタムフィールドの更新のコードを入れることでクリックすると更新することが可能になる。

下記3回のアクセスを行っている。
1. keyを取得するために個人設定のページにアクセス
2. 元の値を取るためにGETアクセス(これをしないとチケットを開いてからしばらくたってクリックすると古い値+1で更新してしまう可能性がある)
3. カスタムフィールドの値を更新するためにPUTアクセス

URLリンク欄って結構長いコードも書けるようで驚き。
・免責
最近のRedmineでどうなっているかは不明。
また、プラグインを入れればいいじゃん、というご意見もごもっとも。

※コードはこちらを利用して変換して貼り付け。


2015年7月9日木曜日

Redmine + Backlogs の残り時間の集計表示をGreasemonkeyスクリプトで

要約

Redmine+Backlogs は便利だけど、あるスプリント内の担当者ごとの残り時間の合計がどこにも表示されないのが不便だよね、と思い、Greasemonkeyで手抜き解決した、というお話。


2015年4月25日土曜日

ブロックパズルの解法

ご無沙汰です。
色々あって技術的な研究から離れていましたが、
一旦落ち着きましたので戻ってまいりました。

リハビリを兼ねて久々にLimboを触りました。

たまたまガチャガチャで木のパズルを手に入れました。
下記のように、完成形は3x3x3の立方体になります。
ばらすとひとつづきの木のブロックになりますが、中にゴムひもが通っていて、回すことができます。2または3ブロックおきに曲がり角があります。



手で少しいじってみましたが、すぐに諦め、計算機で解法を求めることにしました。
(手でやるのも面白そうです。意外と色がヒントになりそうです)

3または2このブロックがつながっていて、関節で必ずどちらかの方向にカーブしなければなりません。すべての関節でカーブした結果、立方体に収まっていればOKとなります。
データ構造は意外と単純で、
連続ブロック数 x 節の数
で表されてしまいます。
ブロックの色は考慮しません。
曲がる方向は上下左右の4通り。これが関節数分の組み合わせが発生します。
関節数はこのパズルでは16あったので、4 ^ 16  の組み合わせになります。
40億通りくらい?
(こんなの手で解けるのでしょうか。)

※コードは割愛

ループを単純に回して、総当りさせてみました。
環境はi5 のCPUのWindowsノートパソコン上のACME-SACです。

解かせてみると試した環境では総当りに10時間くらいかかりそうです。
一晩動かしたら気づけば解けていました。(バグによりやりなおして3晩ほどかかりましたが、、、)
検算として実際のパズルに結果を適用すると完成!当たり前とはいえちょっとうれしい。

パフォーマンスですが、ACME-SACの環境(ほぼWindows上のemuと同じでしょうね)では1または2コアをだいたい専有し、全体の2,30%を使うようでした。
シーケンシャルに試していましたが、並行にするだけで結構早くなりそうな予感です。

ただ、それでもすべてのコアを使えないかもしれません。
その場合はemuを複数立ち上げ、分散してやるとフルに活用できるのではないかと
期待しています。

今回はそこまでは手が回りませんでしたが、久々のLimboは楽しかったです。
グリッド試そうかな。
 Goもやらないとな、、、

さて、このパズルプログラミングの題材としては結構適していると思いました。
ループを使ったり、多次元配列をつかったり、言語の機能が色々と試せます。
各試行は独立しているので並行処理もさせやすいです。
新人研修のネタにいいかも。

2012年7月21日土曜日

picoscopeがいい感じでアップデート

手軽なオシロスコープ、picoscopeのソフトウェアがアップデートされていました。
http://www.picotech.com/

いつのまにか日本語対応もちゃんとしているようで、すばらしい。

驚いたのが、シリアルデコードがRS-232Cに対応している点です。
かなり欲しかった機能なので期待大です。

やってみました。


すばらしい使い勝手の良さです。
この例では信号レベルは3.3Vですね。
abcdeとシリアルターミナルで打ち込んで.みました。
トリガーを適当にかけておくと波形が取り込まれ、シリアルとして解釈してくれます。
スレッショルドはトリガーのスレッショルドと連動してくれるので楽。
ボーレートを選べばいきなりデコードしてくれました。
その他の細かい設定も出来るようです。

すごいねこれ。
2chあればtx/rx取れる。
ロジックアナライザいらないじゃん。

2012年5月2日水曜日

flucard でinfernoを動かす

flucard
http://www.flu-card.com/jp/
というSDカードがあります。
これ自身が無線APとなり、デジタルカメラに入れっぱなしでもネットワーク経由で
画像を取り出せるという便利グッヅです。

なお、中身はlinuxであり、telnetでアクセスできたりと
いろいろできるようで、ちょっと前に話題になっていました。
ものすごい熱を発するのでカメラに入れるのはちょっと躊躇してしまいますが、
最小のLinuxマシンとして興味が湧いたので購入しました。

Telnetでログインできることを確認できたので、本題です。
arm-linuxあるところにinfernoあり、ということで、
infernoのポーティングです。
文鎮化が怖いので、 native infernoのポーティングは出来ませんが、
hosted infernoなら行けそう。

目標は、flucardでinfernoを動かし、styxでマウントして
画像を取り出すことです。

・ビルド環境構築

Qemu上のarm-linuxでセルフビルド(あるいみクロスビルド?)を行いました。
Qemuの環境構築については
http://inferno-hell.blogspot.jp/2011/10/qemuarm.html
http://inferno-hell.blogspot.jp/2012/04/lenny-no.html
 あたりを参照。
特に変更は無いはず。

infernoビルドに必要なソフトウェアをapt-getでインストールし、
infernoのソースツリーを持ってきます。
詳細は
http://inferno-hell.blogspot.jp/2011/10/wm.html
このへん。

ーーーこっから嘘情報ーーー
ただし、ソースツリーはtrunkではなく2009年あたりのIPv6対応前のものとします。
hg clone https://inferno-os.googlecode.com/hg/
hg update a682517fc1ec
IPv6対応にすると、host osがv6に対応していないためか、ネットワークアクセス時にエラーとなるようです。
このリビジョンの根拠は、infernoのipv6対応に関するissueが193にあり、日付から、
これより前のリビジョンで当たりをつけました。

最新のツリーとは若干ビルド方法が異なり、
mkconfig編集
パス通す
Linux/arm/bin,lib ディレクトリをそれぞれ作成(無いとエラーになる)
./makemk.sh実行
mk CONF=emu-g install (mk mkdirsはしない)
といった感じでした。
ーーーここまでーーー

ーーー追加ーーー
mkの前に、ipv6のOFFのための作業がいります。
emu/Linux/emu-gを編集し、
ipif6-posixをipif-posixに変更します。
で、./makemk.sh; mk mkdirs; mk CONF=emu-g install
としてビルド。
ーーーここまでーーー

Linux/arm/bin/emu-gが出来上がります。
ldd emu-gでこのプログラムが必要としているライブラリを確認し、
/lib以下の該当ファイルをとっておきます。

・flucardにinferno環境構築

flucardをパソコンに取り付け、infernoのファイルを配置します。

/sd/
  emu-g    ... inferno本体
  lib/         ... ライブラリをおいておく
  inferno/  ... infernoのルート。qemuからもってくのが面倒だったのでOSXから持っていった
  mkln.sh   ... ライブラリのリンクを貼るスクリプトを作成

こんな感じで配置をします。
mkln.shの中身は

#!/bin/sh
ln -s /mnt/sd/lib/ld-linux.so.3 /lib/
ln -s /mnt/sd/lib/libgcc_s.so.1 /lib/
ln -s /mnt/sd/lib/libpthread.so.0 /lib/
ln -s /mnt/sd/lib/libc.so.6 /lib/
ln -s /mnt/sd/lib/libm.so.6 /lib/

といったところ。sd/lib以下のファイルのリンクを/libに張ります。

・flucard上でinferno 起動

flucardをカードリーダーにさして電源を投入するとAPになります。
パソコンでそのAPに接続し、
192.168.1.1にtelnetログインします。
/mnt/sdにSDカードの内容が見えます。
cd /mnt/sd
./mkln.sh
./emu-g -r inferno
でinfernoが立ち上がります。

infernoのシェルで、
bind -c '#U*' /n/local
listen -A tcp!*!1024 {export /&}
と実行します。1024はとりあえずのポート番号で値はなんでもいいです。
これでflucardのSDの中身がstyxで公開されました。

・パソコン側のinfernoの操作

flucardのAPにつながっているパソコンでinfernoを立ち上げます。
絵を扱うのでwm/wmを起動しておきます。

シェルにて
mount -A tcp!192.168.1.1!1024 /mnt
とすると/mntにflucardがマウントされます。
/mnt/n/local/mnt/sd/
にSDカードが見えます。
この中の画像ファイルを探し、

wm/view ファイル名(小文字に直す)

としてやると、画像が表示できます。lsするとファイル名は大文字ですが、そのままだとviewが画像と思ってくれないので、小文字で指定します。





styxで無線経由で画像を取り出せるとは、胸が熱くなります。



ところで、flucardにはウェブインターフェースがあるから、
ウェブ経由で画像を取り出せばいいじゃん、という意見もあるかと思いますが、
まったくそのとおりなのです。
flucardにinfernoいらないじゃん。


charonで192.168.1.1に接続。
残念ながらcharonでは直接画像は表示できませんでしたが、
画像のダウンロードは可能でした。


ところで、画像の縮小表示ってどうやるんだろうね。

AVRでCFタイプのLANカードを制御しようと思ったが

AVR関連で面白いネタを見つけました。

AVRで動かすWebサーバ

というページなのですが、AVRにPCカードタイプのLANカードをさして
サーバーを立てるという試みです。
感銘を受けたため、 自分も真似することにしました。
手元に各種CF/PCMCIAのカードがあったので、機材には困りません。
調べてみると、どれもNE2000互換のカードばかりで、参照元ページとは制御が異なりそうです。

まずはPCカードの基本について書籍で学び、
AVRのピン割り当てを考えました。
Arduinoベースなのでピンアサインはいろいろ悩みました。

で、ピン配置も決まり、そろそろ配線するか、という段になり、
リード線をカードにさしこもうとしたところ、、、





ぬう、リード線がささらない、、、

完。


2012年4月30日月曜日

Lennyのサポート切れ対策

Debian Lennyがサポート切れになり、移行しなければならなくなりましたが、
組み込み系ではいまだにLennyが使われていると思われます。
しばらくはだましだまし使っていこうと思います。

apt-get が使えないのを何とかすれば何とかなりそうです。
/etc/apt/sources.listを書き換えて、apt-get updateしてやればよさそうです。
 (apt-get install debian-archive-keyring もいるの?)

・intel

deb http://archive.debian.org/debian lenny main contrib non-free


・arm(armel)

deb http://archive.debian.org/debian lenny main

こんな感じでいけました。

# お、ブログの編集画面が使いづらくなっていますな。