最近の更新

関連


その他いろいろ

MODxでつくる! 最強のCMSサイト カバー
MODxでつくる! 最強のCMSサイト

はやくMODx 2.0でないかなあ

モバイル機器でビデオを撮影しリアルタイムで配信/保存して公開できるサービス、Qikのビデオのダウンロード方法。

Python2.6で以下をqik_download.pyとして保存。

#!/usr/bin/python
# -*- coding: utf-8 -*-
import re
import urllib2

def get_streamID_for_uri(uri):
        streamID_parser = re.compile(ur'href="http://qik.com/swfs/qikPlayer[0-9]+\.swf\?streamID=([0-9a-f]+)', re.M)
        body = urllib2.urlopen(uri).read()
        streamID = streamID_parser.search(body).group(1)
        return streamID

def get_download_uri(video_uri):
        streamID = get_streamID_for_uri(video_uri)
        flv_uri = 'http://qikimg.com/download/%s.flv' % streamID
        return flv_uri

if __name__=='__main__':
        while True:
                video_uri = raw_input('input your qik video URL > ')
                print get_download_uri(video_uri)

こんな感じで使います。

$ python qik_download.py
input your qik video URL > (ここでビデオのURLを入力) http://qik.com/61xxxx/32xxxxx
http://qikimg.com/download/12xxxxxxxxxxxxxxxxfae.flv
input your qik video URL > ^C (終了)

出力されたURLをブラウザなどで開いて保存します。

前回、シェルスクリプトでsourceすることでCtrl-C (SIGINT)等をキャッチして本当に終了するか尋ねるスクリプトを公開しました。

今回は任意のコマンド実行時に同様の仕掛けを組み込むプログラムnosigを公開します。

nosigをインストールすることで、今まで

$ yourprogram arg1 arg2

としていたコマンドを

$ nosig yourprogram arg1 arg2

とするだけで、Ctr-C等をトラップし、本当に終了して良いか確認するようになります。

実行に何日もかかるようなプログラムを走らせる際などに安心です。

nosigは指定したコマンド以下の全ての子プロセスにこの機構をロードしますが、用途によっては一番上のプロセスだけにロードしたい場合もあるかもしれません。
そのような場合にはnosigの変わりにnosigparentonlyを使ってください。

実行例

$ nosig sleep 20
Signal 2 caught. Are you sure to quit? [y/n] n
continue..
Signal 2 caught. Are you sure to quit? [y/n] y
quit.

ダウンロード・インストール

ダウンロード: nosig-1.0.0.tar.gz

インストールは

$ make
$ sudo make install

アンインストールは

$ sudo make uninstall

とします。

長い作業をしているシェルスクリプトをうっかりCtrl-Cしてしまって悲しい思いをすることはよくあります。

簡単な対処法としてSIGINTを無視するtrap '' 2をスクリプトに加えるというものがありますが、
常に無視されるというのも本当に終了させたいときに手間なものです。(Ctrl-Zでサスペンドしてkill -9など)

そこで、一度Ctrl-Cを押すと本当に終了して良いか質問した上で終了/続行するスクリプトを使ってみます。
(1/26 複数のシグナルを指定すると狂うバグがあったので修正しました)

以下、sigconfirm.sh

#!/bin/bash

# trap handler
function traphandler() {
  # disable SIG* inside this handler
  trap '' $@
  echo -n "Are you sure to quit? [y/n] "
  read c
  if [ "${c/Y/y}x" == 'yx' ]; then echo 'quit'; exit 1; fi
  echo 'continue.'
  trap "traphandler $*" $@
}

# register trap handler for SIG*
trap "traphandler $*" $@

これを自分のスクリプトでsourceすると、

#!/bin/bash

source sigconfirm.sh 2

while :; do echo ':'; sleep 1; done

(引数2は補足するシグナルの種類。source sigconfirm.h 1 2 3 15 のように複数指定できます)

以下のようになります。

$ ./testsigconfirm.sh
:
:
^CAre you sure to quit? [y/n] n
:
:
^CAre you sure to quit? [y/n] y
$

普通にtrapした場合、trap内部の処理中にまたCtrl-Cが押されると終了してしまうのですが、ここではハンドラの内部ではSIGINTを無視するように設定しているため、Ctrl-Cをうっかり連打してしまっても落としてしまうことがありません。

シェルを使っているとテンポラリのディレクトリやバックアップ用tar.gzの作成などで日付を入力したくなることがあります。

一々時計を見て入力するのは面倒で非効率。ここは自動的に入力させたい。
そしてzshの強力な履歴補完を考えると、日付文字列そのままを挿入するより、

$(date +%Y%m%d)

を入れてくれた方が再利用できて助かります。

以下の数行を.zshrcにコピペしましょう。F5でYYYYmmddに展開されるdateコマンド置換が挿入されます。


# insert `date` for YYYYMMDD on F5
function insert_date {
  LBUFFER=$LBUFFER'$(date +%Y%m%d)'
}
zle -N insert_date
bindkey '^[[15~' insert_date

zshでファンクションキーをbindkeyする方法が分からなくて困りましたが、普通にシェル上でC-V F5と押せば^[[15~とでたので、それを使ってみました。

LinuxのWiiリモコン(Wiimote)用ライブラリ、CWiidを用いて、音楽プレーヤSongbirdをコントロールするスクリプトを書いてみました。

操作方法

操作はきわめて単純です。

python wiimote-songbird-*.py

とすると監視プログラムがforkされるので、あとは1+2同時押しで接続し、適当にボタンを押して操作するだけ。電源ボタンを長押し(4秒くらい?)で切断し、再び接続待ちに入ります。

ボタンと動作の対応表

キー 動作
上/下 音量 +/-
左/右 次の曲/前の曲
B 再生・停止トグル

スクリプトのダウンロードはこちらから: wiimote-songbird-20090907.py
MIT Licence. Python 2.5.2, CWiid 0.6.00で動作確認しています。

vimでファイルを新規作成する際、ファイルタイプに応じてテンプレート(orスケルトン)を自動的にロードするためには、.vimrcに以下のような設定を加えることが多いと思います。

autocmd BufNewFile *.py 0r ~/.vim/template/template.py

しかし、決まり切った内容を拡張子ごとに用意するのも芸がなく、
またテンプレートを使いたくない場合や、複数のテンプレートから選びたい場合に対応できません。

そこで、~/.vim/template にあるテンプレートを(複数あればリストアップし)
ロードするか否か選択できるプラグイン、qtmplsel.vimを書いてみました。

インストール

  1. qtmplsel.vim - Quick Template Selector : vim online から最新版をダウンロード
  2. ダウンロードしたスクリプトを $VIMRUNTIME/plugin か ~/.vim/plugin に入れます。

使い方

:e コマンドや vim の起動時に存在しないファイル名を入力して新規作成すると、

ファイルタイプ
ft=pythonなら サーチパス/python_*
拡張子
*.pyなら サーチパス/*.py
ファイル名
ファイル名=Makefile なら サーチパス/Makefile_*

に該当するテンプレートを ~/.vim/template から列挙し、一つ以上該当するものがあればリストを表示します。

リスト上では k(上) / j(下) で項目を選択し、 Enter で決定、 q でキャンセル(ロードしない)となります。

また、グローバル変数g:qts_templatedirを設定することで、任意の場所をテンプレートファイルのサーチパスに設定することができます。

使用例

qtmplsel.vim screenshot

リスト表示部分などQuickBufを参考にしました。

ソースコードを編集しているときにありがちな状況として、一行の先頭や末尾にはそれほど興味がないが、中央付近を編集したいというものがあります。

例えば、今次に示す行の先頭にカーソルがあるとします。

  cord.set_slot(0, boost::shared_ptr<PipelineCallback<Image> >(new PipelineCallback<Image>()));

ここでshared_ptrの中身を書き換えたい場合、ちょっと思いつくだけでも

  1. 検索する /Pi<CR>
  2. カギ括弧へ移動して右 f<l
  3. Pへ移動する fP
  4. 11番目の単語に移動する 11w
  5. カラム指定 37| (エルでもいいけどパイプ)
  6. lllllllllllllllllllllllllllllllllllll

など様々な方法がありますが、2,3,4,5は確実性・直観性に劣り、1はタイプ数に劣り、6はvim使いとして許されざる入力です。この中なら一番まっとうなのは検索でしょうか。
fやtは明らかに次に何処に行くか分かっていれば使い出がありますが、ひとたび変な場所に飛ばされると混乱するのが常です。(vim歴が浅いだけかも知れませんが)

そこで、ここは自分をはじめとする脳の緩いvimユーザのために、最後の6. lllllllllllllllllllllllllllllllllllllに活路を見出そうと思いました。

37回もlをキーリピートするかわりに、最初に行の中央に移動してからlなりhなりで目的の場所へ行こうという方法です。

幸いvimにはvirtualedit/virtcolという、見た目の文字幅を考慮する仕組みが備わっているのでこれをそのまま利用します。

noremap <expr> gm (virtcol('$')/2).'\|'

元々のgmは画面幅に対して中央になるように、カーソルを水平移動するキーですが、あまり使いそうも無いので上書きしてしまいました。

先日はじめてのvimスクリプト(vimでモーション(or選択範囲)をレジスタの内容で置き換えるオペレータ)を書いてみましたが、

Re: vimでモーション(or選択範囲)をレジスタの内容で置き換えるオペレータ @ 7bit - while ("im the true Vim master"); - vimグループ
でアドバイスを頂いたので&自分で他のスクリプト書いて少し慣れたので修正しました。マークやレジスタの退避やらなんやらは不要のような気がしたので除外。

機能的に前回と違うのは、レジスタ指定出来る(しない場合はデフォルトレジスタ)になったこと。v:register退避のためだけに呼ぶ関数がダーティな気はします。

" replace selection with register
function! s:ReplaceMotion(type, ...)
  let reg = empty(s:lastreg) ? '"' : s:lastreg
  let op_mode = 'v'      " default: character
  let marks   = '<>'     " default: visual mode

  if !a:0 " normal mode
    let marks = '[]'
    if a:type == 'line'
      let op_mode = 'V'
    endif
  endif

  exe 'normal! `'.marks[1].'$'
  let paste_cmd = getpos("'".marks[1]) == getpos('.') ? 'p' : 'P'
  exe 'normal! `'.marks[0].'"_d'.op_mode.'`'.marks[1].'"'.reg.paste_cmd
endfunction

function! s:SaveReg()
  let s:lastreg = v:register
endfunction

" default mapping
if !hasmapto('<Plug>ReplaceMotion', 'n')
  nmap <silent> <C-K> <Plug>ReplaceMotion
endif
if !hasmapto('<Plug>ReplaceVisual', 'v')
  vmap <silent> <C-K> <Plug>ReplaceVisual
endif

" export the plugin mapping
nnoremap <silent> <Plug>ReplaceMotion :<C-U>call <SID>SaveReg()<CR><ESC>:set opfunc=<SID>ReplaceMotion<CR>g@
vnoremap <silent> <Plug>ReplaceVisual :<C-U>call <SID>SaveReg()<CR><ESC>:call <SID>ReplaceMotion('', 1)<CR>

~/.vim/plugin/ 以下に放り込んでプラグインとして使います。

a:type==の所が’list’というわけのわからん物になっていたのでlineに直しました

vimユーザなら超絶便利なciw (1単語を削除して挿入)等のオペレータを多用していることと思います。

一応説明すると、vimにおけるオペレータ( c, d など)とは、ノーマルモードで押下したあと「モーション」入力待ちになり、与えられたモーションに対して所定の操作 (削除して挿入, 削除) を行うものです。モーションとしてはhjklやwなどの移動コマンド、もしくはiwやawといったテキストオブジェクトが使えます。

しかしヤンクした内容を貼り付けようとすると、P(貼り付け)してからDb(前方単語削除)などやや面倒な操作が必要になります。 (多分)

そこで、「レジスタの内容で置き換える」オペレータ <C-K> を定義します。オペレータと殆ど同様に使えるv (キャラクタ単位ビジュアル)でも <C-K> により「現在選択中の領域」をレジスタで置き換えられるように、vnoremapも併せて定義します。

nnoremap <silent> <C-K> :set opfunc=ReplaceMotion<CR>g@
vnoremap <silent> <C-K> :<C-U>call ReplaceMotion('', 1)<CR>
function! ReplaceMotion(type, ...)
  let sel_save = &selection
  let &selection = "inclusive"
  let reg_save = @@
  let mark_save = getpos("'a")

  if a:0 " visual mode
    silent exe "normal! '>$"
    if getpos("'>") == getpos('.')
      silent exe 'normal! `<"_d`>"_d$"0p`<'
    else
      silent exe 'normal! `>lma`<"_d`a"0P`<'
    endif
  elseif a:type == 'char' " char motion
    silent exe "normal! ']$"
    if getpos("']") == getpos('.')
      silent exe 'normal! `["_d`]"_d$"0p`['
    else
      silent exe 'normal! `]lma`["_d`a"0P`['
    endif
  endif

  let &selection = sel_save
  let @@ = reg_save
  call setpos("'a", mark_save)
endfunction

これを.vimrcにコピペすれば、

<C-K>3w  → 現在位置から3単語をレジスタの内容で置換
<C-K>i(  → 現在のカーソル位置を含む括弧内部をレジスタの内容で置換
(ビジュアル選択)<C-K> → 選択部分をレジスタの内容で置換

などの操作が可能になります。

デモの動画を撮ってみました。

  1. 「test, yank, words」をヤンクして<C-K>i(によりfunctionの引数内を置換
  2. vimをヤンクして<C-K>iwによりemacsを置換
  3. ビジュアル選択中に<C-K>を押下して選択部分をレジスタで置換

スクリプトの解説をすると、

nnoremapの方では、ノーマルモードでの<C-K>をオペレータとして定義しています。これはオペレータを実行するコマンドg@を利用していて、g@{motion}とするとモーションの開始/終了範囲がマーク[、]として設定された上でopfuncに指定したコールバックが呼ばれます。
<C-K>ではopfuncを設定し、{motion}の所はユーザに任せることで独自のオペレータ定義を可能にしています。

vnoremapではオペレータではなく、単にマーク<, >を利用して同様の動作を実装しています。if文の中でさらに分岐があるのは、削除オペレータdがexclusive=終端を含まない開区間操作であるためです。似たようなことを4つも書いているのであまり綺麗ではありませんが…

追記: 20090706
Re: vimでモーション(or選択範囲)をレジスタの内容で置き換えるオペレータ @ 7bit - while ("im the true Vim master"); - vimグループ

で突っ込まれた内容を踏まえるなどしてちょっと綺麗 & レジスタ指定を可能に しました。

→ vim レジスタで置換するオペレータ 2 @ 7bit

また、削除オペレータがexclusiveという表現は正しくないようで、オペレータのペンディングに対してexclusive/inclusiveがある模様。dwとdvwで比較すると、dvwの方は終端も含んでいる。たぶんそういうことかな…

zshで

cd -[TAB]

とすると、setopt auto_pushdしていた場合は過去にいたディレクトリが

~% cd -
0 -- /home/**/work/dotfiles/.vim  (一番昔)
1 -- /home/**/work/dotfiles
2 -- /home/**/work                (直近)

のように表示されます。しかし、このままタブを押し続けていくと、最も昔にいたディレクトリから順次選択れていくのはやや直感的ではありません。できれば直近にいたディレクトリを優先してリストアップしてほしい。

zstyleのヘルプを見ても’completion:complete:cd:*’でリストを逆順にする方法が分からず、途方に暮れていたところ…

Zsh Workshop: The Directory Stackを見ていて

cd +[TAB]

が目的の動作だったと閃きました。

~% cd +
1 -- /home/**/work
2 -- /home/**/work/dotfiles
3 -- /home/**/work/dotfiles/.vim

ただUS配列では+はシフトが必要で若干面倒なので、setopt pushd_minusとして+と-の意味を入れ替えると良さそうです。

しかしリスト/メニューを逆順にするzstyleが見つからないのは結構問題です。file-sortに関しては’reverse’というオプションがあるらしいですが、それ以外は候補を自分で生成するしかないのでしょうか。

次のページ »