2016年12月29日木曜日

LibreOffice(calc) マクロとTeraTermマクロを使って簡易リリースツールを作ってみる


WindowsでLibreOffice(calc)BasicマクロとTeraTermマクロを使用した、リリースツールを作ってみます。

リリース先は CentOS6.7です。
Windows側で今回使用するソフトウェアのバージョンは以下のとおり。
Windows10
TeraTerm4.93
LibeOffice5.1.5.2

リリースするファイルと配布先のIPアドレスなどの情報は、CSVファイルに記載することにします。
このCSVファイルを、LibreOfficeで作成し、TeraTermマクロで入力して、ファイル送信します。

TeraTermマクロの仕様は以下のとおり。
TeraTermマクロでファイルを送信するには、サーバ側に openssh-clients パッケージがインストールされている必要があります。
また、文字コード変換には nkf を使用します。
  • CSVファイルを入力する
  • 指示されたサーバにログインする
  • ファイル種別により以下の処理を行う
    • "txt" の場合
      ファイルを送信する
      オーナ、パーミションを設定する
      文字コードをUTF-8、改行コードをLFに変換する
    • "bin" の場合
      ファイルを送信する
      オーナ、パーミションを設定する
    • "cmd" の場合
      指示されたコマンドを実行する
  • デスクトップにTeraTermログファイルを出力する
LibreOffice(calc)Basicマクロの仕様は以下のとおり。
  • CSVファイルを作成する
  • IPアドレス(A列)と送信元ファイル名(B列)でソートする
  • 上記TeraTermマクロを実行する
CSVファイルの項目は以下のとおり
  • IPアドレス
  • 送信元ファイルPATH (txt|bin) または コマンド実行順序(cmd)
  • 送信先ファイルPATH (txt|bin) または コマンド(cmd)
  • オーナ
  • パーミション
  • 種別
    • txt : テキストファイル
    • bin : バイナリファイル
    • cmd : コマンド
  • 備考

1.TeraTermマクロ


マクロは下記PATHに保存します。
C:\workspace\LibreOfficeマクロ\rel.ttl

CSVファイルは下記PATHに格納されるものとします。
C:\workspace\LibreOfficeマクロ\sample.csv

配布先のサーバには、"root" でログインします
マクロのソースコードは以下のとおり。

;
; リリース
;
; [注意]
; サーバ側に下記パッケージがインストール済みであること
;  - openssh-clients
;  - nkf

; SSH接続アカウント情報
remote_prompt = '#'
remote_user = 'root'
remote_pass = 'p@ssw0rd'

; リリースするファイルのリスト
csvfile = 'C:\workspace\LibreOfficeマクロ\sample.csv'
separator = ','
 
; 読み取り専用でCSVファイルを開く
fileopen fh csvfile 0 0

; 1行読み飛ばし
filereadln fh buf

old_ip = '0'
while 1
    ; 1 行入力
    filereadln fh buf
    if result then
        break
    endif

    ; フィールド入力
    strsplit buf separator
    ip = groupmatchstr1
    src = groupmatchstr2
    dst = groupmatchstr3
    owner = groupmatchstr4
    mode = groupmatchstr5
    type = groupmatchstr6

    ; ログイン
    strcompare old_ip ip
    if result != 0 then

        ; IPが変わったら接続中のTerminalを ログアウト
        strcompare old_ip '0'
        if result != 0 then
            sendln 'exit'
            unlink
        endif

        ; ログイン
        sprintf2 conbuf '%s /ssh /auth=password /user=%s /passwd=%s' ip remote_user remote_pass
        connect conbuf
        if result != 2 then
            messagebox 'teraterm macro could not connect to this Server.' 'Error'
            end 
        endif

        ; ログイン待ち
        timeout = 3
        wait remote_prompt
        if result == 0 then 
            disconnect 0 
            end 
        endif
        old_ip = ip

        ; ログファイル
        getspecialfolder log_path 'Desktop'
        getdate log_name '\&h_%Y%m%d_%H%M%S.log'
        strconcat log_path log_name
        logopen log_path 0 1

        ; 接続先情報
        sendln 'date ; uname -n ; whoami'
        wait remote_prompt

    endif

    strcompare type 'cmd'
    if result == 0 then

        sendln dst
        wait remote_prompt

    else

        ; ローカルからリモートへファイル送信
        scpsend src dst

        ; 送信完了まで待機. 徐々に pause 時間を増やす
        n = 1
        while 1
            msec = 800 * n
            mpause msec
            sprintf2 cmdbuf 'ps -ef |grep -v grep |egrep -c "scp .* %s"' dst
            flushrecv
            sendln cmdbuf
            waitln '0' '1'
            if result == 1 then
                break
            endif
            n = n + 1
        endwhile

        ; オーナ設定
        sprintf2 cmdbuf 'chown %s %s' owner dst
        sendln cmdbuf
        wait remote_prompt

        ; パーミション設定
        sprintf2 cmdbuf 'chmod %s %s' mode dst
        sendln cmdbuf
        wait remote_prompt

        ; UTF8 & LF 変換
        strcompare type 'txt'
        if result == 0 then
            sprintf2 cmdbuf 'nkf --overwrite -w -Lu %s' dst
            sendln cmdbuf
            wait remote_prompt
        endif

        ; ファイル情報
        sprintf2 cmdbuf 'ls -l %s ; file %s' dst dst
        sendln cmdbuf
        wait remote_prompt

    endif

endwhile

; ログアウト
strcompare old_ip '0'
if result != 0 then
    sendln 'exit'
    unlink
endif

; CSVファイルクローズ
fileclose fh

end

2.LibreOffice(calc)Basicマクロ


マクロのソースコードは以下のとおり
LibreOffice(calc) > [ツール] > [マクロ] > [マクロの管理] > [LibreOffice Basic] を選択して保存します。
Sub ReleaseStart

    ' 最終行
    Dim oSheet as object
    Dim oCursor as Object
    Dim oRange As Object
    Dim oEndRow as Long
    oSheet = ThisComponent.getSheets().getByIndex(0)
    ThisComponent.CurrentController.setActiveSheet (oSheet)
    oRange = oSheet.getCellRangeByName("A2")
    oCursor = oSheet.createCursorByRange(oRange)
    oCursor.gotoEndOfUsedArea(True)
    oEndRow  =  oCursor.Rows.Count + 1
    
    ' ソート範囲
    Dim sort_info(1) As New com.sun.star.beans.PropertyValue
    Dim sort_fields(1) As New com.sun.star.util.SortField
    oRange = oSheet.getCellRangeByName("A1:G" & oEndRow )
    
    ' ソートキーの列を指定
    sort_fields(0).Field = 0            ' 列番号,0始まり
    sort_fields(0).SortAscending = True ' ASCかどうか
    sort_fields(1).Field = 1            ' 列番号,0始まり
    sort_fields(1).SortAscending = True ' ASCかどうか
    sort_info(0).Name = "SortFields"
    sort_info(0).Value = sort_fields()

    ' ソート範囲に列のヘッダを含むかどうか
    sort_info(1).Name = "ContainsHeader"
    sort_info(1).Value = True

    ' ソート範囲を選択してソート実行
    ThisComponent.getCurrentController().select( oRange )
    oRange.sort( sort_info() )

    ' CSVファイルに保存
    Dim sFilename as String
    Dim args(1) As New com.sun.star.beans.PropertyValue
    sFilename = "C:\workspace\LibreOfficeマクロ\sample.csv"
    args(0).Name = "FilterName"
    args(0).Value = "Text - txt - csv (StarCalc)"
    args(1).Name = "FilterOptions"
    args(1).Value = "44,34,60,1,,0,false,true,true,false"
    ThisComponent.storeToURL(ConvertToUrl(sFilename), args())

    ' ttマクロを実行
    Dim cmd as String    
    cmd = "c:\workspace\teraterm-4.93\ttpmacro.exe /v c:\workspace\LibreOfficeマクロ\rel.ttl"
    shell(cmd,0)

End Sub

3.LibreOffice(calc)にリリース情報登録


下図のように、LibreOffice(calc)の一番左側のシートに、リリース情報を登録します。



4.実行


LibreOffice(calc)の [ツール] > [マクロ] > [マクロを実行] を選択して、上記のマクロを実行します。
実行中は、下図のように、TeraTermのウインドウが表示されます。
また、ファイル転送のたびに、scp のダイアログが表示されます。



TeraTermのログファイルが、IPアドレス単位にデスクトップに出力されます。