2014年10月9日木曜日

RedmineでWebDAV/FTP/SFTP/SCPブラウズを可能にするHubotスクリプト

まずこの改造版Redmineプラグインを用いて、Redmineチケットの登録と更新をHubotへ通知します。

Hubotでこれを
module.exports = (robot) ->
  robot.router.post "/redmine.json", (req, res) ->
    payload = req.body.payload
    action = payload.action
のように受けます。そしてダウンロード試行関数を呼びます。

download = (robot, issueid, room, relPath) ->
  downloadWsfPath = 'D:\\ore ore\\nanorico_download.wsf'
  # 顧客ID文字列
  userName = 'xxx'

  # ローカルダウンロード先
  localInPath = 'D:\\DL here\\'
  try
    spawn = require('child_process').spawn
    child = spawn 'cscript', ['//nologo', downloadWsfPath, issueid, userName, localInPath, relPath]
  catch e
    robot.messageRoom room, "catch=#{e.description}"

のように、WSFファイルを起動します。

nanorico_download.wsfでは、WinSCPのprotocolの値によって、WebDAV/FTP/SFTP/SCPを選択できます。

var protocol = Protocol_Webdav;
//var protocol = Protocol_Ftp;
顧客ID文字列をもとに接続情報を得たのち(省略)、Redmineチケットで指定されたファイルがあればWinSCPでダウンロードし、なければファイルブラウザをRedmineチケット内に表示させます。ファイルブラウザではWiki記法により、WinSCPで得た各ディレクトリ名・ファイル名に、HubotへのGETリクエストリンクを付けています。

try {
  var session = WScript.CreateObject('WinSCP.Session');
 
  var sessionOptions = WScript.CreateObject('WinSCP.SessionOptions');
  sessionOptions.Protocol = protocol;
  sessionOptions.HostName = hostName;
  sessionOptions.UserName = userName;
  sessionOptions.Password = password;
  if (protocol === Protocol_Ftp) {
    sessionOptions.FtpMode = FtpMode_Active;
  }
  try {
    session.Open(sessionOptions);
    // 指定ファイルがサーバにあるなら
    if (session.FileExists(remotePath)) {
      // ダウンロード中である旨を所在に書き込む
      updateFieldCustom(redmineurl, locationFieldId, 'DOWN...');
   
      // 転送オプション
      var transferOptions = WScript.CreateObject('WinSCP.TransferOptions');
      if (protocol === Protocol_Ftp) {
        transferOptions.TransferMode = TransferMode_Binary;
      }
      // ダウンロード
      session.GetFiles(remotePath, localPath, false, transferOptions).Check();
      // ダウンロード完了した旨を所在に書き込む
      updateFieldCustom(redmineurl, locationFieldId, 'DOWN finished');
    }
    // 指定ファイルがサーバにないなら
    else {
      // ファイルが見つからない旨を所在に書き込む
      updateFieldCustom(redmineurl, locationFieldId, 'Not found');
   
      var relDirPath = '';
      // サーバ上の指定パスディレクトリ内容をシステムメッセージに書き込む
      var remoteDirPath = remoteInPath + relDirPath;
      var directoryInfo = session.ListDirectory(remoteDirPath);
      var links = [];
      for (var enumerator = new Enumerator(directoryInfo.Files); !enumerator.atEnd(); enumerator.moveNext()) {
        var fileInfo = enumerator.item();
        var name = fileInfo.Name;
        if (relDirPath !== '' || name !== '..') {
          var link = '\\"' + name;
          if (fileInfo.IsDirectory === true && name !== '..') {
            link += '/';
          }
          link += '\\":http://localhost:8080/';
          if (fileInfo.IsDirectory) {
            link += 'cd';
          } else {
            link += 'file';
          }
          link += '?issueid=' + encodeURI(issueid) + '&path=' + encodeURI(relDirPath);
          if (name !== '..') {
            link += encodeURI(name);
          }
          links.push(link);
        }
      }
      updateFieldCustom(redmineurl, sysmsgFieldId, 'Files in ' + remoteDirPath + '\\r\\n' + links.join('\\r\\n'));
    }
  } finally {
    session.Dispose();
  }
} catch(e) {
  WScript.Echo('catch=' + e.description);
  updateFieldCustom(redmineurl, sysmsgFieldId, e.description);
}

ファイルへのリンクが押されたら、Hubotスクリプトがこのファイル名をチケットに書き込んだあと、チケット表示をリフレッシュします。500 msより短くすると更新前の値が表示されてしまうことが多かったです。

  robot.router.get "/file", (req, res) ->
    # ファイル名をRedmineチケットに書き込み(略)...
    setTimeout () ->
      res.redirect 'back'
    , 500


同様に、ディレクトリへのリンクが押されたら、Redmineチケット内のファイルブラウザの内容を、そのディレクトリの内容へ書き換えます。

なお、最新betaのWinSCPにはバグがあり、GUIで名前がNFDなディレクトリにいた状態が記憶されていると、濁点・半濁点が?になってしまい、次回GUIアクセス時にエラーが出ます。この状態だと、なんと、.NET AssemblyからWinSCPを呼ぶときもうまくいきません。これに気づくのに1時間ハマりました。

エボラ様症状の日本人女性にインド政府、エボラ検査の必要を認めず、アフリカへ行ってないのでエボラでないと断定

というニュースです。

エボラ検査今やってますというニュースを見たのですが、あれは何だったのでしょうか。

アイドルはトイレするか? 1985年当時の一般認識がよくわかる資料映像

アイドルといえば何と言っても「トイレしない」と言われますが…

岡田有希子 Summer Beach (サマー・ビーチ) - YouTube

そこは否定してくださいw

このあたりが当時、
「お約束をちょっとだけ超えちゃった(笑)」
と一般的に認識されるラインだったのでしょうね。

ちなみに、僕このドラマよく覚えてるんですよ。
ラジオとかで散々ユッコ本人が
「キスシーンあるんです!」
と煽ってましたからね。

上のリンクでも言ってますね。
TBSでフジの番宣が入るというのもおおらかなカンジです。

実際の問題のシーンは、二人の顔が光に覆われて、見えなくなっていました。

かなり長い間、あそこでキスしたかしなかったかについて本人は曖昧にしてきて、だいぶ後になってから
「あれは本当はキスしてないんですよ」
みたいに本人がばらしたような記憶があります。

あのエフェクトだったらそりゃしてないだろと普通は思うとおもいますが…。
本人の口から否定を聞きたいというファン心理はあったようにおもいます。

ファンも大変ウブな時代でした。
とくに彼女のファンはね…。
俺含めて。

蛇足ですが、この歌の出だしはオサマ=ビン=ラディンではありません。

2014年10月8日水曜日

Windows上のnode.jsでchild_process.spawn()する際の、とっても低レベルなハマりポイント

次第に、無人の荒野をひた走っているようなカンジになってきましたが…。
単純に、自社システムにとって最も理想的な動作を最もリーズナブルに開発できる道を求めて進んでいるだけなのに…。
なぜに、気がつけば「誰もいない予感!」みたくなってしまうのであろうか。




あたりを参考に。

Windowsというかコマンドプロンプトちゃんとわかってる方ならこんなとこでハマることはもちろんないとおもいますが。

僕はそういうひとではないので、ここで2時間ぐらいハマりました。

child = spawn 'copy', ['D:\\hoge.eps', 'D:\\hogeb.eps']
動作しません。理由:copyは実行形式ではないので。
※copyするのにspawnするひとはいないとおもいますが、簡単な例ってことで

child = spawn 'cmd', ['/c', 'copy D:\\hoge.eps D:\\hogeb.eps']
修正例。動作した。

child = spawn 'cmd', ['/c', 'copy', 'D:\\hoge.eps', 'D:\\hogeb.eps']
動作しない。理由:copyの引数群は、copyの引数であって、cmdの引数ではないので。

wsfPath = 'D:\\Cambodia Dairoku\\141008 WSHスクリプト\\WinSCP.wsf'
filename​ = 'hoge.eps'
remoteDirPath = '/oreore/oredayo/'
remotePath = remoteDirPath + filename
localDirPath = 'D:\\wode difang\\'
localPath = localDirPath + filename
child = spawn wsfPath, [remotePath, localPath]
動作しない。理由:.wsfは実行形式ではないので。

child = spawn 'cscript', ['//nologo', wsfPath, remotePath, localPath]
修正例。動作した。
cmdの場合と異なり、.wsfへの引数群をcscriptへ個々に託せることはcscriptの仕様としてちゃんと文書化されてますので、これで動作します。
パスに空白文字おもいっきし入ってますが、""なくてOKです。

かぐや姫 とんで初体験(Explzhさんつながりで)

内容こちら

ネットの時代となって久しいが、いまだに、見られないコンテンツはある。

法律を破れ、というつもりはない。

ただ願うのは、お金払ってでも見たいとおもうファンがいるならば、それを容易にする法律にしてほしい、ということである。

主役が後年自殺したとかは、製作陣や、当時の本人には、まったく関係のないことである。

魂のこもらない和訳サイトに意義はあるのか? まじめにやれ

http://www.lifehacker.jp/2014/10/141007productivity.html

あえてリンクとしません。
おすすめリンクではないので。

仕事として日々の惰性で和訳しているのが各文のなげやりな直訳調からまるわかりな訳者というのは、ライフハッカーさんにしても、ほかにも、いるし、それでも和訳がないよりあるほうがまし、という需要もあるでしょう。

にしてもこのページはあまりにひどすぎるとおもった。

とはいえ人様のサイトなので、要は、和訳サイトにそこまで求めるのが間違ってるともいえる。

英語ペラペラになる必要はないが、英語サイトをある程度苦なく読めるようになることは、必要だと、あらためておもった。

2014年10月7日火曜日

海外で失敗する日本人のたったひとつのキーワード

それは「ソファー」だとおもっています。

東南アジアへ来た初日にソファーへ座らされたなら、それはかなりの確率で、あなたが単なる「カモ」であることを示しています。

また、ソファーにみずから座ってしまうようなひとが、現場の何を見れるのか?
この点について、多くを語るまでもありません。

東南アジアを訪れる、あるいは東南アジアに在る日本人として、ソファーとは、ほとんど宗教的に避けるべき存在であると、僕はおもっています。